@gajae-code/coding-agent 0.18.5 → 0.18.7
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 +140 -0
- package/dist/types/capability/types.d.ts +4 -0
- package/dist/types/cli-commands.d.ts +10 -0
- package/dist/types/cli-ordinary.d.ts +13 -0
- package/dist/types/cli.d.ts +12 -3
- package/dist/types/commands/contribution-prep.d.ts +0 -3
- package/dist/types/commands/sdk.d.ts +3 -0
- package/dist/types/commands/update.d.ts +1 -0
- package/dist/types/config/model-profile-activation.d.ts +19 -0
- package/dist/types/config/settings.d.ts +4 -0
- package/dist/types/coordinator-mcp/session-reaper.d.ts +5 -0
- package/dist/types/discovery/helpers.d.ts +2 -2
- package/dist/types/edit/modes/replace.d.ts +3 -3
- package/dist/types/edit/streaming.d.ts +2 -2
- package/dist/types/exec/bash-shell-supervisor.d.ts +12 -0
- package/dist/types/runtime-mcp/elicitation.d.ts +12 -0
- package/dist/types/sdk/broker/discovery.d.ts +8 -0
- package/dist/types/sdk/broker/ensure.d.ts +1 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +4 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +9 -0
- package/dist/types/sdk/broker/runtime.d.ts +1 -1
- package/dist/types/sdk/broker/task-artifact-owner-validation.d.ts +55 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +1 -1
- package/dist/types/sdk/bus/telegram-daemon.d.ts +4 -2
- package/dist/types/sdk/cli/diagnostics-cli.d.ts +18 -0
- package/dist/types/sdk/diagnostics/observe-broker.d.ts +185 -0
- package/dist/types/sdk/host/control/operations.d.ts +1 -1
- package/dist/types/sdk/host/host.d.ts +6 -0
- package/dist/types/sdk/index.d.ts +1 -0
- package/dist/types/sdk/router/session-router.d.ts +9 -0
- package/dist/types/sdk/session.d.ts +13 -0
- package/dist/types/session/agent-session.d.ts +5 -1
- package/dist/types/session/internal/managed-session-storage.d.ts +11 -1
- package/dist/types/session/internal/task-artifact-owner-access.d.ts +17 -0
- package/dist/types/session/internal/task-artifact-owner-transcript.d.ts +3 -0
- package/dist/types/session/session-retirement.d.ts +47 -0
- package/dist/types/session/session-storage.d.ts +0 -46
- package/dist/types/session/session-transcript-header.d.ts +2 -0
- package/dist/types/session/task-artifact-owner-codec.d.ts +107 -0
- package/dist/types/session/task-artifact-owner-retirement.d.ts +7 -0
- package/dist/types/session/task-artifact-owner.d.ts +10 -0
- package/dist/types/tools/ask-contract.d.ts +75 -254
- package/dist/types/tools/bash.d.ts +1 -1
- package/package.json +7 -7
- package/scripts/build-sdk-package-smoke.ts +5 -0
- package/scripts/resident-memory-bench.ts +174 -20
- package/src/capability/index.ts +1 -0
- package/src/capability/types.ts +4 -0
- package/src/cli/config-cli.ts +8 -18
- package/src/cli/public-command-entry.ts +5 -0
- package/src/cli/ssh-cli.ts +6 -3
- package/src/cli/web-search-cli.ts +9 -3
- package/src/cli-commands.ts +14 -0
- package/src/cli-main.ts +7 -8
- package/src/cli-ordinary.ts +197 -0
- package/src/cli.ts +25 -182
- package/src/commands/contribution-prep.ts +1 -3
- package/src/commands/sdk.ts +171 -21
- package/src/commands/update.ts +15 -1
- package/src/config/file-lock.ts +91 -2
- package/src/config/model-profile-activation.ts +70 -4
- package/src/config/model-profile-contract.ts +4 -1
- package/src/config/model-profiles.ts +23 -31
- package/src/config/model-resolver.ts +9 -1
- package/src/config/settings.ts +44 -4
- package/src/coordinator-mcp/event-webhook.ts +19 -14
- package/src/coordinator-mcp/policy.ts +14 -4
- package/src/coordinator-mcp/server.ts +142 -7
- package/src/coordinator-mcp/session-reaper.ts +9 -1
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +1 -1
- package/src/discovery/helpers.ts +9 -3
- package/src/discovery/ssh.ts +8 -3
- package/src/edit/modes/replace.ts +6 -6
- package/src/edit/streaming.ts +15 -15
- package/src/exec/bash-shell-supervisor.ts +60 -3
- package/src/gjc-runtime/gc-runtime.ts +2 -1
- package/src/hindsight/config.ts +9 -3
- package/src/internal-urls/docs-index.generated.ts +11 -10
- package/src/memories/index.ts +8 -2
- package/src/modes/acp/acp-agent.ts +724 -370
- package/src/modes/components/tool-execution.ts +1 -1
- package/src/prompts/tools/ask.md +2 -0
- package/src/runtime-mcp/client.ts +13 -4
- package/src/runtime-mcp/elicitation.ts +142 -0
- package/src/sdk/broker/broker.ts +54 -1
- package/src/sdk/broker/daemon-entry.ts +67 -6
- package/src/sdk/broker/discovery.ts +8 -0
- package/src/sdk/broker/ensure.ts +156 -20
- package/src/sdk/broker/lifecycle-ledger.ts +110 -12
- package/src/sdk/broker/lifecycle.ts +334 -348
- package/src/sdk/broker/runtime.ts +5 -1
- package/src/sdk/broker/task-artifact-owner-validation.ts +259 -0
- package/src/sdk/broker/transport.ts +5 -1
- package/src/sdk/bus/chat-daemon-control.ts +2 -2
- package/src/sdk/bus/chat-daemon-runtime.ts +3 -0
- package/src/sdk/bus/index.ts +3 -3
- package/src/sdk/bus/telegram-daemon-contract.ts +1 -1
- package/src/sdk/bus/telegram-daemon-control.ts +15 -12
- package/src/sdk/bus/telegram-daemon.ts +38 -3
- package/src/sdk/cli/diagnostics-cli.ts +247 -0
- package/src/sdk/diagnostics/observe-broker.ts +654 -0
- package/src/sdk/host/control/dispatch.ts +52 -4
- package/src/sdk/host/control/operations.ts +1 -1
- package/src/sdk/host/host.ts +6 -0
- package/src/sdk/host/session-runtime.test.ts +83 -4
- package/src/sdk/host/session-runtime.ts +15 -7
- package/src/sdk/index.ts +1 -0
- package/src/sdk/lifecycle-session.ts +1 -0
- package/src/sdk/mcp/server.ts +15 -3
- package/src/sdk/protocol/operation-registry.ts +1 -1
- package/src/sdk/router/session-router.ts +26 -3
- package/src/sdk/session.ts +51 -8
- package/src/session/agent-session.ts +169 -43
- package/src/session/blob-store.ts +78 -33
- package/src/session/internal/managed-session-storage.ts +203 -4
- package/src/session/internal/task-artifact-owner-access.ts +229 -0
- package/src/session/internal/task-artifact-owner-transcript.ts +68 -0
- package/src/session/session-retirement.ts +155 -0
- package/src/session/session-storage.ts +1 -160
- package/src/session/session-transcript-header.ts +17 -0
- package/src/session/task-artifact-owner-codec.ts +578 -0
- package/src/session/task-artifact-owner-retirement.ts +475 -0
- package/src/session/task-artifact-owner.ts +289 -0
- package/src/setup/hermes/templates/operator-instructions.v1.md +19 -1
- package/src/setup/hermes-setup.ts +4 -1
- package/src/slash-commands/builtin-registry.ts +8 -5
- package/src/tools/ask-contract.test.ts +76 -1
- package/src/tools/ask-contract.ts +57 -6
- package/src/tools/ask.ts +16 -7
- package/src/tools/bash.ts +38 -29
- package/src/tools/descriptors.test.ts +29 -0
- package/src/tools/tool-catalog.generated.ts +7 -4
- package/src/web/search/index.ts +2 -2
package/src/edit/streaming.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* - compute unified diff previews for the in-flight args
|
|
8
8
|
* (`computeDiffPreview`), and
|
|
9
9
|
* - render a text placeholder while no diff exists yet
|
|
10
|
-
* (`
|
|
10
|
+
* (`renderStreamingPlaceholder`).
|
|
11
11
|
*
|
|
12
12
|
* The shared renderer / `ToolExecutionComponent` consult the strategy via
|
|
13
13
|
* the injected `editMode` rather than probing argument shape.
|
|
@@ -72,7 +72,7 @@ export interface EditStreamingStrategy<Args = unknown> {
|
|
|
72
72
|
* Rendered inline while the diff hasn't been computed yet (or when the
|
|
73
73
|
* compute returned `null` because args are still too partial).
|
|
74
74
|
*/
|
|
75
|
-
|
|
75
|
+
renderStreamingPlaceholder(args: Args, uiTheme: Theme): string;
|
|
76
76
|
}
|
|
77
77
|
export interface EditRequestTargetInventory {
|
|
78
78
|
paths: string[];
|
|
@@ -169,7 +169,7 @@ export function getEditRequestTargetInventory(
|
|
|
169
169
|
if (editMode === "hashline") {
|
|
170
170
|
const input = typeof values.input === "string" ? values.input : "";
|
|
171
171
|
const headerPaths = getHashlineTargetPaths(input);
|
|
172
|
-
// `path` is only
|
|
172
|
+
// `path` is only the target for headerless input; explicit §PATH headers are the full target set.
|
|
173
173
|
if (headerPaths.length > 0) return { paths: orderedDistinctPaths(headerPaths) };
|
|
174
174
|
return { paths: orderedDistinctPaths([topLevelPath]) };
|
|
175
175
|
}
|
|
@@ -197,8 +197,8 @@ export function getEditRequestTargetInventory(
|
|
|
197
197
|
return { paths: orderedDistinctPaths([topLevelPath, ...editPaths, partialPath]) };
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
-
const
|
|
201
|
-
const
|
|
200
|
+
const STREAMING_PLACEHOLDER_LINES = 12;
|
|
201
|
+
const STREAMING_PLACEHOLDER_WIDTH = 80;
|
|
202
202
|
|
|
203
203
|
function isHashlineHeaderLine(line: string): boolean {
|
|
204
204
|
return line.trimEnd().startsWith(HL_FILE_PREFIX);
|
|
@@ -236,15 +236,15 @@ function trimHashlineStreamingSyntax(lines: string[]): string[] {
|
|
|
236
236
|
return lines.slice(index).filter(line => !isHashlineEnvelopeMarkerLine(line));
|
|
237
237
|
}
|
|
238
238
|
|
|
239
|
-
function
|
|
239
|
+
function renderHashlineInputPlaceholder(input: string, uiTheme: Theme): string {
|
|
240
240
|
const lines = trimHashlineStreamingSyntax(sanitizeText(input).split("\n"));
|
|
241
241
|
if (!lines.some(line => line.trim().length > 0)) return "";
|
|
242
242
|
|
|
243
|
-
const displayLines = lines.slice(-
|
|
243
|
+
const displayLines = lines.slice(-STREAMING_PLACEHOLDER_LINES);
|
|
244
244
|
const hidden = lines.length - displayLines.length;
|
|
245
245
|
let text = "\n\n";
|
|
246
246
|
text += displayLines
|
|
247
|
-
.map(line => uiTheme.fg("toolOutput", truncateToWidth(replaceTabs(line),
|
|
247
|
+
.map(line => uiTheme.fg("toolOutput", truncateToWidth(replaceTabs(line), STREAMING_PLACEHOLDER_WIDTH)))
|
|
248
248
|
.join("\n");
|
|
249
249
|
if (hidden > 0) {
|
|
250
250
|
text += uiTheme.fg("dim", `\n… (streaming +${hidden} lines)`);
|
|
@@ -376,7 +376,7 @@ const replaceStrategy: EditStreamingStrategy<ReplaceArgs> = {
|
|
|
376
376
|
ctx.signal.throwIfAborted();
|
|
377
377
|
return [toPerFilePreview(args.path, result)];
|
|
378
378
|
},
|
|
379
|
-
|
|
379
|
+
renderStreamingPlaceholder() {
|
|
380
380
|
return "";
|
|
381
381
|
},
|
|
382
382
|
};
|
|
@@ -405,7 +405,7 @@ const patchStrategy: EditStreamingStrategy<PatchArgs> = {
|
|
|
405
405
|
ctx.signal.throwIfAborted();
|
|
406
406
|
return [toPerFilePreview(args.path, result)];
|
|
407
407
|
},
|
|
408
|
-
|
|
408
|
+
renderStreamingPlaceholder() {
|
|
409
409
|
return "";
|
|
410
410
|
},
|
|
411
411
|
};
|
|
@@ -552,7 +552,7 @@ const hashlineStrategy: EditStreamingStrategy<HashlineArgs> = {
|
|
|
552
552
|
try {
|
|
553
553
|
sections = splitHashlineInputs(input, { cwd: ctx.cwd, path: args.path });
|
|
554
554
|
} catch {
|
|
555
|
-
// Single-section
|
|
555
|
+
// Single-section handling keeps the original error rendering for the
|
|
556
556
|
// "haven't typed `§ PATH` yet" case.
|
|
557
557
|
const result = await computeHashlineDiff({ input, path: args.path }, ctx.cwd, {
|
|
558
558
|
autoDropPureInsertDuplicates: ctx.hashlineAutoDropPureInsertDuplicates,
|
|
@@ -590,8 +590,8 @@ const hashlineStrategy: EditStreamingStrategy<HashlineArgs> = {
|
|
|
590
590
|
}
|
|
591
591
|
return previews.length > 0 ? previews : null;
|
|
592
592
|
},
|
|
593
|
-
|
|
594
|
-
return typeof args.input === "string" ?
|
|
593
|
+
renderStreamingPlaceholder(args, uiTheme) {
|
|
594
|
+
return typeof args.input === "string" ? renderHashlineInputPlaceholder(args.input, uiTheme) : "";
|
|
595
595
|
},
|
|
596
596
|
};
|
|
597
597
|
|
|
@@ -642,7 +642,7 @@ const applyPatchStrategy: EditStreamingStrategy<ApplyPatchArgs> = {
|
|
|
642
642
|
}
|
|
643
643
|
return previews.length > 0 ? previews : null;
|
|
644
644
|
},
|
|
645
|
-
|
|
645
|
+
renderStreamingPlaceholder() {
|
|
646
646
|
return "";
|
|
647
647
|
},
|
|
648
648
|
};
|
|
@@ -656,7 +656,7 @@ const vimStrategy: EditStreamingStrategy<unknown> = {
|
|
|
656
656
|
async computeDiffPreview() {
|
|
657
657
|
return null;
|
|
658
658
|
},
|
|
659
|
-
|
|
659
|
+
renderStreamingPlaceholder() {
|
|
660
660
|
return "";
|
|
661
661
|
},
|
|
662
662
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { dlopen, FFIType, ptr } from "bun:ffi";
|
|
2
2
|
import * as childProcess from "node:child_process";
|
|
3
3
|
import { createHmac } from "node:crypto";
|
|
4
|
+
import type { EventEmitter } from "node:events";
|
|
4
5
|
import * as fs from "node:fs/promises";
|
|
5
6
|
import * as os from "node:os";
|
|
6
7
|
import * as path from "node:path";
|
|
@@ -121,6 +122,63 @@ async function reapLinuxAdoptedZombies(excludedPid: number | undefined): Promise
|
|
|
121
122
|
}
|
|
122
123
|
}
|
|
123
124
|
|
|
125
|
+
/**
|
|
126
|
+
* Reap adopted zombies only when the kernel reports a child state change.
|
|
127
|
+
*
|
|
128
|
+
* As the Linux child subreaper, the supervisor inherits orphaned descendants
|
|
129
|
+
* and must reap them, but a full `/proc` sweep is expensive. Polling it on a
|
|
130
|
+
* short interval kept every idle supervisor busy (issue #5972), so sweeps are
|
|
131
|
+
* driven by SIGCHLD instead. At most one sweep runs at a time, and a SIGCHLD that
|
|
132
|
+
* arrives mid-sweep schedules exactly one follow-up so a zombie created after
|
|
133
|
+
* its `/proc` entry was passed is never missed. Returns the unsubscribe hook.
|
|
134
|
+
*/
|
|
135
|
+
export function startLinuxAdoptedZombieReaper(
|
|
136
|
+
excludedPid: number | undefined,
|
|
137
|
+
reap: (excludedPid: number | undefined) => Promise<void> = reapLinuxAdoptedZombies,
|
|
138
|
+
signals: Pick<EventEmitter, "on" | "off"> = process,
|
|
139
|
+
): () => void {
|
|
140
|
+
if (process.platform !== "linux") return () => undefined;
|
|
141
|
+
let running = false;
|
|
142
|
+
let rerun = false;
|
|
143
|
+
let stopped = false;
|
|
144
|
+
let sweepPending = false;
|
|
145
|
+
const sweep = (): void => {
|
|
146
|
+
if (stopped) return;
|
|
147
|
+
if (running) {
|
|
148
|
+
rerun = true;
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (sweepPending) return;
|
|
152
|
+
sweepPending = true;
|
|
153
|
+
running = true;
|
|
154
|
+
void reap(excludedPid)
|
|
155
|
+
.catch(() => undefined)
|
|
156
|
+
.finally(() => {
|
|
157
|
+
running = false;
|
|
158
|
+
sweepPending = false;
|
|
159
|
+
if (!rerun || stopped) return;
|
|
160
|
+
rerun = false;
|
|
161
|
+
// Defer recursive call to avoid stack overflow
|
|
162
|
+
setImmediate(() => {
|
|
163
|
+
if (!stopped && !running) sweep();
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
};
|
|
167
|
+
try {
|
|
168
|
+
signals.on("SIGCHLD", sweep);
|
|
169
|
+
} catch {
|
|
170
|
+
// Signal handler installation may fail in some environments
|
|
171
|
+
}
|
|
172
|
+
return () => {
|
|
173
|
+
stopped = true;
|
|
174
|
+
try {
|
|
175
|
+
signals.off("SIGCHLD", sweep);
|
|
176
|
+
} catch {
|
|
177
|
+
// Signal handler removal may fail in some environments
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
124
182
|
function signalFromExit(code: number | null, signal: NodeJS.Signals | null): NodeJS.Signals | null {
|
|
125
183
|
if (signal) return signal;
|
|
126
184
|
if (code === null || code <= 128) return null;
|
|
@@ -210,8 +268,7 @@ export async function runBashShellSupervisor(): Promise<void> {
|
|
|
210
268
|
stdio: ["pipe", "pipe", "pipe"],
|
|
211
269
|
windowsHide: true,
|
|
212
270
|
});
|
|
213
|
-
const
|
|
214
|
-
zombieReaper.unref();
|
|
271
|
+
const stopZombieReaper = startLinuxAdoptedZombieReaper(worker.pid);
|
|
215
272
|
const pendingRuns: number[] = [];
|
|
216
273
|
let terminating = false;
|
|
217
274
|
let protocolToken: string | undefined;
|
|
@@ -315,7 +372,7 @@ export async function runBashShellSupervisor(): Promise<void> {
|
|
|
315
372
|
);
|
|
316
373
|
});
|
|
317
374
|
worker.once("exit", async (code, signal) => {
|
|
318
|
-
|
|
375
|
+
stopZombieReaper();
|
|
319
376
|
const resultSignal = signalFromExit(code, signal);
|
|
320
377
|
if (code === 0 && resultSignal === null) {
|
|
321
378
|
await reapLinuxSubreaperChildren();
|
|
@@ -30,7 +30,8 @@ import {
|
|
|
30
30
|
listCanonicalBlobs,
|
|
31
31
|
removeCanonicalBlob,
|
|
32
32
|
} from "../session/blob-store";
|
|
33
|
-
import {
|
|
33
|
+
import { probeSessionRetirement, retireSessionTranscript } from "../session/session-retirement";
|
|
34
|
+
import { FileSessionStorage } from "../session/session-storage";
|
|
34
35
|
import {
|
|
35
36
|
collectEmptyDeleteReceipts,
|
|
36
37
|
type EmptyDeleteGcRecord,
|
package/src/hindsight/config.ts
CHANGED
|
@@ -62,11 +62,17 @@ function envBool(value: string | undefined): boolean | undefined {
|
|
|
62
62
|
return ["true", "1", "yes"].includes(value.toLowerCase());
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
/**
|
|
65
|
+
/**
|
|
66
|
+
* Coerce an env var value into a non-negative int, returning undefined (so the
|
|
67
|
+
* settings value applies) for anything that is not plain digits. `parseInt`
|
|
68
|
+
* alone would read "5turns" as 5, "1e3" as 1 and "-3" as -3.
|
|
69
|
+
*/
|
|
66
70
|
function envInt(value: string | undefined): number | undefined {
|
|
67
71
|
if (value === undefined) return undefined;
|
|
68
|
-
const
|
|
69
|
-
|
|
72
|
+
const trimmed = value.trim();
|
|
73
|
+
if (!/^\d+$/.test(trimmed)) return undefined;
|
|
74
|
+
const n = Number(trimmed);
|
|
75
|
+
return Number.isSafeInteger(n) ? n : undefined;
|
|
70
76
|
}
|
|
71
77
|
|
|
72
78
|
function envString(value: string | undefined): string | undefined {
|