@gajae-code/coding-agent 0.15.6 → 0.16.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/CHANGELOG.md +99 -0
- package/dist/types/async/job-manager.d.ts +32 -1
- package/dist/types/browser-backend.d.ts +12 -0
- package/dist/types/cli/args.d.ts +2 -0
- package/dist/types/cli/root-flags.d.ts +14 -0
- package/dist/types/cli/update-cli.d.ts +14 -0
- package/dist/types/cli.d.ts +7 -0
- package/dist/types/commands/launch.d.ts +10 -0
- package/dist/types/commands/sdk.d.ts +2 -0
- package/dist/types/config/autorouting-tier-map.d.ts +24 -0
- package/dist/types/config/billing-path.d.ts +25 -0
- package/dist/types/config/config-schema-version.d.ts +13 -1
- package/dist/types/config/file-lock.d.ts +5 -0
- package/dist/types/config/model-registry.d.ts +22 -0
- package/dist/types/config/settings-schema.d.ts +27 -8
- package/dist/types/config/settings.d.ts +2 -0
- package/dist/types/coordinator-mcp/projection-scan.d.ts +8 -0
- package/dist/types/crash/record-loader.d.ts +15 -0
- package/dist/types/extensibility/extensions/types.d.ts +8 -3
- package/dist/types/gjc-runtime/launch-worktree-reservation.d.ts +21 -0
- package/dist/types/gjc-runtime/launch-worktree.d.ts +25 -1
- package/dist/types/gjc-runtime/managed-owner-supervisor.d.ts +2 -0
- package/dist/types/gjc-runtime/session-state-lock.d.ts +22 -0
- package/dist/types/gjc-runtime/session-state-sidecar.d.ts +66 -1
- package/dist/types/gjc-runtime/tmux-owner-isolation.d.ts +1 -0
- package/dist/types/gjc-runtime/tmux-sessions.d.ts +27 -0
- package/dist/types/main.d.ts +1 -0
- package/dist/types/master-mode/context.d.ts +21 -0
- package/dist/types/master-mode/first-request.d.ts +34 -0
- package/dist/types/master-mode/snapshot.d.ts +32 -0
- package/dist/types/modes/acp/acp-agent.d.ts +21 -21
- package/dist/types/modes/components/frictionless-onboarding-selector.d.ts +10 -0
- package/dist/types/modes/components/model-selector.d.ts +4 -0
- package/dist/types/modes/components/oauth-selector.d.ts +1 -0
- package/dist/types/modes/components/session-selector.d.ts +1 -1
- package/dist/types/modes/components/sessions-dashboard.d.ts +2 -1
- package/dist/types/modes/components/status-line/model-name.d.ts +18 -0
- package/dist/types/modes/components/status-line/priority-row.d.ts +34 -0
- package/dist/types/modes/components/status-line/segments.d.ts +10 -0
- package/dist/types/modes/interactive-mode.d.ts +16 -2
- package/dist/types/modes/print-mode.d.ts +17 -0
- package/dist/types/modes/theme/theme.d.ts +2 -1
- package/dist/types/modes/types.d.ts +2 -0
- package/dist/types/modes/ui-language.d.ts +7 -1
- package/dist/types/sdk/broker/broker.d.ts +79 -2
- package/dist/types/sdk/broker/endpoint-authority.d.ts +24 -0
- package/dist/types/sdk/broker/ensure.d.ts +3 -0
- package/dist/types/sdk/broker/index.d.ts +3 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +6 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +40 -0
- package/dist/types/sdk/broker/master-capability.d.ts +10 -0
- package/dist/types/sdk/broker/session-index.d.ts +40 -11
- package/dist/types/sdk/broker/session-scope.d.ts +72 -0
- package/dist/types/sdk/broker/spawn-authority.d.ts +201 -0
- package/dist/types/sdk/broker/spawn-substrate.d.ts +30 -0
- package/dist/types/sdk/broker/startup-budget.d.ts +52 -0
- package/dist/types/sdk/broker/state-version.d.ts +21 -1
- package/dist/types/sdk/broker/worktree-occupancy.d.ts +28 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +3 -0
- package/dist/types/sdk/bus/discord-daemon.d.ts +1 -1
- package/dist/types/sdk/bus/index.d.ts +9 -1
- package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +1 -1
- package/dist/types/sdk/bus/prompt-reconciliation.d.ts +1 -1
- package/dist/types/sdk/bus/slack-conversation.d.ts +1 -1
- package/dist/types/sdk/bus/slack-daemon.d.ts +1 -1
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +1 -1
- package/dist/types/sdk/cli/index.d.ts +1 -0
- package/dist/types/sdk/cli/master-cli.d.ts +63 -0
- package/dist/types/sdk/cli/rows.d.ts +12 -5
- package/dist/types/sdk/cli/session-cli.d.ts +20 -3
- package/dist/types/sdk/client/client.d.ts +3 -2
- package/dist/types/sdk/host/control/dispatch.d.ts +10 -0
- package/dist/types/sdk/host/control/index.d.ts +1 -1
- package/dist/types/sdk/host/control/operations.d.ts +2 -0
- package/dist/types/sdk/host/control/runtime-gate.d.ts +21 -7
- package/dist/types/sdk/host/events.d.ts +1 -0
- package/dist/types/sdk/host/host.d.ts +10 -0
- package/dist/types/sdk/host/query/cursor.d.ts +4 -2
- package/dist/types/sdk/host/query/handlers.d.ts +1 -0
- package/dist/types/sdk/host/query/revision-store.d.ts +1 -0
- package/dist/types/sdk/host/session-runtime.d.ts +70 -17
- package/dist/types/sdk/lifecycle/broker-client.d.ts +6 -0
- package/dist/types/sdk/lifecycle/service.d.ts +15 -3
- package/dist/types/sdk/lifecycle-session.d.ts +3 -1
- package/dist/types/sdk/prompt-deadline-manager.d.ts +2 -5
- package/dist/types/sdk/receipt-state.d.ts +2 -0
- package/dist/types/sdk/router/session-router.d.ts +6 -0
- package/dist/types/sdk/session.d.ts +16 -0
- package/dist/types/sdk/startup-capability.d.ts +2 -1
- package/dist/types/sdk/turn-result.d.ts +6 -0
- package/dist/types/session/agent-session.d.ts +52 -7
- package/dist/types/session/credential-store-errors.d.ts +1 -0
- package/dist/types/session/fold-coordinator.d.ts +29 -2
- package/dist/types/session/session-manager.d.ts +79 -2
- package/dist/types/session/yield-queue.d.ts +5 -4
- package/dist/types/setup/frictionless-onboarding.d.ts +1 -0
- package/dist/types/tools/ask.d.ts +1 -0
- package/dist/types/tools/bash.d.ts +16 -0
- package/dist/types/tools/browser/launch.d.ts +10 -0
- package/dist/types/tools/browser/registry.d.ts +8 -0
- package/dist/types/tools/gh.d.ts +8 -0
- package/dist/types/tools/index.d.ts +10 -10
- package/dist/types/tools/job.d.ts +3 -1
- package/dist/types/utils/external-editor.d.ts +7 -0
- package/examples/extensions/README.md +1 -1
- package/examples/extensions/pirate.ts +7 -4
- package/package.json +7 -7
- package/scripts/generate-sdk-operation-inventory.ts +13 -1
- package/scripts/verify-gjc-sdk-canonicalization.ts +35 -1
- package/src/async/job-manager.ts +107 -9
- package/src/browser-backend.ts +29 -0
- package/src/cli/accounts-cli.ts +9 -5
- package/src/cli/args.ts +17 -0
- package/src/cli/fast-help.ts +1 -0
- package/src/cli/plugin-cli.ts +29 -0
- package/src/cli/root-flags.ts +5 -0
- package/src/cli/update-cli.ts +140 -23
- package/src/commands/launch.ts +86 -18
- package/src/commands/sdk.ts +135 -28
- package/src/config/autorouting-tier-map.ts +12 -0
- package/src/config/billing-path.ts +42 -0
- package/src/config/config-schema-version.ts +18 -1
- package/src/config/file-lock.ts +158 -83
- package/src/config/model-preset-registry.ts +178 -23
- package/src/config/model-profiles.ts +5 -5
- package/src/config/model-registry.ts +291 -42
- package/src/config/model-resolver.ts +5 -0
- package/src/config/settings-schema.ts +27 -8
- package/src/config/settings.ts +51 -15
- package/src/coordinator-mcp/projection-scan.ts +27 -6
- package/src/coordinator-mcp/question-state.ts +9 -11
- package/src/coordinator-mcp/server.ts +115 -21
- package/src/crash/index-store.ts +2 -0
- package/src/crash/record-loader.ts +10 -0
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +1 -1
- package/src/extensibility/extensions/runner.ts +27 -0
- package/src/extensibility/extensions/types.ts +8 -3
- package/src/extensibility/gjc-plugins/installer.ts +51 -11
- package/src/extensibility/runtime-skill-discovery.ts +110 -3
- package/src/extensibility/skills.ts +22 -12
- package/src/gjc-runtime/launch-worktree-reservation.ts +242 -0
- package/src/gjc-runtime/launch-worktree.ts +285 -4
- package/src/gjc-runtime/managed-owner-supervisor.ts +63 -51
- package/src/gjc-runtime/session-state-lock.ts +213 -14
- package/src/gjc-runtime/session-state-sidecar.ts +938 -39
- package/src/gjc-runtime/tmux-owner-isolation-cli.ts +4 -7
- package/src/gjc-runtime/tmux-owner-isolation.ts +18 -3
- package/src/gjc-runtime/tmux-sessions.ts +252 -13
- package/src/hooks/skill-state.ts +6 -0
- package/src/internal-urls/docs-index.generated.ts +15 -15
- package/src/internal-urls/issue-pr-protocol.ts +4 -2
- package/src/main.ts +61 -3
- package/src/master-mode/context.ts +50 -0
- package/src/master-mode/first-request.ts +65 -0
- package/src/master-mode/snapshot.ts +205 -0
- package/src/modes/acp/acp-agent.ts +610 -161
- package/src/modes/components/footer.ts +4 -2
- package/src/modes/components/frictionless-onboarding-selector.ts +48 -2
- package/src/modes/components/model-selector.ts +76 -8
- package/src/modes/components/oauth-selector.ts +6 -1
- package/src/modes/components/session-selector.ts +23 -15
- package/src/modes/components/sessions-dashboard.ts +8 -5
- package/src/modes/components/settings-selector.ts +1 -0
- package/src/modes/components/status-line/model-name.ts +53 -0
- package/src/modes/components/status-line/priority-row.ts +107 -0
- package/src/modes/components/status-line/segments.ts +23 -9
- package/src/modes/components/tool-status-header.ts +151 -15
- package/src/modes/controllers/command-controller.ts +1 -1
- package/src/modes/controllers/event-controller.ts +30 -4
- package/src/modes/controllers/extension-ui-controller.ts +13 -13
- package/src/modes/controllers/input-controller.ts +30 -2
- package/src/modes/controllers/selector-controller.ts +200 -98
- package/src/modes/interactive-mode.ts +36 -12
- package/src/modes/print-mode.ts +64 -0
- package/src/modes/prompt-action-autocomplete.ts +30 -4
- package/src/modes/runtime-init.ts +12 -9
- package/src/modes/theme/theme.ts +5 -0
- package/src/modes/types.ts +2 -0
- package/src/modes/ui-language.ts +49 -2
- package/src/modes/utils/ui-helpers.ts +22 -3
- package/src/prompts/agent-fragments/browser-aside.md +22 -0
- package/src/prompts/system/master-mode.md +28 -0
- package/src/prompts/tools/ask.md +1 -1
- package/src/prompts/tools/bash.md +1 -0
- package/src/prompts/tools/job.md +1 -1
- package/src/sdk/acp/adapter.ts +5 -0
- package/src/sdk/broker/broker.ts +1646 -27
- package/src/sdk/broker/endpoint-authority.ts +86 -0
- package/src/sdk/broker/ensure.ts +81 -3
- package/src/sdk/broker/index.ts +3 -0
- package/src/sdk/broker/lifecycle-ledger.ts +6 -0
- package/src/sdk/broker/lifecycle.ts +440 -75
- package/src/sdk/broker/master-capability.ts +232 -0
- package/src/sdk/broker/session-index.ts +121 -17
- package/src/sdk/broker/session-scope.ts +272 -0
- package/src/sdk/broker/spawn-authority.ts +1031 -0
- package/src/sdk/broker/spawn-substrate.ts +591 -0
- package/src/sdk/broker/startup-budget.ts +144 -2
- package/src/sdk/broker/state-version.ts +43 -14
- package/src/sdk/broker/transport.ts +1 -0
- package/src/sdk/broker/worktree-occupancy.ts +90 -0
- package/src/sdk/bus/chat-daemon-control.ts +5 -2
- package/src/sdk/bus/chat-daemon-runtime.ts +136 -18
- package/src/sdk/bus/discord-daemon.ts +50 -10
- package/src/sdk/bus/index.ts +84 -7
- package/src/sdk/bus/kind-aware-reconciliation.ts +296 -48
- package/src/sdk/bus/lifecycle-commands.ts +4 -0
- package/src/sdk/bus/notification-service.ts +22 -5
- package/src/sdk/bus/prompt-reconciliation.ts +7 -2
- package/src/sdk/bus/reconciliation-store.ts +55 -31
- package/src/sdk/bus/slack-conversation.ts +1 -1
- package/src/sdk/bus/slack-daemon.ts +72 -38
- package/src/sdk/bus/telegram-daemon-contract.ts +1 -1
- package/src/sdk/cli/index.ts +1 -0
- package/src/sdk/cli/master-cli.ts +259 -0
- package/src/sdk/cli/rows.ts +41 -15
- package/src/sdk/cli/session-cli.ts +297 -26
- package/src/sdk/client/client.ts +14 -8
- package/src/sdk/host/control/dispatch.ts +101 -40
- package/src/sdk/host/control/index.ts +2 -0
- package/src/sdk/host/control/operations.ts +2 -0
- package/src/sdk/host/control/runtime-gate.ts +203 -11
- package/src/sdk/host/events.ts +1 -0
- package/src/sdk/host/host.ts +29 -2
- package/src/sdk/host/query/cursor.ts +52 -7
- package/src/sdk/host/query/handlers.ts +33 -12
- package/src/sdk/host/query/revision-store.ts +12 -0
- package/src/sdk/host/session-runtime.test.ts +673 -14
- package/src/sdk/host/session-runtime.ts +674 -103
- package/src/sdk/host/surface-policy.ts +3 -3
- package/src/sdk/lifecycle/broker-client.ts +28 -0
- package/src/sdk/lifecycle/service.ts +279 -20
- package/src/sdk/lifecycle-session.ts +17 -4
- package/src/sdk/prompt-deadline-manager.ts +2 -1
- package/src/sdk/protocol/operation-inventory.generated.json +105 -3
- package/src/sdk/protocol/operation-registry.ts +14 -4
- package/src/sdk/receipt-state.ts +10 -0
- package/src/sdk/router/session-router.ts +219 -118
- package/src/sdk/session.ts +416 -195
- package/src/sdk/startup-capability.ts +1 -0
- package/src/sdk/turn-result.ts +22 -0
- package/src/session/agent-session.ts +1628 -318
- package/src/session/blob-store.ts +15 -5
- package/src/session/credential-store-errors.ts +2 -0
- package/src/session/fold-coordinator.ts +40 -3
- package/src/session/internal/managed-session-storage.ts +153 -78
- package/src/session/session-manager.ts +850 -97
- package/src/session/yield-queue.ts +24 -10
- package/src/setup/frictionless-onboarding.ts +2 -0
- package/src/slash-commands/builtin-registry.ts +41 -0
- package/src/task/executor.ts +9 -4
- package/src/telemetry/events.ts +1138 -12
- package/src/tools/ask-contract.test.ts +64 -0
- package/src/tools/ask-contract.ts +36 -1
- package/src/tools/ask.ts +10 -8
- package/src/tools/bash-interactive.ts +11 -2
- package/src/tools/bash.ts +412 -75
- package/src/tools/browser/launch.ts +37 -0
- package/src/tools/browser/registry.ts +99 -9
- package/src/tools/cron.ts +6 -4
- package/src/tools/descriptors.test.ts +15 -0
- package/src/tools/descriptors.ts +5 -1
- package/src/tools/gh.ts +104 -48
- package/src/tools/github-cache.ts +2 -2
- package/src/tools/index.ts +10 -6
- package/src/tools/job.ts +4 -1
- package/src/tools/monitor.ts +12 -9
- package/src/tools/resolve.ts +30 -10
- package/src/tools/tool-catalog.generated.ts +2 -2
- package/src/utils/external-editor.ts +72 -1
|
@@ -6,8 +6,13 @@ import { exactUnlink } from "@gajae-code/natives";
|
|
|
6
6
|
import { isEnoent, logger, postmortem } from "@gajae-code/utils";
|
|
7
7
|
|
|
8
8
|
const BLOB_PREFIX = "blob:sha256:";
|
|
9
|
+
const CANONICAL_BLOB_NAME = /^[0-9a-f]{64}$/;
|
|
9
10
|
const TAKE_BLOB_BUFFER_OWNERSHIP = Symbol("takeBlobBufferOwnership");
|
|
10
11
|
|
|
12
|
+
function isCanonicalBlobHash(hash: string): boolean {
|
|
13
|
+
return hash.length === 64 && CANONICAL_BLOB_NAME.test(hash);
|
|
14
|
+
}
|
|
15
|
+
|
|
11
16
|
/**
|
|
12
17
|
* Owner-only permissions for on-disk blob directories and files.
|
|
13
18
|
*
|
|
@@ -1126,6 +1131,7 @@ export class BlobStore {
|
|
|
1126
1131
|
|
|
1127
1132
|
/** Read blob by hash, returns Buffer or null if not found. */
|
|
1128
1133
|
async get(hash: string): Promise<Buffer | null> {
|
|
1134
|
+
if (!isCanonicalBlobHash(hash)) return null;
|
|
1129
1135
|
const blobPath = path.join(this.dir, hash);
|
|
1130
1136
|
try {
|
|
1131
1137
|
const file = Bun.file(blobPath);
|
|
@@ -1139,6 +1145,7 @@ export class BlobStore {
|
|
|
1139
1145
|
|
|
1140
1146
|
/** Synchronously read blob by hash, returns Buffer or null if not found. */
|
|
1141
1147
|
getSync(hash: string): Buffer | null {
|
|
1148
|
+
if (!isCanonicalBlobHash(hash)) return null;
|
|
1142
1149
|
const blobPath = path.join(this.dir, hash);
|
|
1143
1150
|
try {
|
|
1144
1151
|
return fs.readFileSync(blobPath);
|
|
@@ -1155,6 +1162,7 @@ export class BlobStore {
|
|
|
1155
1162
|
|
|
1156
1163
|
/** Synchronously read blob by hash and verify its content hash; returns null if not found. */
|
|
1157
1164
|
getCheckedSync(hash: string): Buffer | null {
|
|
1165
|
+
if (!isCanonicalBlobHash(hash)) return null;
|
|
1158
1166
|
const blobPath = path.join(this.dir, hash);
|
|
1159
1167
|
try {
|
|
1160
1168
|
return verifyBlobFileSync(hash, blobPath);
|
|
@@ -1166,6 +1174,7 @@ export class BlobStore {
|
|
|
1166
1174
|
|
|
1167
1175
|
/** Check if a blob exists. */
|
|
1168
1176
|
async has(hash: string): Promise<boolean> {
|
|
1177
|
+
if (!isCanonicalBlobHash(hash)) return false;
|
|
1169
1178
|
try {
|
|
1170
1179
|
await fsp.access(path.join(this.dir, hash));
|
|
1171
1180
|
return true;
|
|
@@ -1321,6 +1330,7 @@ export class EphemeralBlobStore extends BlobStore {
|
|
|
1321
1330
|
}
|
|
1322
1331
|
|
|
1323
1332
|
getSync(hash: string): Buffer | null {
|
|
1333
|
+
if (!isCanonicalBlobHash(hash)) return null;
|
|
1324
1334
|
const cached = this.#bufferCache.get(hash);
|
|
1325
1335
|
if (cached) {
|
|
1326
1336
|
const blobPath = path.join(this.dir, hash);
|
|
@@ -1374,7 +1384,7 @@ export class EphemeralBlobStore extends BlobStore {
|
|
|
1374
1384
|
const blobPath = path.join(this.dir, entry);
|
|
1375
1385
|
const stat = fs.lstatSync(blobPath);
|
|
1376
1386
|
if (
|
|
1377
|
-
|
|
1387
|
+
!isCanonicalBlobHash(entry) ||
|
|
1378
1388
|
!stat.isFile() ||
|
|
1379
1389
|
stat.isSymbolicLink() ||
|
|
1380
1390
|
stat.uid !== uid ||
|
|
@@ -1534,13 +1544,14 @@ export class ResidentBlobMissingError extends Error {
|
|
|
1534
1544
|
|
|
1535
1545
|
/** Check if a data string is a blob reference. */
|
|
1536
1546
|
export function isBlobRef(data: string): boolean {
|
|
1537
|
-
return data
|
|
1547
|
+
return parseBlobRef(data) !== null;
|
|
1538
1548
|
}
|
|
1539
1549
|
|
|
1540
1550
|
/** Extract the SHA-256 hash from a blob reference string. */
|
|
1541
1551
|
export function parseBlobRef(data: string): string | null {
|
|
1542
1552
|
if (!data.startsWith(BLOB_PREFIX)) return null;
|
|
1543
|
-
|
|
1553
|
+
const hash = data.slice(BLOB_PREFIX.length);
|
|
1554
|
+
return isCanonicalBlobHash(hash) ? hash : null;
|
|
1544
1555
|
}
|
|
1545
1556
|
|
|
1546
1557
|
/** Identify provider transport image data URLs so persistence can externalize and restore them losslessly. */
|
|
@@ -1731,7 +1742,6 @@ export interface CanonicalBlobEntry {
|
|
|
1731
1742
|
readonly nlink: bigint;
|
|
1732
1743
|
}
|
|
1733
1744
|
|
|
1734
|
-
const CANONICAL_BLOB_NAME = /^[0-9a-f]{64}$/;
|
|
1735
1745
|
const BLOB_REFERENCE = /blob:sha256:([0-9a-f]{64})/g;
|
|
1736
1746
|
|
|
1737
1747
|
/** Longest possible `blob:sha256:<hash>` reference, used to bound chunked scans. */
|
|
@@ -1758,7 +1768,7 @@ export async function listCanonicalBlobs(dir: string): Promise<CanonicalBlobEntr
|
|
|
1758
1768
|
|
|
1759
1769
|
const entries: CanonicalBlobEntry[] = [];
|
|
1760
1770
|
for (const name of names) {
|
|
1761
|
-
if (!
|
|
1771
|
+
if (!isCanonicalBlobHash(name)) continue;
|
|
1762
1772
|
const blobPath = path.join(dir, name);
|
|
1763
1773
|
let stat: fs.BigIntStats;
|
|
1764
1774
|
try {
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
* delivery therefore still carries its receipt and can never silently
|
|
24
24
|
* degrade into an ordinary receipt-less completion.
|
|
25
25
|
*/
|
|
26
|
-
import type { AsyncJob } from "../async/job-manager";
|
|
26
|
+
import type { AsyncJob, FoldReason } from "../async/job-manager";
|
|
27
27
|
import foldReceiptPrompt from "../prompts/tools/fold-receipt.md" with { type: "text" };
|
|
28
28
|
|
|
29
29
|
/**
|
|
@@ -68,6 +68,8 @@ export interface FoldReceipt {
|
|
|
68
68
|
foldedAt: number;
|
|
69
69
|
/** Only command kinds can change directory; task-style waits never do. */
|
|
70
70
|
cwdSensitive: boolean;
|
|
71
|
+
/** What triggered the fold; recorded on the job as `metadata.foldReason`. */
|
|
72
|
+
reason: FoldReason;
|
|
71
73
|
}
|
|
72
74
|
|
|
73
75
|
/** A terminal completion observed for a folded job. */
|
|
@@ -106,6 +108,34 @@ export type FoldRequestResult =
|
|
|
106
108
|
| { status: "already-terminal"; reason: string }
|
|
107
109
|
| { status: "capture-failed"; reason: string };
|
|
108
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Session-level answer to "fold the foreground bash now". Consumed by the SDK
|
|
113
|
+
* `bash.background` control, whose declared error codes are exactly these
|
|
114
|
+
* non-folded statuses.
|
|
115
|
+
*/
|
|
116
|
+
export type ForegroundFoldOutcome =
|
|
117
|
+
| { status: "folded"; jobId: string }
|
|
118
|
+
| { status: "already_backgrounded" }
|
|
119
|
+
| { status: "no_active_bash" }
|
|
120
|
+
| { status: "not_foldable"; reason: string };
|
|
121
|
+
|
|
122
|
+
/** Map a non-folded outcome onto the C52 `bash.background` error contract (`not_foldable` | `already_backgrounded` | `no_active_bash`). */
|
|
123
|
+
export function bashBackgroundControlError(outcome: Exclude<ForegroundFoldOutcome, { status: "folded" }>): Error {
|
|
124
|
+
switch (outcome.status) {
|
|
125
|
+
case "already_backgrounded":
|
|
126
|
+
return Object.assign(new Error("The active bash command has already been moved to a background job."), {
|
|
127
|
+
code: "already_backgrounded",
|
|
128
|
+
});
|
|
129
|
+
case "no_active_bash":
|
|
130
|
+
return Object.assign(new Error("No foreground bash command is running."), { code: "no_active_bash" });
|
|
131
|
+
case "not_foldable":
|
|
132
|
+
return Object.assign(
|
|
133
|
+
new Error(`The active bash command cannot be moved to a managed background job: ${outcome.reason}`),
|
|
134
|
+
{ code: "not_foldable" },
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
109
139
|
/** What a delivery should carry, decided by the durable slot state (T2). */
|
|
110
140
|
export type FoldDeliveryDisposition =
|
|
111
141
|
| { kind: "ordinary" }
|
|
@@ -225,8 +255,13 @@ export class FoldCoordinator {
|
|
|
225
255
|
* Nothing awaits before the slot is reserved and the fence is armed, so a
|
|
226
256
|
* completion or a steering submission that races the capture cannot slip
|
|
227
257
|
* past into the old turn.
|
|
258
|
+
*
|
|
259
|
+
* A `steer` fold is the one trigger that does NOT end the turn: the steer
|
|
260
|
+
* that caused it must be consumed by the same run at the tool boundary
|
|
261
|
+
* right after the fold result (subagent-await parity), so no fence is
|
|
262
|
+
* armed, no stop is requested, and no remaining intent is captured.
|
|
228
263
|
*/
|
|
229
|
-
async requestFold(explicit?: FoldAdapter): Promise<FoldRequestResult> {
|
|
264
|
+
async requestFold(explicit?: FoldAdapter, reason: FoldReason = "chord"): Promise<FoldRequestResult> {
|
|
230
265
|
// S1 resolve target.
|
|
231
266
|
const adapter = explicit ?? this.resolveTarget();
|
|
232
267
|
if (!adapter) return { status: "unavailable", reason: "no foldable wait is registered" };
|
|
@@ -244,7 +279,8 @@ export class FoldCoordinator {
|
|
|
244
279
|
// S3 claim + reserve, S4 hand-off is the reservation itself, S5 arm the fence.
|
|
245
280
|
this.#folding.add(job);
|
|
246
281
|
this.#slots.set(job, { state: "reserved", adapter, parked: undefined, parkedAt: undefined });
|
|
247
|
-
const fencesOriginatingTurn =
|
|
282
|
+
const fencesOriginatingTurn =
|
|
283
|
+
reason !== "steer" && (adapter.originatingTurn ?? this.#deps.hasActiveTurn?.() ?? true);
|
|
248
284
|
const releaseFence = fencesOriginatingTurn ? this.#deps.armSteeringFence() : () => {};
|
|
249
285
|
|
|
250
286
|
let remainingIntent: string | undefined;
|
|
@@ -293,6 +329,7 @@ export class FoldCoordinator {
|
|
|
293
329
|
remainingIntent,
|
|
294
330
|
foldedAt: Date.now(),
|
|
295
331
|
cwdSensitive: adapter.cwdSensitive,
|
|
332
|
+
reason,
|
|
296
333
|
};
|
|
297
334
|
|
|
298
335
|
// A2 promote to present, preserving any payload parked during capture.
|