@gajae-code/coding-agent 0.18.11 → 0.18.12
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 +293 -0
- package/dist/types/async/job-manager.d.ts +7 -3
- package/dist/types/async/result-formatting.d.ts +2 -0
- package/dist/types/autoresearch/git.d.ts +1 -1
- package/dist/types/capability/fs.d.ts +2 -2
- package/dist/types/cli/accounts-cli.d.ts +2 -2
- package/dist/types/cli/doctor/install-repairs.d.ts +4 -1
- package/dist/types/cli/install-activation.d.ts +10 -4
- package/dist/types/cli/public-command-errors.d.ts +1 -0
- package/dist/types/cli/update-cli.d.ts +14 -1
- package/dist/types/cli-ordinary.d.ts +2 -2
- package/dist/types/commands/accounts.d.ts +2 -1
- package/dist/types/commands/migrate.d.ts +1 -1
- package/dist/types/commands/sdk.d.ts +5 -0
- package/dist/types/commit/changelog/index.d.ts +1 -0
- package/dist/types/config/autorouting-tier-map.d.ts +30 -0
- package/dist/types/config/config-hot-reload-trust.d.ts +12 -0
- package/dist/types/config/config-hot-reload.d.ts +39 -0
- package/dist/types/config/file-lock.d.ts +8 -1
- package/dist/types/config/model-discovery-manager.d.ts +2 -0
- package/dist/types/config/model-profile-activation.d.ts +62 -6
- package/dist/types/config/model-registry.d.ts +56 -5
- package/dist/types/config/model-resolver.d.ts +2 -0
- package/dist/types/config/models-config-schema.d.ts +10 -0
- package/dist/types/config/settings-schema.d.ts +46 -3
- package/dist/types/config/settings.d.ts +33 -1
- package/dist/types/dap/config.d.ts +8 -4
- package/dist/types/debug/system-info.d.ts +6 -1
- package/dist/types/discovery/mcp-compat.d.ts +3 -1
- package/dist/types/edit/modes/patch.d.ts +5 -0
- package/dist/types/edit/modes/replace.d.ts +3 -0
- package/dist/types/exec/bash-executor.d.ts +12 -0
- package/dist/types/gjc-runtime/managed-owner-admission.d.ts +3 -0
- package/dist/types/gjc-runtime/session-state-lock.d.ts +2 -0
- package/dist/types/gjc-runtime/state-runtime.d.ts +0 -2
- package/dist/types/migrate/adapters/codex.d.ts +2 -1
- package/dist/types/migrate/adapters/index.d.ts +10 -1
- package/dist/types/migrate/executor.d.ts +3 -1
- package/dist/types/migrate/types.d.ts +15 -3
- package/dist/types/modes/components/settings-selector.d.ts +6 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +2 -0
- package/dist/types/modes/theme/theme.d.ts +1 -0
- package/dist/types/runtime-mcp/content-limits.d.ts +4 -0
- package/dist/types/runtime-mcp/manager.d.ts +7 -0
- package/dist/types/runtime-mcp/plugin-mcp-name-filter.d.ts +22 -0
- package/dist/types/runtime-mcp/tool-bridge.d.ts +4 -0
- package/dist/types/sdk/broker/broker-exit.d.ts +2 -2
- package/dist/types/sdk/broker/broker.d.ts +7 -1
- package/dist/types/sdk/broker/daemon-entry.d.ts +11 -1
- package/dist/types/sdk/broker/doctor-restart.d.ts +1 -1
- package/dist/types/sdk/broker/ensure.d.ts +136 -7
- package/dist/types/sdk/broker/hop.d.ts +36 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +18 -10
- package/dist/types/sdk/broker/lock-host-identity.d.ts +5 -0
- package/dist/types/sdk/broker/session-index.d.ts +4 -1
- package/dist/types/sdk/bus/chat-command-policy.d.ts +2 -1
- package/dist/types/sdk/bus/index.d.ts +23 -0
- package/dist/types/sdk/bus/reconciliation-store.d.ts +10 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +3 -1
- package/dist/types/sdk/cli/session-cli.d.ts +0 -1
- package/dist/types/sdk/host/session-runtime.d.ts +32 -0
- package/dist/types/sdk/prompt-deadline-flush.d.ts +42 -4
- package/dist/types/sdk/prompt-deadline-manager.d.ts +2 -0
- package/dist/types/sdk/protocol/adapter-validation.d.ts +10 -4
- package/dist/types/sdk/reconciliation-extensions.d.ts +1 -1
- package/dist/types/sdk/session-list.d.ts +1 -1
- package/dist/types/session/agent-session.d.ts +58 -2
- package/dist/types/session/internal/managed-session-scope.d.ts +2 -2
- package/dist/types/session/internal/managed-session-storage.d.ts +1 -1
- package/dist/types/session/internal/native-publish-outcome.d.ts +1 -1
- package/dist/types/session/messages.d.ts +5 -1
- package/dist/types/session/session-manager.d.ts +13 -3
- package/dist/types/session/startup-auth-config.d.ts +24 -2
- package/dist/types/session/streaming-output.d.ts +11 -0
- package/dist/types/session/terminal-abort.d.ts +3 -1
- package/dist/types/session-import/service.d.ts +1 -1
- package/dist/types/skill-state/workflow-mutation-guard.d.ts +7 -3
- package/dist/types/slash-commands/helpers/provider-auth-status.d.ts +8 -0
- package/dist/types/task/executor.d.ts +19 -2
- package/dist/types/tools/ast-edit-write-path.d.ts +10 -0
- package/dist/types/tools/atomic-file-write.d.ts +9 -7
- package/dist/types/tools/bash-allowed-prefixes.d.ts +11 -0
- package/dist/types/tools/descriptors.d.ts +2 -0
- package/dist/types/tools/fetch.d.ts +1 -1
- package/dist/types/tools/index.d.ts +2 -0
- package/dist/types/tools/python.d.ts +1 -1
- package/dist/types/tools/report-issue.d.ts +41 -0
- package/dist/types/tools/subagent.d.ts +23 -0
- package/dist/types/web/scrapers/types.d.ts +8 -1
- package/dist/types/web/search/providers/insane.d.ts +7 -1
- package/dist/types/web/search/providers/searxng.d.ts +5 -0
- package/package.json +8 -8
- package/scripts/build-binary.ts +2 -1
- package/scripts/capture-subagent-compact-panel-showcase.ts +105 -0
- package/scripts/generate-docs-index.ts +8 -1
- package/scripts/generate-sdk-operation-inventory.ts +22 -4
- package/src/async/job-manager.ts +356 -56
- package/src/async/result-formatting.ts +40 -0
- package/src/autoresearch/git.ts +9 -2
- package/src/autoresearch/prompts/prompt-setup.md +1 -1
- package/src/capability/fs.ts +27 -19
- package/src/capability/index.ts +2 -2
- package/src/cli/accounts-cli.ts +176 -8
- package/src/cli/auth-broker-cli.ts +21 -11
- package/src/cli/doctor/install-repairs.ts +35 -5
- package/src/cli/fast-help.ts +1 -1
- package/src/cli/install-activation.ts +47 -4
- package/src/cli/migrate-cli.ts +7 -5
- package/src/cli/public-command-errors.ts +4 -0
- package/src/cli/root-flags.ts +2 -2
- package/src/cli/stats-cli.ts +9 -5
- package/src/cli/update-cli.ts +224 -7
- package/src/cli-ordinary.ts +7 -2
- package/src/commands/accounts.ts +10 -5
- package/src/commands/migrate.ts +3 -3
- package/src/commands/sdk.ts +199 -42
- package/src/commands/ultragoal.ts +16 -8
- package/src/commit/changelog/index.ts +39 -1
- package/src/commit/message.ts +10 -3
- package/src/config/autorouting-tier-map.ts +30 -0
- package/src/config/config-hot-reload-trust.ts +148 -0
- package/src/config/config-hot-reload.ts +734 -0
- package/src/config/file-lock.ts +216 -56
- package/src/config/model-bindings-applier.ts +85 -47
- package/src/config/model-discovery-manager.ts +10 -0
- package/src/config/model-profile-activation.ts +716 -113
- package/src/config/model-registry.ts +1334 -158
- package/src/config/model-resolver.ts +3 -1
- package/src/config/models-config-schema.ts +6 -0
- package/src/config/settings-schema.ts +60 -3
- package/src/config/settings.ts +458 -24
- package/src/coordinator-mcp/policy.ts +26 -1
- package/src/crash/sanitize.ts +4 -0
- package/src/customization/import.ts +3 -1
- package/src/dap/config.ts +31 -11
- package/src/dap/defaults.json +1 -1
- package/src/debug/crash-diagnostics.ts +2 -1
- package/src/debug/report-bundle.ts +19 -0
- package/src/debug/system-info.ts +8 -3
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/shared/base-url.ts +21 -7
- package/src/discovery/agents-md.ts +1 -1
- package/src/discovery/helpers.ts +1 -2
- package/src/discovery/mcp-compat.ts +120 -17
- package/src/edit/apply-patch/index.ts +12 -1
- package/src/edit/index.ts +13 -17
- package/src/edit/modes/patch.ts +187 -8
- package/src/edit/modes/replace.ts +136 -0
- package/src/eval/js/context-manager.ts +29 -3
- package/src/eval/js/worker-entry.ts +51 -18
- package/src/eval/py/executor.ts +14 -4
- package/src/eval/py/runner.py +144 -5
- package/src/exec/bash-executor.ts +81 -4
- package/src/exec/bash-shell-guardian.ts +4 -1
- package/src/exec/bash-shell-supervisor.ts +8 -4
- package/src/exec/isolated-shell.ts +5 -1
- package/src/export/html/index.ts +46 -6
- package/src/extensibility/custom-tools/wrapper.ts +3 -1
- package/src/extensibility/extensions/loader.ts +8 -1
- package/src/extensibility/plugins/marketplace/fetcher.ts +2 -2
- package/src/gjc-runtime/gc-runtime.ts +33 -6
- package/src/gjc-runtime/launch-tmux.ts +7 -2
- package/src/gjc-runtime/launch-worktree.test.ts +148 -0
- package/src/gjc-runtime/launch-worktree.ts +101 -14
- package/src/gjc-runtime/managed-owner-admission.ts +46 -2
- package/src/gjc-runtime/session-resolution.ts +38 -6
- package/src/gjc-runtime/session-state-lock.ts +59 -14
- package/src/gjc-runtime/state-runtime.ts +23 -19
- package/src/hooks/native-skill-hook.ts +14 -11
- package/src/internal-urls/docs-index.generated.ts +14 -13
- package/src/internal-urls/local-protocol.ts +142 -8
- package/src/lsp/index.ts +29 -0
- package/src/lsp/workspace-path.ts +23 -0
- package/src/migrate/action-planner.ts +57 -0
- package/src/migrate/adapters/claude-code.ts +23 -4
- package/src/migrate/adapters/codex.ts +22 -4
- package/src/migrate/adapters/index.ts +22 -4
- package/src/migrate/adapters/opencode.ts +6 -1
- package/src/migrate/executor.ts +84 -7
- package/src/migrate/report.ts +19 -2
- package/src/migrate/types.ts +14 -4
- package/src/modes/DESIGN.md +51 -0
- package/src/modes/acp/permission-mode.ts +18 -1
- package/src/modes/components/assistant-message.ts +55 -1
- package/src/modes/components/settings-selector.ts +103 -37
- package/src/modes/controllers/command-controller.ts +38 -2
- package/src/modes/controllers/plan-mode-controller.ts +17 -7
- package/src/modes/controllers/selector-controller.ts +62 -6
- package/src/modes/interactive-mode.ts +68 -0
- package/src/modes/theme/theme.ts +15 -0
- package/src/prompts/tools/debug.md +1 -1
- package/src/prompts/tools/read.md +1 -1
- package/src/prompts/tools/report-issue.md +13 -0
- package/src/prompts/tools/task.md +1 -1
- package/src/runtime-credential-selector.ts +2 -2
- package/src/runtime-mcp/content-limits.ts +7 -0
- package/src/runtime-mcp/manager-pool.test.ts +5 -4
- package/src/runtime-mcp/manager.ts +32 -0
- package/src/runtime-mcp/oauth-flow.ts +32 -6
- package/src/runtime-mcp/plugin-mcp-name-filter.ts +62 -0
- package/src/runtime-mcp/render.ts +16 -1
- package/src/runtime-mcp/tool-bridge.ts +126 -17
- package/src/sdk/broker/broker-exit.ts +8 -5
- package/src/sdk/broker/broker.ts +342 -82
- package/src/sdk/broker/daemon-entry.ts +338 -116
- package/src/sdk/broker/doctor-restart.ts +2 -1
- package/src/sdk/broker/ensure.ts +1143 -265
- package/src/sdk/broker/hop.ts +274 -0
- package/src/sdk/broker/lifecycle-ledger.ts +35 -11
- package/src/sdk/broker/lock-host-identity.ts +29 -0
- package/src/sdk/broker/session-index.ts +62 -12
- package/src/sdk/bus/chat-command-policy.ts +16 -3
- package/src/sdk/bus/index.ts +52 -21
- package/src/sdk/bus/reconciliation-store.ts +201 -8
- package/src/sdk/bus/telegram-daemon-contract.ts +3 -1
- package/src/sdk/cli/session-cli.ts +21 -6
- package/src/sdk/host/session-runtime.test.ts +118 -23
- package/src/sdk/host/session-runtime.ts +352 -47
- package/src/sdk/lifecycle/service.ts +1 -0
- package/src/sdk/prompt-deadline-flush.ts +78 -5
- package/src/sdk/prompt-deadline-manager.ts +68 -14
- package/src/sdk/protocol/adapter-validation.ts +53 -11
- package/src/sdk/protocol/operation-inventory.generated.json +101 -2
- package/src/sdk/reconciliation-extensions.ts +1 -0
- package/src/sdk/session-list.ts +1 -0
- package/src/sdk/session.ts +114 -61
- package/src/session/agent-session.ts +1043 -81
- package/src/session/internal/managed-session-scope.ts +126 -39
- package/src/session/internal/managed-session-storage.ts +14 -11
- package/src/session/internal/native-publish-outcome.ts +5 -1
- package/src/session/messages.ts +47 -6
- package/src/session/session-manager.ts +236 -14
- package/src/session/startup-auth-config.ts +116 -8
- package/src/session/streaming-output.ts +262 -4
- package/src/session/terminal-abort.ts +14 -2
- package/src/session-import/service.ts +1 -0
- package/src/skill-state/workflow-mutation-guard.ts +491 -32
- package/src/slash-commands/builtin-registry.ts +15 -3
- package/src/slash-commands/helpers/credential-switch.ts +10 -5
- package/src/slash-commands/helpers/provider-auth-status.ts +456 -0
- package/src/task/executor.ts +103 -12
- package/src/task/index.ts +389 -175
- package/src/tools/ast-edit-write-path.ts +64 -0
- package/src/tools/ast-edit.ts +18 -1
- package/src/tools/atomic-file-write.ts +46 -15
- package/src/tools/auto-generated-guard.ts +3 -0
- package/src/tools/bash-allowed-prefixes.ts +153 -5
- package/src/tools/bash-interactive.ts +14 -2
- package/src/tools/bash.ts +14 -0
- package/src/tools/debug.ts +7 -6
- package/src/tools/descriptors.test.ts +44 -0
- package/src/tools/descriptors.ts +34 -2
- package/src/tools/fetch.ts +3 -2
- package/src/tools/index.ts +2 -0
- package/src/tools/output-meta.ts +23 -2
- package/src/tools/python.ts +1 -1
- package/src/tools/read.ts +17 -35
- package/src/tools/report-issue.ts +184 -0
- package/src/tools/subagent-render.ts +114 -12
- package/src/tools/subagent.ts +108 -1
- package/src/tools/todo-write.ts +41 -3
- package/src/tools/tool-catalog.generated.ts +31 -3
- package/src/tools/write.ts +35 -3
- package/src/utils/commit-message-generator.ts +9 -2
- package/src/utils/file-mentions.ts +29 -1
- package/src/utils/title-generator.ts +7 -2
- package/src/web/scrapers/index.ts +3 -1
- package/src/web/scrapers/types.ts +8 -0
- package/src/web/scrapers/youtube.ts +3 -2
- package/src/web/search/providers/insane.ts +91 -28
- package/src/web/search/providers/searxng.ts +62 -10
package/src/sdk/bus/index.ts
CHANGED
|
@@ -132,7 +132,7 @@ import {
|
|
|
132
132
|
syntheticModelInputError,
|
|
133
133
|
syntheticNamespaceCollision,
|
|
134
134
|
} from "../model-profile-model";
|
|
135
|
-
import {
|
|
135
|
+
import { autosaveWorktreeOnPromptDeadline, deadlineFlushSuppressed } from "../prompt-deadline-flush";
|
|
136
136
|
import {
|
|
137
137
|
createPromptDeadlineLease,
|
|
138
138
|
isAttributableProgressEventType,
|
|
@@ -2659,6 +2659,10 @@ function sdkControlSurface(
|
|
|
2659
2659
|
// the session-wide preflight seam must not be invoked while another
|
|
2660
2660
|
// connection's active preflight could be cancelled by it (review P1).
|
|
2661
2661
|
noOtherConnectionPreflights?: () => boolean,
|
|
2662
|
+
// True only for an operator terminal abort that the broker control route already
|
|
2663
|
+
// authorized (`TerminalAbortInput.operator`, which a public SDK caller cannot grant):
|
|
2664
|
+
// it addresses the session's active turn, not the requesting connection's own prompt.
|
|
2665
|
+
operatorAuthorized?: boolean,
|
|
2662
2666
|
) => Promise<
|
|
2663
2667
|
| {
|
|
2664
2668
|
ok: true;
|
|
@@ -3178,6 +3182,9 @@ function sdkControlSurface(
|
|
|
3178
3182
|
// invoking it (review thread P1).
|
|
3179
3183
|
() =>
|
|
3180
3184
|
![...pendingPreflightCancellations.values()].some(entry => entry.connectionId !== requesterConnectionId),
|
|
3185
|
+
// Broker-authorized operator authority is the one case where the abort
|
|
3186
|
+
// addresses a turn another connection submitted (see the parameter note).
|
|
3187
|
+
input.operator === true,
|
|
3181
3188
|
);
|
|
3182
3189
|
// Preflight cancellation happens ONLY for a NEWLY ADMITTED abort,
|
|
3183
3190
|
// after the durable admission/replay decision inside
|
|
@@ -4281,6 +4288,34 @@ export function boundedCorrelatedAgentEndFrame(frame: Record<string, unknown>):
|
|
|
4281
4288
|
};
|
|
4282
4289
|
}
|
|
4283
4290
|
|
|
4291
|
+
/** Connection-scoped identity of a queued prompt submission an abort may address. */
|
|
4292
|
+
export interface TerminalAbortSubmissionScope {
|
|
4293
|
+
connectionId?: string;
|
|
4294
|
+
terminal: boolean;
|
|
4295
|
+
}
|
|
4296
|
+
|
|
4297
|
+
/**
|
|
4298
|
+
* Whether a terminal abort addresses this prompt submission.
|
|
4299
|
+
*
|
|
4300
|
+
* An ordinary abort is scoped to the requesting connection's own prompt: `connectionId`
|
|
4301
|
+
* identifies the connection that submitted it, and a submission that already reached a
|
|
4302
|
+
* terminal state is never addressed. Broker-authorized operator authority
|
|
4303
|
+
* (`TerminalAbortInput.operator`, granted only through the broker control route) is the
|
|
4304
|
+
* documented exception — "operator authority changes only connection ownership, never
|
|
4305
|
+
* those settlement proofs" — so it addresses the session's submission even when another
|
|
4306
|
+
* connection submitted it. Without that override every operator abort issued over a
|
|
4307
|
+
* second connection (the SDK client case, where each request is its own connection)
|
|
4308
|
+
* reported no_active_turn while the turn was still running.
|
|
4309
|
+
*/
|
|
4310
|
+
export function terminalAbortAddressesSubmission(input: {
|
|
4311
|
+
connectionId: string | undefined;
|
|
4312
|
+
operatorAuthorized: boolean;
|
|
4313
|
+
submission: TerminalAbortSubmissionScope;
|
|
4314
|
+
}): boolean {
|
|
4315
|
+
if (input.submission.terminal) return false;
|
|
4316
|
+
return input.operatorAuthorized || input.submission.connectionId === input.connectionId;
|
|
4317
|
+
}
|
|
4318
|
+
|
|
4284
4319
|
export function createNotificationsExtension(
|
|
4285
4320
|
api: ExtensionAPI,
|
|
4286
4321
|
options: {
|
|
@@ -6408,21 +6443,12 @@ export function createNotificationsExtension(
|
|
|
6408
6443
|
if (
|
|
6409
6444
|
winner.kind === "failed" &&
|
|
6410
6445
|
winner.code === "prompt_deadline_exceeded" &&
|
|
6411
|
-
settings
|
|
6446
|
+
!deadlineFlushSuppressed(settings)
|
|
6412
6447
|
) {
|
|
6413
|
-
//
|
|
6414
|
-
//
|
|
6415
|
-
// honours the default inside a linked worktree the session owns.
|
|
6416
|
-
const configured = settings?.get("sdk.flushWorktreeOnDeadline");
|
|
6417
|
-
const hasExplicitSetting =
|
|
6418
|
-
typeof settings?.has === "function"
|
|
6419
|
-
? settings.has("sdk.flushWorktreeOnDeadline")
|
|
6420
|
-
: configured === true;
|
|
6421
|
-
const explicitOptIn = hasExplicitSetting === true && configured === true;
|
|
6448
|
+
// Same opt-in as the session runtime: user/global config or a runtime
|
|
6449
|
+
// override, never a project `.gjc` file or the schema default.
|
|
6422
6450
|
await runBoundedDeadlineFlush(signal =>
|
|
6423
|
-
|
|
6424
|
-
agentDir: settings?.getAgentDir(),
|
|
6425
|
-
explicitOptIn,
|
|
6451
|
+
autosaveWorktreeOnPromptDeadline(ctx.cwd, settings, {
|
|
6426
6452
|
isCurrent: () =>
|
|
6427
6453
|
deadlineAttemptStatus(promptSubmissionKey(correlation), submission, deadlineAttempt) ===
|
|
6428
6454
|
"current",
|
|
@@ -6736,7 +6762,14 @@ export function createNotificationsExtension(
|
|
|
6736
6762
|
}
|
|
6737
6763
|
return { aborted: true, disposition: "cancelled" as const };
|
|
6738
6764
|
},
|
|
6739
|
-
async (
|
|
6765
|
+
async (
|
|
6766
|
+
connectionId,
|
|
6767
|
+
scope,
|
|
6768
|
+
idempotencyKey,
|
|
6769
|
+
preflightCancel,
|
|
6770
|
+
noOtherConnectionPreflights,
|
|
6771
|
+
operatorAuthorized = false,
|
|
6772
|
+
) => {
|
|
6740
6773
|
// Capture the steering snapshot at ADMISSION (before the durable
|
|
6741
6774
|
// marker transaction): client steering admitted while the abort
|
|
6742
6775
|
// is in flight classifies as post-snapshot and is preserved at
|
|
@@ -7098,9 +7131,9 @@ export function createNotificationsExtension(
|
|
|
7098
7131
|
return "failed";
|
|
7099
7132
|
}
|
|
7100
7133
|
};
|
|
7101
|
-
|
|
7102
|
-
(
|
|
7103
|
-
);
|
|
7134
|
+
const addresses = (submission: TerminalAbortSubmissionScope): boolean =>
|
|
7135
|
+
terminalAbortAddressesSubmission({ connectionId, operatorAuthorized, submission });
|
|
7136
|
+
let active = [...promptSubmissions.entries()].find(([, submission]) => addresses(submission));
|
|
7104
7137
|
if (!active) {
|
|
7105
7138
|
// DURABLY reserve the key even for a no-active-turn abort: the
|
|
7106
7139
|
// generic idempotency cache is in-memory only, so after restart
|
|
@@ -7130,9 +7163,7 @@ export function createNotificationsExtension(
|
|
|
7130
7163
|
// and the durable no-effect row would block a same-key retry from
|
|
7131
7164
|
// stopping it — fall through to the pre-run / active fencing path
|
|
7132
7165
|
// when a submission now exists (review thread P1).
|
|
7133
|
-
active = [...promptSubmissions.entries()].find(
|
|
7134
|
-
([, submission]) => submission.connectionId === connectionId && !submission.terminal,
|
|
7135
|
-
);
|
|
7166
|
+
active = [...promptSubmissions.entries()].find(([, submission]) => addresses(submission));
|
|
7136
7167
|
if (!active) {
|
|
7137
7168
|
// Close the remaining acceptance race: cancel the requester's
|
|
7138
7169
|
// preflights HERE, in the same synchronous region as the
|
|
@@ -670,11 +670,22 @@ export interface ReconciliationStore {
|
|
|
670
670
|
delete(): Promise<void>;
|
|
671
671
|
}
|
|
672
672
|
|
|
673
|
+
export interface ReconciliationStoreInstrumentationEvent {
|
|
674
|
+
at: number;
|
|
675
|
+
phase: "enqueued" | "started" | "completed" | "failed";
|
|
676
|
+
operation?: string;
|
|
677
|
+
substep?: string;
|
|
678
|
+
error?: string;
|
|
679
|
+
/** Detailed information about lock acquisition, promise identity, db state, etc. */
|
|
680
|
+
detail?: string;
|
|
681
|
+
}
|
|
682
|
+
|
|
673
683
|
export function createReconciliationStore(options: {
|
|
674
684
|
sessionFile: string | null | undefined;
|
|
675
685
|
sessionId: string;
|
|
676
686
|
fs?: ReconciliationStoreFs;
|
|
677
687
|
now?: () => number;
|
|
688
|
+
onInstrumentationForTests?: (event: ReconciliationStoreInstrumentationEvent) => void;
|
|
678
689
|
}): ReconciliationStore {
|
|
679
690
|
const fileFs = options.fs ?? nodeFs;
|
|
680
691
|
const now = options.now ?? Date.now;
|
|
@@ -701,20 +712,56 @@ export function createReconciliationStore(options: {
|
|
|
701
712
|
const directory = path.dirname(filePath);
|
|
702
713
|
let temporary: string | undefined;
|
|
703
714
|
try {
|
|
715
|
+
try {
|
|
716
|
+
options.onInstrumentationForTests?.({ at: Date.now(), phase: "started", substep: "mkdir" });
|
|
717
|
+
} catch {}
|
|
704
718
|
await fileFs.mkdir(directory, { recursive: true, mode: 0o700 });
|
|
719
|
+
try {
|
|
720
|
+
options.onInstrumentationForTests?.({ at: Date.now(), phase: "completed", substep: "mkdir" });
|
|
721
|
+
} catch {}
|
|
705
722
|
temporary = `${filePath}.${process.pid}.${Date.now()}.${randomUUID()}.tmp`;
|
|
723
|
+
try {
|
|
724
|
+
options.onInstrumentationForTests?.({ at: Date.now(), phase: "started", substep: "writeFile" });
|
|
725
|
+
} catch {}
|
|
706
726
|
await fileFs.writeFile(temporary, `${JSON.stringify(document)}\n`, { mode: 0o600 });
|
|
707
727
|
try {
|
|
728
|
+
options.onInstrumentationForTests?.({ at: Date.now(), phase: "completed", substep: "writeFile" });
|
|
729
|
+
} catch {}
|
|
730
|
+
try {
|
|
731
|
+
try {
|
|
732
|
+
options.onInstrumentationForTests?.({ at: Date.now(), phase: "started", substep: "open" });
|
|
733
|
+
} catch {}
|
|
708
734
|
const handle = await fileFs.open(temporary, "r+");
|
|
709
735
|
try {
|
|
736
|
+
options.onInstrumentationForTests?.({ at: Date.now(), phase: "completed", substep: "open" });
|
|
737
|
+
} catch {}
|
|
738
|
+
try {
|
|
739
|
+
try {
|
|
740
|
+
options.onInstrumentationForTests?.({ at: Date.now(), phase: "started", substep: "sync" });
|
|
741
|
+
} catch {}
|
|
710
742
|
await handle.sync();
|
|
743
|
+
try {
|
|
744
|
+
options.onInstrumentationForTests?.({ at: Date.now(), phase: "completed", substep: "sync" });
|
|
745
|
+
} catch {}
|
|
711
746
|
} finally {
|
|
747
|
+
try {
|
|
748
|
+
options.onInstrumentationForTests?.({ at: Date.now(), phase: "started", substep: "close" });
|
|
749
|
+
} catch {}
|
|
712
750
|
await handle.close();
|
|
751
|
+
try {
|
|
752
|
+
options.onInstrumentationForTests?.({ at: Date.now(), phase: "completed", substep: "close" });
|
|
753
|
+
} catch {}
|
|
713
754
|
}
|
|
714
755
|
} catch {
|
|
715
756
|
// fsync optional on some fs seams
|
|
716
757
|
}
|
|
758
|
+
try {
|
|
759
|
+
options.onInstrumentationForTests?.({ at: Date.now(), phase: "started", substep: "rename" });
|
|
760
|
+
} catch {}
|
|
717
761
|
await fileFs.rename(temporary, filePath);
|
|
762
|
+
try {
|
|
763
|
+
options.onInstrumentationForTests?.({ at: Date.now(), phase: "completed", substep: "rename" });
|
|
764
|
+
} catch {}
|
|
718
765
|
} catch (error) {
|
|
719
766
|
// Every persistence-path failure (mkdir included) is evidence a drained
|
|
720
767
|
// window must surface, never silently treat as quiescent (#4743).
|
|
@@ -723,6 +770,9 @@ export function createReconciliationStore(options: {
|
|
|
723
770
|
code: "reconciliation_persist_failed",
|
|
724
771
|
});
|
|
725
772
|
unreportedPersistFailures.push(coded);
|
|
773
|
+
try {
|
|
774
|
+
options.onInstrumentationForTests?.({ at: Date.now(), phase: "failed", error: coded.message });
|
|
775
|
+
} catch {}
|
|
726
776
|
throw coded;
|
|
727
777
|
}
|
|
728
778
|
};
|
|
@@ -795,7 +845,26 @@ export function createReconciliationStore(options: {
|
|
|
795
845
|
const transact = async (
|
|
796
846
|
mutator: (records: DurableReconciliationRecord[]) => DurableReconciliationRecord[],
|
|
797
847
|
): Promise<void> => {
|
|
848
|
+
const promiseId = `reconcil-transact-${randomUUID().slice(0, 8)}`;
|
|
849
|
+
const enqueueTime = Date.now();
|
|
798
850
|
const run = async () => {
|
|
851
|
+
const lockWaitMs = Date.now() - enqueueTime;
|
|
852
|
+
try {
|
|
853
|
+
options.onInstrumentationForTests?.({
|
|
854
|
+
at: enqueueTime,
|
|
855
|
+
phase: "enqueued",
|
|
856
|
+
operation: "transact",
|
|
857
|
+
detail: `promise=${promiseId}`,
|
|
858
|
+
});
|
|
859
|
+
} catch {}
|
|
860
|
+
try {
|
|
861
|
+
options.onInstrumentationForTests?.({
|
|
862
|
+
at: Date.now(),
|
|
863
|
+
phase: "started",
|
|
864
|
+
operation: "transact",
|
|
865
|
+
detail: `promise=${promiseId} lock-wait=${lockWaitMs}ms`,
|
|
866
|
+
});
|
|
867
|
+
} catch {}
|
|
799
868
|
const next = mutator(memory.map(r => ({ ...r })));
|
|
800
869
|
await writeAtomic({
|
|
801
870
|
version: RECONCILIATION_STORE_VERSION,
|
|
@@ -805,19 +874,55 @@ export function createReconciliationStore(options: {
|
|
|
805
874
|
...(terminalKeyMemory.length > 0 ? { evictedTerminalKeys: terminalKeyMemory } : {}),
|
|
806
875
|
});
|
|
807
876
|
memory = next;
|
|
877
|
+
try {
|
|
878
|
+
options.onInstrumentationForTests?.({
|
|
879
|
+
at: Date.now(),
|
|
880
|
+
phase: "completed",
|
|
881
|
+
operation: "transact",
|
|
882
|
+
detail: `promise=${promiseId}`,
|
|
883
|
+
});
|
|
884
|
+
} catch {}
|
|
808
885
|
};
|
|
809
886
|
const pending = chain.then(run, run);
|
|
810
|
-
|
|
887
|
+
const settled = pending.then(
|
|
811
888
|
() => undefined,
|
|
812
889
|
() => undefined,
|
|
813
890
|
);
|
|
814
|
-
|
|
891
|
+
chain = settled;
|
|
892
|
+
try {
|
|
893
|
+
await pending;
|
|
894
|
+
} catch (error) {
|
|
895
|
+
try {
|
|
896
|
+
options.onInstrumentationForTests?.({
|
|
897
|
+
at: Date.now(),
|
|
898
|
+
phase: "failed",
|
|
899
|
+
operation: "transact",
|
|
900
|
+
detail: `promise=${promiseId} lock-wait=${Date.now() - enqueueTime}ms`,
|
|
901
|
+
error: error instanceof Error ? error.message : String(error),
|
|
902
|
+
});
|
|
903
|
+
} catch {}
|
|
904
|
+
throw error;
|
|
905
|
+
}
|
|
815
906
|
};
|
|
816
907
|
|
|
817
908
|
const transactTerminalScopes = async (
|
|
818
909
|
mutator: (scopes: DurableTerminalScopeRecord[]) => DurableTerminalScopeRecord[],
|
|
819
910
|
): Promise<void> => {
|
|
820
911
|
const run = async () => {
|
|
912
|
+
try {
|
|
913
|
+
options.onInstrumentationForTests?.({
|
|
914
|
+
at: Date.now(),
|
|
915
|
+
phase: "enqueued",
|
|
916
|
+
operation: "transactTerminalScopes",
|
|
917
|
+
});
|
|
918
|
+
} catch {}
|
|
919
|
+
try {
|
|
920
|
+
options.onInstrumentationForTests?.({
|
|
921
|
+
at: Date.now(),
|
|
922
|
+
phase: "started",
|
|
923
|
+
operation: "transactTerminalScopes",
|
|
924
|
+
});
|
|
925
|
+
} catch {}
|
|
821
926
|
const next = mutator(terminalMemory.map(s => ({ ...s })));
|
|
822
927
|
await writeAtomic({
|
|
823
928
|
version: RECONCILIATION_STORE_VERSION,
|
|
@@ -827,13 +932,33 @@ export function createReconciliationStore(options: {
|
|
|
827
932
|
...(terminalKeyMemory.length > 0 ? { evictedTerminalKeys: terminalKeyMemory } : {}),
|
|
828
933
|
});
|
|
829
934
|
terminalMemory = next;
|
|
935
|
+
try {
|
|
936
|
+
options.onInstrumentationForTests?.({
|
|
937
|
+
at: Date.now(),
|
|
938
|
+
phase: "completed",
|
|
939
|
+
operation: "transactTerminalScopes",
|
|
940
|
+
});
|
|
941
|
+
} catch {}
|
|
830
942
|
};
|
|
831
943
|
const pending = chain.then(run, run);
|
|
832
|
-
|
|
944
|
+
const settled = pending.then(
|
|
833
945
|
() => undefined,
|
|
834
946
|
() => undefined,
|
|
835
947
|
);
|
|
836
|
-
|
|
948
|
+
chain = settled;
|
|
949
|
+
try {
|
|
950
|
+
await pending;
|
|
951
|
+
} catch (error) {
|
|
952
|
+
try {
|
|
953
|
+
options.onInstrumentationForTests?.({
|
|
954
|
+
at: Date.now(),
|
|
955
|
+
phase: "failed",
|
|
956
|
+
operation: "transactTerminalScopes",
|
|
957
|
+
error: error instanceof Error ? error.message : String(error),
|
|
958
|
+
});
|
|
959
|
+
} catch {}
|
|
960
|
+
throw error;
|
|
961
|
+
}
|
|
837
962
|
};
|
|
838
963
|
|
|
839
964
|
const transactTerminalState = async (
|
|
@@ -843,6 +968,20 @@ export function createReconciliationStore(options: {
|
|
|
843
968
|
},
|
|
844
969
|
): Promise<void> => {
|
|
845
970
|
const run = async () => {
|
|
971
|
+
try {
|
|
972
|
+
options.onInstrumentationForTests?.({
|
|
973
|
+
at: Date.now(),
|
|
974
|
+
phase: "enqueued",
|
|
975
|
+
operation: "transactTerminalState",
|
|
976
|
+
});
|
|
977
|
+
} catch {}
|
|
978
|
+
try {
|
|
979
|
+
options.onInstrumentationForTests?.({
|
|
980
|
+
at: Date.now(),
|
|
981
|
+
phase: "started",
|
|
982
|
+
operation: "transactTerminalState",
|
|
983
|
+
});
|
|
984
|
+
} catch {}
|
|
846
985
|
const next = mutator({
|
|
847
986
|
scopes: terminalMemory.map(s => ({ ...s })),
|
|
848
987
|
keys: terminalKeyMemory.map(k => ({ ...k })),
|
|
@@ -856,19 +995,53 @@ export function createReconciliationStore(options: {
|
|
|
856
995
|
});
|
|
857
996
|
terminalMemory = next.scopes;
|
|
858
997
|
terminalKeyMemory = next.keys;
|
|
998
|
+
try {
|
|
999
|
+
options.onInstrumentationForTests?.({
|
|
1000
|
+
at: Date.now(),
|
|
1001
|
+
phase: "completed",
|
|
1002
|
+
operation: "transactTerminalState",
|
|
1003
|
+
});
|
|
1004
|
+
} catch {}
|
|
859
1005
|
};
|
|
860
1006
|
const pending = chain.then(run, run);
|
|
861
|
-
|
|
1007
|
+
const settled = pending.then(
|
|
862
1008
|
() => undefined,
|
|
863
1009
|
() => undefined,
|
|
864
1010
|
);
|
|
865
|
-
|
|
1011
|
+
chain = settled;
|
|
1012
|
+
try {
|
|
1013
|
+
await pending;
|
|
1014
|
+
} catch (error) {
|
|
1015
|
+
try {
|
|
1016
|
+
options.onInstrumentationForTests?.({
|
|
1017
|
+
at: Date.now(),
|
|
1018
|
+
phase: "failed",
|
|
1019
|
+
operation: "transactTerminalState",
|
|
1020
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1021
|
+
});
|
|
1022
|
+
} catch {}
|
|
1023
|
+
throw error;
|
|
1024
|
+
}
|
|
866
1025
|
};
|
|
867
1026
|
|
|
868
1027
|
const transactTerminalKeys = async (
|
|
869
1028
|
mutator: (keys: EvictedTerminalKeyEntry[]) => EvictedTerminalKeyEntry[],
|
|
870
1029
|
): Promise<void> => {
|
|
871
1030
|
const run = async () => {
|
|
1031
|
+
try {
|
|
1032
|
+
options.onInstrumentationForTests?.({
|
|
1033
|
+
at: Date.now(),
|
|
1034
|
+
phase: "enqueued",
|
|
1035
|
+
operation: "transactTerminalKeys",
|
|
1036
|
+
});
|
|
1037
|
+
} catch {}
|
|
1038
|
+
try {
|
|
1039
|
+
options.onInstrumentationForTests?.({
|
|
1040
|
+
at: Date.now(),
|
|
1041
|
+
phase: "started",
|
|
1042
|
+
operation: "transactTerminalKeys",
|
|
1043
|
+
});
|
|
1044
|
+
} catch {}
|
|
872
1045
|
const next = mutator(terminalKeyMemory.map(k => ({ ...k })));
|
|
873
1046
|
await writeAtomic({
|
|
874
1047
|
version: RECONCILIATION_STORE_VERSION,
|
|
@@ -878,13 +1051,33 @@ export function createReconciliationStore(options: {
|
|
|
878
1051
|
...(next.length > 0 ? { evictedTerminalKeys: next } : {}),
|
|
879
1052
|
});
|
|
880
1053
|
terminalKeyMemory = next;
|
|
1054
|
+
try {
|
|
1055
|
+
options.onInstrumentationForTests?.({
|
|
1056
|
+
at: Date.now(),
|
|
1057
|
+
phase: "completed",
|
|
1058
|
+
operation: "transactTerminalKeys",
|
|
1059
|
+
});
|
|
1060
|
+
} catch {}
|
|
881
1061
|
};
|
|
882
1062
|
const pending = chain.then(run, run);
|
|
883
|
-
|
|
1063
|
+
const settled = pending.then(
|
|
884
1064
|
() => undefined,
|
|
885
1065
|
() => undefined,
|
|
886
1066
|
);
|
|
887
|
-
|
|
1067
|
+
chain = settled;
|
|
1068
|
+
try {
|
|
1069
|
+
await pending;
|
|
1070
|
+
} catch (error) {
|
|
1071
|
+
try {
|
|
1072
|
+
options.onInstrumentationForTests?.({
|
|
1073
|
+
at: Date.now(),
|
|
1074
|
+
phase: "failed",
|
|
1075
|
+
operation: "transactTerminalKeys",
|
|
1076
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1077
|
+
});
|
|
1078
|
+
} catch {}
|
|
1079
|
+
throw error;
|
|
1080
|
+
}
|
|
888
1081
|
};
|
|
889
1082
|
|
|
890
1083
|
const deleteStore = async (): Promise<void> => {
|
|
@@ -301,8 +301,10 @@ export const SDK_LIFECYCLE_ROUTER_PROTOCOL_VERSION = 1;
|
|
|
301
301
|
* Generation 202 joins queued-removal terminal publication before ordinary
|
|
302
302
|
* abort acknowledgement, replacing owners that still acknowledge cancellation
|
|
303
303
|
* before its terminal record is durable.
|
|
304
|
+
* Generation 203 replaces owners that still treat a project `.gjc` file as an
|
|
305
|
+
* explicit deadline-autosave opt-in for a primary checkout.
|
|
304
306
|
*/
|
|
305
|
-
export const DAEMON_GENERATION =
|
|
307
|
+
export const DAEMON_GENERATION = 204;
|
|
306
308
|
|
|
307
309
|
/**
|
|
308
310
|
* Serving-compatibility boundary for daemon lifecycle requests. Epoch 7
|
|
@@ -258,17 +258,32 @@ function normalizeSessionFailure(error: unknown, args: SdkSessionCliArgs): Publi
|
|
|
258
258
|
}
|
|
259
259
|
|
|
260
260
|
/** Lifecycle terminality/retryability is not, by itself, proof of an effect outcome. */
|
|
261
|
+
/**
|
|
262
|
+
* Lifecycle codes the broker produces when it refuses the request payload itself. Input shape is
|
|
263
|
+
decided before the request can be dispatched, and an outcome the broker cannot establish comes
|
|
264
|
+
back as `terminal_uncertain` instead, so these codes never stand for an applied operation. They
|
|
265
|
+
still collapse into `operation_failed` below, which cannot say why the request was refused, so
|
|
266
|
+
the refusal class survives as one fixed diagnostic.
|
|
267
|
+
*/
|
|
268
|
+
const LIFECYCLE_INPUT_REFUSAL_CODES = new Set(["invalid_input", "invalid_request"]);
|
|
269
|
+
|
|
261
270
|
export function lifecyclePublicFailure(outcome: Extract<SessionLifecycleResult, { ok: false }>): PublicCommandFailure {
|
|
262
271
|
const failure = sdkPublicFailure(outcome.error.code);
|
|
263
272
|
// The service emits retryable protocol_error only when requestSent is explicitly false.
|
|
264
273
|
const proof: PublicEffectProof =
|
|
265
274
|
outcome.certainty === "retryable" && outcome.error.code === "protocol_error" ? "pre-send" : "unknown";
|
|
266
|
-
// `operation_failed` cannot distinguish a conflict from any other failed
|
|
267
|
-
//
|
|
268
|
-
// rendered: it may carry request keys, paths, or credentials, and its cause is not
|
|
269
|
-
//
|
|
275
|
+
// `operation_failed` cannot distinguish a conflict or an input refusal from any other failed
|
|
276
|
+
// operation, so each survives as one fixed diagnostic. The broker message itself is never
|
|
277
|
+
// rendered: it may carry request keys, paths, or credentials, and its cause is not decidable
|
|
278
|
+
// from the code alone.
|
|
279
|
+
let diagnostic: PublicCommandDiagnosticCode | undefined;
|
|
280
|
+
if (outcome.error.code === "idempotency_conflict") {
|
|
281
|
+
diagnostic = "lifecycle_idempotency_conflict";
|
|
282
|
+
} else if (LIFECYCLE_INPUT_REFUSAL_CODES.has(outcome.error.code)) {
|
|
283
|
+
diagnostic = "lifecycle_input_refused";
|
|
284
|
+
}
|
|
270
285
|
const diagnostics: readonly PublicCommandDiagnosticCode[] | undefined =
|
|
271
|
-
|
|
286
|
+
diagnostic === undefined ? undefined : [diagnostic];
|
|
272
287
|
return new PublicCommandFailure({
|
|
273
288
|
...failure.input,
|
|
274
289
|
...(diagnostics === undefined ? {} : { diagnostics }),
|
|
@@ -2209,7 +2224,7 @@ async function runRawControl(
|
|
|
2209
2224
|
input: JsonRecord,
|
|
2210
2225
|
args: SdkSessionCliArgs,
|
|
2211
2226
|
): Promise<unknown> {
|
|
2212
|
-
const invalid = validateAdapterControl(operation, input);
|
|
2227
|
+
const invalid = validateAdapterControl(operation, input, { allowUltrafastTier: true });
|
|
2213
2228
|
if (invalid) throw new SdkSessionCliError(invalid.code, invalid.message, 2);
|
|
2214
2229
|
await ensureBroker({ agentDir });
|
|
2215
2230
|
const operatorRequest = operatorAbortBrokerRequest(sessionId, operation, input, args);
|