spacecode 2.12.1 → 2.12.3
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 +20 -10
- package/dist/index.js.map +3 -3
- package/dist/repl.mjs +239 -39
- package/package.json +1 -1
package/dist/repl.mjs
CHANGED
|
@@ -6904,6 +6904,164 @@ var init_mcp_rpc_pending = __esm({
|
|
|
6904
6904
|
}
|
|
6905
6905
|
});
|
|
6906
6906
|
|
|
6907
|
+
// ../agent/src/import/mcp-sse-parser.ts
|
|
6908
|
+
function createSseParser(onData) {
|
|
6909
|
+
let buffer = "";
|
|
6910
|
+
let dataLines = [];
|
|
6911
|
+
let skipLf = false;
|
|
6912
|
+
function handleLine(line) {
|
|
6913
|
+
if (line === "") {
|
|
6914
|
+
if (dataLines.length === 0) return;
|
|
6915
|
+
const payload = dataLines.join("\n");
|
|
6916
|
+
dataLines = [];
|
|
6917
|
+
onData(payload);
|
|
6918
|
+
return;
|
|
6919
|
+
}
|
|
6920
|
+
if (line.startsWith(":")) return;
|
|
6921
|
+
const colon = line.indexOf(":");
|
|
6922
|
+
if (colon === -1) {
|
|
6923
|
+
if (line === "data") dataLines.push("");
|
|
6924
|
+
return;
|
|
6925
|
+
}
|
|
6926
|
+
if (line.slice(0, colon) !== "data") return;
|
|
6927
|
+
const value = line.slice(colon + 1);
|
|
6928
|
+
dataLines.push(value.startsWith(" ") ? value.slice(1) : value);
|
|
6929
|
+
}
|
|
6930
|
+
return {
|
|
6931
|
+
push(chunk) {
|
|
6932
|
+
buffer += chunk;
|
|
6933
|
+
let start = 0;
|
|
6934
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
6935
|
+
const ch = buffer[i];
|
|
6936
|
+
if (skipLf && i === start && ch === "\n") {
|
|
6937
|
+
skipLf = false;
|
|
6938
|
+
start = i + 1;
|
|
6939
|
+
continue;
|
|
6940
|
+
}
|
|
6941
|
+
skipLf = false;
|
|
6942
|
+
if (ch === "\n") {
|
|
6943
|
+
handleLine(buffer.slice(start, i));
|
|
6944
|
+
start = i + 1;
|
|
6945
|
+
} else if (ch === "\r") {
|
|
6946
|
+
handleLine(buffer.slice(start, i));
|
|
6947
|
+
start = i + 1;
|
|
6948
|
+
if (buffer[i + 1] === "\n") i++, start++;
|
|
6949
|
+
else if (i + 1 === buffer.length) skipLf = true;
|
|
6950
|
+
}
|
|
6951
|
+
}
|
|
6952
|
+
buffer = buffer.slice(start);
|
|
6953
|
+
},
|
|
6954
|
+
end() {
|
|
6955
|
+
buffer = "";
|
|
6956
|
+
dataLines = [];
|
|
6957
|
+
skipLf = false;
|
|
6958
|
+
}
|
|
6959
|
+
};
|
|
6960
|
+
}
|
|
6961
|
+
var init_mcp_sse_parser = __esm({
|
|
6962
|
+
"../agent/src/import/mcp-sse-parser.ts"() {
|
|
6963
|
+
"use strict";
|
|
6964
|
+
}
|
|
6965
|
+
});
|
|
6966
|
+
|
|
6967
|
+
// ../agent/src/import/mcp-http-transport.ts
|
|
6968
|
+
function createHttpTransport(opts) {
|
|
6969
|
+
const aborter = new AbortController();
|
|
6970
|
+
let sessionId = null;
|
|
6971
|
+
let closed = false;
|
|
6972
|
+
let reported = false;
|
|
6973
|
+
const fail = (reason) => {
|
|
6974
|
+
if (closed || reported) return;
|
|
6975
|
+
reported = true;
|
|
6976
|
+
closed = true;
|
|
6977
|
+
aborter.abort();
|
|
6978
|
+
opts.onClose(reason);
|
|
6979
|
+
};
|
|
6980
|
+
const deliver = (parsed) => {
|
|
6981
|
+
for (const m2 of Array.isArray(parsed) ? parsed : [parsed]) opts.onMessage(m2);
|
|
6982
|
+
};
|
|
6983
|
+
const headers = () => ({
|
|
6984
|
+
...opts.headers,
|
|
6985
|
+
"content-type": "application/json",
|
|
6986
|
+
accept: "application/json, text/event-stream",
|
|
6987
|
+
"mcp-protocol-version": opts.protocolVersion,
|
|
6988
|
+
...sessionId !== null ? { "mcp-session-id": sessionId } : {}
|
|
6989
|
+
});
|
|
6990
|
+
async function readStream(res) {
|
|
6991
|
+
if (!res.body) return;
|
|
6992
|
+
const decoder = new TextDecoder();
|
|
6993
|
+
const parser = createSseParser((data) => {
|
|
6994
|
+
let parsed;
|
|
6995
|
+
try {
|
|
6996
|
+
parsed = JSON.parse(data);
|
|
6997
|
+
} catch (err) {
|
|
6998
|
+
if (!(err instanceof SyntaxError)) throw err;
|
|
6999
|
+
return;
|
|
7000
|
+
}
|
|
7001
|
+
deliver(parsed);
|
|
7002
|
+
});
|
|
7003
|
+
for await (const chunk of res.body) parser.push(decoder.decode(chunk, { stream: true }));
|
|
7004
|
+
parser.push(decoder.decode());
|
|
7005
|
+
parser.end();
|
|
7006
|
+
}
|
|
7007
|
+
async function post(message) {
|
|
7008
|
+
const hadSession = sessionId !== null;
|
|
7009
|
+
let res;
|
|
7010
|
+
try {
|
|
7011
|
+
res = await opts.fetch(opts.url, { method: "POST", headers: headers(), body: JSON.stringify(message), signal: aborter.signal });
|
|
7012
|
+
} catch (err) {
|
|
7013
|
+
return fail(`request failed: ${err instanceof Error ? err.name : "error"}`);
|
|
7014
|
+
}
|
|
7015
|
+
if (closed) return;
|
|
7016
|
+
if (res.status === 401 || res.status === 403) return fail("needs authorization (OAuth is not supported)");
|
|
7017
|
+
if (res.status === 404 && hadSession) return fail("session expired");
|
|
7018
|
+
if (res.status >= 400) return fail(`HTTP ${res.status}`);
|
|
7019
|
+
const sid = res.headers.get("mcp-session-id");
|
|
7020
|
+
if (sessionId === null && sid) sessionId = sid;
|
|
7021
|
+
if (res.status === 202) return;
|
|
7022
|
+
const type = (res.headers.get("content-type") ?? "").toLowerCase();
|
|
7023
|
+
try {
|
|
7024
|
+
if (type.startsWith("text/event-stream")) await readStream(res);
|
|
7025
|
+
else if (type.startsWith("application/json")) {
|
|
7026
|
+
let parsed;
|
|
7027
|
+
try {
|
|
7028
|
+
parsed = JSON.parse(await res.text());
|
|
7029
|
+
} catch (err) {
|
|
7030
|
+
if (!(err instanceof SyntaxError)) throw err;
|
|
7031
|
+
return fail("invalid JSON in response");
|
|
7032
|
+
}
|
|
7033
|
+
deliver(parsed);
|
|
7034
|
+
}
|
|
7035
|
+
} catch (err) {
|
|
7036
|
+
fail(`request failed: ${err instanceof Error ? err.name : "error"}`);
|
|
7037
|
+
}
|
|
7038
|
+
}
|
|
7039
|
+
return {
|
|
7040
|
+
send(message) {
|
|
7041
|
+
if (closed) throw new Error(CLOSED);
|
|
7042
|
+
void post(message);
|
|
7043
|
+
},
|
|
7044
|
+
async close() {
|
|
7045
|
+
if (closed) return;
|
|
7046
|
+
closed = true;
|
|
7047
|
+
aborter.abort();
|
|
7048
|
+
if (sessionId === null) return;
|
|
7049
|
+
try {
|
|
7050
|
+
await opts.fetch(opts.url, { method: "DELETE", headers: { ...opts.headers, "mcp-protocol-version": opts.protocolVersion, "mcp-session-id": sessionId } });
|
|
7051
|
+
} catch {
|
|
7052
|
+
}
|
|
7053
|
+
}
|
|
7054
|
+
};
|
|
7055
|
+
}
|
|
7056
|
+
var CLOSED;
|
|
7057
|
+
var init_mcp_http_transport = __esm({
|
|
7058
|
+
"../agent/src/import/mcp-http-transport.ts"() {
|
|
7059
|
+
"use strict";
|
|
7060
|
+
init_mcp_sse_parser();
|
|
7061
|
+
CLOSED = "MCP server connection is closed";
|
|
7062
|
+
}
|
|
7063
|
+
});
|
|
7064
|
+
|
|
6907
7065
|
// ../agent/src/import/mcp-rpc.ts
|
|
6908
7066
|
function createRpcSession(deps) {
|
|
6909
7067
|
const pending = new PendingRequests();
|
|
@@ -7152,6 +7310,8 @@ var init_src = __esm({
|
|
|
7152
7310
|
init_claude_json_mcp();
|
|
7153
7311
|
init_mcp_rpc_message();
|
|
7154
7312
|
init_mcp_rpc_pending();
|
|
7313
|
+
init_mcp_sse_parser();
|
|
7314
|
+
init_mcp_http_transport();
|
|
7155
7315
|
init_mcp_rpc();
|
|
7156
7316
|
init_mcp_tool_result();
|
|
7157
7317
|
init_mcp_client();
|
|
@@ -7809,7 +7969,7 @@ var init_import_claude = __esm({
|
|
|
7809
7969
|
init_api_key();
|
|
7810
7970
|
init_profile_runtime();
|
|
7811
7971
|
init_import_adapt();
|
|
7812
|
-
USAGE = "Usage: spacecode import
|
|
7972
|
+
USAGE = "Usage: spacecode import claude [--dry-run] [--overwrite] [--no-adapt] [--yes] [--restore-original]";
|
|
7813
7973
|
}
|
|
7814
7974
|
});
|
|
7815
7975
|
|
|
@@ -7924,6 +8084,18 @@ var init_stdio_transport = __esm({
|
|
|
7924
8084
|
function approvalEnv(env3) {
|
|
7925
8085
|
return Object.entries(env3).map(([k2, v2]) => `${k2}=${v2}`).sort();
|
|
7926
8086
|
}
|
|
8087
|
+
function approvalKey(def) {
|
|
8088
|
+
const envNames = approvalEnv(def.env);
|
|
8089
|
+
return def.transport === "http" ? { command: `mcp-http:${def.url}`, args: [], envNames } : { command: def.command, args: def.args, envNames };
|
|
8090
|
+
}
|
|
8091
|
+
function isSafeMcpUrl(url) {
|
|
8092
|
+
try {
|
|
8093
|
+
const u3 = new URL(url);
|
|
8094
|
+
return u3.protocol === "https:" || u3.protocol === "http:" && ["localhost", "127.0.0.1", "[::1]"].includes(u3.hostname);
|
|
8095
|
+
} catch {
|
|
8096
|
+
return false;
|
|
8097
|
+
}
|
|
8098
|
+
}
|
|
7927
8099
|
function mcpToolName(server, tool) {
|
|
7928
8100
|
return `mcp__${sanitize2(server)}__${sanitize2(tool)}`;
|
|
7929
8101
|
}
|
|
@@ -7981,11 +8153,10 @@ var init_mcp_manager = __esm({
|
|
|
7981
8153
|
}
|
|
7982
8154
|
for (const def of this.deps.defs) {
|
|
7983
8155
|
try {
|
|
7984
|
-
|
|
7985
|
-
|
|
7986
|
-
if (!
|
|
7987
|
-
|
|
7988
|
-
const hit = getCachedTools(this.cache, serverCacheKey({ name: def.name, command: def.command, args: def.args, envNames }, tc.hash));
|
|
8156
|
+
const key = approvalKey(def);
|
|
8157
|
+
if (!await this.deps.isStdioApproved(key)) continue;
|
|
8158
|
+
if (!expandServerEnv({ command: def.transport === "http" ? def.url : def.command, args: def.args, env: def.env }, this.deps.env).ok) continue;
|
|
8159
|
+
const hit = getCachedTools(this.cache, serverCacheKey({ name: def.name, ...key }, tc.hash));
|
|
7989
8160
|
if (hit) this.cachedTools.set(def.name, this.usable(def.name, hit).tools);
|
|
7990
8161
|
} catch (err) {
|
|
7991
8162
|
this.cacheNotes.push(`${def.name}: cached tools skipped (${err instanceof Error ? err.message : String(err)})`);
|
|
@@ -8038,7 +8209,7 @@ var init_mcp_manager = __esm({
|
|
|
8038
8209
|
if (!tc) return Promise.resolve();
|
|
8039
8210
|
this.cacheWrite = this.cacheWrite.then(async () => {
|
|
8040
8211
|
try {
|
|
8041
|
-
const key = serverCacheKey({ name: def.name,
|
|
8212
|
+
const key = serverCacheKey({ name: def.name, ...approvalKey(def) }, tc.hash);
|
|
8042
8213
|
const next = putCachedTools(this.cache, key, tools.map((t) => ({ name: t.name, description: t.description, inputSchema: t.inputSchema })));
|
|
8043
8214
|
if (next === this.cache) return;
|
|
8044
8215
|
await tc.write(serializeToolCache(next));
|
|
@@ -8053,38 +8224,56 @@ var init_mcp_manager = __esm({
|
|
|
8053
8224
|
const name = def.name;
|
|
8054
8225
|
const skip = (reason) => void this.servers.set(name, { name, def, status: "skipped", reason });
|
|
8055
8226
|
const fail = (reason) => void this.servers.set(name, { name, def, status: "failed", reason });
|
|
8056
|
-
|
|
8057
|
-
|
|
8227
|
+
const http = def.transport === "http";
|
|
8228
|
+
if (http && !isSafeMcpUrl(def.url)) return skip("its URL must be https (or localhost)");
|
|
8229
|
+
const key = approvalKey(def);
|
|
8058
8230
|
let approved;
|
|
8059
8231
|
try {
|
|
8060
|
-
approved = await this.deps.isStdioApproved(
|
|
8232
|
+
approved = await this.deps.isStdioApproved(key);
|
|
8061
8233
|
} catch (err) {
|
|
8062
8234
|
return fail(`approval check failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
8063
8235
|
}
|
|
8064
|
-
if (!approved) return skip(`its command is not approved on this machine (${def.origin} definition)`);
|
|
8065
|
-
const expanded = expandServerEnv({ command: def.command, args: def.args, env: def.env }, this.deps.env);
|
|
8236
|
+
if (!approved) return skip(`its ${http ? "URL and headers are" : "command is"} not approved on this machine (${def.origin} definition)`);
|
|
8237
|
+
const expanded = expandServerEnv({ command: http ? def.url : def.command, args: def.args, env: def.env }, this.deps.env);
|
|
8066
8238
|
if (!expanded.ok) return skip(`set ${expanded.missing.join(", ")} in your environment`);
|
|
8239
|
+
if (http && !isSafeMcpUrl(expanded.command)) return skip("its URL must be https (or localhost)");
|
|
8067
8240
|
this.servers.set(name, { name, def, status: "connecting" });
|
|
8068
8241
|
let transport;
|
|
8069
8242
|
try {
|
|
8070
8243
|
let session2;
|
|
8071
8244
|
let closeReason = null;
|
|
8072
|
-
|
|
8073
|
-
|
|
8074
|
-
|
|
8075
|
-
|
|
8076
|
-
|
|
8077
|
-
|
|
8078
|
-
|
|
8079
|
-
|
|
8080
|
-
|
|
8081
|
-
|
|
8082
|
-
|
|
8083
|
-
|
|
8084
|
-
|
|
8085
|
-
|
|
8245
|
+
const onClose = (reason) => {
|
|
8246
|
+
closeReason = reason;
|
|
8247
|
+
session2.close(reason);
|
|
8248
|
+
const cur = this.servers.get(name);
|
|
8249
|
+
if (cur?.status === "ready") this.servers.set(name, { name, def, status: "failed", reason: `server ${reason}` });
|
|
8250
|
+
};
|
|
8251
|
+
let send;
|
|
8252
|
+
if (http) {
|
|
8253
|
+
const t = createHttpTransport({
|
|
8254
|
+
url: expanded.command,
|
|
8255
|
+
headers: expanded.env,
|
|
8256
|
+
fetch: this.deps.fetch ?? ((url, init) => fetch(url, { ...init, redirect: "error" })),
|
|
8257
|
+
protocolVersion: MCP_PROTOCOL_VERSION,
|
|
8258
|
+
onMessage: (m2) => void session2.handleMessage(m2),
|
|
8259
|
+
onClose
|
|
8260
|
+
});
|
|
8261
|
+
transport = t;
|
|
8262
|
+
send = (m2) => t.send(m2);
|
|
8263
|
+
} else {
|
|
8264
|
+
const t = (this.deps.start ?? startStdioTransport)({
|
|
8265
|
+
command: expanded.command,
|
|
8266
|
+
args: expanded.args,
|
|
8267
|
+
env: expanded.env,
|
|
8268
|
+
cwd: this.deps.cwd,
|
|
8269
|
+
onMessage: (m2) => void session2.handleMessage(m2),
|
|
8270
|
+
onClose
|
|
8271
|
+
});
|
|
8272
|
+
transport = t;
|
|
8273
|
+
send = (m2) => t.send(m2);
|
|
8274
|
+
}
|
|
8086
8275
|
session2 = createRpcSession({
|
|
8087
|
-
send
|
|
8276
|
+
send,
|
|
8088
8277
|
setTimer: (fn, ms) => setTimeout(fn, ms),
|
|
8089
8278
|
clearTimer: (h) => clearTimeout(h)
|
|
8090
8279
|
});
|
|
@@ -8208,10 +8397,10 @@ var init_mcp_manager = __esm({
|
|
|
8208
8397
|
async function runApproveMcp(deps) {
|
|
8209
8398
|
const { defs, statusLines } = await loadMcpDefs(deps);
|
|
8210
8399
|
if (!deps.quiet) for (const l of statusLines) deps.log(l);
|
|
8211
|
-
const stdio = defs
|
|
8400
|
+
const stdio = defs;
|
|
8212
8401
|
const todo = [];
|
|
8213
8402
|
for (const d of stdio) {
|
|
8214
|
-
const key =
|
|
8403
|
+
const key = approvalKey(d);
|
|
8215
8404
|
if (await deps.trust.stdioStatus(key) === "unapproved") todo.push(d);
|
|
8216
8405
|
}
|
|
8217
8406
|
if (todo.length === 0) {
|
|
@@ -8226,13 +8415,18 @@ async function runApproveMcp(deps) {
|
|
|
8226
8415
|
${todo.length} imported MCP server(s) want to run a command on this machine. Nothing spawns until you approve it (you can also run \`spacecode approve-mcp\` later).`);
|
|
8227
8416
|
let approved = 0;
|
|
8228
8417
|
for (const d of todo) {
|
|
8229
|
-
deps.log(
|
|
8418
|
+
deps.log(
|
|
8419
|
+
d.transport === "http" ? `
|
|
8420
|
+
MCP server ${show(d.name)} (${d.origin} definition) wants to connect from this machine to:
|
|
8421
|
+
${show(d.url)}
|
|
8422
|
+
headers it will send (NAME=where the value comes from): ${approvalEnv(d.env).join(", ") || "(none)"}` : `
|
|
8230
8423
|
MCP server ${show(d.name)} (${d.origin} definition) wants to run on this machine:
|
|
8231
8424
|
${show(d.command)} ${d.args.map(show).join(" ")}
|
|
8232
|
-
environment it will receive (NAME=where the value comes from): ${approvalEnv(d.env).join(", ") || "(none)"}`
|
|
8233
|
-
|
|
8425
|
+
environment it will receive (NAME=where the value comes from): ${approvalEnv(d.env).join(", ") || "(none)"}`
|
|
8426
|
+
);
|
|
8427
|
+
const answer = (await deps.ask("Approve? [y/N] ") ?? "").trim().toLowerCase();
|
|
8234
8428
|
if (answer === "y" || answer === "yes") {
|
|
8235
|
-
await deps.trust.approveStdio(
|
|
8429
|
+
await deps.trust.approveStdio(approvalKey(d));
|
|
8236
8430
|
deps.log(" approved");
|
|
8237
8431
|
approved++;
|
|
8238
8432
|
} else deps.log(" not approved");
|
|
@@ -35864,7 +36058,7 @@ var require_websocket_server = __commonJS({
|
|
|
35864
36058
|
var keyRegex = /^[+/0-9A-Za-z]{22}==$/;
|
|
35865
36059
|
var RUNNING = 0;
|
|
35866
36060
|
var CLOSING = 1;
|
|
35867
|
-
var
|
|
36061
|
+
var CLOSED2 = 2;
|
|
35868
36062
|
var WebSocketServer2 = class extends EventEmitter3 {
|
|
35869
36063
|
/**
|
|
35870
36064
|
* Create a `WebSocketServer` instance.
|
|
@@ -35993,7 +36187,7 @@ var require_websocket_server = __commonJS({
|
|
|
35993
36187
|
* @public
|
|
35994
36188
|
*/
|
|
35995
36189
|
close(cb) {
|
|
35996
|
-
if (this._state ===
|
|
36190
|
+
if (this._state === CLOSED2) {
|
|
35997
36191
|
if (cb) {
|
|
35998
36192
|
this.once("close", () => {
|
|
35999
36193
|
cb(new Error("The server is not running"));
|
|
@@ -36217,7 +36411,7 @@ var require_websocket_server = __commonJS({
|
|
|
36217
36411
|
};
|
|
36218
36412
|
}
|
|
36219
36413
|
function emitClose(server) {
|
|
36220
|
-
server._state =
|
|
36414
|
+
server._state = CLOSED2;
|
|
36221
36415
|
server.emit("close");
|
|
36222
36416
|
}
|
|
36223
36417
|
function socketOnError() {
|
|
@@ -104173,7 +104367,7 @@ Skills are loaded on demand with the skill tool; bodies are not in the prompt. /
|
|
|
104173
104367
|
(a) => a.kind === "skill" && (a.name === name || a.name.startsWith(`${name}.`) && a.description.startsWith(SIBLING_PREFIX))
|
|
104174
104368
|
);
|
|
104175
104369
|
for (const a of assets) await deps.client.delete("skill", a.name);
|
|
104176
|
-
return `Deleted skill "${name}" and ${assets.length - 1} file(s) from the profile. Re-running import
|
|
104370
|
+
return `Deleted skill "${name}" and ${assets.length - 1} file(s) from the profile. Re-running "spacecode import claude" would import it again.`;
|
|
104177
104371
|
}
|
|
104178
104372
|
return "Usage: /skills | /skills show <name> [file] | /skills delete <name>";
|
|
104179
104373
|
}
|
|
@@ -105893,7 +106087,13 @@ function clearOnResize(stdout) {
|
|
|
105893
106087
|
|
|
105894
106088
|
// src/index.tsx
|
|
105895
106089
|
var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1);
|
|
105896
|
-
if (process.argv[2] === "import-claude") {
|
|
106090
|
+
if (process.argv[2] === "import" || process.argv[2] === "import-claude") {
|
|
106091
|
+
const importArgs = process.argv[2] === "import" ? process.argv.slice(4) : process.argv.slice(3);
|
|
106092
|
+
const importAgent = process.argv[2] === "import" ? process.argv[3] : "claude";
|
|
106093
|
+
if (importAgent !== "claude") {
|
|
106094
|
+
console.error(`Unknown agent "${importAgent ?? ""}". Supported: claude`);
|
|
106095
|
+
process.exit(2);
|
|
106096
|
+
}
|
|
105897
106097
|
const { runImportClaude: runImportClaude2 } = await Promise.resolve().then(() => (init_import_claude(), import_claude_exports));
|
|
105898
106098
|
const { readFile: readFile12, readdir: readdir6 } = await import("node:fs/promises");
|
|
105899
106099
|
const { execFile: execFile6 } = await import("node:child_process");
|
|
@@ -105901,7 +106101,7 @@ if (process.argv[2] === "import-claude") {
|
|
|
105901
106101
|
execFile6("git", ["rev-parse", "--show-toplevel"], { cwd: process.cwd() }, (err, stdout) => resolve2(err ? null : stdout.trim() || null));
|
|
105902
106102
|
});
|
|
105903
106103
|
const code = await runImportClaude2({
|
|
105904
|
-
argv:
|
|
106104
|
+
argv: ["import-claude", ...importArgs],
|
|
105905
106105
|
env: process.env,
|
|
105906
106106
|
fs: { readFile: (p) => readFile12(p, "utf-8"), readdir: (p) => readdir6(p) },
|
|
105907
106107
|
readFile: (p) => readFile12(p, "utf-8"),
|