@code-yeongyu/senpi 2026.8.31 → 2026.9.2-4
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/CHANGELOG.md +119 -2
- package/dist/beta/omo-local-update-fingerprint.d.ts.map +1 -1
- package/dist/beta/omo-local-update-fingerprint.js +0 -1
- package/dist/beta/omo-local-update-fingerprint.js.map +1 -1
- package/dist/core/agent-session.d.ts +1 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +7 -4
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/options.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/options.js +6 -2
- package/dist/core/extensions/builtin/claude-sdk-oauth/options.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/stream.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/stream.js +2 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/stream.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/context-pipeline.d.ts +6 -0
- package/dist/core/extensions/builtin/compaction/context-pipeline.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/context-pipeline.js +11 -0
- package/dist/core/extensions/builtin/compaction/context-pipeline.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/extension-wiring.js +1 -1
- package/dist/core/extensions/builtin/compaction/extension-wiring.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.js +4 -4
- package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.d.ts +3 -0
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.d.ts.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.js +110 -0
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.js.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js +2 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-5.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-5.js +7 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-5.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-6.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-6.js +7 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-6.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-7.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-7.js +7 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-7.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-8.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-8.js +7 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-8.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-5.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-5.js +2 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-5.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/execution-tooling.d.ts +50 -0
- package/dist/core/extensions/builtin/prompt-preset/execution-tooling.d.ts.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset/execution-tooling.js +66 -0
- package/dist/core/extensions/builtin/prompt-preset/execution-tooling.js.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts +5 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js +6 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k2-6.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k2-6.js +11 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k2-6.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.js +11 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k3.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js +2 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/presets.js +18 -1
- package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.d.ts +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.js +1 -0
- package/dist/core/extensions/builtin/prompt-preset/settings.js.map +1 -1
- package/dist/core/extensions/builtin/recommended-models/index.d.ts +1 -1
- package/dist/core/extensions/builtin/recommended-models/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/recommended-models/index.js +1 -1
- package/dist/core/extensions/builtin/recommended-models/index.js.map +1 -1
- package/dist/core/provider-composer.d.ts.map +1 -1
- package/dist/core/provider-composer.js +17 -8
- package/dist/core/provider-composer.js.map +1 -1
- package/dist/core/retry-fallback/settings.d.ts.map +1 -1
- package/dist/core/retry-fallback/settings.js +1 -0
- package/dist/core/retry-fallback/settings.js.map +1 -1
- package/dist/core/settings-manager.d.ts +2 -2
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +5 -3
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +4 -4
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +10 -6
- package/dist/main.js.map +1 -1
- package/dist/modes/app-server/daemon/process.d.ts +13 -2
- package/dist/modes/app-server/daemon/process.d.ts.map +1 -1
- package/dist/modes/app-server/daemon/process.js +58 -12
- package/dist/modes/app-server/daemon/process.js.map +1 -1
- package/dist/modes/app-server/daemon.js +62 -4
- package/dist/modes/app-server/daemon.js.map +1 -1
- package/dist/modes/index.d.ts +1 -1
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/index.js +1 -1
- package/dist/modes/index.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +11 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +35 -6
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/tips/catalog/ethos-tips.js +1 -1
- package/dist/modes/interactive/tips/catalog/ethos-tips.js.map +1 -1
- package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
- package/dist/modes/rpc/connection-handler.js +8 -3
- package/dist/modes/rpc/connection-handler.js.map +1 -1
- package/dist/modes/rpc/custom-capability.d.ts +1 -0
- package/dist/modes/rpc/custom-capability.d.ts.map +1 -1
- package/dist/modes/rpc/custom-capability.js +1 -0
- package/dist/modes/rpc/custom-capability.js.map +1 -1
- package/dist/modes/rpc/host-ensure.d.ts.map +1 -1
- package/dist/modes/rpc/host-ensure.js +114 -22
- package/dist/modes/rpc/host-ensure.js.map +1 -1
- package/dist/modes/rpc/host-lifecycle.d.ts +15 -0
- package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -1
- package/dist/modes/rpc/host-lifecycle.js +180 -55
- package/dist/modes/rpc/host-lifecycle.js.map +1 -1
- package/dist/modes/rpc/host-watchdog.d.ts +2 -2
- package/dist/modes/rpc/host-watchdog.d.ts.map +1 -1
- package/dist/modes/rpc/host-watchdog.js +89 -21
- package/dist/modes/rpc/host-watchdog.js.map +1 -1
- package/dist/modes/rpc/multi-session-host.d.ts +4 -4
- package/dist/modes/rpc/multi-session-host.d.ts.map +1 -1
- package/dist/modes/rpc/multi-session-host.js +98 -60
- package/dist/modes/rpc/multi-session-host.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +8 -0
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +70 -8
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
- package/dist/modes/rpc/session-command-router.js +7 -2
- package/dist/modes/rpc/session-command-router.js.map +1 -1
- package/dist/modes/rpc/session-event-fanout.d.ts +38 -0
- package/dist/modes/rpc/session-event-fanout.d.ts.map +1 -0
- package/dist/modes/rpc/session-event-fanout.js +133 -0
- package/dist/modes/rpc/session-event-fanout.js.map +1 -0
- package/dist/modes/rpc/session-event-writer.d.ts +4 -13
- package/dist/modes/rpc/session-event-writer.d.ts.map +1 -1
- package/dist/modes/rpc/session-event-writer.js +34 -96
- package/dist/modes/rpc/session-event-writer.js.map +1 -1
- package/dist/modes/rpc/socket-transport.d.ts +13 -0
- package/dist/modes/rpc/socket-transport.d.ts.map +1 -0
- package/dist/modes/rpc/socket-transport.js +92 -0
- package/dist/modes/rpc/socket-transport.js.map +1 -0
- package/docs/extensions.md +1 -1
- package/docs/rpc.md +11 -5
- package/docs/settings.md +8 -8
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +57 -0
- package/node_modules/@code-yeongyu/senpi-codemode/README.md +4 -2
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/extension/skill-contribution.ts +43 -9
- package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +4 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +10 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/SKILL.md +1 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/runtime-apis.md +1 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool-options.ts +3 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +2 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts +3 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +2 -2
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.d.ts +5 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.js +26 -4
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/anthropic.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/google.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/groq.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opengateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/profiles.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/profiles.js +3 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/profiles.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +2 -2
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +7 -7
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"socket-transport.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/socket-transport.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAIvC,eAAO,MAAM,mBAAmB,KAAK,CAAC;AACtC,eAAO,MAAM,oBAAoB,YAAY,CAAC;AAC9C,eAAO,MAAM,sBAAsB,iCAAiC,CAAC;AACrE,eAAO,MAAM,2BAA2B,OAAQ,CAAC;AAEjD,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAO5D;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQtE;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMtE;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAIpE;AAED,wBAAgB,6BAA6B,CAC5C,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,CAAC,QAAQ,EACzB,MAAM,CAAC,EAAE,UAAU,GACjB,MAAM,CAUR;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,IAAI,GAAG,IAAI,CA8BxG;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAE5E"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { createHash, randomBytes, timingSafeEqual } from "node:crypto";
|
|
2
|
+
import { chmod, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
3
|
+
import { dirname, win32 } from "node:path";
|
|
4
|
+
const WINDOWS_PIPE_PREFIX = "\\\\.\\pipe\\senpi-rpc-";
|
|
5
|
+
export const SOCKET_SECRET_BYTES = 32;
|
|
6
|
+
export const SOCKET_SECRET_SUFFIX = ".secret";
|
|
7
|
+
export const SOCKET_SECRET_FILE_ENV = "SENPI_RPC_SOCKET_SECRET_FILE";
|
|
8
|
+
export const SOCKET_HANDSHAKE_TIMEOUT_MS = 2_000;
|
|
9
|
+
export function socketSecretPath(logicalPath) {
|
|
10
|
+
if (logicalPath.toLowerCase().startsWith("\\\\.\\pipe\\")) {
|
|
11
|
+
throw new Error(`Windows RPC named-pipe addresses need a logical filesystem path for their secret: ${logicalPath}`);
|
|
12
|
+
}
|
|
13
|
+
return `${logicalPath}${SOCKET_SECRET_SUFFIX}`;
|
|
14
|
+
}
|
|
15
|
+
export async function ensureSocketSecret(path) {
|
|
16
|
+
try {
|
|
17
|
+
const existing = await readFile(path);
|
|
18
|
+
if (existing.length === SOCKET_SECRET_BYTES)
|
|
19
|
+
return existing;
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
if (!isNodeErrorCode(error, "ENOENT"))
|
|
23
|
+
throw error;
|
|
24
|
+
}
|
|
25
|
+
return createSocketSecret(path);
|
|
26
|
+
}
|
|
27
|
+
export async function createSocketSecret(path) {
|
|
28
|
+
await mkdir(dirname(path), { recursive: true });
|
|
29
|
+
const secret = randomBytes(SOCKET_SECRET_BYTES);
|
|
30
|
+
await writeFile(path, secret, { mode: 0o600 });
|
|
31
|
+
await chmod(path, 0o600);
|
|
32
|
+
return secret;
|
|
33
|
+
}
|
|
34
|
+
export async function readSocketSecret(path) {
|
|
35
|
+
const secret = await readFile(path);
|
|
36
|
+
if (secret.length !== SOCKET_SECRET_BYTES)
|
|
37
|
+
throw new Error(`invalid RPC socket secret: ${path}`);
|
|
38
|
+
return secret;
|
|
39
|
+
}
|
|
40
|
+
export function resolveSocketTransportAddress(socketPath, platform, secret) {
|
|
41
|
+
if (platform !== "win32")
|
|
42
|
+
return socketPath;
|
|
43
|
+
if (socketPath.toLowerCase().startsWith("\\\\.\\pipe\\"))
|
|
44
|
+
return socketPath;
|
|
45
|
+
if (!/^[a-zA-Z]:[\\/]/.test(socketPath) && !/^\\\\[^/]/.test(socketPath)) {
|
|
46
|
+
throw new Error(`Windows RPC socket path must be drive-qualified or UNC: ${socketPath}`);
|
|
47
|
+
}
|
|
48
|
+
const canonical = win32.normalize(socketPath).toLowerCase();
|
|
49
|
+
const identity = Buffer.concat([Buffer.from(canonical, "utf8"), Buffer.from(secret ?? [])]);
|
|
50
|
+
const name = createHash("sha256").update(identity).digest("hex").slice(0, 32);
|
|
51
|
+
return `${WINDOWS_PIPE_PREFIX}${name}`;
|
|
52
|
+
}
|
|
53
|
+
export function authenticateSocket(socket, secret, onAuthenticated) {
|
|
54
|
+
let received = Buffer.alloc(0);
|
|
55
|
+
const finish = () => {
|
|
56
|
+
clearTimeout(timer);
|
|
57
|
+
socket.off("data", onData);
|
|
58
|
+
socket.off("error", onError);
|
|
59
|
+
};
|
|
60
|
+
const onError = () => {
|
|
61
|
+
finish();
|
|
62
|
+
socket.destroy();
|
|
63
|
+
};
|
|
64
|
+
const timer = setTimeout(() => {
|
|
65
|
+
finish();
|
|
66
|
+
socket.destroy();
|
|
67
|
+
}, SOCKET_HANDSHAKE_TIMEOUT_MS);
|
|
68
|
+
const onData = (chunk) => {
|
|
69
|
+
received = Buffer.concat([received, chunk]);
|
|
70
|
+
if (received.length < secret.length)
|
|
71
|
+
return;
|
|
72
|
+
finish();
|
|
73
|
+
if (!timingSafeEqual(received.subarray(0, secret.length), Buffer.from(secret))) {
|
|
74
|
+
socket.destroy();
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const remainder = received.subarray(secret.length);
|
|
78
|
+
if (remainder.length > 0)
|
|
79
|
+
socket.unshift(remainder);
|
|
80
|
+
onAuthenticated();
|
|
81
|
+
};
|
|
82
|
+
socket.on("data", onData);
|
|
83
|
+
socket.once("error", onError);
|
|
84
|
+
socket.once("close", finish);
|
|
85
|
+
}
|
|
86
|
+
export function sendSocketHandshake(socket, secret) {
|
|
87
|
+
socket.write(Buffer.from(secret));
|
|
88
|
+
}
|
|
89
|
+
function isNodeErrorCode(error, code) {
|
|
90
|
+
return error instanceof Error && "code" in error && error.code === code;
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=socket-transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"socket-transport.js","sourceRoot":"","sources":["../../../src/modes/rpc/socket-transport.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash, randomBytes, timingSafeEqual } from \"node:crypto\";\nimport { chmod, mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport type { Socket } from \"node:net\";\nimport { dirname, win32 } from \"node:path\";\n\nconst WINDOWS_PIPE_PREFIX = \"\\\\\\\\.\\\\pipe\\\\senpi-rpc-\";\nexport const SOCKET_SECRET_BYTES = 32;\nexport const SOCKET_SECRET_SUFFIX = \".secret\";\nexport const SOCKET_SECRET_FILE_ENV = \"SENPI_RPC_SOCKET_SECRET_FILE\";\nexport const SOCKET_HANDSHAKE_TIMEOUT_MS = 2_000;\n\nexport function socketSecretPath(logicalPath: string): string {\n\tif (logicalPath.toLowerCase().startsWith(\"\\\\\\\\.\\\\pipe\\\\\")) {\n\t\tthrow new Error(\n\t\t\t`Windows RPC named-pipe addresses need a logical filesystem path for their secret: ${logicalPath}`,\n\t\t);\n\t}\n\treturn `${logicalPath}${SOCKET_SECRET_SUFFIX}`;\n}\n\nexport async function ensureSocketSecret(path: string): Promise<Buffer> {\n\ttry {\n\t\tconst existing = await readFile(path);\n\t\tif (existing.length === SOCKET_SECRET_BYTES) return existing;\n\t} catch (error: unknown) {\n\t\tif (!isNodeErrorCode(error, \"ENOENT\")) throw error;\n\t}\n\treturn createSocketSecret(path);\n}\n\nexport async function createSocketSecret(path: string): Promise<Buffer> {\n\tawait mkdir(dirname(path), { recursive: true });\n\tconst secret = randomBytes(SOCKET_SECRET_BYTES);\n\tawait writeFile(path, secret, { mode: 0o600 });\n\tawait chmod(path, 0o600);\n\treturn secret;\n}\n\nexport async function readSocketSecret(path: string): Promise<Buffer> {\n\tconst secret = await readFile(path);\n\tif (secret.length !== SOCKET_SECRET_BYTES) throw new Error(`invalid RPC socket secret: ${path}`);\n\treturn secret;\n}\n\nexport function resolveSocketTransportAddress(\n\tsocketPath: string,\n\tplatform: NodeJS.Platform,\n\tsecret?: Uint8Array,\n): string {\n\tif (platform !== \"win32\") return socketPath;\n\tif (socketPath.toLowerCase().startsWith(\"\\\\\\\\.\\\\pipe\\\\\")) return socketPath;\n\tif (!/^[a-zA-Z]:[\\\\/]/.test(socketPath) && !/^\\\\\\\\[^/]/.test(socketPath)) {\n\t\tthrow new Error(`Windows RPC socket path must be drive-qualified or UNC: ${socketPath}`);\n\t}\n\tconst canonical = win32.normalize(socketPath).toLowerCase();\n\tconst identity = Buffer.concat([Buffer.from(canonical, \"utf8\"), Buffer.from(secret ?? [])]);\n\tconst name = createHash(\"sha256\").update(identity).digest(\"hex\").slice(0, 32);\n\treturn `${WINDOWS_PIPE_PREFIX}${name}`;\n}\n\nexport function authenticateSocket(socket: Socket, secret: Uint8Array, onAuthenticated: () => void): void {\n\tlet received = Buffer.alloc(0);\n\tconst finish = (): void => {\n\t\tclearTimeout(timer);\n\t\tsocket.off(\"data\", onData);\n\t\tsocket.off(\"error\", onError);\n\t};\n\tconst onError = (): void => {\n\t\tfinish();\n\t\tsocket.destroy();\n\t};\n\tconst timer = setTimeout(() => {\n\t\tfinish();\n\t\tsocket.destroy();\n\t}, SOCKET_HANDSHAKE_TIMEOUT_MS);\n\tconst onData = (chunk: Buffer): void => {\n\t\treceived = Buffer.concat([received, chunk]);\n\t\tif (received.length < secret.length) return;\n\t\tfinish();\n\t\tif (!timingSafeEqual(received.subarray(0, secret.length), Buffer.from(secret))) {\n\t\t\tsocket.destroy();\n\t\t\treturn;\n\t\t}\n\t\tconst remainder = received.subarray(secret.length);\n\t\tif (remainder.length > 0) socket.unshift(remainder);\n\t\tonAuthenticated();\n\t};\n\tsocket.on(\"data\", onData);\n\tsocket.once(\"error\", onError);\n\tsocket.once(\"close\", finish);\n}\n\nexport function sendSocketHandshake(socket: Socket, secret: Uint8Array): void {\n\tsocket.write(Buffer.from(secret));\n}\n\nfunction isNodeErrorCode(error: unknown, code: string): boolean {\n\treturn error instanceof Error && \"code\" in error && error.code === code;\n}\n"]}
|
package/docs/extensions.md
CHANGED
|
@@ -116,7 +116,7 @@ The bundled `model-fallback` extension registers `/fallback` to manage global pe
|
|
|
116
116
|
Use the quick-set form in scripts or any non-TUI mode:
|
|
117
117
|
|
|
118
118
|
```text
|
|
119
|
-
/fallback anthropic/claude-fable-5 ccapi/kimi-k3:max
|
|
119
|
+
/fallback anthropic/claude-fable-5-1 ccapi/kimi-k3:max
|
|
120
120
|
```
|
|
121
121
|
|
|
122
122
|
The first argument is the exact primary model selector; each later argument is an ordered fallback selector. Quick-set validates selectors before saving. At least one fallback is required:
|
package/docs/rpc.md
CHANGED
|
@@ -49,7 +49,7 @@ Multi-session mode lets one `senpi --mode rpc` process serve several independent
|
|
|
49
49
|
# Shared JSONL over stdio (legacy multi-session host)
|
|
50
50
|
senpi --mode rpc --multi-session [options]
|
|
51
51
|
|
|
52
|
-
# One shared host over a
|
|
52
|
+
# One shared host over a local socket; each accepted connection has its own JSONL feed
|
|
53
53
|
senpi --mode rpc --listen unix:///tmp/senpi-rpc.sock [options]
|
|
54
54
|
senpi --mode rpc --listen /tmp/senpi-rpc.sock [options]
|
|
55
55
|
```
|
|
@@ -58,10 +58,16 @@ senpi --mode rpc --listen /tmp/senpi-rpc.sock [options]
|
|
|
58
58
|
`unix://@name` where supported by the host platform. Socket mode accepts concurrent connections while retaining one
|
|
59
59
|
process-global session registry.
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
On Windows, listeners and clients deterministically map the logical socket path to
|
|
62
|
+
`\\.\pipe\senpi-rpc-<sha256[:32]>`. Callers keep using the same `unix://` CLI value; the logical path remains the
|
|
63
|
+
ownership and settings identity, and callers never construct the pipe name themselves.
|
|
64
|
+
|
|
65
|
+
Socket event visibility is attachment-scoped: each connection receives agent events only from sessions attached to that
|
|
66
|
+
connection, with every record tagged by its routing `sessionId`. Content-free `session_closed` lifecycle records remain
|
|
67
|
+
broadcast to all connections so observers can track the session roster. Correlated responses and dialog extension UI
|
|
68
|
+
requests (select, confirm, input, and editor) are requester-only; other extension UI state records go to the session's
|
|
69
|
+
attached connections. To observe a foreign session, open it by its existing
|
|
70
|
+
`sessionPath`; the host attaches that connection during `open_session`.
|
|
65
71
|
|
|
66
72
|
### Client information and rendered components
|
|
67
73
|
|
package/docs/settings.md
CHANGED
|
@@ -87,7 +87,7 @@ Permission rules are a confirmation policy, not a sandbox. Senpi, extensions, pa
|
|
|
87
87
|
| `modelThinkingLevels` | object | - | Per-model reasoning effort memory (`"provider/id": "level"`) |
|
|
88
88
|
| `modelLastOnThinkingLevels` | object | - | Per-model last non-off reasoning level, used by `/reasoning on` to restore the previous effort |
|
|
89
89
|
| `modelServiceTiers` | object | - | Per-model service tier memory (`"provider/id": "auto" \| "priority"`) |
|
|
90
|
-
| `promptPreset` | string | `"auto"` | Force a system prompt preset: `"auto"`, `"kimi-k2-6"`, `"kimi-k2-7"`, `"kimi-k3"`, `"glm-5.2"`, `"glm-5.3"`, `"grok-4.5"`, `"grok-4.6"`, `"claude-fable-5"`, `"claude-opus-5"`, `"claude-opus-4-5"`, `"claude-opus-4-6"`, `"claude-opus-4-7"`, `"claude-opus-4-8"`, `"deepseek-v4-flash"`, `"deepseek-v4-flash-0731"`, `"deepseek-v4-pro"`, `"gpt-5"`, `"gpt-5.2"`, `"gpt-5.3-codex"`, `"gpt-5.4"`, `"gpt-5.5"`, or `"gpt-5.6"` |
|
|
90
|
+
| `promptPreset` | string | `"auto"` | Force a system prompt preset: `"auto"`, `"kimi-k2-6"`, `"kimi-k2-7"`, `"kimi-k3"`, `"glm-5.2"`, `"glm-5.3"`, `"grok-4.5"`, `"grok-4.6"`, `"claude-fable-5"`, `"claude-fable-5-1"`, `"claude-opus-5"`, `"claude-opus-4-5"`, `"claude-opus-4-6"`, `"claude-opus-4-7"`, `"claude-opus-4-8"`, `"deepseek-v4-flash"`, `"deepseek-v4-flash-0731"`, `"deepseek-v4-pro"`, `"gpt-5"`, `"gpt-5.2"`, `"gpt-5.3-codex"`, `"gpt-5.4"`, `"gpt-5.5"`, or `"gpt-5.6"` |
|
|
91
91
|
| `hideThinkingBlock` | boolean | `false` | Hide thinking blocks in output |
|
|
92
92
|
| `showCacheMissNotices` | boolean | `false` | Show transcript notices for significant prompt-cache misses and compaction or branch-summary usage |
|
|
93
93
|
| `thinkingBudgets` | object | - | Custom token budgets per thinking level. Anthropic, Google, and Bedrock use these natively. OpenAI-compatible models use them when `compat.thinkingTokenBudgetField` (or `supportsThinkingTokenBudget`) is set. |
|
|
@@ -212,14 +212,14 @@ Set `PI_SKIP_VERSION_CHECK=1` to disable the senpi version update check. Use `--
|
|
|
212
212
|
| Setting | Type | Default | Description |
|
|
213
213
|
|---------|------|---------|-------------|
|
|
214
214
|
| `retry.enabled` | boolean | `true` | Enable automatic agent-level retry on transient errors |
|
|
215
|
-
| `retry.maxRetries` | number | `
|
|
215
|
+
| `retry.maxRetries` | number | `5` | Maximum agent-level retry attempts |
|
|
216
216
|
| `retry.baseDelayMs` | number | `2000` | Base delay for agent-level exponential backoff (2s, 4s, 8s) |
|
|
217
217
|
| `retry.modelFallback` | boolean | `true` | Let eligible retry failures advance through configured per-model fallback chains |
|
|
218
218
|
| `retry.fallbackChains` | `Record<string, string[]>` | `{}` | Ordered exact model-selector to fallback-selector chains |
|
|
219
219
|
| `retry.fallbackRevertPolicy` | `"cooldown-expiry"` \| `"never"` | `"cooldown-expiry"` | Automatic primary-model restoration policy |
|
|
220
220
|
| `retry.abortServerSideFallback` | boolean | `true` | Abort a turn when the provider substitutes a different model after a classifier decline |
|
|
221
221
|
| `retry.provider.timeoutMs` | number | `300000` | Provider/SDK request timeout and stream idle timeout in milliseconds |
|
|
222
|
-
| `retry.provider.streamStartTimeoutMs` | number | `
|
|
222
|
+
| `retry.provider.streamStartTimeoutMs` | number | `300000` | Maximum wait for the first provider stream event; `0` disables |
|
|
223
223
|
| `retry.provider.streamRetryTimeoutMs` | number | `30000` | First-request liveness cap after a known provider stream/transport timeout; `0` disables the cap |
|
|
224
224
|
| `retry.provider.maxRetries` | number | `0` | Provider/SDK retry attempts |
|
|
225
225
|
| `retry.provider.maxRetryDelayMs` | number | `60000` | Max server-requested delay honored on the same model before the fallback chain engages (60s) |
|
|
@@ -236,11 +236,11 @@ Keep `retry.provider.maxRetries` at `0` unless provider-level retries are explic
|
|
|
236
236
|
{
|
|
237
237
|
"retry": {
|
|
238
238
|
"enabled": true,
|
|
239
|
-
"maxRetries":
|
|
239
|
+
"maxRetries": 5,
|
|
240
240
|
"baseDelayMs": 2000,
|
|
241
241
|
"provider": {
|
|
242
242
|
"timeoutMs": 3600000,
|
|
243
|
-
"streamStartTimeoutMs":
|
|
243
|
+
"streamStartTimeoutMs": 300000,
|
|
244
244
|
"streamRetryTimeoutMs": 30000,
|
|
245
245
|
"maxRetries": 0,
|
|
246
246
|
"maxRetryDelayMs": 60000
|
|
@@ -251,14 +251,14 @@ Keep `retry.provider.maxRetries` at `0` unless provider-level retries are explic
|
|
|
251
251
|
|
|
252
252
|
#### Model fallback chains
|
|
253
253
|
|
|
254
|
-
`retry.fallbackChains` maps a primary-model selector to an ordered list of fallback selectors. A selector is `provider/model` with an optional `:thinking-level` suffix, or a bare `model` id that applies to every provider serving that model family. Bare selectors expand against the models you actually have: providers holding an OAuth credential are preferred, then a fixed precedence order, and OpenRouter is never chosen by expansion. Senpi ships
|
|
254
|
+
`retry.fallbackChains` maps a primary-model selector to an ordered list of fallback selectors. A selector is `provider/model` with an optional `:thinking-level` suffix, or a bare `model` id that applies to every provider serving that model family. Bare selectors expand against the models you actually have: providers holding an OAuth credential are preferred, then a fixed precedence order, and OpenRouter is never chosen by expansion. Senpi ships bare default chains for `claude-fable-5-1` and `claude-fable-5`, so Fable 5.1 and Fable 5 keep a fallback chain whichever provider serves them; set a key to `[]` to opt out entirely, or set one `provider/claude-fable-5-1` key to override just that provider. For example, this switches Fable 5.1 to Kimi K3 at `max` thinking when an eligible failure occurs:
|
|
255
255
|
|
|
256
256
|
```json
|
|
257
257
|
{
|
|
258
258
|
"retry": {
|
|
259
259
|
"modelFallback": true,
|
|
260
260
|
"fallbackChains": {
|
|
261
|
-
"anthropic/claude-fable-5": ["ccapi/kimi-k3:max"]
|
|
261
|
+
"anthropic/claude-fable-5-1": ["ccapi/kimi-k3:max"]
|
|
262
262
|
},
|
|
263
263
|
"fallbackRevertPolicy": "cooldown-expiry"
|
|
264
264
|
}
|
|
@@ -488,7 +488,7 @@ When multiple sources specify a session directory, precedence is `--session-dir`
|
|
|
488
488
|
{
|
|
489
489
|
"modelThinkingLevels": {
|
|
490
490
|
"openai-codex/gpt-5.6-sol": "xhigh",
|
|
491
|
-
"anthropic/claude-fable-5": "high"
|
|
491
|
+
"anthropic/claude-fable-5-1": "high"
|
|
492
492
|
},
|
|
493
493
|
"modelServiceTiers": {
|
|
494
494
|
"openai-codex/gpt-5.6-sol": "priority"
|
|
@@ -12,6 +12,63 @@
|
|
|
12
12
|
|
|
13
13
|
### Removed
|
|
14
14
|
|
|
15
|
+
## [2026.9.2-4] - 2026-09-02
|
|
16
|
+
|
|
17
|
+
### Breaking Changes
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
### Removed
|
|
26
|
+
|
|
27
|
+
## [2026.9.2-3] - 2026-09-02
|
|
28
|
+
|
|
29
|
+
### Breaking Changes
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- The eval prompt's JS runtime line is now runtime-aware: on a bun kernel it names `Bun <version>` and
|
|
36
|
+
`Bun.*` builtins, and only while the bundled `bun-1-4` skill is active it adds a MUST READ pointer to
|
|
37
|
+
that skill's absolute path before the first js cell; node kernels keep the Node.js worker wording.
|
|
38
|
+
`activeBunSkillPath()` exposes the same gate the `resources_discover` contribution uses.
|
|
39
|
+
- The bundled `bun-1-4` skill description is rewritten as a fact-framed MUST READ notice with
|
|
40
|
+
English-only copy (Korean trigger words removed; the `Bun.stringWidth` example no longer uses Hangul).
|
|
41
|
+
|
|
42
|
+
### Fixed
|
|
43
|
+
|
|
44
|
+
- Compiled binaries now contribute the bundled `bun-1-4` skill by resolving the codemode sidecar shipped next to the executable, and a missing skill is reported on stderr so it can no longer corrupt the RPC protocol stream on stdout.
|
|
45
|
+
|
|
46
|
+
### Removed
|
|
47
|
+
|
|
48
|
+
## [2026.9.2-2] - 2026-09-02
|
|
49
|
+
|
|
50
|
+
### Breaking Changes
|
|
51
|
+
|
|
52
|
+
### Added
|
|
53
|
+
|
|
54
|
+
### Changed
|
|
55
|
+
|
|
56
|
+
### Fixed
|
|
57
|
+
|
|
58
|
+
### Removed
|
|
59
|
+
|
|
60
|
+
## [2026.9.2] - 2026-09-02
|
|
61
|
+
|
|
62
|
+
### Breaking Changes
|
|
63
|
+
|
|
64
|
+
### Added
|
|
65
|
+
|
|
66
|
+
### Changed
|
|
67
|
+
|
|
68
|
+
### Fixed
|
|
69
|
+
|
|
70
|
+
### Removed
|
|
71
|
+
|
|
15
72
|
## [2026.8.31] - 2026-08-31
|
|
16
73
|
|
|
17
74
|
### Breaking Changes
|
|
@@ -36,7 +36,9 @@ task-tool names are known.
|
|
|
36
36
|
resolves absolute executable paths, and the eval prompt host line names the
|
|
37
37
|
JS runtime (`node`/`bun`).
|
|
38
38
|
- JavaScript import rewriting for supported local modules and package imports
|
|
39
|
-
in the persistent Node.js
|
|
39
|
+
in the persistent JS worker (Bun when senpi runs on bun, Node.js otherwise).
|
|
40
|
+
- On a Bun >= 1.4 kernel the eval prompt names the bundled `bun-1-4` skill as
|
|
41
|
+
MUST READ before the first js cell; node kernels keep the Node.js wording.
|
|
40
42
|
- GPT models receive a terse `eval` prompt dialect that prioritizes composing
|
|
41
43
|
active tools through `tool.<name>(args)` and documents detach-on-timeout.
|
|
42
44
|
|
|
@@ -44,7 +46,7 @@ task-tool names are known.
|
|
|
44
46
|
|
|
45
47
|
| Language | Default | Runtime | Notes |
|
|
46
48
|
| --- | --- | --- | --- |
|
|
47
|
-
| `js` | enabled |
|
|
49
|
+
| `js` | enabled | In-process worker on senpi's own runtime (Bun or Node.js 24+) | Supports top-level `await` and `return`; the eval prompt's runtime line follows the kernel. |
|
|
48
50
|
| `py` | enabled | `python3` or `python` | Optional interpreter detected at session start. |
|
|
49
51
|
| `rb` | disabled | `ruby` | Optional interpreter detected at session start. |
|
|
50
52
|
| `jl` | disabled | `julia` | Optional interpreter detected at session start. |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-yeongyu/senpi-codemode",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.9.2-4",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Source-only senpi extension package for codemode evaluation tools",
|
|
6
6
|
"type": "module",
|
|
@@ -31,14 +31,14 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@babel/parser": "8.0.4",
|
|
34
|
-
"@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.
|
|
34
|
+
"@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.9.2-4",
|
|
35
35
|
"typebox": "1.3.18"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
|
-
"@code-yeongyu/senpi": "2026.
|
|
38
|
+
"@code-yeongyu/senpi": "2026.9.2-4"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@code-yeongyu/senpi": "2026.
|
|
41
|
+
"@code-yeongyu/senpi": "2026.9.2-4"
|
|
42
42
|
},
|
|
43
43
|
"keywords": [
|
|
44
44
|
"senpi",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { type CodemodeRuntimeAssetEnvironment, resolveCodemodeRuntimeAsset } from "../kernels/shared/runtime-asset.ts";
|
|
4
5
|
|
|
5
6
|
const BUN_SKILL_BASE_DIR = dirname(fileURLToPath(import.meta.url));
|
|
6
7
|
|
|
@@ -27,29 +28,62 @@ export function bunVersionSupportsSkill(version: string | undefined): boolean {
|
|
|
27
28
|
return major > 1 || (major === 1 && minor >= 4);
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
const BUN_SKILL_PACKAGE_RELATIVE_PATH = join("skill", "bun-1-4", "SKILL.md");
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Absolute path of the bundled bun-1-4 SKILL.md, or undefined (logged once) when it is not shipped.
|
|
35
|
+
*
|
|
36
|
+
* A compiled Bun binary has no readable module-relative asset, so resolution falls back to the
|
|
37
|
+
* codemode sidecar shipped next to the executable, exactly as the Ruby and Julia kernel runners do.
|
|
38
|
+
* The miss is reported on stderr because stdout carries the RPC protocol stream.
|
|
39
|
+
*/
|
|
40
|
+
export function bundledBunSkillPath(
|
|
41
|
+
baseDir: string = BUN_SKILL_BASE_DIR,
|
|
42
|
+
environment: CodemodeRuntimeAssetEnvironment = {},
|
|
43
|
+
): string | undefined {
|
|
44
|
+
const localPath = join(baseDir, "..", "skill", "bun-1-4", "SKILL.md");
|
|
45
|
+
const candidate = resolveCodemodeRuntimeAsset(localPath, BUN_SKILL_PACKAGE_RELATIVE_PATH, environment);
|
|
33
46
|
if (existsSync(candidate)) return candidate;
|
|
34
47
|
if (!loggedMissingBunSkill) {
|
|
35
48
|
loggedMissingBunSkill = true;
|
|
36
|
-
|
|
49
|
+
// A compiled binary never has the module-relative asset, so naming only that path
|
|
50
|
+
// would hide the sidecar location an operator actually has to populate.
|
|
51
|
+
const executableDir = dirname(environment.executablePath ?? process.execPath);
|
|
52
|
+
const sidecarPath = join(
|
|
53
|
+
executableDir,
|
|
54
|
+
"node_modules",
|
|
55
|
+
"@code-yeongyu",
|
|
56
|
+
"senpi-codemode",
|
|
57
|
+
"src",
|
|
58
|
+
BUN_SKILL_PACKAGE_RELATIVE_PATH,
|
|
59
|
+
);
|
|
60
|
+
console.error(
|
|
61
|
+
`[senpi-codemode] bundled bun-1-4 skill not found at ${localPath} or ${sidecarPath}; skipping contribution`,
|
|
62
|
+
);
|
|
37
63
|
}
|
|
38
64
|
return undefined;
|
|
39
65
|
}
|
|
40
66
|
|
|
41
67
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* A node kernel never
|
|
68
|
+
* Absolute path of the bundled bun-1-4 SKILL.md when it is active for this process:
|
|
69
|
+
* the in-process js eval kernel itself runs bun >= 1.4 (`process.versions.bun`) and the
|
|
70
|
+
* asset is shipped. A node kernel never activates it, regardless of any bun binary on PATH.
|
|
45
71
|
*/
|
|
72
|
+
export function activeBunSkillPath(
|
|
73
|
+
getKernelBunVersion: BunKernelVersionSource = kernelBunVersion,
|
|
74
|
+
baseDir?: string,
|
|
75
|
+
): string | undefined {
|
|
76
|
+
if (!bunVersionSupportsSkill(getKernelBunVersion())) return undefined;
|
|
77
|
+
return bundledBunSkillPath(baseDir);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Builds the `resources_discover` handler that contributes the active bun-1-4 skill, if any. */
|
|
46
81
|
export function createBunSkillDiscoverHandler(
|
|
47
82
|
getKernelBunVersion: BunKernelVersionSource = kernelBunVersion,
|
|
48
83
|
baseDir?: string,
|
|
49
84
|
): () => { skillPaths: string[] } | undefined {
|
|
50
85
|
return () => {
|
|
51
|
-
|
|
52
|
-
const skillPath = bundledBunSkillPath(baseDir);
|
|
86
|
+
const skillPath = activeBunSkillPath(getKernelBunVersion, baseDir);
|
|
53
87
|
return skillPath === undefined ? undefined : { skillPaths: [skillPath] };
|
|
54
88
|
};
|
|
55
89
|
}
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
import { jsRuntimeInfo, jsRuntimeLabel } from "./extension/runtime-info.ts";
|
|
17
17
|
import type { CodemodeSessionManager, CreateCodemodeSessionManagerOptions } from "./extension/session-manager.ts";
|
|
18
18
|
import { SessionManagerProxy } from "./extension/session-manager-proxy.ts";
|
|
19
|
-
import { registerBunSkillContribution } from "./extension/skill-contribution.ts";
|
|
19
|
+
import { activeBunSkillPath, registerBunSkillContribution } from "./extension/skill-contribution.ts";
|
|
20
20
|
import { WAKE_SOURCE_STATE_EVENT, type WakeSourceState } from "./extension/wake-source-state.ts";
|
|
21
21
|
import { EvalDetachedCellManager, type EvalDetachedCellStatusEntry } from "./tool/detached-cell-manager.ts";
|
|
22
22
|
import {
|
|
@@ -68,6 +68,7 @@ export default function senpiCodemode(pi: CodemodeExtensionAPI, options: SenpiCo
|
|
|
68
68
|
const manager = new SessionManagerProxy();
|
|
69
69
|
const complete = options.complete ?? ((request, ctx) => createCompletionHandler()(ctx)(request));
|
|
70
70
|
const renderers = { renderCall: renderEvalCall, renderResult: renderEvalResult };
|
|
71
|
+
const bunSkillPath = activeBunSkillPath();
|
|
71
72
|
let activeRuntime: SessionRuntime | undefined;
|
|
72
73
|
let activeModelId: string | undefined;
|
|
73
74
|
let activeContext: ExtensionContext | undefined;
|
|
@@ -125,6 +126,7 @@ export default function senpiCodemode(pi: CodemodeExtensionAPI, options: SenpiCo
|
|
|
125
126
|
spawnDefaultAgent: runtime.settings.taskTools.task,
|
|
126
127
|
hostLine: hostLine(),
|
|
127
128
|
runtimes: runtime.runtimes,
|
|
129
|
+
...(bunSkillPath === undefined ? {} : { bunSkillPath }),
|
|
128
130
|
...(modelId === undefined ? {} : { modelId }),
|
|
129
131
|
}),
|
|
130
132
|
);
|
|
@@ -159,6 +161,7 @@ export default function senpiCodemode(pi: CodemodeExtensionAPI, options: SenpiCo
|
|
|
159
161
|
renderers,
|
|
160
162
|
hostLine: hostLine(),
|
|
161
163
|
runtimes: { js: jsRuntimeInfo() },
|
|
164
|
+
...(bunSkillPath === undefined ? {} : { bunSkillPath }),
|
|
162
165
|
}),
|
|
163
166
|
);
|
|
164
167
|
pi.registerRemovedToolHint(
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { EvalRuntimeInfo } from "../tool/types.ts";
|
|
2
|
+
|
|
1
3
|
export interface EnabledLanguages {
|
|
2
4
|
readonly py: boolean;
|
|
3
5
|
readonly js: boolean;
|
|
@@ -18,6 +20,10 @@ export interface EvalPromptOptions {
|
|
|
18
20
|
readonly modelId?: string;
|
|
19
21
|
/** Preformatted host line (e.g. "darwin arm64 · Apple M5 Max · 18 cores"); enables the host-sizing note. */
|
|
20
22
|
readonly hostLine?: string;
|
|
23
|
+
/** Identity of the in-process js kernel; a bun runtime swaps the Node.js worker line for the Bun one. */
|
|
24
|
+
readonly jsRuntime?: EvalRuntimeInfo;
|
|
25
|
+
/** Absolute path of the active bun-1-4 skill; rendered as a MUST READ pointer only on a bun kernel. */
|
|
26
|
+
readonly bunSkillPath?: string;
|
|
21
27
|
}
|
|
22
28
|
|
|
23
29
|
/** Prompt dialect for the eval-first batching emphasis. */
|
|
@@ -132,7 +138,7 @@ Fields:
|
|
|
132
138
|
A detached cell keeps its language kernel busy while it finishes; another language can continue. Do not re-run a detached cell: the same-language busy error names its cell id and output tail. Completion arrives as one notification with the final value/error and buffered output. Stopping a cell interrupts its kernel; the stop result states whether kernel state survived or the kernel was restarted and its variables lost.
|
|
133
139
|
|
|
134
140
|
{{#if py}}Live event loop: use top-level \`await\` directly; \`asyncio.run(…)\` raises "cannot be called from a running event loop".{{/if}}
|
|
135
|
-
{{#if js}}JS runs under Node.js worker: top-level \`await\`/\`return\` work; \`fetch\`/\`Buffer\` available.{{/if}}
|
|
141
|
+
{{#if js}}{{#if jsBun}}JS runs in-process on Bun {{jsVersion}}: top-level \`await\`/\`return\` work; \`Bun.*\` builtins available.{{#if bunSkillPath}} MUST READ the bun-1-4 skill at {{bunSkillPath}} before your first js cell — its builtins replace the npm packages you would otherwise install.{{/if}}{{else}}JS runs under Node.js worker: top-level \`await\`/\`return\` work; \`fetch\`/\`Buffer\` available.{{/if}}{{/if}}
|
|
136
142
|
{{#if rb}}Ruby: synchronous; helper options are keyword args{{#if spawns}} (e.g. \`output("id", limit: 2)\`){{/if}}; the last expression auto-displays unless it is \`nil\`, an assignment, or a definition (like IRB).{{/if}}
|
|
137
143
|
{{#if jl}}Julia: synchronous; helper options are standard keyword args{{#if spawns}} (e.g. \`output("id", limit=2)\`){{/if}}; the last expression auto-displays unless it is an assignment or a definition (like the Julia REPL).{{/if}}
|
|
138
144
|
On error, fix and re-run only the failing step. State usually survives a normal error, but a timeout or stop may have restarted the kernel — its message says which. Before rebuilding state, check a sentinel (a variable you defined earlier); only re-establish what is actually gone, since blind re-runs duplicate side effects.
|
|
@@ -212,6 +218,9 @@ export function buildEvalPrompt(
|
|
|
212
218
|
styleKimi: style === "kimi",
|
|
213
219
|
styleDefault: style === "default",
|
|
214
220
|
hostLine: options.hostLine ?? "",
|
|
221
|
+
jsBun: options.jsRuntime?.name === "bun",
|
|
222
|
+
jsVersion: options.jsRuntime?.version ?? "",
|
|
223
|
+
bunSkillPath: options.bunSkillPath ?? "",
|
|
215
224
|
};
|
|
216
225
|
const examples = REUSE_CHAIN_EXAMPLES.filter((example) => enabled[example.language])
|
|
217
226
|
.map((example) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: bun-1-4
|
|
3
|
-
description: "MUST
|
|
3
|
+
description: "MUST READ before your first js eval cell: this session's eval js kernel runs Bun 1.4+ (this skill is present only when it does). Also read before any bun -e, script, server, CLI, test, bundle, or package-management work. Bun 1.4 ships builtins that replace 15+ npm deps — check here BEFORE installing sharp, puppeteer/playwright (scraping), marked, node-cron, node-pty, concurrently, serve-static, tar, json5, fast-xml-parser, string-width. Triggers: eval js, bun, Bun.serve, bun test, bun build, bun install, bun run, image resize, headless browser, markdown render, cron, PTY."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Bun 1.4 — Use the Builtins First
|
package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/runtime-apis.md
CHANGED
|
@@ -139,7 +139,7 @@ Blog: [#also-built-in](https://bun.com/blog/bun-v1.4#also-built-in)
|
|
|
139
139
|
Docs: <https://bun.com/docs/runtime/utils>
|
|
140
140
|
|
|
141
141
|
```ts
|
|
142
|
-
Bun.stringWidth("
|
|
142
|
+
Bun.stringWidth("\x1b[32mgreen\x1b[0m e\u0301"); // terminal columns, ANSI + grapheme aware
|
|
143
143
|
Bun.sliceAnsi(str, 0, 20); // slice by columns, preserving ANSI codes
|
|
144
144
|
Bun.wrapAnsi(str, 80); // wrap by columns
|
|
145
145
|
```
|
|
@@ -39,8 +39,10 @@ export interface CreateEvalToolOptions {
|
|
|
39
39
|
readonly spawnDefaultAgent?: string;
|
|
40
40
|
readonly modelId?: string;
|
|
41
41
|
readonly hostLine?: string;
|
|
42
|
-
/** Display identity of each language's runtime, shown in headers and details. */
|
|
42
|
+
/** Display identity of each language's runtime, shown in headers and details; `js` also selects the prompt's runtime line. */
|
|
43
43
|
readonly runtimes?: EvalRuntimes;
|
|
44
|
+
/** Absolute path of the active bun-1-4 skill; the prompt names it as MUST READ on a bun kernel. */
|
|
45
|
+
readonly bunSkillPath?: string;
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
export interface EvalCellInvocation {
|
|
@@ -31,6 +31,8 @@ export function createEvalTool(options: CreateEvalToolOptions): ToolDefinition<E
|
|
|
31
31
|
...(options.spawnDefaultAgent === undefined ? {} : { spawnDefaultAgent: options.spawnDefaultAgent }),
|
|
32
32
|
...(options.modelId === undefined ? {} : { modelId: options.modelId }),
|
|
33
33
|
...(options.hostLine === undefined ? {} : { hostLine: options.hostLine }),
|
|
34
|
+
...(options.runtimes?.js === undefined ? {} : { jsRuntime: options.runtimes.js }),
|
|
35
|
+
...(options.bunSkillPath === undefined ? {} : { bunSkillPath: options.bunSkillPath }),
|
|
34
36
|
});
|
|
35
37
|
const languages = enabledLanguageList(options.enabledLanguages);
|
|
36
38
|
const cellManager =
|
|
@@ -21,6 +21,9 @@ export declare function agentLoop(prompts: AgentMessage[], context: AgentContext
|
|
|
21
21
|
export declare function agentLoopContinue(context: AgentContext, config: AgentLoopConfig, signal: AbortSignal | undefined, streamFn: StreamFn): EventStream<AgentEvent, AgentMessage[]>;
|
|
22
22
|
export declare function runAgentLoop(prompts: AgentMessage[], context: AgentContext, config: AgentLoopConfig, emit: AgentEventSink, signal: AbortSignal | undefined, streamFn: StreamFn): Promise<AgentMessage[]>;
|
|
23
23
|
export declare function runAgentLoopContinue(context: AgentContext, config: AgentLoopConfig, emit: AgentEventSink, signal: AbortSignal | undefined, streamFn: StreamFn): Promise<AgentMessage[]>;
|
|
24
|
+
export declare class StreamStartTimeoutError extends Error {
|
|
25
|
+
constructor(timeoutMs: number);
|
|
26
|
+
}
|
|
24
27
|
/** Build the provider context using the same transform and conversion pipeline as an agent request. */
|
|
25
28
|
export declare function buildProviderContext(context: AgentContext, config: Pick<AgentLoopConfig, "convertToLlm" | "transformContext">, signal?: AbortSignal): Promise<Context>;
|
|
26
29
|
export interface PreparedAgentToolCall {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../src/agent-loop.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAIN,KAAK,OAAO,EAEZ,WAAW,EAIX,MAAM,uBAAuB,CAAC;AAU/B,OAAO,KAAK,EACX,YAAY,EACZ,UAAU,EACV,eAAe,EAEf,YAAY,EACZ,SAAS,EACT,aAAa,EAEb,QAAQ,EACR,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAEzE;;;GAGG;AACH,wBAAgB,SAAS,CACxB,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,QAAQ,EAAE,QAAQ,GAChB,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,CAiBzC;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAChC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,QAAQ,EAAE,QAAQ,GAChB,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,CAwBzC;AAED,wBAAsB,YAAY,CACjC,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,QAAQ,EAAE,QAAQ,GAChB,OAAO,CAAC,YAAY,EAAE,CAAC,CAgBzB;AAED,wBAAsB,oBAAoB,CACzC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,QAAQ,EAAE,QAAQ,GAChB,OAAO,CAAC,YAAY,EAAE,CAAC,CAiBzB;
|
|
1
|
+
{"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../src/agent-loop.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAIN,KAAK,OAAO,EAEZ,WAAW,EAIX,MAAM,uBAAuB,CAAC;AAU/B,OAAO,KAAK,EACX,YAAY,EACZ,UAAU,EACV,eAAe,EAEf,YAAY,EACZ,SAAS,EACT,aAAa,EAEb,QAAQ,EACR,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAEzE;;;GAGG;AACH,wBAAgB,SAAS,CACxB,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,QAAQ,EAAE,QAAQ,GAChB,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,CAiBzC;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAChC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,QAAQ,EAAE,QAAQ,GAChB,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,CAwBzC;AAED,wBAAsB,YAAY,CACjC,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,QAAQ,EAAE,QAAQ,GAChB,OAAO,CAAC,YAAY,EAAE,CAAC,CAgBzB;AAED,wBAAsB,oBAAoB,CACzC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,QAAQ,EAAE,QAAQ,GAChB,OAAO,CAAC,YAAY,EAAE,CAAC,CAiBzB;AAmBD,qBAAa,uBAAwB,SAAQ,KAAK;gBACrC,SAAS,EAAE,MAAM;CAM7B;AAqPD,uGAAuG;AACvG,wBAAsB,oBAAoB,CACzC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,cAAc,GAAG,kBAAkB,CAAC,EAClE,MAAM,CAAC,EAAE,WAAW,GAClB,OAAO,CAAC,OAAO,CAAC,CAgBlB;AA+lBD,MAAM,WAAW,qBAAqB;IACrC,QAAQ,EAAE,aAAa,CAAC;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;CACd;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,GAAG,aAAa,CAYrG;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,GAAG,qBAAqB,CAOpG"}
|
|
@@ -82,9 +82,9 @@ class StreamIdleTimeoutError extends Error {
|
|
|
82
82
|
// The wording must keep matching the retryable-error classifier
|
|
83
83
|
// ("timed out" in packages/ai/src/utils/retry.ts) so a dead stream start is
|
|
84
84
|
// retried instead of dead-ending the session.
|
|
85
|
-
class StreamStartTimeoutError extends Error {
|
|
85
|
+
export class StreamStartTimeoutError extends Error {
|
|
86
86
|
constructor(timeoutMs) {
|
|
87
|
-
super(`Provider stream start timed out after ${timeoutMs}ms`);
|
|
87
|
+
super(`Provider stream start timed out after ${timeoutMs}ms (raise streamStartTimeoutMs — retry.provider.streamStartTimeoutMs in senpi settings; 0 disables)`);
|
|
88
88
|
this.name = "StreamStartTimeoutError";
|
|
89
89
|
}
|
|
90
90
|
}
|