@pikiloom/kernel 0.2.20 → 0.3.1
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/README.md +20 -7
- package/dist/drivers/acp.js +30 -163
- package/dist/drivers/claude.d.ts +4 -21
- package/dist/drivers/claude.js +88 -57
- package/dist/drivers/codex.d.ts +0 -10
- package/dist/drivers/codex.js +47 -144
- package/dist/drivers/gemini.js +9 -27
- package/dist/drivers/hermes.d.ts +1 -2
- package/dist/drivers/hermes.js +1 -4
- package/dist/drivers/index.d.ts +5 -4
- package/dist/drivers/index.js +8 -4
- package/dist/{workspace → drivers}/native.d.ts +0 -1
- package/dist/{workspace → drivers}/native.js +1 -1
- package/dist/drivers/rpc.d.ts +45 -0
- package/dist/drivers/rpc.js +130 -0
- package/dist/drivers/shared.d.ts +21 -0
- package/dist/drivers/shared.js +66 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +10 -2
- package/dist/protocol/index.d.ts +5 -0
- package/dist/protocol/index.js +10 -0
- package/dist/runtime/hub.js +4 -8
- package/dist/workspace/index.d.ts +1 -2
- package/dist/workspace/index.js +3 -2
- package/dist/workspace/mcp.js +6 -16
- package/dist/workspace/npm-search.d.ts +9 -0
- package/dist/workspace/npm-search.js +21 -0
- package/dist/workspace/sessions.js +6 -9
- package/dist/workspace/skills.d.ts +11 -0
- package/dist/workspace/skills.js +14 -20
- package/llms.txt +11 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -205,7 +205,8 @@ interrupts only the current turn and the next queued task promotes.
|
|
|
205
205
|
| `ClaudeDriver` | `claude` | `claude` CLI, stream-json (+ `--effort`, partial messages) | ✓ | — | ✓ | ✓ |
|
|
206
206
|
| `CodexDriver` | `codex` | `codex app-server` JSON-RPC (HITL via `requestUserInput`) | ✓ | via askUser | ✓ | ✓ |
|
|
207
207
|
| `GeminiDriver` | `gemini` | `gemini --output-format stream-json` | — | — | ✓ | ✓ |
|
|
208
|
-
| `
|
|
208
|
+
| `AcpDriver` | *(config)* | generic ACP ndjson JSON-RPC — any ACP CLI: `new AcpDriver({ id, command, args })` | — | via askUser | ✓ | — |
|
|
209
|
+
| `HermesDriver` | `hermes` | ACP preset over `AcpDriver` (`hermes acp`) | — | via askUser | ✓ | — |
|
|
209
210
|
| `EchoDriver` | `echo` | none (hermetic, in-process) | ✓ | ✓ | ✓ | ✓ |
|
|
210
211
|
|
|
211
212
|
Write your own by implementing `AgentDriver` and passing it to `createLoom({ drivers })` (or
|
|
@@ -311,16 +312,28 @@ node-builtins-only and additive — every existing port/default is unchanged.
|
|
|
311
312
|
|
|
312
313
|
## Exports
|
|
313
314
|
|
|
314
|
-
Main entry `@pikiloom/kernel`
|
|
315
|
-
`@pikiloom/kernel/surfaces`, `@pikiloom/kernel/protocol`.
|
|
315
|
+
Main entry `@pikiloom/kernel` is the public API, pinned by `test/api-surface.test.ts`.
|
|
316
|
+
Subpaths: `@pikiloom/kernel/drivers`, `@pikiloom/kernel/surfaces`, `@pikiloom/kernel/protocol`.
|
|
317
|
+
Driver-internal parser/settle helpers are exported only from their modules (for white-box
|
|
318
|
+
tests) and are NOT part of the public surface.
|
|
316
319
|
|
|
317
320
|
- Runtime: `createLoom`, `Loom`, `Hub`, `SessionRunner`, `runTurn`, `PtyBridge`, `ptyAvailable`, `attachTui`
|
|
318
|
-
- Drivers: `EchoDriver`, `ClaudeDriver`, `CodexDriver`, `GeminiDriver`, `HermesDriver`
|
|
321
|
+
- Drivers: `EchoDriver`, `ClaudeDriver`, `CodexDriver`, `GeminiDriver`, `AcpDriver` (+ `AcpDriverConfig`), `HermesDriver`
|
|
322
|
+
- Native discovery (driver-axis): `discover{Claude,Codex,Gemini}NativeSessions`, `encodeClaudeProjectDir` + type `DiscoverOptions`
|
|
319
323
|
- Surfaces: `WebSurface`, `CliSurface`
|
|
320
324
|
- Ports/defaults: `FsSessionStore`, `NullModelResolver`, `NoopToolProvider`, `PassthroughSystemPromptBuilder`, `AutoCancelInteractionHandler`, `DeferToTerminalInteractionHandler`, `NoopCatalog`, `defaultBaseDir`
|
|
321
|
-
- Workspace: `resolveLoomPaths`, `SessionsManager`, `SkillsManager`, `McpRegistry`, `ensureDirSymlink`, `
|
|
322
|
-
-
|
|
323
|
-
-
|
|
325
|
+
- Workspace: `resolveLoomPaths`, `normalizeStateDirName`, `SessionsManager`, `SkillsManager`, `McpRegistry`, `ensureDirSymlink`, `parseSkillMeta` + types `LoomPaths`, `LoomScope`, `ManagedSessionInfo`, `SkillInfo`, `SkillMeta`, `McpCatalogEntry`
|
|
326
|
+
- Multi-account: `accountTokenSupported`, `accountTokenEnvVar`, `accountTokenEnv` — which env var carries an agent's auth token, so an app can inject a selected account's token per spawn (claude: `CLAUDE_CODE_OAUTH_TOKEN`; storage/selection stay app-side)
|
|
327
|
+
- Protocol: `UniversalSnapshot`, `diffSnapshot`, `applySnapshotPatch`, `emptySnapshot`, `PROTOCOL_VERSION`, `makeSessionKey`, `splitSessionKey`, all wire/`Client*`/`Server*` message types
|
|
328
|
+
- Types: `AgentDriver`, `AgentTurnInput`, `DriverContext`, `DriverEvent`, `DriverResult`, `NativeSessionInfo`, `LoomIO`, `PromptInput`, `Surface`, `Plugin`, `SpawnContribution`, `SessionStore`, `ModelResolver`, `ToolProvider`, `SystemPromptBuilder`, `InteractionHandler`, `Catalog`, …
|
|
329
|
+
|
|
330
|
+
### Claude driver tuning (env)
|
|
331
|
+
|
|
332
|
+
The claude driver's background-hold / stall / recovery heuristics ship sane defaults and can
|
|
333
|
+
be tuned per deployment: `PIKILOOM_CLAUDE_BG_HOLD_MS`, `PIKILOOM_CLAUDE_BG_AGENT_HOLD_MS`,
|
|
334
|
+
`PIKILOOM_CLAUDE_BG_HOLD_RECHECK_MS`, `PIKILOOM_CLAUDE_BG_SETTLE_QUIET_MS`,
|
|
335
|
+
`PIKILOOM_CLAUDE_MODEL_STALL_MS`, `PIKILOOM_CLAUDE_TRUNCATED_RECOVERY` (=0 disables),
|
|
336
|
+
`PIKILOOM_CLAUDE_RESUME_NOOP_RETRIES`.
|
|
324
337
|
|
|
325
338
|
---
|
|
326
339
|
|
package/dist/drivers/acp.js
CHANGED
|
@@ -1,132 +1,7 @@
|
|
|
1
|
-
import { spawn } from 'node:child_process';
|
|
2
|
-
import { createInterface } from 'node:readline';
|
|
3
1
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
4
|
-
import { dirname
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
constructor(code, message) {
|
|
8
|
-
super(message);
|
|
9
|
-
this.code = code;
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
// ── ACP JSON-RPC client over a child process' stdio (ndjson framing) ───────────
|
|
13
|
-
class AcpClient {
|
|
14
|
-
bin;
|
|
15
|
-
args;
|
|
16
|
-
env;
|
|
17
|
-
cwd;
|
|
18
|
-
proc = null;
|
|
19
|
-
nextId = 1;
|
|
20
|
-
pending = new Map();
|
|
21
|
-
notifyCb;
|
|
22
|
-
requestCb;
|
|
23
|
-
stderrTail = [];
|
|
24
|
-
constructor(bin, args, env, cwd) {
|
|
25
|
-
this.bin = bin;
|
|
26
|
-
this.args = args;
|
|
27
|
-
this.env = env;
|
|
28
|
-
this.cwd = cwd;
|
|
29
|
-
}
|
|
30
|
-
onNotification(cb) { this.notifyCb = cb; }
|
|
31
|
-
onRequest(cb) { this.requestCb = cb; }
|
|
32
|
-
stderrText() { return this.stderrTail.join('\n'); }
|
|
33
|
-
start() {
|
|
34
|
-
try {
|
|
35
|
-
this.proc = spawn(this.bin, this.args, {
|
|
36
|
-
cwd: this.cwd,
|
|
37
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
38
|
-
env: this.env ? { ...process.env, ...this.env } : process.env,
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
catch {
|
|
42
|
-
return false;
|
|
43
|
-
}
|
|
44
|
-
const rl = createInterface({ input: this.proc.stdout, crlfDelay: Infinity });
|
|
45
|
-
rl.on('line', (line) => this.onLine(line));
|
|
46
|
-
this.proc.stderr.on('data', (chunk) => {
|
|
47
|
-
for (const ln of chunk.toString('utf8').split('\n')) {
|
|
48
|
-
const t = ln.trim();
|
|
49
|
-
if (!t)
|
|
50
|
-
continue;
|
|
51
|
-
this.stderrTail.push(t.slice(0, 240));
|
|
52
|
-
if (this.stderrTail.length > 20)
|
|
53
|
-
this.stderrTail.shift();
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
this.proc.on('close', () => { for (const cb of this.pending.values())
|
|
57
|
-
cb({ error: { message: 'acp process exited' } }); this.pending.clear(); });
|
|
58
|
-
this.proc.on('error', () => { });
|
|
59
|
-
return true;
|
|
60
|
-
}
|
|
61
|
-
onLine(line) {
|
|
62
|
-
const t = line.trim();
|
|
63
|
-
if (!t)
|
|
64
|
-
return;
|
|
65
|
-
let m;
|
|
66
|
-
try {
|
|
67
|
-
m = JSON.parse(t);
|
|
68
|
-
}
|
|
69
|
-
catch {
|
|
70
|
-
return;
|
|
71
|
-
} // non-JSON stdout noise
|
|
72
|
-
if (m.method && m.id != null) {
|
|
73
|
-
void this.handleRequest(m);
|
|
74
|
-
return;
|
|
75
|
-
} // agent -> client request
|
|
76
|
-
if (m.id != null) { // response to one of our requests
|
|
77
|
-
const cb = this.pending.get(m.id);
|
|
78
|
-
if (cb) {
|
|
79
|
-
this.pending.delete(m.id);
|
|
80
|
-
cb(m);
|
|
81
|
-
}
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
if (m.method)
|
|
85
|
-
this.notifyCb?.(m.method, m.params ?? {}); // notification (session/update)
|
|
86
|
-
}
|
|
87
|
-
async handleRequest(m) {
|
|
88
|
-
const id = m.id;
|
|
89
|
-
if (!this.requestCb) {
|
|
90
|
-
this.respondError(id, -32601, `Method not implemented: ${m.method}`);
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
try {
|
|
94
|
-
const result = await this.requestCb(m.method, m.params ?? {});
|
|
95
|
-
this.respond(id, result ?? null);
|
|
96
|
-
}
|
|
97
|
-
catch (e) {
|
|
98
|
-
const code = e instanceof AcpRpcError ? e.code : -32603;
|
|
99
|
-
this.respondError(id, code, e?.message || 'handler error');
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
request(method, params, timeoutMs = 60_000) {
|
|
103
|
-
return new Promise((resolve) => {
|
|
104
|
-
if (!this.proc || this.proc.killed) {
|
|
105
|
-
resolve({ error: { message: 'not connected' } });
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
const id = this.nextId++;
|
|
109
|
-
const timer = setTimeout(() => { this.pending.delete(id); resolve({ error: { message: `ACP '${method}' timed out` } }); }, timeoutMs);
|
|
110
|
-
this.pending.set(id, (m) => { clearTimeout(timer); resolve(m); });
|
|
111
|
-
this.write({ jsonrpc: '2.0', id, method, params });
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
notify(method, params) { this.write({ jsonrpc: '2.0', method, params }); }
|
|
115
|
-
respond(id, result) { this.write({ jsonrpc: '2.0', id, result }); }
|
|
116
|
-
respondError(id, code, message) { this.write({ jsonrpc: '2.0', id, error: { code, message } }); }
|
|
117
|
-
write(msg) {
|
|
118
|
-
if (!this.proc || this.proc.killed)
|
|
119
|
-
return;
|
|
120
|
-
try {
|
|
121
|
-
this.proc.stdin.write(JSON.stringify(msg) + '\n');
|
|
122
|
-
}
|
|
123
|
-
catch { /* stream closed */ }
|
|
124
|
-
}
|
|
125
|
-
kill() { try {
|
|
126
|
-
this.proc?.kill('SIGTERM');
|
|
127
|
-
}
|
|
128
|
-
catch { /* ignore */ } this.proc = null; }
|
|
129
|
-
}
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
import { RpcError, StdioRpcClient } from './rpc.js';
|
|
4
|
+
import { attachedFileNote, contextPercent, imageMimeForFile, wireAbort } from './shared.js';
|
|
130
5
|
// ── pikiloom McpServerSpec[] -> ACP mcpServers[] ───────────────────────────────
|
|
131
6
|
export function toAcpMcpServers(servers) {
|
|
132
7
|
if (!servers || !servers.length)
|
|
@@ -145,29 +20,19 @@ export function toAcpMcpServers(servers) {
|
|
|
145
20
|
}
|
|
146
21
|
return out;
|
|
147
22
|
}
|
|
148
|
-
const IMAGE_EXTS = new Set(['.png', '.jpg', '.jpeg', '.gif', '.webp']);
|
|
149
|
-
function mimeForExt(ext) {
|
|
150
|
-
if (ext === '.jpg' || ext === '.jpeg')
|
|
151
|
-
return 'image/jpeg';
|
|
152
|
-
if (ext === '.gif')
|
|
153
|
-
return 'image/gif';
|
|
154
|
-
if (ext === '.webp')
|
|
155
|
-
return 'image/webp';
|
|
156
|
-
return 'image/png';
|
|
157
|
-
}
|
|
158
23
|
// ACP prompt content blocks: text + inline base64 images; other attachments noted as text.
|
|
159
24
|
export function buildAcpPromptBlocks(prompt, attachments) {
|
|
160
25
|
const blocks = [];
|
|
161
26
|
for (const f of attachments) {
|
|
162
|
-
const
|
|
163
|
-
if (
|
|
27
|
+
const mime = imageMimeForFile(f);
|
|
28
|
+
if (mime) {
|
|
164
29
|
try {
|
|
165
|
-
blocks.push({ type: 'image', mimeType:
|
|
30
|
+
blocks.push({ type: 'image', mimeType: mime, data: readFileSync(f).toString('base64') });
|
|
166
31
|
continue;
|
|
167
32
|
}
|
|
168
33
|
catch { /* fall through to a text note */ }
|
|
169
34
|
}
|
|
170
|
-
blocks.push({ type: 'text', text:
|
|
35
|
+
blocks.push({ type: 'text', text: attachedFileNote(f) });
|
|
171
36
|
}
|
|
172
37
|
blocks.push({ type: 'text', text: prompt });
|
|
173
38
|
return blocks;
|
|
@@ -260,12 +125,13 @@ export function applyAcpUpdate(update, s, tools, emit) {
|
|
|
260
125
|
case 'usage_update': {
|
|
261
126
|
if (typeof update.size === 'number')
|
|
262
127
|
s.contextWindow = update.size;
|
|
263
|
-
if (typeof update.used === 'number')
|
|
264
|
-
s.contextUsed = update.used;
|
|
265
128
|
if (typeof update.used === 'number') {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
129
|
+
s.contextUsed = update.used;
|
|
130
|
+
emit({ type: 'usage', usage: {
|
|
131
|
+
inputTokens: null, outputTokens: null, cachedInputTokens: null,
|
|
132
|
+
contextUsedTokens: update.used,
|
|
133
|
+
contextPercent: contextPercent(update.used > 0 ? update.used : null, s.contextWindow),
|
|
134
|
+
} });
|
|
269
135
|
}
|
|
270
136
|
return;
|
|
271
137
|
}
|
|
@@ -321,7 +187,7 @@ function fallbackOptionId(options, fallback) {
|
|
|
321
187
|
function readAcpTextFile(params) {
|
|
322
188
|
const p = String(params?.path || '');
|
|
323
189
|
if (!p || !existsSync(p))
|
|
324
|
-
throw new
|
|
190
|
+
throw new RpcError(-32602, `file not found: ${p}`);
|
|
325
191
|
let content = readFileSync(p, 'utf8');
|
|
326
192
|
const line = typeof params?.line === 'number' ? params.line : null;
|
|
327
193
|
const limit = typeof params?.limit === 'number' ? params.limit : null;
|
|
@@ -335,7 +201,7 @@ function readAcpTextFile(params) {
|
|
|
335
201
|
function writeAcpTextFile(params) {
|
|
336
202
|
const p = String(params?.path || '');
|
|
337
203
|
if (!p)
|
|
338
|
-
throw new
|
|
204
|
+
throw new RpcError(-32602, 'path required');
|
|
339
205
|
try {
|
|
340
206
|
mkdirSync(dirname(p), { recursive: true });
|
|
341
207
|
}
|
|
@@ -351,9 +217,11 @@ function acpUsage(s, raw) {
|
|
|
351
217
|
output = n(raw.outputTokens ?? raw.output_tokens);
|
|
352
218
|
cached = n(raw.cachedReadTokens ?? raw.cached_read_tokens ?? raw.cachedInputTokens);
|
|
353
219
|
}
|
|
354
|
-
const
|
|
355
|
-
|
|
356
|
-
|
|
220
|
+
const used = s.contextUsed;
|
|
221
|
+
return {
|
|
222
|
+
inputTokens: input, outputTokens: output, cachedInputTokens: cached, contextUsedTokens: used,
|
|
223
|
+
contextPercent: contextPercent(used || null, s.contextWindow), turnOutputTokens: output,
|
|
224
|
+
};
|
|
357
225
|
}
|
|
358
226
|
export class AcpDriver {
|
|
359
227
|
id;
|
|
@@ -376,19 +244,18 @@ export class AcpDriver {
|
|
|
376
244
|
}
|
|
377
245
|
async run(input, ctx) {
|
|
378
246
|
const env = { ...(this.cfg.env || {}), ...(input.env || {}) };
|
|
379
|
-
const client = new
|
|
247
|
+
const client = new StdioRpcClient({ command: this.cfg.command, args: this.cfg.args, env, cwd: input.workdir, label: this.id });
|
|
380
248
|
const state = { text: '', reasoning: '', contextWindow: null, contextUsed: null };
|
|
381
249
|
const tools = new Set();
|
|
382
250
|
let sessionId = input.sessionId ?? null;
|
|
383
251
|
let permSeq = 0;
|
|
384
252
|
if (!client.start())
|
|
385
253
|
return { ok: false, text: '', error: `failed to start ${this.cfg.command}`, stopReason: 'error' };
|
|
386
|
-
const
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
ctx.signal.addEventListener('abort', onAbort, { once: true });
|
|
254
|
+
const unwireAbort = wireAbort(ctx.signal, () => {
|
|
255
|
+
if (sessionId)
|
|
256
|
+
client.notify('session/cancel', { sessionId });
|
|
257
|
+
client.kill();
|
|
258
|
+
});
|
|
392
259
|
client.onNotification((method, params) => {
|
|
393
260
|
if (method === 'session/update')
|
|
394
261
|
applyAcpUpdate(params?.update ?? params, state, tools, ctx.emit);
|
|
@@ -398,14 +265,14 @@ export class AcpDriver {
|
|
|
398
265
|
case 'session/request_permission': return this.resolvePermission(params, ctx, `${this.id}-perm-${++permSeq}`);
|
|
399
266
|
case 'fs/read_text_file':
|
|
400
267
|
if (!this.cfg.fsAccess)
|
|
401
|
-
throw new
|
|
268
|
+
throw new RpcError(-32601, 'fs/read_text_file not supported');
|
|
402
269
|
return readAcpTextFile(params);
|
|
403
270
|
case 'fs/write_text_file':
|
|
404
271
|
if (!this.cfg.fsAccess)
|
|
405
|
-
throw new
|
|
272
|
+
throw new RpcError(-32601, 'fs/write_text_file not supported');
|
|
406
273
|
return writeAcpTextFile(params);
|
|
407
274
|
default:
|
|
408
|
-
throw new
|
|
275
|
+
throw new RpcError(-32601, `Method not implemented: ${method}`);
|
|
409
276
|
}
|
|
410
277
|
});
|
|
411
278
|
try {
|
|
@@ -447,7 +314,7 @@ export class AcpDriver {
|
|
|
447
314
|
return { ok: true, text: state.text, reasoning: state.reasoning || undefined, error: null, stopReason, sessionId, usage };
|
|
448
315
|
}
|
|
449
316
|
finally {
|
|
450
|
-
|
|
317
|
+
unwireAbort();
|
|
451
318
|
client.kill();
|
|
452
319
|
}
|
|
453
320
|
}
|
package/dist/drivers/claude.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AgentDriver, AgentTurnInput, DriverContext, DriverResult, DriverEvent, TuiInput, TuiSpec, NativeSessionInfo } from '../contracts/driver.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { UniversalPlan } from '../protocol/index.js';
|
|
3
3
|
export declare class ClaudeDriver implements AgentDriver {
|
|
4
4
|
private readonly bin;
|
|
5
5
|
readonly id = "claude";
|
|
@@ -18,19 +18,6 @@ export declare class ClaudeDriver implements AgentDriver {
|
|
|
18
18
|
run(input: AgentTurnInput, ctx: DriverContext): Promise<DriverResult>;
|
|
19
19
|
private usage;
|
|
20
20
|
}
|
|
21
|
-
export interface ClaudeUsageState {
|
|
22
|
-
input: number | null;
|
|
23
|
-
output: number | null;
|
|
24
|
-
cached: number | null;
|
|
25
|
-
cacheCreation?: number | null;
|
|
26
|
-
contextWindow?: number | null;
|
|
27
|
-
turnOutputTokensBase?: number | null;
|
|
28
|
-
thinkingEstTokens?: number | null;
|
|
29
|
-
}
|
|
30
|
-
export declare function claudeUsageOf(s: ClaudeUsageState): UniversalUsage;
|
|
31
|
-
export declare function applyClaudeThinkingEstimate(s: any, ev: any): boolean;
|
|
32
|
-
export declare function claudeContextWindowFromModel(model: unknown): number | null;
|
|
33
|
-
export declare function claudeEffectiveContextWindow(advertised: number | null): number | null;
|
|
34
21
|
export declare function handleClaudeEvent(ev: any, s: any, emit: (e: DriverEvent) => void): void;
|
|
35
22
|
export declare function claudeBgHoldCapMs(): number;
|
|
36
23
|
export declare function claudeBgAgentHoldCapMs(): number;
|
|
@@ -40,6 +27,9 @@ export declare function claudeBgSettleQuietMs(): number;
|
|
|
40
27
|
export declare function claudeModelStallMs(): number;
|
|
41
28
|
export declare const CLAUDE_TRUNCATED_RECOVERY_PROMPT: string;
|
|
42
29
|
export declare function claudeTruncatedRecoveryEnabled(): boolean;
|
|
30
|
+
export declare function isClaudeSyntheticResumeNoise(text: string): boolean;
|
|
31
|
+
export declare function claudeProducedRealOutput(s: any): boolean;
|
|
32
|
+
export declare function claudeResumeNoopRetryLimit(): number;
|
|
43
33
|
export declare function claudeUserEventHasToolResult(ev: any): boolean;
|
|
44
34
|
export declare function isTerminalTaskStatus(status: unknown): boolean;
|
|
45
35
|
export declare function trackClaudeBackgroundTask(ev: any, s: any): void;
|
|
@@ -53,11 +43,4 @@ export declare function decideClaudeResultSettle(input: {
|
|
|
53
43
|
sawBackground: boolean;
|
|
54
44
|
}): ClaudeResultSettleDecision;
|
|
55
45
|
export declare function claudeUserMessage(text: string, attachments?: string[]): string;
|
|
56
|
-
export declare function emitClaudeImages(blocks: any[], s: any, emit: (e: DriverEvent) => void): void;
|
|
57
46
|
export declare function todoWriteToPlan(input: any): UniversalPlan | null;
|
|
58
|
-
export declare function readClaudeTaskCreateId(ev: any, block: any): string | null;
|
|
59
|
-
export declare function rebuildClaudeTaskPlan(s: any): UniversalPlan | null;
|
|
60
|
-
export declare function applyTaskUpdateToTodoPlan(plan: UniversalPlan | null | undefined, taskId: string, rawStatus: string): UniversalPlan | null;
|
|
61
|
-
export declare function shortToolValue(value: unknown, max?: number): string;
|
|
62
|
-
export declare function summarizeToolUse(name: string, input: any): string;
|
|
63
|
-
export declare function firstResultLine(content: any): string;
|