mirror of
https://github.com/mksglu/context-mode.git
synced 2026-10-02 04:14:38 +08:00
feat: cross-platform start.mjs + Windows-safe CLI + expanded CI
- Add start.mjs: cross-platform Node.js entry point replacing start.sh - Update plugin.json, .mcp.json: command "node" + start.mjs - CLI: replace rm -rf, cp -r, 2>/dev/null with Node.js fs equivalents - CLI: add cpSync, rmSync to imports for cross-platform file ops - CI: add search-wiring, search-fallback, subagent-budget tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
2be94b0309
commit
728d8417eb
@@ -21,8 +21,8 @@
|
||||
],
|
||||
"mcpServers": {
|
||||
"context-mode": {
|
||||
"command": "sh",
|
||||
"args": ["${CLAUDE_PLUGIN_ROOT}/start.sh"]
|
||||
"command": "node",
|
||||
"args": ["${CLAUDE_PLUGIN_ROOT}/start.mjs"]
|
||||
}
|
||||
},
|
||||
"skills": "./skills/"
|
||||
|
||||
@@ -60,5 +60,14 @@ jobs:
|
||||
- name: Stream cap tests
|
||||
run: npx tsx tests/stream-cap.test.ts
|
||||
|
||||
- name: Search wiring tests
|
||||
run: npx tsx tests/search-wiring.test.ts
|
||||
|
||||
- name: Search fallback tests
|
||||
run: npx tsx tests/search-fallback-integration.test.ts
|
||||
|
||||
- name: Subagent budget tests
|
||||
run: npx tsx tests/subagent-budget.test.ts
|
||||
|
||||
- name: Doctor (verify server starts)
|
||||
run: npx tsx src/cli.ts doctor
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"context-mode": {
|
||||
"command": "sh",
|
||||
"args": ["${CLAUDE_PLUGIN_ROOT}/start.sh"]
|
||||
"command": "node",
|
||||
"args": ["${CLAUDE_PLUGIN_ROOT}/start.mjs"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@
|
||||
"skills",
|
||||
".claude-plugin",
|
||||
".mcp.json",
|
||||
"start.sh",
|
||||
"start.mjs",
|
||||
"README.md",
|
||||
"LICENSE"
|
||||
],
|
||||
|
||||
+12
-11
@@ -13,7 +13,7 @@
|
||||
import * as p from "@clack/prompts";
|
||||
import color from "picocolors";
|
||||
import { execSync } from "node:child_process";
|
||||
import { readFileSync, writeFileSync, copyFileSync, chmodSync, accessSync, readdirSync, constants } from "node:fs";
|
||||
import { readFileSync, writeFileSync, copyFileSync, cpSync, chmodSync, accessSync, readdirSync, rmSync, constants } from "node:fs";
|
||||
import { resolve, dirname } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { homedir } from "node:os";
|
||||
@@ -416,12 +416,12 @@ async function upgrade() {
|
||||
|
||||
// Step 2: Install dependencies + build
|
||||
s.start("Installing dependencies & building");
|
||||
execSync("npm install --no-audit --no-fund 2>/dev/null", {
|
||||
execSync("npm install --no-audit --no-fund", {
|
||||
cwd: srcDir,
|
||||
stdio: "pipe",
|
||||
timeout: 60000,
|
||||
});
|
||||
execSync("npm run build 2>/dev/null", {
|
||||
execSync("npm run build", {
|
||||
cwd: srcDir,
|
||||
stdio: "pipe",
|
||||
timeout: 30000,
|
||||
@@ -432,19 +432,19 @@ async function upgrade() {
|
||||
s.start("Installing files");
|
||||
const items = [
|
||||
"build", "hooks", "skills", ".claude-plugin",
|
||||
"start.sh", "server.bundle.mjs", "package.json", ".mcp.json",
|
||||
"start.mjs", "server.bundle.mjs", "package.json", ".mcp.json",
|
||||
];
|
||||
for (const item of items) {
|
||||
try {
|
||||
execSync(`rm -rf "${pluginRoot}/${item}"`, { stdio: "pipe" });
|
||||
execSync(`cp -r "${srcDir}/${item}" "${pluginRoot}/"`, { stdio: "pipe" });
|
||||
rmSync(resolve(pluginRoot, item), { recursive: true, force: true });
|
||||
cpSync(resolve(srcDir, item), resolve(pluginRoot, item), { recursive: true });
|
||||
} catch { /* some files may not exist */ }
|
||||
}
|
||||
s.stop(color.green("Files installed"));
|
||||
|
||||
// Install production deps in plugin root
|
||||
s.start("Installing production dependencies");
|
||||
execSync("npm install --production --no-audit --no-fund 2>/dev/null", {
|
||||
execSync("npm install --production --no-audit --no-fund", {
|
||||
cwd: pluginRoot,
|
||||
stdio: "pipe",
|
||||
timeout: 60000,
|
||||
@@ -460,8 +460,9 @@ async function upgrade() {
|
||||
const newCacheDir = cacheMatch[1] + newVersion;
|
||||
s.start(`Migrating cache: ${oldDirVersion} → ${newVersion}`);
|
||||
try {
|
||||
execSync(`rm -rf "${newCacheDir}"`, { stdio: "pipe" });
|
||||
execSync(`mv "${pluginRoot}" "${newCacheDir}"`, { stdio: "pipe" });
|
||||
rmSync(newCacheDir, { recursive: true, force: true });
|
||||
cpSync(pluginRoot, newCacheDir, { recursive: true });
|
||||
rmSync(pluginRoot, { recursive: true, force: true });
|
||||
pluginRoot = newCacheDir;
|
||||
s.stop(color.green(`Cache directory: ${newVersion}`));
|
||||
changes.push(`Migrated cache: ${oldDirVersion} → ${newVersion}`);
|
||||
@@ -485,7 +486,7 @@ async function upgrade() {
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
execSync(`rm -rf "${tmpDir}"`, { stdio: "pipe" });
|
||||
rmSync(tmpDir, { recursive: true, force: true });
|
||||
|
||||
changes.push(
|
||||
newVersion !== localVersion
|
||||
@@ -502,7 +503,7 @@ async function upgrade() {
|
||||
p.log.error(color.red("GitHub pull failed") + ` — ${message}`);
|
||||
p.log.info(color.dim("Continuing with hooks/settings fix..."));
|
||||
// Cleanup on failure
|
||||
try { execSync(`rm -rf "${tmpDir}"`, { stdio: "pipe" }); } catch { /* ignore */ }
|
||||
try { rmSync(tmpDir, { recursive: true, force: true }); } catch { /* ignore */ }
|
||||
}
|
||||
|
||||
// Step 3: Backup settings.json
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env node
|
||||
import { execSync } from "node:child_process";
|
||||
import { existsSync } from "node:fs";
|
||||
import { dirname, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
process.chdir(__dirname);
|
||||
|
||||
if (!process.env.CLAUDE_PROJECT_DIR) {
|
||||
process.env.CLAUDE_PROJECT_DIR = process.cwd();
|
||||
}
|
||||
|
||||
// Ensure native module is available
|
||||
if (!existsSync(resolve(__dirname, "node_modules", "better-sqlite3"))) {
|
||||
try {
|
||||
execSync("npm install better-sqlite3 --no-package-lock --no-save --silent", {
|
||||
cwd: __dirname,
|
||||
stdio: "pipe",
|
||||
timeout: 60000,
|
||||
});
|
||||
} catch { /* best effort */ }
|
||||
}
|
||||
|
||||
// Bundle exists (CI-built) — start instantly
|
||||
if (existsSync(resolve(__dirname, "server.bundle.mjs"))) {
|
||||
await import("./server.bundle.mjs");
|
||||
} else {
|
||||
// Dev or npm install — full build
|
||||
if (!existsSync(resolve(__dirname, "node_modules"))) {
|
||||
try {
|
||||
execSync("npm install --silent", { cwd: __dirname, stdio: "pipe", timeout: 60000 });
|
||||
} catch { /* best effort */ }
|
||||
}
|
||||
if (!existsSync(resolve(__dirname, "build", "server.js"))) {
|
||||
try {
|
||||
execSync("npx tsc --silent", { cwd: __dirname, stdio: "pipe", timeout: 30000 });
|
||||
} catch { /* best effort */ }
|
||||
}
|
||||
await import("./build/server.js");
|
||||
}
|
||||
Reference in New Issue
Block a user