@gajae-code/coding-agent 0.11.10 → 0.11.11
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 +38 -0
- package/dist/types/cli.d.ts +8 -1
- package/dist/types/config/model-profile-activation.d.ts +1 -0
- package/dist/types/config/model-profile-contract.d.ts +2 -0
- package/dist/types/config/settings-schema.d.ts +57 -2
- package/dist/types/config/settings.d.ts +1 -0
- package/dist/types/extensibility/extensions/types.d.ts +21 -0
- package/dist/types/gjc-runtime/linux-proc.d.ts +22 -14
- package/dist/types/gjc-runtime/ralplan-runtime.d.ts +60 -0
- package/dist/types/gjc-runtime/state-runtime.d.ts +3 -1
- package/dist/types/modes/acp/acp-agent.d.ts +14 -9
- package/dist/types/modes/components/queue-pane.d.ts +8 -0
- package/dist/types/modes/components/queued-message-selector.d.ts +6 -0
- package/dist/types/modes/components/welcome.d.ts +1 -0
- package/dist/types/modes/interactive-mode.d.ts +5 -1
- package/dist/types/runtime/memory-domain.d.ts +9 -0
- package/dist/types/runtime/memory-guard-contract.d.ts +71 -0
- package/dist/types/runtime/memory-guard.d.ts +39 -0
- package/dist/types/runtime/memory-limit.d.ts +11 -0
- package/dist/types/runtime-mcp/manager.d.ts +8 -0
- package/dist/types/sdk/acp/final-text.d.ts +19 -0
- package/dist/types/sdk/acp/mcp.d.ts +23 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +2 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +2 -1
- package/dist/types/sdk/bus/index.d.ts +3 -1
- package/dist/types/sdk/bus/rate-limit-pool.d.ts +2 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +6 -4
- package/dist/types/sdk/bus/telegram-daemon.d.ts +23 -3
- package/dist/types/sdk/host/control/operations.d.ts +1 -0
- package/dist/types/sdk/lifecycle-session.d.ts +10 -1
- package/dist/types/sdk/startup-capability.d.ts +6 -0
- package/dist/types/session/agent-session.d.ts +9 -11
- package/dist/types/session/fallback-chain-controller.d.ts +18 -2
- package/dist/types/session/internal/managed-session-scope.d.ts +27 -0
- package/dist/types/session/session-manager.d.ts +34 -0
- package/dist/types/task/executor.d.ts +6 -0
- package/dist/types/task/types.d.ts +36 -0
- package/dist/types/task/ultragoal-redteam-activation.d.ts +33 -0
- package/dist/types/tools/resource-gc.d.ts +19 -0
- package/package.json +8 -8
- package/scripts/generate-sdk-operation-inventory.ts +2 -0
- package/scripts/run-test-manifest.ts +6 -4
- package/src/cli/args.ts +14 -8
- package/src/cli/fast-help.ts +1 -1
- package/src/cli.ts +48 -2
- package/src/commands/sdk.ts +91 -7
- package/src/config/model-profile-activation.ts +1 -0
- package/src/config/model-profile-contract.ts +13 -0
- package/src/config/model-profiles.ts +24 -0
- package/src/config/settings-schema.ts +61 -2
- package/src/config/settings.ts +8 -0
- package/src/defaults/gjc/skills/ralplan/SKILL.md +21 -2
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +1 -1
- package/src/extensibility/extensions/runner.ts +4 -0
- package/src/extensibility/extensions/types.ts +14 -0
- package/src/gjc-runtime/deep-interview-ambiguity.ts +16 -2
- package/src/gjc-runtime/deep-interview-state.ts +25 -3
- package/src/gjc-runtime/linux-proc.ts +70 -36
- package/src/gjc-runtime/ralplan-runtime.ts +252 -1
- package/src/gjc-runtime/state-runtime.ts +48 -11
- package/src/internal-urls/docs-index.generated.ts +4 -4
- package/src/internal-urls/local-protocol.ts +23 -4
- package/src/modes/acp/acp-agent.ts +554 -60
- package/src/modes/acp/acp-event-mapper.ts +93 -6
- package/src/modes/components/model-selector.ts +15 -1
- package/src/modes/components/notifications-settings-editor.ts +1 -1
- package/src/modes/components/queue-pane.ts +55 -9
- package/src/modes/components/queued-message-selector.ts +53 -10
- package/src/modes/components/tool-status-header.ts +1 -4
- package/src/modes/components/welcome.ts +18 -3
- package/src/modes/controllers/command-controller.ts +4 -0
- package/src/modes/controllers/extension-ui-controller.ts +4 -10
- package/src/modes/controllers/input-controller.ts +44 -3
- package/src/modes/interactive-mode.ts +65 -26
- package/src/modes/runtime-init.ts +1 -0
- package/src/prompts/agents/executor.md +1 -1
- package/src/runtime/memory-domain.ts +66 -0
- package/src/runtime/memory-guard-contract.ts +73 -0
- package/src/runtime/memory-guard.ts +292 -0
- package/src/runtime/memory-limit.ts +50 -0
- package/src/runtime-mcp/manager.ts +26 -6
- package/src/sdk/acp/adapter.ts +8 -1
- package/src/sdk/acp/final-text.ts +40 -0
- package/src/sdk/acp/mcp.ts +26 -0
- package/src/sdk/broker/lifecycle.ts +82 -1
- package/src/sdk/bus/chat-daemon-cli.ts +2 -2
- package/src/sdk/bus/chat-daemon-control.ts +4 -3
- package/src/sdk/bus/config.ts +1 -1
- package/src/sdk/bus/index.ts +162 -22
- package/src/sdk/bus/rate-limit-pool.ts +8 -0
- package/src/sdk/bus/telegram-daemon-contract.ts +6 -4
- package/src/sdk/bus/telegram-daemon.ts +531 -53
- package/src/sdk/host/control/dispatch.ts +2 -0
- package/src/sdk/host/control/operations.ts +1 -0
- package/src/sdk/host/host.ts +2 -2
- package/src/sdk/lifecycle-session.ts +19 -3
- package/src/sdk/protocol/operation-inventory.generated.json +47 -0
- package/src/sdk/protocol/operation-registry.ts +1 -0
- package/src/sdk/session.ts +12 -1
- package/src/sdk/startup-capability.ts +6 -0
- package/src/session/agent-session.ts +256 -142
- package/src/session/fallback-chain-controller.ts +47 -8
- package/src/session/internal/managed-session-scope.ts +40 -10
- package/src/session/internal/native-publish-outcome.ts +8 -3
- package/src/session/session-manager.ts +608 -25
- package/src/task/executor.ts +11 -3
- package/src/task/index.ts +2 -0
- package/src/task/types.ts +22 -11
- package/src/task/ultragoal-redteam-activation.ts +75 -0
- package/src/tools/resource-gc.ts +496 -120
- package/src/workflow/workflow-intent-diff.ts +4 -1
|
@@ -30,6 +30,7 @@ export class FallbackChainController {
|
|
|
30
30
|
|
|
31
31
|
#attemptStarted = false;
|
|
32
32
|
#totalAttemptsUsed = 0;
|
|
33
|
+
#restoredEntryIndices = new Set<number>();
|
|
33
34
|
skips: Array<{ selector: string; reason: string }> = [];
|
|
34
35
|
exhaustedForTurn = false;
|
|
35
36
|
|
|
@@ -46,6 +47,10 @@ export class FallbackChainController {
|
|
|
46
47
|
return this.#totalAttemptsUsed;
|
|
47
48
|
}
|
|
48
49
|
|
|
50
|
+
#maxTotalAttempts(): number {
|
|
51
|
+
return this.maxAttempts * this.chain.entries.length + this.#restoredEntryIndices.size;
|
|
52
|
+
}
|
|
53
|
+
|
|
49
54
|
currentSelector(): string | undefined {
|
|
50
55
|
return this.chain.entries[this.activeIndex];
|
|
51
56
|
}
|
|
@@ -59,7 +64,7 @@ export class FallbackChainController {
|
|
|
59
64
|
/** Charge an upstream request at its concrete transport boundary. */
|
|
60
65
|
onAttemptStarted(): void {
|
|
61
66
|
if (!this.currentSelector() || this.exhaustedForTurn) return;
|
|
62
|
-
if (this.#totalAttemptsUsed >= this
|
|
67
|
+
if (this.#totalAttemptsUsed >= this.#maxTotalAttempts()) {
|
|
63
68
|
this.activeIndex = this.chain.entries.length;
|
|
64
69
|
this.exhaustedForTurn = true;
|
|
65
70
|
return;
|
|
@@ -82,6 +87,7 @@ export class FallbackChainController {
|
|
|
82
87
|
this.attemptsUsed = 0;
|
|
83
88
|
this.#totalAttemptsUsed = 0;
|
|
84
89
|
this.tried = [];
|
|
90
|
+
this.#restoredEntryIndices.clear();
|
|
85
91
|
this.#attemptStarted = false;
|
|
86
92
|
}
|
|
87
93
|
|
|
@@ -91,6 +97,7 @@ export class FallbackChainController {
|
|
|
91
97
|
this.skips = [...skips];
|
|
92
98
|
this.attemptsUsed = 0;
|
|
93
99
|
this.#totalAttemptsUsed = 0;
|
|
100
|
+
this.#restoredEntryIndices.clear();
|
|
94
101
|
this.#attemptStarted = false;
|
|
95
102
|
this.exhaustedForTurn = this.activeIndex >= this.chain.entries.length;
|
|
96
103
|
}
|
|
@@ -104,7 +111,7 @@ export class FallbackChainController {
|
|
|
104
111
|
}
|
|
105
112
|
this.#attemptStarted = false;
|
|
106
113
|
this.tried.push({ selector, triggerClass, reason });
|
|
107
|
-
if (this.#totalAttemptsUsed >= this
|
|
114
|
+
if (this.#totalAttemptsUsed >= this.#maxTotalAttempts()) {
|
|
108
115
|
this.activeIndex = this.chain.entries.length;
|
|
109
116
|
this.exhaustedForTurn = true;
|
|
110
117
|
return "exhausted";
|
|
@@ -126,19 +133,23 @@ export class FallbackChainController {
|
|
|
126
133
|
}
|
|
127
134
|
|
|
128
135
|
/**
|
|
129
|
-
* Restore the entry that just advanced
|
|
130
|
-
*
|
|
136
|
+
* Restore the entry that just advanced for one attempt with a rotated credential.
|
|
137
|
+
* Each non-terminal entry may be restored once, so credential rotation remains
|
|
138
|
+
* bounded and cannot consume the attempts reserved for downstream entries.
|
|
131
139
|
*/
|
|
132
140
|
restorePreviousEntryForRetry(): boolean {
|
|
141
|
+
const previousIndex = this.activeIndex - 1;
|
|
133
142
|
if (
|
|
134
|
-
|
|
143
|
+
previousIndex < 0 ||
|
|
135
144
|
this.exhaustedForTurn ||
|
|
136
|
-
this.#
|
|
145
|
+
this.#restoredEntryIndices.has(previousIndex) ||
|
|
146
|
+
this.#totalAttemptsUsed >= this.#maxTotalAttempts()
|
|
137
147
|
) {
|
|
138
148
|
return false;
|
|
139
149
|
}
|
|
140
|
-
this.
|
|
141
|
-
this.
|
|
150
|
+
this.#restoredEntryIndices.add(previousIndex);
|
|
151
|
+
this.activeIndex = previousIndex;
|
|
152
|
+
this.attemptsUsed = this.maxAttempts - 1;
|
|
142
153
|
this.exhaustedForTurn = false;
|
|
143
154
|
this.#attemptStarted = false;
|
|
144
155
|
return true;
|
|
@@ -157,6 +168,7 @@ export class FallbackChainController {
|
|
|
157
168
|
this.attemptsUsed = 0;
|
|
158
169
|
this.#totalAttemptsUsed = 0;
|
|
159
170
|
this.tried = [];
|
|
171
|
+
this.#restoredEntryIndices.clear();
|
|
160
172
|
this.skips = [];
|
|
161
173
|
this.exhaustedForTurn = this.chain.entries.length === 0;
|
|
162
174
|
this.#attemptStarted = false;
|
|
@@ -174,6 +186,33 @@ export function cappedExponentialWithFullJitter(
|
|
|
174
186
|
return Math.floor(Math.max(0, cap) * Math.max(0, Math.min(1, random())));
|
|
175
187
|
}
|
|
176
188
|
|
|
189
|
+
/**
|
|
190
|
+
* Legacy auto-compaction retry delay.
|
|
191
|
+
*
|
|
192
|
+
* Deliberately the mirror image of `effectiveFallbackDelay`: this path recovers
|
|
193
|
+
* Retry-After by regex over provider error prose (`#parseRetryAfterMsFromError`),
|
|
194
|
+
* so it follows the documented legacy rule — `retry.maxDelayMs` caps every
|
|
195
|
+
* legacy session retry delay, including provider retry-after hints. Managed
|
|
196
|
+
* fallback stays uncapped because it retries within its own per-entry budget;
|
|
197
|
+
* compaction has no such budget, so the final candidate would otherwise sleep
|
|
198
|
+
* for the full server-suggested duration.
|
|
199
|
+
*
|
|
200
|
+
* `maxDelayMs <= 0` means "no cap", matching `cappedExponentialWithFullJitter`.
|
|
201
|
+
* A missing, NaN, or infinite hint collapses to "no usable hint".
|
|
202
|
+
*/
|
|
203
|
+
export function compactionRetryDelay(
|
|
204
|
+
baseDelayMs: number,
|
|
205
|
+
maxDelayMs: number,
|
|
206
|
+
attempt: number,
|
|
207
|
+
retryAfterMs: number | undefined,
|
|
208
|
+
): number {
|
|
209
|
+
const exponential = baseDelayMs * 2 ** Math.max(0, attempt);
|
|
210
|
+
const hint = Number.isFinite(retryAfterMs) ? Math.max(0, retryAfterMs as number) : 0;
|
|
211
|
+
const hinted = Math.max(exponential, hint);
|
|
212
|
+
const bounded = maxDelayMs > 0 ? Math.min(hinted, maxDelayMs) : hinted;
|
|
213
|
+
return Math.max(0, bounded);
|
|
214
|
+
}
|
|
215
|
+
|
|
177
216
|
/** Retry-After is intentionally uncapped. */
|
|
178
217
|
export function effectiveFallbackDelay(
|
|
179
218
|
baseDelayMs: number,
|
|
@@ -2400,7 +2400,11 @@ type SourceArtifactCleanup = {
|
|
|
2400
2400
|
tree: NativeDirectoryTreeSnapshot;
|
|
2401
2401
|
};
|
|
2402
2402
|
|
|
2403
|
-
function cleanupAuthorityMatches(
|
|
2403
|
+
export function cleanupAuthorityMatches(
|
|
2404
|
+
cleanup: SourceArtifactCleanup,
|
|
2405
|
+
parent: string,
|
|
2406
|
+
platform: NodeJS.Platform = process.platform,
|
|
2407
|
+
): boolean {
|
|
2404
2408
|
try {
|
|
2405
2409
|
const stat = fs.lstatSync(cleanup.retainedPath, { bigint: true });
|
|
2406
2410
|
if (
|
|
@@ -2408,15 +2412,26 @@ function cleanupAuthorityMatches(cleanup: SourceArtifactCleanup, parent: string)
|
|
|
2408
2412
|
!stat.isDirectory() ||
|
|
2409
2413
|
stat.isSymbolicLink() ||
|
|
2410
2414
|
stat.dev !== cleanup.identity.dev ||
|
|
2411
|
-
stat.ino !== cleanup.identity.ino
|
|
2412
|
-
stat.size !== cleanup.identity.size ||
|
|
2413
|
-
stat.mtimeNs !== cleanup.identity.mtimeNs
|
|
2415
|
+
stat.ino !== cleanup.identity.ino
|
|
2414
2416
|
)
|
|
2415
2417
|
return false;
|
|
2416
2418
|
const snapshot = native.snapshotDirectoryTree(cleanup.retainedPath);
|
|
2419
|
+
const observedRoot = snapshot.snapshot?.entries.find(
|
|
2420
|
+
entry => entry.relativePath === "" && entry.kind === "directory",
|
|
2421
|
+
);
|
|
2422
|
+
if (
|
|
2423
|
+
!snapshot.ok ||
|
|
2424
|
+
!snapshot.snapshot ||
|
|
2425
|
+
!observedRoot ||
|
|
2426
|
+
(platform === "win32"
|
|
2427
|
+
? observedRoot.dev !== cleanup.identity.dev.toString() ||
|
|
2428
|
+
observedRoot.ino !== cleanup.identity.ino.toString() ||
|
|
2429
|
+
BigInt(observedRoot.size) !== cleanup.identity.size ||
|
|
2430
|
+
BigInt(observedRoot.mtimeNs) !== cleanup.identity.mtimeNs
|
|
2431
|
+
: stat.size !== cleanup.identity.size || stat.mtimeNs !== cleanup.identity.mtimeNs)
|
|
2432
|
+
)
|
|
2433
|
+
return false;
|
|
2417
2434
|
return (
|
|
2418
|
-
!!snapshot.ok &&
|
|
2419
|
-
!!snapshot.snapshot &&
|
|
2420
2435
|
sameArtifactTree(snapshot.snapshot, cleanup.tree) &&
|
|
2421
2436
|
cleanup.tree.entries.length === 1 &&
|
|
2422
2437
|
cleanup.tree.entries[0]?.relativePath === "" &&
|
|
@@ -2427,8 +2442,9 @@ function cleanupAuthorityMatches(cleanup: SourceArtifactCleanup, parent: string)
|
|
|
2427
2442
|
}
|
|
2428
2443
|
}
|
|
2429
2444
|
|
|
2430
|
-
function detachArtifactRootForMigration(
|
|
2445
|
+
export function detachArtifactRootForMigration(
|
|
2431
2446
|
plan: DetachedArtifactRoot,
|
|
2447
|
+
platform: NodeJS.Platform = process.platform,
|
|
2432
2448
|
):
|
|
2433
2449
|
| { detached: DetachedArtifactRoot; detachOutcome: "clean" }
|
|
2434
2450
|
| { detached: DetachedArtifactRoot; detachOutcome: "cleanup_pending"; cleanup: SourceArtifactCleanup } {
|
|
@@ -2464,14 +2480,27 @@ function detachArtifactRootForMigration(
|
|
|
2464
2480
|
if (!stat.isDirectory() || stat.isSymbolicLink() || path.dirname(placeholder) !== path.dirname(plan.originalPath))
|
|
2465
2481
|
throw new Error("durability_failed");
|
|
2466
2482
|
const snapshot = native.snapshotDirectoryTree(placeholder);
|
|
2483
|
+
if (!snapshot.ok || !snapshot.snapshot) throw new Error("durability_failed");
|
|
2484
|
+
// Windows directory size/mtime authority is the native tree root, never Bun's
|
|
2485
|
+
// zero-valued directory lstat. Capturing Bun values here would guarantee a
|
|
2486
|
+
// mismatch against the native-authoritative check below.
|
|
2487
|
+
const placeholderRoot = snapshot.snapshot.entries.find(
|
|
2488
|
+
entry => entry.relativePath === "" && entry.kind === "directory",
|
|
2489
|
+
);
|
|
2490
|
+
if (!placeholderRoot) throw new Error("durability_failed");
|
|
2467
2491
|
const cleanup: SourceArtifactCleanup = {
|
|
2468
2492
|
state: "cleanup_pending",
|
|
2469
2493
|
role: "exchange_placeholder",
|
|
2470
2494
|
retainedPath: placeholder,
|
|
2471
|
-
identity: {
|
|
2472
|
-
|
|
2495
|
+
identity: {
|
|
2496
|
+
dev: stat.dev,
|
|
2497
|
+
ino: stat.ino,
|
|
2498
|
+
size: platform === "win32" ? BigInt(placeholderRoot.size) : stat.size,
|
|
2499
|
+
mtimeNs: platform === "win32" ? BigInt(placeholderRoot.mtimeNs) : stat.mtimeNs,
|
|
2500
|
+
},
|
|
2501
|
+
tree: snapshot.snapshot,
|
|
2473
2502
|
};
|
|
2474
|
-
if (!
|
|
2503
|
+
if (!cleanupAuthorityMatches(cleanup, path.dirname(plan.originalPath), platform))
|
|
2475
2504
|
throw new Error("durability_failed");
|
|
2476
2505
|
return { detached, detachOutcome: "cleanup_pending", cleanup };
|
|
2477
2506
|
}
|
|
@@ -2798,6 +2827,7 @@ export async function reconcileManagedTombstones(
|
|
|
2798
2827
|
const tombstone = path.join(directory, name);
|
|
2799
2828
|
const targets = retiredTargets(scope, tombstone);
|
|
2800
2829
|
if (!targets) continue;
|
|
2830
|
+
if (targets.every(target => cleanupCompleted(scope, tombstone, target))) continue;
|
|
2801
2831
|
let lock: ManagedStorageLock | undefined;
|
|
2802
2832
|
try {
|
|
2803
2833
|
lock = await acquireManagedLock(
|
|
@@ -171,9 +171,14 @@ function legalOutcome(outcome: NativePublishOutcome): boolean {
|
|
|
171
171
|
outcome.durabilityState === "not_attempted" &&
|
|
172
172
|
preMutationReasons.has(outcome.reason) &&
|
|
173
173
|
((outcome.phase === "rename" &&
|
|
174
|
-
[
|
|
175
|
-
|
|
176
|
-
|
|
174
|
+
[
|
|
175
|
+
"destination_exists",
|
|
176
|
+
"atomic_unavailable",
|
|
177
|
+
"cross_device",
|
|
178
|
+
"permission_denied",
|
|
179
|
+
"io_failure",
|
|
180
|
+
"interrupted",
|
|
181
|
+
].includes(outcome.reason)) ||
|
|
177
182
|
(outcome.phase === "preflight" &&
|
|
178
183
|
!["atomic_unavailable", "cross_device", "interrupted"].includes(outcome.reason)) ||
|
|
179
184
|
(outcome.phase === "file_sync" && outcome.reason === "io_failure"))
|