@mclawnet/agent 0.6.34 → 0.6.36
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/cli.js +75 -7
- package/dist/__tests__/bootstrap-deps.test.d.ts +2 -0
- package/dist/__tests__/bootstrap-deps.test.d.ts.map +1 -0
- package/dist/__tests__/collect-manifest.test.d.ts +2 -0
- package/dist/__tests__/collect-manifest.test.d.ts.map +1 -0
- package/dist/__tests__/hub-connection-on-activity.test.d.ts +2 -0
- package/dist/__tests__/hub-connection-on-activity.test.d.ts.map +1 -0
- package/dist/__tests__/hub-connection-wake-watch.test.d.ts +2 -0
- package/dist/__tests__/hub-connection-wake-watch.test.d.ts.map +1 -0
- package/dist/__tests__/ideas-rest-client.test.d.ts +2 -0
- package/dist/__tests__/ideas-rest-client.test.d.ts.map +1 -0
- package/dist/__tests__/legacy-claude-execute-compat.test.d.ts +2 -0
- package/dist/__tests__/legacy-claude-execute-compat.test.d.ts.map +1 -0
- package/dist/__tests__/no-adapter-cycle.test.d.ts +2 -0
- package/dist/__tests__/no-adapter-cycle.test.d.ts.map +1 -0
- package/dist/__tests__/runtime-env-defaults.test.d.ts +2 -0
- package/dist/__tests__/runtime-env-defaults.test.d.ts.map +1 -0
- package/dist/__tests__/session-manager-exit-reason.test.d.ts +2 -0
- package/dist/__tests__/session-manager-exit-reason.test.d.ts.map +1 -0
- package/dist/__tests__/session-manager-merge.test.d.ts +2 -0
- package/dist/__tests__/session-manager-merge.test.d.ts.map +1 -0
- package/dist/__tests__/session-manager-sticky.test.d.ts +2 -0
- package/dist/__tests__/session-manager-sticky.test.d.ts.map +1 -0
- package/dist/__tests__/session-protocol-dispatch.test.d.ts +2 -0
- package/dist/__tests__/session-protocol-dispatch.test.d.ts.map +1 -0
- package/dist/__tests__/worktree-bridge.test.d.ts +2 -0
- package/dist/__tests__/worktree-bridge.test.d.ts.map +1 -0
- package/dist/backend-adapter.d.ts +6 -232
- package/dist/backend-adapter.d.ts.map +1 -1
- package/dist/backend-factory-AFF6I7YF.js +11 -0
- package/dist/backend-factory.d.ts +23 -1
- package/dist/backend-factory.d.ts.map +1 -1
- package/dist/bootstrap-deps.d.ts +84 -0
- package/dist/bootstrap-deps.d.ts.map +1 -0
- package/dist/bootstrap-deps.js +173 -0
- package/dist/bootstrap-deps.js.map +1 -0
- package/dist/{chunk-PJ5M6Q36.js → chunk-376QZ7JB.js} +2 -2
- package/dist/chunk-376QZ7JB.js.map +1 -0
- package/dist/{chunk-2JDX6XFD.js → chunk-GOCWMRBB.js} +1817 -298
- package/dist/chunk-GOCWMRBB.js.map +1 -0
- package/dist/{chunk-M2CDVPQF.js → chunk-JH6RGJBQ.js} +2 -2
- package/dist/{chunk-MFXF77LG.js → chunk-VAEFJLPL.js} +25 -3
- package/dist/chunk-VAEFJLPL.js.map +1 -0
- package/dist/{dist-VLBO5CT3.js → dist-NWVHAP5R.js} +330 -23
- package/dist/dist-NWVHAP5R.js.map +1 -0
- package/dist/errors.d.ts +20 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/hub-connection.d.ts +25 -1
- package/dist/hub-connection.d.ts.map +1 -1
- package/dist/ideas-rest-client.d.ts +25 -0
- package/dist/ideas-rest-client.d.ts.map +1 -0
- package/dist/index.js +3 -3
- package/dist/{linux-IHA4O633.js → linux-MBU6ERXL.js} +3 -3
- package/dist/{macos-G4VK2253.js → macos-I2DUWFUH.js} +3 -3
- package/dist/projects-handler.d.ts +146 -1
- package/dist/projects-handler.d.ts.map +1 -1
- package/dist/runtime-env-defaults.d.ts +18 -0
- package/dist/runtime-env-defaults.d.ts.map +1 -0
- package/dist/service/index.js +5 -5
- package/dist/session-manager.d.ts +59 -0
- package/dist/session-manager.d.ts.map +1 -1
- package/dist/start.d.ts.map +1 -1
- package/dist/start.js +3 -2
- package/dist/{windows-P6U3JLUZ.js → windows-PEJ3KOLC.js} +3 -3
- package/dist/worktree-bridge.d.ts +51 -0
- package/dist/worktree-bridge.d.ts.map +1 -0
- package/package.json +10 -8
- package/dist/backend-factory-RUYUBJVF.js +0 -9
- package/dist/chunk-2JDX6XFD.js.map +0 -1
- package/dist/chunk-MFXF77LG.js.map +0 -1
- package/dist/chunk-PJ5M6Q36.js.map +0 -1
- package/dist/dist-VLBO5CT3.js.map +0 -1
- /package/dist/{backend-factory-RUYUBJVF.js.map → backend-factory-AFF6I7YF.js.map} +0 -0
- /package/dist/{chunk-M2CDVPQF.js.map → chunk-JH6RGJBQ.js.map} +0 -0
- /package/dist/{linux-IHA4O633.js.map → linux-MBU6ERXL.js.map} +0 -0
- /package/dist/{macos-G4VK2253.js.map → macos-I2DUWFUH.js.map} +0 -0
- /package/dist/{windows-P6U3JLUZ.js.map → windows-PEJ3KOLC.js.map} +0 -0
package/cli.js
CHANGED
|
@@ -39,13 +39,39 @@ function printNeedsInit() {
|
|
|
39
39
|
// === init ===
|
|
40
40
|
program
|
|
41
41
|
.command("init")
|
|
42
|
-
.description("Initialize ~/.clawnet/settings.json (token + name)")
|
|
42
|
+
.description("Initialize ~/.clawnet/settings.json (token + name) and check CLI dependencies")
|
|
43
43
|
.option("--token <token>", "Agent token (skip interactive prompt)")
|
|
44
44
|
.option("--name <name>", "Agent name (skip interactive prompt)")
|
|
45
45
|
.option("--hub-url <url>", "Hub WebSocket URL (defaults to wss://mclaw.work/ws/agent)")
|
|
46
|
+
.option("--skip-deps", "Skip CLI dependency check / install / config patching")
|
|
47
|
+
.option("--yes", "Non-interactive: accept all install prompts")
|
|
46
48
|
.action(async (opts) => {
|
|
47
49
|
const { saveConfig, loadConfig } = await import("./dist/index.js");
|
|
48
50
|
|
|
51
|
+
if (!opts.skipDeps) {
|
|
52
|
+
const { bootstrapDeps } = await import("./dist/bootstrap-deps.js");
|
|
53
|
+
const isTty = process.stdin.isTTY === true && process.stdout.isTTY === true;
|
|
54
|
+
const interactive = isTty && !opts.yes;
|
|
55
|
+
try {
|
|
56
|
+
const report = await bootstrapDeps({
|
|
57
|
+
homeDir: (await import("os")).homedir(),
|
|
58
|
+
interactive,
|
|
59
|
+
install: true,
|
|
60
|
+
promptFn: prompt,
|
|
61
|
+
});
|
|
62
|
+
if (report.present.length) console.log(` ✓ CLIs present: ${report.present.join(", ")}`);
|
|
63
|
+
if (report.installed.length) console.log(` ✓ Installed: ${report.installed.join(", ")}`);
|
|
64
|
+
if (report.missing.filter((m) => !report.installed.includes(m)).length)
|
|
65
|
+
console.log(` ⚠ Still missing: ${report.missing.filter((m) => !report.installed.includes(m)).join(", ")}`);
|
|
66
|
+
for (const c of report.configChanges) console.log(` • ${c}`);
|
|
67
|
+
for (const h of report.envHints) console.log(` ⚠ ${h}`);
|
|
68
|
+
console.log();
|
|
69
|
+
} catch (err) {
|
|
70
|
+
console.error("[clawnet] bootstrap-deps failed:", err.message || err);
|
|
71
|
+
console.error(" Continuing with token setup. Re-run 'clawnet-agent doctor' to retry.");
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
49
75
|
const existing = loadConfig();
|
|
50
76
|
|
|
51
77
|
let token = opts.token;
|
|
@@ -77,11 +103,53 @@ program
|
|
|
77
103
|
|
|
78
104
|
const hubUrl = opts.hubUrl || existing.hubUrl || "wss://mclaw.work/ws/agent";
|
|
79
105
|
|
|
80
|
-
saveConfig({ token, name, hubUrl, backendType: "claude
|
|
106
|
+
saveConfig({ token, name, hubUrl, backendType: "claude" });
|
|
81
107
|
console.log("\n✓ Saved to ~/.clawnet/settings.json");
|
|
82
108
|
console.log(" Run 'clawnet-agent start' to start the agent.\n");
|
|
83
109
|
});
|
|
84
110
|
|
|
111
|
+
// === doctor ===
|
|
112
|
+
program
|
|
113
|
+
.command("doctor")
|
|
114
|
+
.description("Diagnose CLI dependencies and config (read-only by default; --fix to install/patch)")
|
|
115
|
+
.option("--fix", "Install missing CLIs and patch missing config keys")
|
|
116
|
+
.option("--yes", "Non-interactive: accept all install prompts (only with --fix)")
|
|
117
|
+
.action(async (opts) => {
|
|
118
|
+
const { bootstrapDeps } = await import("./dist/bootstrap-deps.js");
|
|
119
|
+
const { homedir } = await import("os");
|
|
120
|
+
const isTty = process.stdin.isTTY === true && process.stdout.isTTY === true;
|
|
121
|
+
const interactive = opts.fix && isTty && !opts.yes;
|
|
122
|
+
const report = await bootstrapDeps({
|
|
123
|
+
homeDir: homedir(),
|
|
124
|
+
interactive,
|
|
125
|
+
install: Boolean(opts.fix),
|
|
126
|
+
promptFn: prompt,
|
|
127
|
+
});
|
|
128
|
+
console.log("ClawNet Agent — Doctor Report\n");
|
|
129
|
+
console.log("CLI dependencies:");
|
|
130
|
+
for (const name of ["claude", "codex"]) {
|
|
131
|
+
const present = report.present.includes(name);
|
|
132
|
+
const installed = report.installed.includes(name);
|
|
133
|
+
const status = installed ? "installed (this run)" : present ? "present" : "MISSING";
|
|
134
|
+
console.log(` ${present || installed ? "✓" : "✗"} ${name}: ${status}`);
|
|
135
|
+
}
|
|
136
|
+
console.log("\nConfig:");
|
|
137
|
+
if (report.configChanges.length === 0) {
|
|
138
|
+
console.log(" ✓ ~/.codex/config.toml and ~/.claude/settings.json look fine");
|
|
139
|
+
} else {
|
|
140
|
+
for (const c of report.configChanges) console.log(` • ${c}`);
|
|
141
|
+
}
|
|
142
|
+
if (report.envHints.length > 0) {
|
|
143
|
+
console.log("\nEnvironment:");
|
|
144
|
+
for (const h of report.envHints) console.log(` ⚠ ${h}`);
|
|
145
|
+
}
|
|
146
|
+
const stillMissing = report.missing.filter((m) => !report.installed.includes(m));
|
|
147
|
+
if (stillMissing.length > 0 && !opts.fix) {
|
|
148
|
+
console.log(`\nRun 'clawnet-agent doctor --fix' to install missing CLIs and patch config.`);
|
|
149
|
+
}
|
|
150
|
+
if (stillMissing.length > 0) process.exit(1);
|
|
151
|
+
});
|
|
152
|
+
|
|
85
153
|
// === start (default command) ===
|
|
86
154
|
program
|
|
87
155
|
.command("start", { isDefault: true })
|
|
@@ -90,7 +158,7 @@ program
|
|
|
90
158
|
.option("--hub-url <url>", "Hub WebSocket URL")
|
|
91
159
|
.option("--token <token>", "Agent token")
|
|
92
160
|
.option("--name <name>", "Agent name")
|
|
93
|
-
.option("--backend <type>", "Backend type", "claude
|
|
161
|
+
.option("--backend <type>", "Backend type", "claude")
|
|
94
162
|
.action(async (opts) => {
|
|
95
163
|
if (opts.foreground) {
|
|
96
164
|
// Foreground mode: directly run agent (existing behavior)
|
|
@@ -109,8 +177,8 @@ program
|
|
|
109
177
|
}
|
|
110
178
|
|
|
111
179
|
let adapter;
|
|
112
|
-
const backendType = opts.backend || "claude
|
|
113
|
-
if (backendType === "claude
|
|
180
|
+
const backendType = opts.backend || "claude";
|
|
181
|
+
if (backendType === "claude") {
|
|
114
182
|
try {
|
|
115
183
|
const { ClaudeCodeAdapter } = await import("@mclawnet/claude-adapter");
|
|
116
184
|
adapter = new ClaudeCodeAdapter();
|
|
@@ -280,8 +348,8 @@ const CONFIG_SCHEMA = [
|
|
|
280
348
|
},
|
|
281
349
|
{
|
|
282
350
|
key: "backendType",
|
|
283
|
-
description: "LLM backend implementation. Currently only 'claude
|
|
284
|
-
default: "claude
|
|
351
|
+
description: "LLM backend implementation. Currently only 'claude' is supported.",
|
|
352
|
+
default: "claude",
|
|
285
353
|
},
|
|
286
354
|
{
|
|
287
355
|
key: "embedding.provider",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap-deps.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/bootstrap-deps.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collect-manifest.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/collect-manifest.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hub-connection-on-activity.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/hub-connection-on-activity.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hub-connection-wake-watch.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/hub-connection-wake-watch.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ideas-rest-client.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/ideas-rest-client.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy-claude-execute-compat.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/legacy-claude-execute-compat.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-adapter-cycle.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/no-adapter-cycle.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-env-defaults.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/runtime-env-defaults.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-manager-exit-reason.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/session-manager-exit-reason.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-manager-merge.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/session-manager-merge.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-manager-sticky.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/session-manager-sticky.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-protocol-dispatch.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/session-protocol-dispatch.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worktree-bridge.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/worktree-bridge.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,236 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Backend interface types — moved to @mclawnet/backend-types so that
|
|
3
|
+
* adapter packages (claude-adapter, codex-adapter, future ones) can depend
|
|
4
|
+
* on these types WITHOUT taking a build-time dependency on @mclawnet/agent.
|
|
3
5
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* - OpenClawAdapter: spawn `openclaw gateway` (legacy)
|
|
7
|
-
* - CodexAdapter: M3.S3 — `codex app-server --listen stdio://`
|
|
8
|
-
*
|
|
9
|
-
* M3.S1 introduces:
|
|
10
|
-
* - Typed permission flow (PermissionRequest / PermissionDecision)
|
|
11
|
-
* - Typed BackendOutput envelope replacing the historical `onOutput(msg: unknown)`
|
|
12
|
-
* - `backendSessionId` replaces the previous `claudeSessionId` (see plan D7).
|
|
13
|
-
*/
|
|
14
|
-
export interface PermissionRequest {
|
|
15
|
-
/** Stable identifier for the pending tool call. */
|
|
16
|
-
callId: string;
|
|
17
|
-
/** Tool name as reported by the backend (e.g. 'shell', 'apply_patch', 'Write'). */
|
|
18
|
-
toolName: string;
|
|
19
|
-
/** Raw tool input as the backend supplied it. */
|
|
20
|
-
input: unknown;
|
|
21
|
-
/** Optional backend-supplied context (sandbox, cwd, reason, ...). */
|
|
22
|
-
meta?: {
|
|
23
|
-
backend?: "claude" | "codex" | string;
|
|
24
|
-
reason?: string;
|
|
25
|
-
cwd?: string;
|
|
26
|
-
[k: string]: unknown;
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* S0 finding: neither claude `--permission-mode default` (no wire channel)
|
|
31
|
-
* nor codex `ReviewDecision` supports "approve with modifiedInput", so the
|
|
32
|
-
* S1 contract is a 4-state enum. `allow_session` may degrade to `allow` for
|
|
33
|
-
* backends that don't track session-scoped approvals.
|
|
34
|
-
*/
|
|
35
|
-
export interface PermissionDecision {
|
|
36
|
-
callId: string;
|
|
37
|
-
decision: "allow" | "allow_session" | "deny" | "abort";
|
|
38
|
-
reason?: string;
|
|
39
|
-
}
|
|
40
|
-
export type BackendOutput = {
|
|
41
|
-
kind: "assistant_text";
|
|
42
|
-
text: string;
|
|
43
|
-
} | {
|
|
44
|
-
kind: "tool_use";
|
|
45
|
-
toolName: string;
|
|
46
|
-
input: unknown;
|
|
47
|
-
callId: string;
|
|
48
|
-
} | {
|
|
49
|
-
kind: "tool_result";
|
|
50
|
-
callId: string;
|
|
51
|
-
output: unknown;
|
|
52
|
-
isError?: boolean;
|
|
53
|
-
} | {
|
|
54
|
-
kind: "system";
|
|
55
|
-
subtype: string;
|
|
56
|
-
data: unknown;
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Adapter-internal diagnostic only. Hub and wire layers MUST NOT consume
|
|
60
|
-
* `raw` — promote a new typed variant instead when hub needs to read it.
|
|
6
|
+
* agent still re-exports them via this barrel for backward compatibility,
|
|
7
|
+
* so existing internal imports (`./backend-adapter.js`) keep working.
|
|
61
8
|
*/
|
|
62
|
-
|
|
63
|
-
kind: "raw";
|
|
64
|
-
backend: string;
|
|
65
|
-
payload: unknown;
|
|
66
|
-
};
|
|
67
|
-
export interface BackendProcess {
|
|
68
|
-
/** Unique identifier (e.g., Claude session ID) */
|
|
69
|
-
id: string;
|
|
70
|
-
/** Working directory for this process */
|
|
71
|
-
workDir: string;
|
|
72
|
-
/**
|
|
73
|
-
* OS process id of the underlying backend process, if applicable.
|
|
74
|
-
*
|
|
75
|
-
* Optional because not every backend is a child process — a future in-process
|
|
76
|
-
* adapter (mock / stubbed / WASM) wouldn't have one. SessionManager uses pid
|
|
77
|
-
* for the PR-C checkpoint: a restart probes `process.kill(pid, 0)` to decide
|
|
78
|
-
* whether the recorded session is `dead` or an `orphan`. Adapters that omit
|
|
79
|
-
* pid forfeit the dead/orphan classification — checkpointed sessions will
|
|
80
|
-
* silently appear as "no longer here", which is also acceptable behavior.
|
|
81
|
-
*/
|
|
82
|
-
pid?: number;
|
|
83
|
-
/** Kill the backend process */
|
|
84
|
-
kill(): Promise<void>;
|
|
85
|
-
/**
|
|
86
|
-
* Whether the backend process is still alive and capable of accepting input.
|
|
87
|
-
* Returns false if the process has exited, is being killed, or its stdin is no
|
|
88
|
-
* longer writable. Used by SessionManager.isHealthy() to detect stale entries.
|
|
89
|
-
*/
|
|
90
|
-
isAlive(): boolean;
|
|
91
|
-
}
|
|
92
|
-
export interface SpawnOptions {
|
|
93
|
-
/** ClawNet session ID */
|
|
94
|
-
sessionId: string;
|
|
95
|
-
/** Working directory for the backend process */
|
|
96
|
-
workDir?: string;
|
|
97
|
-
/** Resume a previous session (e.g., Claude --resume UUID) */
|
|
98
|
-
resumeId?: string;
|
|
99
|
-
/** System prompt to append (e.g., role prompt for swarm mode) */
|
|
100
|
-
systemPrompt?: string;
|
|
101
|
-
/** Load BrainCore + CoreSkill via --add-dir */
|
|
102
|
-
useBrainCore?: boolean;
|
|
103
|
-
/** Path to MCP config JSON file for --mcp-config */
|
|
104
|
-
mcpConfigPath?: string;
|
|
105
|
-
/** Memory system role ID. When set, SessionManager auto-injects memory prompt + MCP config */
|
|
106
|
-
roleId?: string;
|
|
107
|
-
/**
|
|
108
|
-
* Optional first user input. When set, SessionManager uses this as the
|
|
109
|
-
* semantic-retrieval query for `buildMemorySection` (Pipeline A) so the
|
|
110
|
-
* injected memory section is relevant to what the user is about to ask.
|
|
111
|
-
* Falls back to an empty query (importance-top-K) when omitted.
|
|
112
|
-
*/
|
|
113
|
-
initialUserInput?: string;
|
|
114
|
-
/** Extra directories to mount via --add-dir */
|
|
115
|
-
additionalDirs?: string[];
|
|
116
|
-
/** Optional allowlist of tool names to forward to the backend (PR3.5). */
|
|
117
|
-
allowedTools?: string[];
|
|
118
|
-
/** Optional denylist of tool names to forward to the backend (PR3.5). */
|
|
119
|
-
disallowedTools?: string[];
|
|
120
|
-
/**
|
|
121
|
-
* Override CLAUDE_CODE_MAX_OUTPUT_TOKENS for this spawn. Drives the
|
|
122
|
-
* server-side hard limit (200k − maxOutputTokens) and the CLI's own
|
|
123
|
-
* effective window. Lower = wider prompt budget. SessionManager pulls this
|
|
124
|
-
* from `getRecommendedMaxOutputTokens()` on each spawn so the ladder
|
|
125
|
-
* (32k → 16k → 8k) survives across `--resume` restarts.
|
|
126
|
-
*
|
|
127
|
-
* Optional: when omitted the CLI uses its own default — adapters that
|
|
128
|
-
* don't honour it lose D-lite escalation but never crash.
|
|
129
|
-
*/
|
|
130
|
-
maxOutputTokens?: number;
|
|
131
|
-
/**
|
|
132
|
-
* Optional backend kind for this spawn. When set, SessionManager resolves
|
|
133
|
-
* an adapter via its `resolveAdapter` hook (typically `createBackendAdapter`)
|
|
134
|
-
* and uses it for this process instead of the default constructor adapter.
|
|
135
|
-
* Omitted = use the default adapter (back-compat).
|
|
136
|
-
*/
|
|
137
|
-
backend?: "claude" | "codex";
|
|
138
|
-
/**
|
|
139
|
-
* Per-role sandbox level. Each adapter maps to its own permission model:
|
|
140
|
-
* - codex-adapter: `-c sandbox_mode="<value>"` (OS-level seatbelt /
|
|
141
|
-
* landlock — strong enforcement)
|
|
142
|
-
* - claude-adapter: `--permission-mode` (LLM-soft approval; UI should
|
|
143
|
-
* tooltip that claude has no real OS sandbox)
|
|
144
|
-
*
|
|
145
|
-
* Values: "read-only" | "workspace-write" | "full-access".
|
|
146
|
-
* Default (undefined): adapter-specific — claude uses constructor
|
|
147
|
-
* permissionMode (typically bypassPermissions), codex uses
|
|
148
|
-
* "workspace-write".
|
|
149
|
-
*/
|
|
150
|
-
sandbox?: "read-only" | "workspace-write" | "full-access";
|
|
151
|
-
}
|
|
152
|
-
export interface BackendAdapter {
|
|
153
|
-
/** Backend type identifier */
|
|
154
|
-
type: string;
|
|
155
|
-
/** Spawn a new backend process */
|
|
156
|
-
spawn(options: SpawnOptions): Promise<BackendProcess>;
|
|
157
|
-
/** Stop a running backend process */
|
|
158
|
-
stop(process: BackendProcess): Promise<void>;
|
|
159
|
-
/** Send user input to the backend process */
|
|
160
|
-
send(process: BackendProcess, input: string): void;
|
|
161
|
-
/**
|
|
162
|
-
* Register output handler. Handler receives `unknown` today (legacy claude
|
|
163
|
-
* stream-json frames); adapters are migrating to emit `BackendOutput`
|
|
164
|
-
* envelopes. Consumers that need typed output should narrow with the
|
|
165
|
-
* `BackendOutput` discriminator.
|
|
166
|
-
*/
|
|
167
|
-
onOutput(process: BackendProcess, handler: (msg: unknown) => void): void;
|
|
168
|
-
/**
|
|
169
|
-
* M3.S1 — Optional permission flow.
|
|
170
|
-
* - codex-adapter (S3): implemented; maps from `ReviewDecision` wire format.
|
|
171
|
-
* - claude-adapter: M3 stays on `bypassPermissions` and does NOT implement
|
|
172
|
-
* these. M4+ will add via an MCP permission-prompt tool.
|
|
173
|
-
*/
|
|
174
|
-
onPermissionRequest?(process: BackendProcess, handler: (req: PermissionRequest) => void): void;
|
|
175
|
-
respondToPermission?(process: BackendProcess, decision: PermissionDecision): Promise<void>;
|
|
176
|
-
/** Turn-complete handler. */
|
|
177
|
-
onTurnComplete?(process: BackendProcess, handler: (info: {
|
|
178
|
-
backendSessionId?: string;
|
|
179
|
-
cost?: number;
|
|
180
|
-
duration?: number;
|
|
181
|
-
contextUsage?: {
|
|
182
|
-
used: number;
|
|
183
|
-
total: number;
|
|
184
|
-
};
|
|
185
|
-
backendMeta?: Record<string, unknown>;
|
|
186
|
-
}) => void): void;
|
|
187
|
-
/** Register error handler */
|
|
188
|
-
onError?(process: BackendProcess, handler: (error: Error) => void): void;
|
|
189
|
-
/**
|
|
190
|
-
* Register a handler that fires the moment the backend reports its session
|
|
191
|
-
* is initialized (e.g. Claude CLI's `system/init` frame, codex `thread_id`).
|
|
192
|
-
* Used by hub to persist `backendSessionId` early — without this we have to
|
|
193
|
-
* wait for `turn_complete`, and a mid-turn crash would leave db's
|
|
194
|
-
* backend_session_id NULL despite a valid jsonl file existing on disk.
|
|
195
|
-
*
|
|
196
|
-
* Optional: adapters that don't implement this lose the early-backfill
|
|
197
|
-
* capability — db's backend_session_id will only be populated on
|
|
198
|
-
* `turn_complete`, so any session whose first turn crashes will be
|
|
199
|
-
* unrecoverable via `--resume`. Other backends (codex, openclaw) should
|
|
200
|
-
* implement this if they have an analogous "session ready" signal.
|
|
201
|
-
*/
|
|
202
|
-
onSessionStarted?(process: BackendProcess, handler: (info: {
|
|
203
|
-
backendSessionId: string;
|
|
204
|
-
}) => void): void;
|
|
205
|
-
/**
|
|
206
|
-
* Register a handler that fires when the underlying process exits on its
|
|
207
|
-
* own (crash, EPIPE, OOM, manual SIGKILL from outside) — *not* when we
|
|
208
|
-
* deliberately call kill() ourselves. Used by SessionManager to auto-evict
|
|
209
|
-
* dead Map entries and notify hub via onSessionError.
|
|
210
|
-
*
|
|
211
|
-
* Optional: adapters that don't implement this lose auto-eviction —
|
|
212
|
-
* SessionManager's Map will keep the dead entry, isHealthy() will still
|
|
213
|
-
* fall back to BackendProcess.isAlive() so the unhealthy-fallback-resume
|
|
214
|
-
* branch in hub-connection.ts still works, but the orphan Map entry will
|
|
215
|
-
* accumulate until the next abortSession/closeSession call.
|
|
216
|
-
*/
|
|
217
|
-
onExit?(process: BackendProcess, handler: (code: number | null) => void): void;
|
|
218
|
-
/**
|
|
219
|
-
* Register a handler for token-budget warnings. Fires when the backend
|
|
220
|
-
* estimates the prompt is approaching the server-side hard limit.
|
|
221
|
-
* SessionManager uses this to escalate the max_output_tokens ladder so
|
|
222
|
-
* the next spawn gets a wider budget.
|
|
223
|
-
*
|
|
224
|
-
* Optional: adapters that can't introspect token usage simply skip this —
|
|
225
|
-
* the ladder stays at index 0 forever, falling back to claude-code's own
|
|
226
|
-
* auto-compact (which works most of the time, just less defensively).
|
|
227
|
-
*/
|
|
228
|
-
onTokenBudgetWarning?(process: BackendProcess, handler: (info: {
|
|
229
|
-
used: number;
|
|
230
|
-
hardLimit: number;
|
|
231
|
-
threshold: number;
|
|
232
|
-
distanceToHard: number;
|
|
233
|
-
maxOutputTokens: number;
|
|
234
|
-
}) => void): void;
|
|
235
|
-
}
|
|
9
|
+
export type { BackendAdapter, BackendProcess, BackendOutput, PermissionDecision, PermissionRequest, SpawnOptions, } from "@mclawnet/backend-types";
|
|
236
10
|
//# sourceMappingURL=backend-adapter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend-adapter.d.ts","sourceRoot":"","sources":["../src/backend-adapter.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"backend-adapter.d.ts","sourceRoot":"","sources":["../src/backend-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,YAAY,EACV,cAAc,EACd,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,GACb,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__resetBackendFactoryCache,
|
|
3
|
+
collectAgentManifest,
|
|
4
|
+
createBackendAdapter
|
|
5
|
+
} from "./chunk-VAEFJLPL.js";
|
|
6
|
+
export {
|
|
7
|
+
__resetBackendFactoryCache,
|
|
8
|
+
collectAgentManifest,
|
|
9
|
+
createBackendAdapter
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=backend-factory-AFF6I7YF.js.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { BackendAdapter } from "./backend-adapter.js";
|
|
2
|
-
|
|
2
|
+
import type { AgentManifestPayload, BackendKind } from "@mclawnet/shared";
|
|
3
|
+
export type { BackendKind };
|
|
3
4
|
export declare function __resetBackendFactoryCache(): void;
|
|
4
5
|
export interface BackendFactoryContext {
|
|
5
6
|
/** Role instance / template name — surfaces in error messages so users know
|
|
@@ -13,7 +14,28 @@ export interface BackendFactoryContext {
|
|
|
13
14
|
* - "codex" → @mclawnet/codex-adapter via dynamic import so the codex bundle
|
|
14
15
|
* isn't pulled into claude-only deployments.
|
|
15
16
|
*
|
|
17
|
+
* Why dynamic import (and why codex-adapter is `optionalDependencies` in
|
|
18
|
+
* agent's package.json, not `dependencies`):
|
|
19
|
+
* - agent owns the runtime relationship "I load adapters on demand".
|
|
20
|
+
* - Adapters only depend on @mclawnet/backend-types (the interface package),
|
|
21
|
+
* so there is no build-time cycle.
|
|
22
|
+
* - `optionalDependencies` keeps the "user installs just @mclawnet/agent
|
|
23
|
+
* and codex backend works out of the box" UX: npm/pnpm will try to
|
|
24
|
+
* install codex-adapter; if that fails (network, platform issue, user
|
|
25
|
+
* opted out via --no-optional), the dynamic import below throws and
|
|
26
|
+
* the agent surfaces a clear error instead of crashing at startup.
|
|
27
|
+
* - Promoting codex-adapter to `dependencies` would force install, which
|
|
28
|
+
* is fine for monorepo but unfriendly to claude-only deployments.
|
|
29
|
+
*
|
|
16
30
|
* Results are cached per kind; subsequent calls return the same instance.
|
|
17
31
|
*/
|
|
18
32
|
export declare function createBackendAdapter(kind: BackendKind | undefined, ctx?: BackendFactoryContext): Promise<BackendAdapter>;
|
|
33
|
+
/**
|
|
34
|
+
* Probe every known backend adapter and aggregate their `getManifest()` output
|
|
35
|
+
* into a single payload the agent can ship to the hub. Failures (binary not on
|
|
36
|
+
* PATH, adapter package broken, etc.) become `installed: false` entries rather
|
|
37
|
+
* than rejecting the whole collection — the hub still wants to know "we tried
|
|
38
|
+
* but it isn't available" for each kind.
|
|
39
|
+
*/
|
|
40
|
+
export declare function collectAgentManifest(): Promise<AgentManifestPayload>;
|
|
19
41
|
//# sourceMappingURL=backend-factory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend-factory.d.ts","sourceRoot":"","sources":["../src/backend-factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"backend-factory.d.ts","sourceRoot":"","sources":["../src/backend-factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAI1E,YAAY,EAAE,WAAW,EAAE,CAAC;AAI5B,wBAAgB,0BAA0B,IAAI,IAAI,CAEjD;AAED,MAAM,WAAW,qBAAqB;IACpC;8EAC0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,WAAW,GAAG,SAAS,EAC7B,GAAG,GAAE,qBAA0B,GAC9B,OAAO,CAAC,cAAc,CAAC,CAsCzB;AAgBD;;;;;;GAMG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAkB1E"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
export interface DetectResult {
|
|
2
|
+
found: boolean;
|
|
3
|
+
path?: string;
|
|
4
|
+
}
|
|
5
|
+
export interface DetectOptions {
|
|
6
|
+
/** Override which/where lookup. Tests inject a fake; runtime defaults to execFileSync. */
|
|
7
|
+
whichFn?: (bin: string) => string;
|
|
8
|
+
}
|
|
9
|
+
export declare function detectCli(bin: string, opts?: DetectOptions): DetectResult;
|
|
10
|
+
export interface PatchResult {
|
|
11
|
+
/** Human-readable change log entries; empty array = no changes. */
|
|
12
|
+
patched: string[];
|
|
13
|
+
}
|
|
14
|
+
export interface PatchOptions {
|
|
15
|
+
homeDir: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Merge defaults into ~/.codex/config.toml.
|
|
19
|
+
*
|
|
20
|
+
* Two paths:
|
|
21
|
+
* - File absent → write a fresh stringified TOML with our defaults.
|
|
22
|
+
* - File exists → parse to detect missing keys, then APPEND missing
|
|
23
|
+
* fragments as raw text. We never re-stringify the parsed AST, because
|
|
24
|
+
* smol-toml's stringify drops comments and may reorder keys (verified
|
|
25
|
+
* by regression test). Appending preserves the user's original bytes.
|
|
26
|
+
*
|
|
27
|
+
* Never touches user-set model_provider / model / per-provider fields.
|
|
28
|
+
*/
|
|
29
|
+
export declare function patchCodexConfig(opts: PatchOptions): PatchResult;
|
|
30
|
+
/**
|
|
31
|
+
* Ensure ~/.claude/settings.json exists.
|
|
32
|
+
*
|
|
33
|
+
* Currently a thin presence-check: claude-code's own config schema evolves
|
|
34
|
+
* fast and we don't want to fight it. Just create an empty object if absent
|
|
35
|
+
* so downstream tools can rely on the file's existence.
|
|
36
|
+
*/
|
|
37
|
+
export declare function patchClaudeConfig(opts: PatchOptions): PatchResult;
|
|
38
|
+
export declare function detectEnvVar(name: string): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Read ~/.codex/config.toml and return the currently-active model_provider
|
|
41
|
+
* string. Returns undefined when the file is absent, malformed, or has no
|
|
42
|
+
* model_provider key set.
|
|
43
|
+
*
|
|
44
|
+
* Used by bootstrapDeps to gate provider-specific env-var hints — we only
|
|
45
|
+
* warn about COPILOT_API_KEY when the user actually picked copilot-api.
|
|
46
|
+
*/
|
|
47
|
+
export declare function detectActiveCodexProvider(homeDir: string): string | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Build a platform-specific user-facing instruction for setting
|
|
50
|
+
* COPILOT_API_KEY. The copilot-api proxy (the localhost:4141 forwarder)
|
|
51
|
+
* does not validate the bearer token — any non-empty string works — but
|
|
52
|
+
* codex's env_key check fails hard if the variable is missing. So the hint
|
|
53
|
+
* has to tell the user exactly which shell command to run.
|
|
54
|
+
*
|
|
55
|
+
* Platform split kept here (not at the call site) so future locales / new
|
|
56
|
+
* platforms can extend the matrix without touching bootstrapDeps logic.
|
|
57
|
+
*/
|
|
58
|
+
export declare function buildCopilotApiEnvHint(opts: {
|
|
59
|
+
platform: NodeJS.Platform | string;
|
|
60
|
+
}): string;
|
|
61
|
+
export interface BootstrapOptions {
|
|
62
|
+
homeDir: string;
|
|
63
|
+
/** When true, prompt user before installing CLIs. */
|
|
64
|
+
interactive: boolean;
|
|
65
|
+
/** When false, never install (doctor mode). */
|
|
66
|
+
install: boolean;
|
|
67
|
+
whichFn?: (bin: string) => string;
|
|
68
|
+
installFn?: (cliName: "claude" | "codex") => Promise<void>;
|
|
69
|
+
promptFn?: (question: string) => Promise<string>;
|
|
70
|
+
}
|
|
71
|
+
export interface BootstrapReport {
|
|
72
|
+
/** CLIs that were already installed. */
|
|
73
|
+
present: string[];
|
|
74
|
+
/** CLIs missing at start. */
|
|
75
|
+
missing: string[];
|
|
76
|
+
/** CLIs installed during this run. */
|
|
77
|
+
installed: string[];
|
|
78
|
+
/** Config patcher change logs (codex + claude). */
|
|
79
|
+
configChanges: string[];
|
|
80
|
+
/** Hint strings to print to user about env vars that need attention. */
|
|
81
|
+
envHints: string[];
|
|
82
|
+
}
|
|
83
|
+
export declare function bootstrapDeps(opts: BootstrapOptions): Promise<BootstrapReport>;
|
|
84
|
+
//# sourceMappingURL=bootstrap-deps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap-deps.d.ts","sourceRoot":"","sources":["../src/bootstrap-deps.ts"],"names":[],"mappings":"AA6BA,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,0FAA0F;IAC1F,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;CACnC;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,aAAkB,GAAG,YAAY,CAyB7E;AAED,MAAM,WAAW,WAAW;IAC1B,mEAAmE;IACnE,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB;AASD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,YAAY,GAAG,WAAW,CAqEhE;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,GAAG,WAAW,CAejE;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGlD;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAU7E;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAA;CAAE,GAAG,MAAM,CAmB3F;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,WAAW,EAAE,OAAO,CAAC;IACrB,+CAA+C;IAC/C,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IAClC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAClD;AAED,MAAM,WAAW,eAAe;IAC9B,wCAAwC;IACxC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,6BAA6B;IAC7B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,sCAAsC;IACtC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,mDAAmD;IACnD,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,wEAAwE;IACxE,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAmBD,wBAAsB,aAAa,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAwDpF"}
|