spacecode 2.5.5 → 2.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/repl.mjs +165 -2
- package/package.json +1 -1
package/dist/repl.mjs
CHANGED
|
@@ -6103,6 +6103,38 @@ var init_skill_prompt = __esm({
|
|
|
6103
6103
|
}
|
|
6104
6104
|
});
|
|
6105
6105
|
|
|
6106
|
+
// ../agent/src/import/mcp-json-summary.ts
|
|
6107
|
+
function listMcpSpawns(text) {
|
|
6108
|
+
const result = [];
|
|
6109
|
+
let data;
|
|
6110
|
+
try {
|
|
6111
|
+
data = JSON.parse(text);
|
|
6112
|
+
} catch {
|
|
6113
|
+
return result;
|
|
6114
|
+
}
|
|
6115
|
+
if (typeof data !== "object" || data === null) return result;
|
|
6116
|
+
const mcpServers = data["mcpServers"];
|
|
6117
|
+
if (typeof mcpServers !== "object" || mcpServers === null) return result;
|
|
6118
|
+
for (const [name, value] of Object.entries(mcpServers)) {
|
|
6119
|
+
if (typeof value !== "object" || value === null) continue;
|
|
6120
|
+
const entry = value;
|
|
6121
|
+
const command = entry["command"];
|
|
6122
|
+
if (typeof command !== "string") continue;
|
|
6123
|
+
const argsRaw = entry["args"];
|
|
6124
|
+
const args = Array.isArray(argsRaw) ? argsRaw.filter((a) => typeof a === "string") : [];
|
|
6125
|
+
const envRaw = entry["env"];
|
|
6126
|
+
const envNames = typeof envRaw === "object" && envRaw !== null ? Object.keys(envRaw).sort() : [];
|
|
6127
|
+
result.push({ name, command, args, envNames });
|
|
6128
|
+
}
|
|
6129
|
+
result.sort((a, b2) => a.name.localeCompare(b2.name));
|
|
6130
|
+
return result;
|
|
6131
|
+
}
|
|
6132
|
+
var init_mcp_json_summary = __esm({
|
|
6133
|
+
"../agent/src/import/mcp-json-summary.ts"() {
|
|
6134
|
+
"use strict";
|
|
6135
|
+
}
|
|
6136
|
+
});
|
|
6137
|
+
|
|
6106
6138
|
// ../agent/src/index.ts
|
|
6107
6139
|
var init_src = __esm({
|
|
6108
6140
|
"../agent/src/index.ts"() {
|
|
@@ -6151,6 +6183,7 @@ var init_src = __esm({
|
|
|
6151
6183
|
init_skill_prompt();
|
|
6152
6184
|
init_skill_tool();
|
|
6153
6185
|
init_skill_source();
|
|
6186
|
+
init_mcp_json_summary();
|
|
6154
6187
|
}
|
|
6155
6188
|
});
|
|
6156
6189
|
|
|
@@ -6192,6 +6225,16 @@ var init_api_key = __esm({
|
|
|
6192
6225
|
});
|
|
6193
6226
|
|
|
6194
6227
|
// src/import-gate.ts
|
|
6228
|
+
var import_gate_exports = {};
|
|
6229
|
+
__export(import_gate_exports, {
|
|
6230
|
+
REPO_SOURCE_FILES: () => REPO_SOURCE_FILES,
|
|
6231
|
+
createNodeTrustStore: () => createNodeTrustStore,
|
|
6232
|
+
importGateStatus: () => importGateStatus,
|
|
6233
|
+
nodeTrustFs: () => nodeTrustFs,
|
|
6234
|
+
readRepoSources: () => readRepoSources,
|
|
6235
|
+
sha256: () => sha256,
|
|
6236
|
+
writeTextAtomic: () => writeTextAtomic
|
|
6237
|
+
});
|
|
6195
6238
|
import { createHash, randomUUID } from "node:crypto";
|
|
6196
6239
|
import { chmod, mkdir, readFile, readdir, realpath, rename, writeFile } from "node:fs/promises";
|
|
6197
6240
|
import { dirname as dirname3, join as join2 } from "node:path";
|
|
@@ -6260,7 +6303,12 @@ function nodeTrustFs() {
|
|
|
6260
6303
|
return { readText: readOrNull, writeTextAtomic, realPath: (p) => realpath(p) };
|
|
6261
6304
|
}
|
|
6262
6305
|
function createNodeTrustStore(configDir) {
|
|
6263
|
-
|
|
6306
|
+
let store = trustStores.get(configDir);
|
|
6307
|
+
if (!store) {
|
|
6308
|
+
store = new TrustStore({ fs: nodeTrustFs(), path: join2(configDir, "trust.json"), hash: sha256 });
|
|
6309
|
+
trustStores.set(configDir, store);
|
|
6310
|
+
}
|
|
6311
|
+
return store;
|
|
6264
6312
|
}
|
|
6265
6313
|
async function importGateStatus(deps) {
|
|
6266
6314
|
const lines2 = [];
|
|
@@ -6289,7 +6337,7 @@ async function importGateStatus(deps) {
|
|
|
6289
6337
|
}
|
|
6290
6338
|
return lines2;
|
|
6291
6339
|
}
|
|
6292
|
-
var REPO_SOURCE_FILES, MAX_REPO_SKILL_FILES, MAX_REPO_SKILL_BYTES, sha256;
|
|
6340
|
+
var REPO_SOURCE_FILES, MAX_REPO_SKILL_FILES, MAX_REPO_SKILL_BYTES, sha256, trustStores;
|
|
6293
6341
|
var init_import_gate = __esm({
|
|
6294
6342
|
"src/import-gate.ts"() {
|
|
6295
6343
|
"use strict";
|
|
@@ -6298,6 +6346,7 @@ var init_import_gate = __esm({
|
|
|
6298
6346
|
MAX_REPO_SKILL_FILES = 200;
|
|
6299
6347
|
MAX_REPO_SKILL_BYTES = 256 * 1024;
|
|
6300
6348
|
sha256 = (text) => createHash("sha256").update(text).digest("hex");
|
|
6349
|
+
trustStores = /* @__PURE__ */ new Map();
|
|
6301
6350
|
}
|
|
6302
6351
|
});
|
|
6303
6352
|
|
|
@@ -6706,6 +6755,86 @@ var init_import_claude = __esm({
|
|
|
6706
6755
|
}
|
|
6707
6756
|
});
|
|
6708
6757
|
|
|
6758
|
+
// src/repo-trust-prompt.ts
|
|
6759
|
+
var repo_trust_prompt_exports = {};
|
|
6760
|
+
__export(repo_trust_prompt_exports, {
|
|
6761
|
+
describeRepoSources: () => describeRepoSources,
|
|
6762
|
+
promptRepoTrust: () => promptRepoTrust
|
|
6763
|
+
});
|
|
6764
|
+
function ruleLists(path12, text, lines2, warnings) {
|
|
6765
|
+
let data;
|
|
6766
|
+
try {
|
|
6767
|
+
data = JSON.parse(text);
|
|
6768
|
+
} catch (err) {
|
|
6769
|
+
if (!(err instanceof SyntaxError)) throw err;
|
|
6770
|
+
warnings.push(`${path12}: not valid JSON, nothing from it loads`);
|
|
6771
|
+
return;
|
|
6772
|
+
}
|
|
6773
|
+
const perms = typeof data === "object" && data !== null ? data.permissions : void 0;
|
|
6774
|
+
if (typeof perms !== "object" || perms === null) return;
|
|
6775
|
+
for (const effect of ["allow", "deny", "ask"]) {
|
|
6776
|
+
const list2 = perms[effect];
|
|
6777
|
+
if (!Array.isArray(list2)) continue;
|
|
6778
|
+
for (const rule of list2) if (typeof rule === "string") lines2.push(` ${effect}: ${show(rule)} (${path12})`);
|
|
6779
|
+
}
|
|
6780
|
+
}
|
|
6781
|
+
function describeRepoSources(files) {
|
|
6782
|
+
const out = [];
|
|
6783
|
+
const warnings = [];
|
|
6784
|
+
if (files[".mcp.json"] !== void 0) {
|
|
6785
|
+
let valid = true;
|
|
6786
|
+
try {
|
|
6787
|
+
JSON.parse(files[".mcp.json"]);
|
|
6788
|
+
} catch (err) {
|
|
6789
|
+
if (!(err instanceof SyntaxError)) throw err;
|
|
6790
|
+
valid = false;
|
|
6791
|
+
warnings.push(".mcp.json: not valid JSON, nothing from it loads");
|
|
6792
|
+
}
|
|
6793
|
+
for (const s of valid ? listMcpSpawns(files[".mcp.json"]) : []) {
|
|
6794
|
+
const env3 = s.envNames.length ? ` env: ${s.envNames.join(", ")}` : "";
|
|
6795
|
+
out.push(` spawn: ${show(s.command)} ${s.args.map(show).join(" ")} [server ${show(s.name)}]${env3}`);
|
|
6796
|
+
}
|
|
6797
|
+
}
|
|
6798
|
+
for (const p of [".claude/settings.json", ".claude/settings.local.json"]) {
|
|
6799
|
+
if (files[p] !== void 0) ruleLists(p, files[p], out, warnings);
|
|
6800
|
+
}
|
|
6801
|
+
const names = Object.keys(files).sort();
|
|
6802
|
+
for (const k2 of names) {
|
|
6803
|
+
const m2 = /^\.claude\/commands\/([^/]+)\.md$/.exec(k2);
|
|
6804
|
+
if (m2) out.push(` command: /${show(m2[1]).slice(1, -1)}`);
|
|
6805
|
+
}
|
|
6806
|
+
const skills = /* @__PURE__ */ new Set();
|
|
6807
|
+
for (const k2 of names) {
|
|
6808
|
+
const m2 = /^\.claude\/skills\/([^/]+)\//.exec(k2);
|
|
6809
|
+
if (m2) skills.add(m2[1]);
|
|
6810
|
+
}
|
|
6811
|
+
for (const s of [...skills].sort()) out.push(` skill: ${show(s)}`);
|
|
6812
|
+
if (files["CLAUDE.local.md"] !== void 0) out.push(" instructions: CLAUDE.local.md");
|
|
6813
|
+
return [...warnings.map((w2) => ` warning: ${w2}`), ...out];
|
|
6814
|
+
}
|
|
6815
|
+
async function promptRepoTrust(cwd2, files, io) {
|
|
6816
|
+
io.write(`
|
|
6817
|
+
This repository has Claude Code sources that can run code or change permissions:
|
|
6818
|
+
${cwd2}
|
|
6819
|
+
${describeRepoSources(files).join("\n")}
|
|
6820
|
+
|
|
6821
|
+
`);
|
|
6822
|
+
io.write(" 1) Trust (remembered until these files change)\n 2) Trust for this session only\n 3) Never trust this repo\n 4) Skip (load nothing, ask again next time)\n");
|
|
6823
|
+
const answer = (await io.ask("Choose 1-4 [4]: "))?.trim() ?? "";
|
|
6824
|
+
if (answer === "1") return "trusted";
|
|
6825
|
+
if (answer === "2") return "session";
|
|
6826
|
+
if (answer === "3") return "never";
|
|
6827
|
+
return "skip";
|
|
6828
|
+
}
|
|
6829
|
+
var show;
|
|
6830
|
+
var init_repo_trust_prompt = __esm({
|
|
6831
|
+
"src/repo-trust-prompt.ts"() {
|
|
6832
|
+
"use strict";
|
|
6833
|
+
init_src();
|
|
6834
|
+
show = (s) => JSON.stringify(s);
|
|
6835
|
+
}
|
|
6836
|
+
});
|
|
6837
|
+
|
|
6709
6838
|
// ../../node_modules/es-toolkit/dist/function/debounce.mjs
|
|
6710
6839
|
function debounce(func, debounceMs, { signal, edges } = {}) {
|
|
6711
6840
|
let pendingThis = void 0;
|
|
@@ -103221,6 +103350,40 @@ var rawCount = process.env.LAUNCH_COUNT ? parseInt(process.env.LAUNCH_COUNT, 10)
|
|
|
103221
103350
|
var launchCount = rawCount !== void 0 && Number.isNaN(rawCount) ? void 0 : rawCount;
|
|
103222
103351
|
var yolo = process.argv.includes("--yolo");
|
|
103223
103352
|
var resumeLatest = process.argv.includes("--continue");
|
|
103353
|
+
if (process.stdin.isTTY && process.stdout.isTTY) {
|
|
103354
|
+
try {
|
|
103355
|
+
const { readRepoSources: readRepoSources2, createNodeTrustStore: createNodeTrustStore2 } = await Promise.resolve().then(() => (init_import_gate(), import_gate_exports));
|
|
103356
|
+
const { promptRepoTrust: promptRepoTrust2 } = await Promise.resolve().then(() => (init_repo_trust_prompt(), repo_trust_prompt_exports));
|
|
103357
|
+
const files = await readRepoSources2(process.cwd());
|
|
103358
|
+
if (Object.keys(files).length > 0) {
|
|
103359
|
+
const store = createNodeTrustStore2(process.env.SPACECODE_CONFIG_DIR?.trim() || path11.join(os5.homedir(), ".spacecode"));
|
|
103360
|
+
if (await store.repoStatus(process.cwd(), files) === "untrusted") {
|
|
103361
|
+
const { createInterface } = await import("node:readline/promises");
|
|
103362
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
103363
|
+
try {
|
|
103364
|
+
const decision = await promptRepoTrust2(process.cwd(), files, {
|
|
103365
|
+
write: (t) => {
|
|
103366
|
+
process.stdout.write(t);
|
|
103367
|
+
},
|
|
103368
|
+
ask: async (q2) => {
|
|
103369
|
+
try {
|
|
103370
|
+
return await rl.question(q2);
|
|
103371
|
+
} catch {
|
|
103372
|
+
return null;
|
|
103373
|
+
}
|
|
103374
|
+
}
|
|
103375
|
+
});
|
|
103376
|
+
if (decision !== "skip") await store.setRepo(process.cwd(), files, decision);
|
|
103377
|
+
} finally {
|
|
103378
|
+
rl.close();
|
|
103379
|
+
}
|
|
103380
|
+
}
|
|
103381
|
+
}
|
|
103382
|
+
} catch (err) {
|
|
103383
|
+
process.stderr.write(`Repo trust check failed (${err instanceof Error ? err.message : String(err)}); repo sources stay untrusted.
|
|
103384
|
+
`);
|
|
103385
|
+
}
|
|
103386
|
+
}
|
|
103224
103387
|
var restoreCiVariables = hideCiVariables(process.env, Boolean(process.stdout.isTTY));
|
|
103225
103388
|
var render2;
|
|
103226
103389
|
var App3;
|