@gajae-code/coding-agent 0.18.6 → 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 +39 -0
- package/dist/types/capability/types.d.ts +4 -0
- package/dist/types/config/settings.d.ts +4 -0
- package/dist/types/discovery/helpers.d.ts +2 -2
- package/dist/types/runtime-mcp/elicitation.d.ts +12 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +9 -0
- package/dist/types/sdk/broker/task-artifact-owner-validation.d.ts +55 -0
- package/dist/types/sdk/bus/telegram-daemon.d.ts +3 -2
- package/dist/types/sdk/host/host.d.ts +6 -0
- package/dist/types/sdk/router/session-router.d.ts +7 -0
- 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/package.json +7 -7
- 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-main.ts +7 -8
- package/src/commands/sdk.ts +112 -21
- package/src/config/settings.ts +44 -4
- package/src/discovery/helpers.ts +9 -3
- package/src/discovery/ssh.ts +8 -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 +2 -2
- package/src/modes/acp/acp-agent.ts +75 -3
- package/src/runtime-mcp/client.ts +13 -4
- package/src/runtime-mcp/elicitation.ts +142 -0
- package/src/sdk/broker/broker.ts +8 -1
- package/src/sdk/broker/lifecycle.ts +109 -7
- package/src/sdk/broker/task-artifact-owner-validation.ts +259 -0
- 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.ts +4 -2
- package/src/sdk/host/host.ts +6 -0
- package/src/sdk/host/session-runtime.test.ts +43 -2
- package/src/sdk/host/session-runtime.ts +2 -2
- package/src/sdk/mcp/server.ts +15 -3
- package/src/sdk/router/session-router.ts +19 -2
- package/src/sdk/session.ts +14 -0
- package/src/session/agent-session.ts +57 -6
- package/src/session/internal/managed-session-storage.ts +107 -1
- 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/config/settings.ts
CHANGED
|
@@ -1104,6 +1104,41 @@ export class Settings implements NotificationSettingsReader {
|
|
|
1104
1104
|
if (saveError !== undefined) throw saveError;
|
|
1105
1105
|
}
|
|
1106
1106
|
|
|
1107
|
+
/** Copy execution settings without reloading, persisting, or sharing mutable layers. */
|
|
1108
|
+
snapshot(): Settings {
|
|
1109
|
+
const cloned = new Settings({ cwd: this.#cwd, agentDir: this.#agentDir, inMemory: true });
|
|
1110
|
+
cloned.#global = structuredClone(this.#global);
|
|
1111
|
+
cloned.#project = structuredClone(this.#project);
|
|
1112
|
+
cloned.#overrides = structuredClone(this.#overrides);
|
|
1113
|
+
cloned.#merged = structuredClone(this.#merged);
|
|
1114
|
+
cloned.#schemaReport = structuredClone(this.#schemaReport);
|
|
1115
|
+
cloned.#autoroutingEffective = structuredClone(this.#autoroutingEffective);
|
|
1116
|
+
cloned.#autoroutingLocalIssues = structuredClone(this.#autoroutingLocalIssues);
|
|
1117
|
+
cloned.#schemaMigrationPending = this.#schemaMigrationPending;
|
|
1118
|
+
cloned.#futureSchemaVersion = this.#futureSchemaVersion;
|
|
1119
|
+
cloned.#hasMalformedConfigRoot = this.#hasMalformedConfigRoot;
|
|
1120
|
+
cloned.#hasRecoveredConfigSyntax = this.#hasRecoveredConfigSyntax;
|
|
1121
|
+
cloned.#hasInvalidNotificationGlobal = this.#hasInvalidNotificationGlobal;
|
|
1122
|
+
cloned.#notificationValidationGeneration = this.#notificationValidationGeneration;
|
|
1123
|
+
cloned.#rawNotificationConfig = structuredClone(this.#rawNotificationConfig);
|
|
1124
|
+
cloned.#durableRawNotificationConfig = structuredClone(this.#durableRawNotificationConfig);
|
|
1125
|
+
cloned.#durableNotificationFingerprint = this.#durableNotificationFingerprint;
|
|
1126
|
+
return cloned;
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
/** Resolve a retained execution's project layer without persistence or global hooks. */
|
|
1130
|
+
async snapshotForCwd(cwd: string): Promise<Settings> {
|
|
1131
|
+
const cloned = this.snapshot();
|
|
1132
|
+
if (path.resolve(cwd) === path.resolve(this.#cwd)) return cloned;
|
|
1133
|
+
cloned.#cwd = path.resolve(cwd);
|
|
1134
|
+
cloned.#readonly = true;
|
|
1135
|
+
cloned.#project = {};
|
|
1136
|
+
cloned.#rebuildMerged();
|
|
1137
|
+
cloned.#project = await cloned.#loadProjectSettings(true);
|
|
1138
|
+
await cloned.#normalizeAfterLoad(false);
|
|
1139
|
+
return cloned;
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1107
1142
|
async cloneForCwd(cwd: string): Promise<Settings> {
|
|
1108
1143
|
// A clone shares the same config queue. Settle an already-reserved local
|
|
1109
1144
|
// debounce before the clone can enqueue a durable selector, preventing it
|
|
@@ -1572,9 +1607,14 @@ export class Settings implements NotificationSettingsReader {
|
|
|
1572
1607
|
return reconciled.settings;
|
|
1573
1608
|
}
|
|
1574
1609
|
|
|
1575
|
-
async #loadProjectSettings(): Promise<RawSettings> {
|
|
1610
|
+
async #loadProjectSettings(bypassCache = false): Promise<RawSettings> {
|
|
1576
1611
|
try {
|
|
1577
|
-
const result = await loadCapability(settingsCapability.id, {
|
|
1612
|
+
const result = await loadCapability(settingsCapability.id, {
|
|
1613
|
+
cwd: this.#cwd,
|
|
1614
|
+
agentDir: this.#agentDir,
|
|
1615
|
+
settings: this,
|
|
1616
|
+
bypassCache,
|
|
1617
|
+
});
|
|
1578
1618
|
let merged: RawSettings = {};
|
|
1579
1619
|
for (const item of result.items as SettingsCapabilityItem[]) {
|
|
1580
1620
|
if (item.level !== "project") continue;
|
|
@@ -1637,7 +1677,7 @@ export class Settings implements NotificationSettingsReader {
|
|
|
1637
1677
|
return settings;
|
|
1638
1678
|
}
|
|
1639
1679
|
|
|
1640
|
-
async #normalizeAfterLoad(): Promise<void> {
|
|
1680
|
+
async #normalizeAfterLoad(publishHooks = true): Promise<void> {
|
|
1641
1681
|
this.#sanitizeModelSelectorRecords();
|
|
1642
1682
|
this.#rebuildMerged();
|
|
1643
1683
|
if (!this.#futureSchemaVersion) {
|
|
@@ -1653,7 +1693,7 @@ export class Settings implements NotificationSettingsReader {
|
|
|
1653
1693
|
await this.flush();
|
|
1654
1694
|
this.#sanitizeModelSelectorRecords();
|
|
1655
1695
|
this.#rebuildMerged();
|
|
1656
|
-
this.#fireAllHooks();
|
|
1696
|
+
if (publishHooks) this.#fireAllHooks();
|
|
1657
1697
|
}
|
|
1658
1698
|
|
|
1659
1699
|
#sanitizeModelSelectorRecords(): void {
|
package/src/discovery/helpers.ts
CHANGED
|
@@ -203,10 +203,13 @@ export function getProjectPath(ctx: LoadContext, source: SourceId, subpath: stri
|
|
|
203
203
|
|
|
204
204
|
/** Build the filesystem authority for a provider read. */
|
|
205
205
|
export function getReadOptions(
|
|
206
|
-
ctx: Pick<
|
|
206
|
+
ctx: Pick<
|
|
207
|
+
LoadContext,
|
|
208
|
+
"home" | "isolatedHome" | "userAgentDir" | "homeIdentity" | "userAgentIdentity" | "bypassCache"
|
|
209
|
+
>,
|
|
207
210
|
scope: ReadScope,
|
|
208
211
|
): ReadFileOptions | undefined {
|
|
209
|
-
if (!ctx.isolatedHome) return undefined;
|
|
212
|
+
if (!ctx.isolatedHome) return ctx.bypassCache ? { bypassCache: true } : undefined;
|
|
210
213
|
return {
|
|
211
214
|
isolatedHome: true,
|
|
212
215
|
home: ctx.home,
|
|
@@ -219,7 +222,10 @@ export function getReadOptions(
|
|
|
219
222
|
}
|
|
220
223
|
|
|
221
224
|
export async function getReadOptionsForContainment(
|
|
222
|
-
ctx: Pick<
|
|
225
|
+
ctx: Pick<
|
|
226
|
+
LoadContext,
|
|
227
|
+
"home" | "isolatedHome" | "userAgentDir" | "homeIdentity" | "userAgentIdentity" | "bypassCache"
|
|
228
|
+
>,
|
|
223
229
|
scope: ReadScope,
|
|
224
230
|
containmentRoot?: string,
|
|
225
231
|
): Promise<ReadFileOptions | undefined> {
|
package/src/discovery/ssh.ts
CHANGED
|
@@ -34,9 +34,14 @@ interface SSHConfigFile {
|
|
|
34
34
|
|
|
35
35
|
function parsePort(value: number | string | undefined): number | undefined {
|
|
36
36
|
if (value === undefined) return undefined;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
// The JSON is not validated against SSHConfigFile, so anything else (e.g. an
|
|
38
|
+
// array, which parseInt would coerce: parseInt([2222]) === 2222) is rejected.
|
|
39
|
+
if (typeof value !== "number" && typeof value !== "string") return undefined;
|
|
40
|
+
// `Number.parseInt` accepts trailing garbage (parseInt("22oops") === 22), so a
|
|
41
|
+
// string must be plain digits.
|
|
42
|
+
if (typeof value === "string" && !/^\d+$/.test(value)) return undefined;
|
|
43
|
+
const port = typeof value === "number" ? value : Number.parseInt(value, 10);
|
|
44
|
+
return Number.isInteger(port) && port >= 1 && port <= 65535 ? port : undefined;
|
|
40
45
|
}
|
|
41
46
|
|
|
42
47
|
function parseCompat(value: boolean | string | undefined): boolean | undefined {
|
|
@@ -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 {
|