@clawos-dev/clawd 0.2.559 → 0.2.561
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/app-builder-plugin/mcp-server.cjs +2 -0
- package/dist/cli.cjs +150 -92
- package/dist/dispatch/mcp-server.cjs +2 -0
- package/dist/persona-defaults/persona-app-builder/mcp/clawd-app-builder/mcp-server.cjs +2 -0
- package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/mcp-server.cjs +2 -0
- package/dist/pi-mcp-bridge/extension.cjs +1705 -30
- package/dist/share-ui/assets/{guest-CYJu0n-K.js → guest-CbQApsnE.js} +133 -133
- package/dist/share-ui/guest.html +1 -1
- package/package.json +1 -1
|
@@ -24750,6 +24750,8 @@ var INNER_TAG_UNESCAPE_RE = new RegExp(`<\\\\(\\\\*)(/?)(${INNER_TAG_NAMES})\\b`
|
|
|
24750
24750
|
// ../protocol/src/tool-family.ts
|
|
24751
24751
|
var CLOUD_TOOL_SUFFIX = "-cloud";
|
|
24752
24752
|
var CODEX_CLOUD_TOOL_ID = `codex${CLOUD_TOOL_SUFFIX}`;
|
|
24753
|
+
var PI_TOOL_ID = "pi";
|
|
24754
|
+
var PI_CLOUD_TOOL_ID = `${PI_TOOL_ID}${CLOUD_TOOL_SUFFIX}`;
|
|
24753
24755
|
|
|
24754
24756
|
// src/deploy/deploy-file.ts
|
|
24755
24757
|
var import_promises = __toESM(require("fs/promises"), 1);
|
package/dist/cli.cjs
CHANGED
|
@@ -9750,16 +9750,23 @@ var init_dispatch_format = __esm({
|
|
|
9750
9750
|
function isCodexFamily(tool) {
|
|
9751
9751
|
return tool === "codex" || tool === CODEX_CLOUD_TOOL_ID;
|
|
9752
9752
|
}
|
|
9753
|
+
function isPiFamily(tool) {
|
|
9754
|
+
return tool === PI_TOOL_ID || tool === PI_CLOUD_TOOL_ID;
|
|
9755
|
+
}
|
|
9756
|
+
function isCloudTool(tool) {
|
|
9757
|
+
return typeof tool === "string" && tool.length > CLOUD_TOOL_SUFFIX.length && tool.endsWith(CLOUD_TOOL_SUFFIX);
|
|
9758
|
+
}
|
|
9753
9759
|
function isRpcAgentTool(tool) {
|
|
9754
|
-
return isCodexFamily(tool) || tool
|
|
9760
|
+
return isCodexFamily(tool) || isPiFamily(tool);
|
|
9755
9761
|
}
|
|
9756
|
-
var CLOUD_TOOL_SUFFIX, CODEX_CLOUD_TOOL_ID, PI_TOOL_ID;
|
|
9762
|
+
var CLOUD_TOOL_SUFFIX, CODEX_CLOUD_TOOL_ID, PI_TOOL_ID, PI_CLOUD_TOOL_ID;
|
|
9757
9763
|
var init_tool_family = __esm({
|
|
9758
9764
|
"../protocol/src/tool-family.ts"() {
|
|
9759
9765
|
"use strict";
|
|
9760
9766
|
CLOUD_TOOL_SUFFIX = "-cloud";
|
|
9761
9767
|
CODEX_CLOUD_TOOL_ID = `codex${CLOUD_TOOL_SUFFIX}`;
|
|
9762
9768
|
PI_TOOL_ID = "pi";
|
|
9769
|
+
PI_CLOUD_TOOL_ID = `${PI_TOOL_ID}${CLOUD_TOOL_SUFFIX}`;
|
|
9763
9770
|
}
|
|
9764
9771
|
});
|
|
9765
9772
|
|
|
@@ -45685,7 +45692,7 @@ function cloneState(s2) {
|
|
|
45685
45692
|
}
|
|
45686
45693
|
var CLOUD_IDLE_KILL_DELAY_MS = 5 * 6e4;
|
|
45687
45694
|
function idleKillDelayOf(state) {
|
|
45688
|
-
if (state.file.tool
|
|
45695
|
+
if (isCloudTool(state.file.tool)) return CLOUD_IDLE_KILL_DELAY_MS;
|
|
45689
45696
|
const ms = state.subSessionMeta?.idleKillDelayMs;
|
|
45690
45697
|
return ms !== void 0 && ms > 0 ? ms : void 0;
|
|
45691
45698
|
}
|
|
@@ -45861,7 +45868,7 @@ function buildSpawnContext(state, deps) {
|
|
|
45861
45868
|
const meta = state.subSessionMeta;
|
|
45862
45869
|
if (meta?.personaMode) {
|
|
45863
45870
|
ctx.personaMode = meta.personaMode;
|
|
45864
|
-
const workDir = file.tool
|
|
45871
|
+
const workDir = isCloudTool(file.tool) ? void 0 : meta.userWorkDir;
|
|
45865
45872
|
let promptArgs;
|
|
45866
45873
|
if (meta.personaMode === "guest") {
|
|
45867
45874
|
if (!meta.callerDisplayName) {
|
|
@@ -46127,7 +46134,7 @@ function pushEventToBufferInPlace(next, event, deps) {
|
|
|
46127
46134
|
if (canCloseStdin) {
|
|
46128
46135
|
next.stdinClosed = true;
|
|
46129
46136
|
effects.push({ kind: "close-stdin" });
|
|
46130
|
-
} else if (isRpcAgentTool(tool) && tool
|
|
46137
|
+
} else if (isRpcAgentTool(tool) && !isCloudTool(tool)) {
|
|
46131
46138
|
if (tool === PI_TOOL_ID) next.stdinClosed = true;
|
|
46132
46139
|
effects.push({ kind: "kill", signal: "SIGTERM" });
|
|
46133
46140
|
} else {
|
|
@@ -51787,7 +51794,11 @@ function codexGuestCliArgs(cs, opts = {}) {
|
|
|
51787
51794
|
function codexMcpCliArgs(defs) {
|
|
51788
51795
|
const out = [];
|
|
51789
51796
|
for (const d2 of defs) {
|
|
51790
|
-
const cfg = "url" in d2 ? {
|
|
51797
|
+
const cfg = "url" in d2 ? {
|
|
51798
|
+
url: d2.url,
|
|
51799
|
+
...d2.bearerTokenEnvVar ? { bearer_token_env_var: d2.bearerTokenEnvVar } : {},
|
|
51800
|
+
...d2.httpHeaders && Object.keys(d2.httpHeaders).length > 0 ? { http_headers: d2.httpHeaders } : {}
|
|
51801
|
+
} : {
|
|
51791
51802
|
command: d2.command,
|
|
51792
51803
|
...d2.args && d2.args.length > 0 ? { args: d2.args } : {},
|
|
51793
51804
|
...d2.env && Object.keys(d2.env).length > 0 ? { env: d2.env } : {}
|
|
@@ -51983,11 +51994,11 @@ function stringValue2(value) {
|
|
|
51983
51994
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
51984
51995
|
}
|
|
51985
51996
|
|
|
51986
|
-
// src/tools/
|
|
51997
|
+
// src/tools/mcp-server-defs.ts
|
|
51987
51998
|
var import_node_fs17 = __toESM(require("fs"), 1);
|
|
51988
51999
|
var import_node_path15 = __toESM(require("path"), 1);
|
|
51989
52000
|
var HTTP_TYPES = /* @__PURE__ */ new Set(["http", "sse", "streamable_http", "streamable-http"]);
|
|
51990
|
-
function
|
|
52001
|
+
function loadMcpServerDefs(args) {
|
|
51991
52002
|
const out = [];
|
|
51992
52003
|
const seen = /* @__PURE__ */ new Set();
|
|
51993
52004
|
const sources = [...args.mcpConfigPaths, import_node_path15.default.join(args.cwd, ".mcp.json")];
|
|
@@ -51998,7 +52009,7 @@ function loadCodexMcpServerDefs(args) {
|
|
|
51998
52009
|
} catch (e) {
|
|
51999
52010
|
const code = e.code;
|
|
52000
52011
|
if (code !== "ENOENT") {
|
|
52001
|
-
args.logger?.warn("
|
|
52012
|
+
args.logger?.warn("mcp config unreadable, skipped", { file, code: code ?? "parse-error" });
|
|
52002
52013
|
}
|
|
52003
52014
|
continue;
|
|
52004
52015
|
}
|
|
@@ -52009,28 +52020,34 @@ function loadCodexMcpServerDefs(args) {
|
|
|
52009
52020
|
const type = typeof def.type === "string" ? def.type.toLowerCase() : typeof def.url === "string" ? "http" : "stdio";
|
|
52010
52021
|
if (HTTP_TYPES.has(type)) {
|
|
52011
52022
|
if (typeof def.url !== "string" || !def.url) {
|
|
52012
|
-
args.logger?.warn("
|
|
52023
|
+
args.logger?.warn("mcp server http without url, skipped", { file, name });
|
|
52013
52024
|
continue;
|
|
52014
52025
|
}
|
|
52015
52026
|
if (seen.has(name)) {
|
|
52016
|
-
args.logger?.warn("
|
|
52027
|
+
args.logger?.warn("mcp server name collision, first-wins", { file, name });
|
|
52017
52028
|
continue;
|
|
52018
52029
|
}
|
|
52019
52030
|
seen.add(name);
|
|
52020
52031
|
const headers = def.headers && typeof def.headers === "object" ? Object.fromEntries(Object.entries(def.headers).filter((kv) => typeof kv[1] === "string")) : {};
|
|
52021
|
-
|
|
52032
|
+
const bearerTokenEnvVar = typeof def.bearer_token_env_var === "string" && def.bearer_token_env_var ? def.bearer_token_env_var : void 0;
|
|
52033
|
+
out.push({
|
|
52034
|
+
name,
|
|
52035
|
+
url: def.url,
|
|
52036
|
+
...Object.keys(headers).length > 0 ? { httpHeaders: headers } : {},
|
|
52037
|
+
...bearerTokenEnvVar ? { bearerTokenEnvVar } : {}
|
|
52038
|
+
});
|
|
52022
52039
|
continue;
|
|
52023
52040
|
}
|
|
52024
52041
|
if (type !== "stdio") {
|
|
52025
|
-
args.logger?.warn("
|
|
52042
|
+
args.logger?.warn("mcp server type unsupported, skipped", { file, name, type });
|
|
52026
52043
|
continue;
|
|
52027
52044
|
}
|
|
52028
52045
|
if (typeof def.command !== "string" || !def.command) {
|
|
52029
|
-
args.logger?.warn("
|
|
52046
|
+
args.logger?.warn("mcp server missing command, skipped", { file, name });
|
|
52030
52047
|
continue;
|
|
52031
52048
|
}
|
|
52032
52049
|
if (seen.has(name)) {
|
|
52033
|
-
args.logger?.warn("
|
|
52050
|
+
args.logger?.warn("mcp server name collision, first-wins", { file, name });
|
|
52034
52051
|
continue;
|
|
52035
52052
|
}
|
|
52036
52053
|
seen.add(name);
|
|
@@ -52327,7 +52344,7 @@ function createCodexSession(ctx, sink, deps = {}) {
|
|
|
52327
52344
|
);
|
|
52328
52345
|
args.push(
|
|
52329
52346
|
...codexMcpCliArgs(
|
|
52330
|
-
|
|
52347
|
+
loadMcpServerDefs({
|
|
52331
52348
|
mcpConfigPaths: (ctx.mcpConfigs ?? []).map((m3) => m3.path),
|
|
52332
52349
|
cwd: ctx.cwd,
|
|
52333
52350
|
baseEnv: clawdEnv,
|
|
@@ -63152,21 +63169,43 @@ init_protocol();
|
|
|
63152
63169
|
|
|
63153
63170
|
// src/tools/pi-rpc-client.ts
|
|
63154
63171
|
init_stdout_splitter();
|
|
63172
|
+
function piStdioLineStream(proc) {
|
|
63173
|
+
const lineCbs = [];
|
|
63174
|
+
const closeCbs = [];
|
|
63175
|
+
let buf = "";
|
|
63176
|
+
proc.stdout.on("data", (chunk) => {
|
|
63177
|
+
const { newBuf, lines } = splitStdoutChunk(buf, chunk);
|
|
63178
|
+
buf = newBuf;
|
|
63179
|
+
for (const line of lines) for (const cb of lineCbs) cb(line);
|
|
63180
|
+
});
|
|
63181
|
+
proc.stdout.on("close", () => {
|
|
63182
|
+
for (const cb of closeCbs) cb();
|
|
63183
|
+
});
|
|
63184
|
+
return {
|
|
63185
|
+
write: (line) => {
|
|
63186
|
+
proc.stdin?.write(line + "\n");
|
|
63187
|
+
},
|
|
63188
|
+
onLine: (cb) => {
|
|
63189
|
+
lineCbs.push(cb);
|
|
63190
|
+
},
|
|
63191
|
+
onClose: (cb) => {
|
|
63192
|
+
closeCbs.push(cb);
|
|
63193
|
+
},
|
|
63194
|
+
close: () => {
|
|
63195
|
+
proc.stdin?.end();
|
|
63196
|
+
}
|
|
63197
|
+
};
|
|
63198
|
+
}
|
|
63155
63199
|
var PiRpcClient = class {
|
|
63156
|
-
constructor(
|
|
63157
|
-
this.
|
|
63200
|
+
constructor(stream, opts = {}) {
|
|
63201
|
+
this.stream = stream;
|
|
63158
63202
|
this.opts = opts;
|
|
63159
|
-
|
|
63160
|
-
|
|
63161
|
-
this.buf = newBuf;
|
|
63162
|
-
for (const line of lines) this.onLine(line);
|
|
63163
|
-
});
|
|
63164
|
-
proc.stdout.on("close", () => this.handleClose());
|
|
63203
|
+
stream.onLine((line) => this.onLine(line));
|
|
63204
|
+
stream.onClose(() => this.handleClose());
|
|
63165
63205
|
}
|
|
63166
|
-
|
|
63206
|
+
stream;
|
|
63167
63207
|
opts;
|
|
63168
63208
|
nextId = 1;
|
|
63169
|
-
buf = "";
|
|
63170
63209
|
closed = false;
|
|
63171
63210
|
/** endInput() 之后:写端已关,再写会让 Node 异步 emit ERR_STREAM_WRITE_AFTER_END,直接拒掉 */
|
|
63172
63211
|
inputClosed = false;
|
|
@@ -63185,14 +63224,14 @@ var PiRpcClient = class {
|
|
|
63185
63224
|
if (this.closed || this.inputClosed) return;
|
|
63186
63225
|
this.write(frame);
|
|
63187
63226
|
}
|
|
63188
|
-
/** 关写端 = pi
|
|
63227
|
+
/** 关写端 = pi 的优雅退出信号(本机 stdin EOF → 进程退出 code 0;云上 = 断开会话通道) */
|
|
63189
63228
|
endInput() {
|
|
63190
63229
|
if (this.inputClosed) return;
|
|
63191
63230
|
this.inputClosed = true;
|
|
63192
|
-
this.
|
|
63231
|
+
this.stream.close();
|
|
63193
63232
|
}
|
|
63194
63233
|
write(o2) {
|
|
63195
|
-
this.
|
|
63234
|
+
this.stream.write(JSON.stringify(o2));
|
|
63196
63235
|
}
|
|
63197
63236
|
onLine(line) {
|
|
63198
63237
|
const t2 = line.replace(/\r$/, "").trim();
|
|
@@ -63381,43 +63420,9 @@ function makeImageFetcher(fetchImpl = fetch, opts = {}) {
|
|
|
63381
63420
|
};
|
|
63382
63421
|
}
|
|
63383
63422
|
|
|
63384
|
-
// src/pi-
|
|
63385
|
-
|
|
63386
|
-
|
|
63387
|
-
// src/tools/pi-session.ts
|
|
63388
|
-
var PI_THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh", "max"];
|
|
63389
|
-
function buildPiArgs(ctx, opts) {
|
|
63390
|
-
const args = ["--mode", "rpc", "--session-id", opts.sessionId];
|
|
63391
|
-
if (ctx.model) args.push("--model", ctx.model);
|
|
63392
|
-
if (ctx.effort && PI_THINKING_LEVELS.includes(ctx.effort)) args.push("--thinking", ctx.effort);
|
|
63393
|
-
if (ctx.extraSystemPrompt) args.push("--append-system-prompt", ctx.extraSystemPrompt);
|
|
63394
|
-
if (ctx.addDirs && ctx.addDirs.length > 0) args.push("--append-system-prompt", piAddDirsPrompt(ctx.addDirs));
|
|
63395
|
-
if (opts.skillsDir) args.push("--skill", opts.skillsDir);
|
|
63396
|
-
if (opts.mcpBridgePath) args.push("-e", opts.mcpBridgePath);
|
|
63397
|
-
args.push("--exclude-tools", "ask_question");
|
|
63398
|
-
return args;
|
|
63399
|
-
}
|
|
63400
|
-
function piAddDirsPrompt(dirs) {
|
|
63401
|
-
return `\u9664\u5F53\u524D\u76EE\u5F55\u5916\uFF0C\u4EE5\u4E0B\u76EE\u5F55\u4E5F\u662F\u4F60\u7684\u5DE5\u4F5C\u76EE\u5F55\uFF08\u53EF\u8BFB\u53EF\u5199\uFF0C\u9879\u76EE\u6587\u4EF6\u5C31\u5728\u8FD9\u91CC\uFF09\uFF1A
|
|
63402
|
-
${dirs.map((d2) => `- ${d2}`).join("\n")}`;
|
|
63403
|
-
}
|
|
63404
|
-
function createPiSession(ctx, sink, deps = {}) {
|
|
63405
|
-
const cmd = process.env.PI_BIN ?? "pi";
|
|
63406
|
-
const sessionId = ctx.toolSessionId ?? (0, import_node_crypto10.randomUUID)();
|
|
63407
|
-
const skillsDir = import_node_path39.default.join(ctx.cwd, ".claude", "skills");
|
|
63408
|
-
const exists = deps.skillsDirExists ?? ((d2) => import_node_fs35.default.existsSync(d2));
|
|
63409
|
-
const args = buildPiArgs(ctx, {
|
|
63410
|
-
sessionId,
|
|
63411
|
-
skillsDir: exists(skillsDir) ? skillsDir : void 0,
|
|
63412
|
-
mcpBridgePath: deps.mcpBridgePath
|
|
63413
|
-
});
|
|
63414
|
-
const env = {
|
|
63415
|
-
...process.env,
|
|
63416
|
-
...ctx.env,
|
|
63417
|
-
...deps.mcpBridgePath ? { [PI_MCP_CONFIGS_ENV]: JSON.stringify((ctx.mcpConfigs ?? []).map((m3) => m3.path)) } : {}
|
|
63418
|
-
};
|
|
63419
|
-
const proc = deps.spawnOverride ? deps.spawnOverride(cmd, args, ctx.cwd, env) : (0, import_node_child_process10.spawn)(cmd, args, { cwd: ctx.cwd, env, stdio: ["pipe", "pipe", "pipe"] });
|
|
63420
|
-
const alive = () => proc.exitCode === null && proc.signalCode === null;
|
|
63423
|
+
// src/tools/pi-session-driver.ts
|
|
63424
|
+
function drivePiSession(opts) {
|
|
63425
|
+
const { sink, stream, sessionId, logger } = opts;
|
|
63421
63426
|
const st2 = createPiTranslatorState();
|
|
63422
63427
|
let busy = false;
|
|
63423
63428
|
let handshakeFailed = false;
|
|
@@ -63431,17 +63436,17 @@ function createPiSession(ctx, sink, deps = {}) {
|
|
|
63431
63436
|
const handleUiRequest = (ev) => {
|
|
63432
63437
|
const method = str3(ev.method);
|
|
63433
63438
|
const id = str3(ev.id);
|
|
63434
|
-
|
|
63439
|
+
logger?.warn("pi extension_ui_request unexpected in clawd session", { method });
|
|
63435
63440
|
if (id && (method === "select" || method === "confirm" || method === "input" || method === "editor")) {
|
|
63436
63441
|
client.send({ type: "extension_ui_response", id, cancelled: true });
|
|
63437
63442
|
}
|
|
63438
63443
|
};
|
|
63439
|
-
const client = new PiRpcClient(
|
|
63444
|
+
const client = new PiRpcClient(stream, {
|
|
63440
63445
|
onEvent: (ev) => {
|
|
63441
63446
|
if (ev.type === "agent_start") busy = true;
|
|
63442
63447
|
if (ev.type === "agent_settled") busy = false;
|
|
63443
63448
|
if (ev.type === "response") {
|
|
63444
|
-
|
|
63449
|
+
logger?.warn("pi response without pending id", { command: str3(ev.command), error: str3(ev.error) });
|
|
63445
63450
|
return;
|
|
63446
63451
|
}
|
|
63447
63452
|
if (ev.type === "extension_ui_request") {
|
|
@@ -63450,14 +63455,15 @@ function createPiSession(ctx, sink, deps = {}) {
|
|
|
63450
63455
|
}
|
|
63451
63456
|
const events = translatePiEvent(ev, st2);
|
|
63452
63457
|
if (events.length) sink.pushEvents(events);
|
|
63458
|
+
if (ev.type === "agent_settled") opts.onTurnCompleted?.();
|
|
63453
63459
|
},
|
|
63454
|
-
onClose: () => finish(
|
|
63460
|
+
onClose: () => finish(opts.exitCodeOnClose?.() ?? null)
|
|
63455
63461
|
});
|
|
63456
63462
|
const ready = client.request({ type: "get_state" }).then((r2) => {
|
|
63457
63463
|
if (!r2.success) throw new Error(r2.error ?? "get_state failed");
|
|
63458
63464
|
const data = rec3(r2.data);
|
|
63459
63465
|
const sid = str3(data?.sessionId) ?? sessionId;
|
|
63460
|
-
if (sid !== sessionId)
|
|
63466
|
+
if (sid !== sessionId) logger?.error("pi sessionId mismatch", { expected: sessionId, actual: sid });
|
|
63461
63467
|
const model = rec3(data?.model);
|
|
63462
63468
|
const patch = {};
|
|
63463
63469
|
const mid = str3(model?.id);
|
|
@@ -63472,24 +63478,14 @@ function createPiSession(ctx, sink, deps = {}) {
|
|
|
63472
63478
|
handshakeFailed = true;
|
|
63473
63479
|
sink.onError(`pi get_state failed: ${e.message}`);
|
|
63474
63480
|
});
|
|
63475
|
-
|
|
63476
|
-
proc.stdin?.on("error", (err) => deps.logger?.warn("pi stdin error (write dropped)", { message: err.message }));
|
|
63477
|
-
proc.on("error", (err) => {
|
|
63478
|
-
const message = err.message;
|
|
63479
|
-
deps.logger?.error("pi spawn failed", { message });
|
|
63480
|
-
const described = describeSpawnError(err, cmd, ctx.cwd);
|
|
63481
|
-
sink.onError(described === message ? `pi spawn failed: ${message}` : described);
|
|
63482
|
-
});
|
|
63483
|
-
proc.on("exit", (code) => finish(code));
|
|
63484
|
-
const fetchImage = deps.fetchImage ?? makeImageFetcher();
|
|
63485
|
-
return {
|
|
63481
|
+
const session = {
|
|
63486
63482
|
startTurn(text) {
|
|
63487
63483
|
void ready.then(async () => {
|
|
63488
63484
|
if (handshakeFailed) {
|
|
63489
63485
|
fail("pi session not ready (get_state failed)");
|
|
63490
63486
|
return;
|
|
63491
63487
|
}
|
|
63492
|
-
const input = await piPromptInput(text, { fetchImage });
|
|
63488
|
+
const input = await piPromptInput(text, { fetchImage: opts.fetchImage });
|
|
63493
63489
|
const r2 = await client.request({
|
|
63494
63490
|
type: "prompt",
|
|
63495
63491
|
...input,
|
|
@@ -63500,24 +63496,86 @@ function createPiSession(ctx, sink, deps = {}) {
|
|
|
63500
63496
|
}).catch((e) => fail(`pi prompt failed: ${e.message}`));
|
|
63501
63497
|
},
|
|
63502
63498
|
respondPermission(requestId) {
|
|
63503
|
-
|
|
63499
|
+
logger?.warn("pi respondPermission ignored: pi has no approvals", { requestId });
|
|
63504
63500
|
},
|
|
63505
63501
|
interrupt() {
|
|
63506
63502
|
st2.aborted = true;
|
|
63507
63503
|
void client.request({ type: "abort" }).catch(() => {
|
|
63508
63504
|
});
|
|
63509
63505
|
},
|
|
63510
|
-
|
|
63506
|
+
// 信号由 runner 透传 reducer 的 kill effect;怎么落地由壳定(本机 endInput + 宽限 + kill;云上关流)
|
|
63507
|
+
async stop(signal = "SIGTERM") {
|
|
63508
|
+
await opts.kill(signal);
|
|
63509
|
+
}
|
|
63510
|
+
};
|
|
63511
|
+
return { session, finish, client };
|
|
63512
|
+
}
|
|
63513
|
+
|
|
63514
|
+
// src/pi-mcp-bridge/bridge.ts
|
|
63515
|
+
var PI_MCP_CONFIGS_ENV = "CLAWD_PI_MCP_CONFIGS";
|
|
63516
|
+
|
|
63517
|
+
// src/tools/pi-session.ts
|
|
63518
|
+
var PI_THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh", "max"];
|
|
63519
|
+
function buildPiArgs(ctx, opts) {
|
|
63520
|
+
const args = ["--mode", "rpc", "--session-id", opts.sessionId];
|
|
63521
|
+
if (ctx.model) args.push("--model", ctx.model);
|
|
63522
|
+
if (ctx.effort && PI_THINKING_LEVELS.includes(ctx.effort)) args.push("--thinking", ctx.effort);
|
|
63523
|
+
if (ctx.extraSystemPrompt) args.push("--append-system-prompt", ctx.extraSystemPrompt);
|
|
63524
|
+
if (ctx.addDirs && ctx.addDirs.length > 0) args.push("--append-system-prompt", piAddDirsPrompt(ctx.addDirs));
|
|
63525
|
+
if (opts.skillsDir) args.push("--skill", opts.skillsDir);
|
|
63526
|
+
if (opts.mcpBridgePath) args.push("-e", opts.mcpBridgePath);
|
|
63527
|
+
args.push("--exclude-tools", "ask_question");
|
|
63528
|
+
return args;
|
|
63529
|
+
}
|
|
63530
|
+
function piAddDirsPrompt(dirs) {
|
|
63531
|
+
return `\u9664\u5F53\u524D\u76EE\u5F55\u5916\uFF0C\u4EE5\u4E0B\u76EE\u5F55\u4E5F\u662F\u4F60\u7684\u5DE5\u4F5C\u76EE\u5F55\uFF08\u53EF\u8BFB\u53EF\u5199\uFF0C\u9879\u76EE\u6587\u4EF6\u5C31\u5728\u8FD9\u91CC\uFF09\uFF1A
|
|
63532
|
+
${dirs.map((d2) => `- ${d2}`).join("\n")}`;
|
|
63533
|
+
}
|
|
63534
|
+
function createPiSession(ctx, sink, deps = {}) {
|
|
63535
|
+
const cmd = process.env.PI_BIN ?? "pi";
|
|
63536
|
+
const sessionId = ctx.toolSessionId ?? (0, import_node_crypto10.randomUUID)();
|
|
63537
|
+
const skillsDir = import_node_path39.default.join(ctx.cwd, ".claude", "skills");
|
|
63538
|
+
const exists = deps.skillsDirExists ?? ((d2) => import_node_fs35.default.existsSync(d2));
|
|
63539
|
+
const args = buildPiArgs(ctx, {
|
|
63540
|
+
sessionId,
|
|
63541
|
+
skillsDir: exists(skillsDir) ? skillsDir : void 0,
|
|
63542
|
+
mcpBridgePath: deps.mcpBridgePath
|
|
63543
|
+
});
|
|
63544
|
+
const env = {
|
|
63545
|
+
...process.env,
|
|
63546
|
+
...ctx.env,
|
|
63547
|
+
...deps.mcpBridgePath ? { [PI_MCP_CONFIGS_ENV]: JSON.stringify((ctx.mcpConfigs ?? []).map((m3) => m3.path)) } : {}
|
|
63548
|
+
};
|
|
63549
|
+
const proc = deps.spawnOverride ? deps.spawnOverride(cmd, args, ctx.cwd, env) : (0, import_node_child_process10.spawn)(cmd, args, { cwd: ctx.cwd, env, stdio: ["pipe", "pipe", "pipe"] });
|
|
63550
|
+
const alive = () => proc.exitCode === null && proc.signalCode === null;
|
|
63551
|
+
const driver = drivePiSession({
|
|
63552
|
+
sink,
|
|
63553
|
+
stream: piStdioLineStream(proc),
|
|
63554
|
+
sessionId,
|
|
63555
|
+
logger: deps.logger,
|
|
63556
|
+
fetchImage: deps.fetchImage ?? makeImageFetcher(),
|
|
63557
|
+
kill: async (signal) => {
|
|
63511
63558
|
if (!alive()) return;
|
|
63512
63559
|
if (signal === "SIGKILL") {
|
|
63513
63560
|
proc.kill("SIGKILL");
|
|
63514
63561
|
return;
|
|
63515
63562
|
}
|
|
63516
|
-
client.endInput();
|
|
63563
|
+
driver.client.endInput();
|
|
63517
63564
|
await new Promise((r2) => setTimeout(r2, deps.graceMs ?? 2e3));
|
|
63518
|
-
if (alive()) proc.kill(signal
|
|
63519
|
-
}
|
|
63520
|
-
|
|
63565
|
+
if (alive()) proc.kill(signal);
|
|
63566
|
+
},
|
|
63567
|
+
exitCodeOnClose: () => proc.exitCode
|
|
63568
|
+
});
|
|
63569
|
+
proc.stderr?.on("data", (c2) => deps.logger?.warn("pi stderr", { line: c2.toString().slice(0, 500) }));
|
|
63570
|
+
proc.stdin?.on("error", (err) => deps.logger?.warn("pi stdin error (write dropped)", { message: err.message }));
|
|
63571
|
+
proc.on("error", (err) => {
|
|
63572
|
+
const message = err.message;
|
|
63573
|
+
deps.logger?.error("pi spawn failed", { message });
|
|
63574
|
+
const described = describeSpawnError(err, cmd, ctx.cwd);
|
|
63575
|
+
sink.onError(described === message ? `pi spawn failed: ${message}` : described);
|
|
63576
|
+
});
|
|
63577
|
+
proc.on("exit", (code) => driver.finish(code));
|
|
63578
|
+
return driver.session;
|
|
63521
63579
|
}
|
|
63522
63580
|
|
|
63523
63581
|
// src/tools/pi-history.ts
|
|
@@ -63807,7 +63865,7 @@ async function queryPiModels(deps = {}) {
|
|
|
63807
63865
|
const proc = deps.spawnOverride ? deps.spawnOverride(cmd, args) : (0, import_node_child_process11.spawn)(cmd, args, { stdio: ["pipe", "pipe", "pipe"] });
|
|
63808
63866
|
proc.stdin?.on("error", () => {
|
|
63809
63867
|
});
|
|
63810
|
-
const client = new PiRpcClient(proc);
|
|
63868
|
+
const client = new PiRpcClient(piStdioLineStream(proc));
|
|
63811
63869
|
const timeoutMs = deps.timeoutMs ?? 15e3;
|
|
63812
63870
|
let timer;
|
|
63813
63871
|
let timedOut = false;
|
|
@@ -71092,7 +71150,7 @@ function computeMethodAccess(args) {
|
|
|
71092
71150
|
}
|
|
71093
71151
|
|
|
71094
71152
|
// src/version.ts
|
|
71095
|
-
var version = "0.2.
|
|
71153
|
+
var version = "0.2.561".length > 0 ? "0.2.561" : "dev";
|
|
71096
71154
|
|
|
71097
71155
|
// src/cli-probe/probe.ts
|
|
71098
71156
|
var fs78 = __toESM(require("fs"), 1);
|
|
@@ -74485,7 +74543,7 @@ async function startDaemon(config) {
|
|
|
74485
74543
|
skills,
|
|
74486
74544
|
agents,
|
|
74487
74545
|
// skills:list 按 tool 路由:codex → app-server skills/list;缺省 claude → SkillsScanner(同步包成 Promise)。
|
|
74488
|
-
getSkillsForTool: (tool, cwd) => tool === "codex" ? listCodexSkills(cwd) : tool
|
|
74546
|
+
getSkillsForTool: (tool, cwd) => tool === "codex" ? listCodexSkills(cwd) : isCloudTool(tool) ? Promise.resolve([]) : Promise.resolve(skills.list({ cwd })),
|
|
74489
74547
|
history,
|
|
74490
74548
|
// history:read 按 session.tool 路由:codex → adapter.historyReader(CodexHistoryReader);缺省 claude。
|
|
74491
74549
|
getHistoryReader: (tool) => getAdapter(tool).historyReader ?? history,
|
|
@@ -24564,6 +24564,8 @@ var INNER_TAG_UNESCAPE_RE = new RegExp(`<\\\\(\\\\*)(/?)(${INNER_TAG_NAMES})\\b`
|
|
|
24564
24564
|
// ../protocol/src/tool-family.ts
|
|
24565
24565
|
var CLOUD_TOOL_SUFFIX = "-cloud";
|
|
24566
24566
|
var CODEX_CLOUD_TOOL_ID = `codex${CLOUD_TOOL_SUFFIX}`;
|
|
24567
|
+
var PI_TOOL_ID = "pi";
|
|
24568
|
+
var PI_CLOUD_TOOL_ID = `${PI_TOOL_ID}${CLOUD_TOOL_SUFFIX}`;
|
|
24567
24569
|
|
|
24568
24570
|
// src/tools/claude-history.ts
|
|
24569
24571
|
var import_node_crypto = __toESM(require("crypto"), 1);
|
|
@@ -24750,6 +24750,8 @@ var INNER_TAG_UNESCAPE_RE = new RegExp(`<\\\\(\\\\*)(/?)(${INNER_TAG_NAMES})\\b`
|
|
|
24750
24750
|
// ../protocol/src/tool-family.ts
|
|
24751
24751
|
var CLOUD_TOOL_SUFFIX = "-cloud";
|
|
24752
24752
|
var CODEX_CLOUD_TOOL_ID = `codex${CLOUD_TOOL_SUFFIX}`;
|
|
24753
|
+
var PI_TOOL_ID = "pi";
|
|
24754
|
+
var PI_CLOUD_TOOL_ID = `${PI_TOOL_ID}${CLOUD_TOOL_SUFFIX}`;
|
|
24753
24755
|
|
|
24754
24756
|
// src/deploy/deploy-file.ts
|
|
24755
24757
|
var import_promises = __toESM(require("fs/promises"), 1);
|
|
@@ -24750,6 +24750,8 @@ var INNER_TAG_UNESCAPE_RE = new RegExp(`<\\\\(\\\\*)(/?)(${INNER_TAG_NAMES})\\b`
|
|
|
24750
24750
|
// ../protocol/src/tool-family.ts
|
|
24751
24751
|
var CLOUD_TOOL_SUFFIX = "-cloud";
|
|
24752
24752
|
var CODEX_CLOUD_TOOL_ID = `codex${CLOUD_TOOL_SUFFIX}`;
|
|
24753
|
+
var PI_TOOL_ID = "pi";
|
|
24754
|
+
var PI_CLOUD_TOOL_ID = `${PI_TOOL_ID}${CLOUD_TOOL_SUFFIX}`;
|
|
24753
24755
|
|
|
24754
24756
|
// src/deploy/deploy-file.ts
|
|
24755
24757
|
var import_promises = __toESM(require("fs/promises"), 1);
|