spacecode 2.12.0 → 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 +263 -43
- 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
|
}
|
|
@@ -104418,9 +104612,24 @@ async function runCoreTurn(d, prompt) {
|
|
|
104418
104612
|
...body === void 0 ? {} : { body: JSON.stringify(body) },
|
|
104419
104613
|
signal: d.signal
|
|
104420
104614
|
});
|
|
104421
|
-
if (!res.ok) throw new CoreTurnError(`core run request failed (${res.status}) ${method} ${path13.split("?")[0]}
|
|
104615
|
+
if (!res.ok) throw new CoreTurnError(`core run request failed (${res.status}) ${method} ${path13.split("?")[0]}`, res.status);
|
|
104422
104616
|
return res.json();
|
|
104423
104617
|
};
|
|
104618
|
+
const poll = async (path13) => {
|
|
104619
|
+
for (let attempt = 0; ; attempt++) {
|
|
104620
|
+
try {
|
|
104621
|
+
return await call("GET", path13);
|
|
104622
|
+
} catch (err) {
|
|
104623
|
+
const transient = err instanceof CoreTurnError && err.status !== void 0 && err.status >= 500;
|
|
104624
|
+
if (!transient || d.signal.aborted) throw err;
|
|
104625
|
+
if (attempt >= POLL_RETRIES) throw new CoreTurnError(`${err.message} (gave up after ${POLL_RETRIES} retries)`, err.status);
|
|
104626
|
+
d.emit({ type: "text", seq: ++seq, content: `(run service answered ${err.status}; retry ${attempt + 1}/${POLL_RETRIES})
|
|
104627
|
+
|
|
104628
|
+
` });
|
|
104629
|
+
await d.sleep(Math.min(8e3, 1e3 * 2 ** attempt));
|
|
104630
|
+
}
|
|
104631
|
+
}
|
|
104632
|
+
};
|
|
104424
104633
|
let runId = d.getRunId();
|
|
104425
104634
|
if (!runId) {
|
|
104426
104635
|
const created = await call("POST", "", {
|
|
@@ -104442,7 +104651,7 @@ async function runCoreTurn(d, prompt) {
|
|
|
104442
104651
|
let state = null;
|
|
104443
104652
|
for (; ; ) {
|
|
104444
104653
|
if (d.signal.aborted) throw new CoreTurnError("aborted");
|
|
104445
|
-
const events = (await
|
|
104654
|
+
const events = (await poll(`/${runId}/events?after=${cur.after}&limit=200`)).events;
|
|
104446
104655
|
for (const e of events) {
|
|
104447
104656
|
cur.after = Math.max(cur.after, e.seq);
|
|
104448
104657
|
if (!e.applied) continue;
|
|
@@ -104454,7 +104663,7 @@ async function runCoreTurn(d, prompt) {
|
|
|
104454
104663
|
}
|
|
104455
104664
|
if (e.type === "verifier_result" && Array.isArray(p.problems) && p.problems.length > 0) say(`task ${String(p.taskId)}: verifier: ${p.problems.join("; ")}`);
|
|
104456
104665
|
}
|
|
104457
|
-
state = (await
|
|
104666
|
+
state = (await poll(`/${runId}`)).state;
|
|
104458
104667
|
const now = {};
|
|
104459
104668
|
for (const id of state.order) now[id] = state.tasks[id].status;
|
|
104460
104669
|
const changed = state.order.filter((id) => now[id] !== cur.known[id]);
|
|
@@ -104485,7 +104694,7 @@ async function runCoreTurn(d, prompt) {
|
|
|
104485
104694
|
cur.tokensBase = state.tokensUsed;
|
|
104486
104695
|
return { success: (state.status === "done" || state.status === "needs_user") && patchFailures === 0, text: lastText, tokens };
|
|
104487
104696
|
}
|
|
104488
|
-
var newRunCursor, TERMINAL, DEFAULT_BUDGET, DEFAULT_MAX_WAIT_MS, CoreTurnError;
|
|
104697
|
+
var newRunCursor, TERMINAL, DEFAULT_BUDGET, DEFAULT_MAX_WAIT_MS, CoreTurnError, POLL_RETRIES;
|
|
104489
104698
|
var init_core_turn = __esm({
|
|
104490
104699
|
"src/core/core-turn.ts"() {
|
|
104491
104700
|
"use strict";
|
|
@@ -104494,7 +104703,12 @@ var init_core_turn = __esm({
|
|
|
104494
104703
|
DEFAULT_BUDGET = 5e5;
|
|
104495
104704
|
DEFAULT_MAX_WAIT_MS = 30 * 6e4;
|
|
104496
104705
|
CoreTurnError = class extends Error {
|
|
104706
|
+
constructor(message, status) {
|
|
104707
|
+
super(message);
|
|
104708
|
+
this.status = status;
|
|
104709
|
+
}
|
|
104497
104710
|
};
|
|
104711
|
+
POLL_RETRIES = 5;
|
|
104498
104712
|
}
|
|
104499
104713
|
});
|
|
104500
104714
|
|
|
@@ -105873,7 +106087,13 @@ function clearOnResize(stdout) {
|
|
|
105873
106087
|
|
|
105874
106088
|
// src/index.tsx
|
|
105875
106089
|
var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1);
|
|
105876
|
-
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
|
+
}
|
|
105877
106097
|
const { runImportClaude: runImportClaude2 } = await Promise.resolve().then(() => (init_import_claude(), import_claude_exports));
|
|
105878
106098
|
const { readFile: readFile12, readdir: readdir6 } = await import("node:fs/promises");
|
|
105879
106099
|
const { execFile: execFile6 } = await import("node:child_process");
|
|
@@ -105881,7 +106101,7 @@ if (process.argv[2] === "import-claude") {
|
|
|
105881
106101
|
execFile6("git", ["rev-parse", "--show-toplevel"], { cwd: process.cwd() }, (err, stdout) => resolve2(err ? null : stdout.trim() || null));
|
|
105882
106102
|
});
|
|
105883
106103
|
const code = await runImportClaude2({
|
|
105884
|
-
argv:
|
|
106104
|
+
argv: ["import-claude", ...importArgs],
|
|
105885
106105
|
env: process.env,
|
|
105886
106106
|
fs: { readFile: (p) => readFile12(p, "utf-8"), readdir: (p) => readdir6(p) },
|
|
105887
106107
|
readFile: (p) => readFile12(p, "utf-8"),
|