@gajae-code/coding-agent 0.12.4 → 0.12.6
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 +36 -0
- package/README.md +4 -1
- package/dist/types/async/job-manager.d.ts +9 -1
- package/dist/types/eval/backend.d.ts +2 -2
- package/dist/types/exec/bash-executor.d.ts +10 -8
- package/dist/types/extensibility/extensions/runner.d.ts +9 -7
- package/dist/types/gjc-runtime/launch-tmux.d.ts +22 -3
- package/dist/types/gjc-runtime/psmux-detect.d.ts +3 -0
- package/dist/types/gjc-runtime/team-launch.d.ts +3 -1
- package/dist/types/gjc-runtime/team-runtime.d.ts +14 -2
- package/dist/types/gjc-runtime/team-store.d.ts +0 -4
- package/dist/types/gjc-runtime/team-workers.d.ts +5 -0
- package/dist/types/gjc-runtime/tmux-common.d.ts +1 -0
- package/dist/types/gjc-runtime/tmux-provider-context.d.ts +57 -0
- package/dist/types/gjc-runtime/tmux-sessions.d.ts +8 -1
- package/dist/types/gjc-runtime/ultragoal-change-set.d.ts +3 -0
- package/dist/types/gjc-runtime/ultragoal-review-source.d.ts +83 -0
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +57 -4
- package/dist/types/internal-urls/registry-helpers.d.ts +18 -0
- package/dist/types/modes/components/gjc-bundle-settings.d.ts +1 -0
- package/dist/types/modes/components/plugin-settings.d.ts +2 -0
- package/dist/types/modes/components/settings-selector.d.ts +2 -0
- package/dist/types/sdk/broker/broker.d.ts +18 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +13 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +1 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +5 -2
- package/dist/types/sdk/bus/index.d.ts +4 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +7 -3
- package/dist/types/sdk/bus/telegram-daemon.d.ts +25 -3
- package/dist/types/sdk/bus/topic-registry.d.ts +63 -3
- package/dist/types/sdk/host/host.d.ts +23 -2
- package/dist/types/sdk/host/reverse-leases.d.ts +7 -4
- package/dist/types/session/agent-session.d.ts +5 -4
- package/dist/types/session/artifacts.d.ts +8 -5
- package/dist/types/session/attempt-record-store.d.ts +19 -0
- package/dist/types/session/client-bridge.d.ts +14 -0
- package/dist/types/session/internal/managed-session-storage.d.ts +7 -23
- package/dist/types/session/messages.d.ts +4 -1
- package/dist/types/session/session-manager.d.ts +7 -5
- package/dist/types/session/session-storage.d.ts +8 -0
- package/dist/types/session/streaming-output.d.ts +32 -0
- package/dist/types/task/executor.d.ts +1 -1
- package/dist/types/task/index.d.ts +2 -1
- package/dist/types/task/receipt.d.ts +3 -0
- package/dist/types/task/types.d.ts +194 -0
- package/dist/types/task/worktree.d.ts +13 -6
- package/dist/types/tools/bash.d.ts +1 -1
- package/dist/types/tools/fetch.d.ts +3 -0
- package/dist/types/tools/output-meta.d.ts +37 -5
- package/dist/types/tools/subagent.d.ts +2 -0
- package/dist/types/tools/tool-result.d.ts +1 -0
- package/dist/types/utils/artifact-id.d.ts +2 -0
- package/dist/types/utils/git.d.ts +1 -0
- package/package.json +8 -8
- package/scripts/capture-sticky-viewport-showcase.ts +131 -5
- package/scripts/verify-gjc-sdk-canonicalization.ts +128 -183
- package/scripts/verify-sticky-viewport-showcase.ts +620 -93
- package/src/async/job-manager.ts +13 -5
- package/src/config/model-profiles.ts +8 -0
- package/src/config/settings-schema.ts +17 -3
- package/src/cursor.ts +20 -13
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +5 -2
- package/src/eval/backend.ts +2 -2
- package/src/exec/bash-executor.ts +425 -151
- package/src/extensibility/extensions/runner.ts +80 -6
- package/src/extensibility/extensions/wrapper.ts +22 -15
- package/src/extensibility/runtime-skill-discovery.ts +4 -6
- package/src/gjc-runtime/launch-tmux.ts +309 -293
- package/src/gjc-runtime/managed-owner-supervisor.ts +6 -2
- package/src/gjc-runtime/psmux-detect.ts +52 -6
- package/src/gjc-runtime/team-launch.ts +50 -2
- package/src/gjc-runtime/team-runtime.ts +716 -251
- package/src/gjc-runtime/team-store.ts +25 -7
- package/src/gjc-runtime/team-workers.ts +161 -1
- package/src/gjc-runtime/tmux-common.ts +16 -4
- package/src/gjc-runtime/tmux-gc.ts +37 -5
- package/src/gjc-runtime/tmux-owner-isolation.ts +2 -0
- package/src/gjc-runtime/tmux-provider-context.ts +451 -0
- package/src/gjc-runtime/tmux-sessions.ts +409 -156
- package/src/gjc-runtime/ultragoal-change-set.ts +90 -44
- package/src/gjc-runtime/ultragoal-receipt-freshness.ts +7 -0
- package/src/gjc-runtime/ultragoal-review-source.ts +378 -0
- package/src/gjc-runtime/ultragoal-runtime.ts +640 -159
- package/src/gjc-runtime/workflow-manifest.generated.json +40 -1
- package/src/gjc-runtime/workflow-manifest.ts +12 -0
- package/src/internal-urls/agent-protocol.ts +98 -38
- package/src/internal-urls/artifact-protocol.ts +28 -17
- package/src/internal-urls/docs-index.generated.ts +6 -6
- package/src/internal-urls/local-protocol.ts +39 -18
- package/src/internal-urls/registry-helpers.ts +62 -0
- package/src/modes/acp/acp-agent.ts +51 -13
- package/src/modes/acp/acp-client-bridge.ts +154 -11
- package/src/modes/components/gjc-bundle-settings.ts +2 -0
- package/src/modes/components/plugin-settings.ts +5 -0
- package/src/modes/components/settings-selector.ts +4 -0
- package/src/modes/controllers/selector-controller.ts +1 -0
- package/src/prompts/tools/bash.md +2 -2
- package/src/prompts/tools/monitor.md +4 -4
- package/src/sdk/acp/adapter.ts +200 -9
- package/src/sdk/broker/broker.ts +93 -10
- package/src/sdk/broker/lifecycle-ledger.ts +227 -11
- package/src/sdk/broker/lifecycle.ts +692 -98
- package/src/sdk/bus/chat-daemon-control.ts +33 -5
- package/src/sdk/bus/index.ts +347 -14
- package/src/sdk/bus/telegram-daemon-contract.ts +7 -3
- package/src/sdk/bus/telegram-daemon.ts +283 -44
- package/src/sdk/bus/topic-registry.ts +133 -10
- package/src/sdk/host/host.ts +187 -9
- package/src/sdk/host/reverse-leases.ts +249 -42
- package/src/sdk/session.ts +8 -6
- package/src/session/agent-session.ts +930 -354
- package/src/session/artifacts.ts +211 -74
- package/src/session/attempt-record-store.ts +106 -0
- package/src/session/client-bridge.ts +15 -0
- package/src/session/internal/managed-session-scope.ts +332 -198
- package/src/session/internal/managed-session-storage.ts +162 -450
- package/src/session/messages.ts +32 -7
- package/src/session/session-manager.ts +31 -28
- package/src/session/session-storage.ts +190 -53
- package/src/session/streaming-output.ts +198 -40
- package/src/task/executor.ts +5 -2
- package/src/task/index.ts +277 -64
- package/src/task/provider-retry-status.ts +4 -1
- package/src/task/receipt.ts +26 -2
- package/src/task/render.ts +42 -1
- package/src/task/types.ts +52 -0
- package/src/task/worktree.ts +122 -43
- package/src/tools/bash.ts +818 -239
- package/src/tools/eval.ts +99 -4
- package/src/tools/fetch.ts +77 -15
- package/src/tools/find.ts +7 -3
- package/src/tools/monitor.ts +7 -1
- package/src/tools/output-meta.ts +706 -116
- package/src/tools/search.ts +9 -4
- package/src/tools/subagent-render.ts +5 -2
- package/src/tools/subagent.ts +8 -0
- package/src/tools/tool-result.ts +1 -0
- package/src/utils/artifact-id.ts +6 -0
- package/src/utils/git.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.12.6] - 2026-07-31
|
|
6
|
+
### Added
|
|
7
|
+
|
|
8
|
+
- Added the bundled `lunamaxxing` OpenAI Codex profile, mapping every role to GPT-5.6 Luna with medium default reasoning, xhigh executor reasoning, and maximum planner/critic/architect reasoning.
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Settings now requests a repaint after asynchronous GJC bundle and plugin views rebuild, so loaded content and mutation results appear without an extra keypress (#3643).
|
|
13
|
+
- Deferred `agent_end` publication again settles public session readiness before slow extension handlers finish, while retaining exact cancellation leases through queued extension delivery and draining that delivery before session shutdown.
|
|
14
|
+
- Ultragoal validation-batch hydration now fails closed unless deferred and final-close evidence exactly matches a complete authoritative cumulative Git/CI inventory and durable batch tuple. Explicit malformed, partial, unknown, reordered, or stale receipt data is rejected; Git path capture is byte-safe, NUL-delimited, and includes untracked files; incomplete capture conservatively requires computer-control QA; shared settings and tool registries cannot use partial diffs to bypass that suite; validate/checkpoint replacement hydration is identical; and current/replacement receipts are byte-bound to ledger payloads (#3541).
|
|
15
|
+
- Fixture quality gates that complete intermediate Ultragoal stories now write file-backed adversarial artifact proof; skill-state hooks and computer red-team fixtures match the unconditional adversarial path check so #3543 CI stays fail-closed without weakening hydration exactness (#3543).
|
|
16
|
+
- Runtime settings reconciliation now validates every `web_search.fallback` entry against the declared provider enum instead of accepting unsupported or non-string array items (#3601).
|
|
17
|
+
- Ultragoal critic-gate, dogfood, review, durable-completion, and runtime test suites now pin `CI_DEV_CHANGED_PATHS` hermetically in their setup/teardown. Their temp checkpoints live inside the enclosing git work tree, so the CI planner's changed paths (which include computer control surface paths on branches that touch them) previously leaked into the computed change set and falsely triggered the mandatory computer red-team suite (`COMPUTER_REDTEAM_CASE_MISSING: … must include kill-switch-bypass`). The production kill-switch-bypass gate is unchanged; only the test fixtures now isolate their own contract from the host branch's diff (#3533).
|
|
18
|
+
- Ultragoal critic-gate, dogfood, review, durable-completion, and runtime test suites now relocate temp dirs to `os.tmpdir()` (outside the enclosing git work tree) and pin `CI_DEV_CHANGED_PATHS` to a non-computer test path. The prior in-repo temp dirs caused `computeCheckpointChangeSet` to return `captureIncomplete=true` under parallel shard load (git command timeouts), which unconditionally triggered the mandatory computer red-team suite even when no computer surface was touched. The production kill-switch-bypass gate is unchanged; the `.tmp-*` gitignore entry prevents in-repo test artifacts from polluting untracked-file inventory (#3533).
|
|
19
|
+
- Telegram topic delete settlement is now fence-epoch bound, two-phase, and durably route-atomic. `TopicRegistry.settleDelete` requires the caller's dispatched authority epoch to still equal both the record's own epoch and the session's current epoch, so a held earlier delete can no longer settle a newer scan/close-started fence for the same session and topic and release its quarantine; it now removes the record but deliberately *retains* the topic-id quarantine and returns a settlement token instead of publishing routes, so no colliding survivor becomes routable and no settled id becomes adoptable while the clear is still only in memory. `commitSettledDelete` publishes the rebuilt inbound routes and releases the quarantine only after the durable topic-state persist resolves, and `rollbackSettledDelete` undoes a failed persist as a compare-and-set that applies only while the post-settlement state is still exactly current, so a stale rollback can no longer resurrect a deleted record over a newer fence. A refused settlement returns no token and is therefore structurally incapable of being rolled back. Authority-epoch advancement is routed through a single saturating helper capped at `Number.MAX_SAFE_INTEGER`, and settlement fails closed (keeping the fence) on a non-safe-integer, negative, or already-saturated epoch instead of settling against an unsound comparison. Telegram's first create-compensation path now marks compensation complete only after that durable clear commits, so a failed persist leaves the fence supervised rather than stranding a cleared memory state against a `delete_pending` disk state.
|
|
20
|
+
- The Telegram notification self-heal reaper now reclaims abandoned publication staging files in the agent `notifications/` directory. `writeJsonAtomic` stages a sibling `<name>.<pid>.<epoch-ms>.<suffix>.tmp` and renames it over the destination; if the staging write or the rename fails, or the process dies between the two, that temp is never published and never read again. No prefix in the reaper's leak-artifact list claimed `.tmp`, so one unreachable file accumulated per failed attempt — permanently, across the roots registry, daemon state, callback aliases, seen-update ids, and the topic registry snapshot. This is most visible where a rename-blocking condition persists (a Windows `EPERM` from an antivirus or indexer holding a handle, `EACCES`, `EIO`, `ENOSPC`). Reaping is shape-matched and still bounded by the existing five-minute mtime grace window, so a temp that an in-flight publication is still staging is never removed, and reclaiming it here also recovers temps orphaned by a crash, which no writer-side unwind can reach.
|
|
21
|
+
- The Telegram notification self-heal reaper now reclaims abandoned publication staging files in the agent `notifications/` directory. `writeJsonAtomic` stages a sibling `<name>.<pid>.<epoch-ms>.<suffix>.tmp` and renames it over the destination; if the staging write or the rename fails, or the process dies between the two, that temp is never published and never read again. No prefix in the reaper's leak-artifact list claimed `.tmp`, so one unreachable file accumulated per failed attempt — permanently, across the roots registry, daemon state, callback aliases, seen-update ids, and the topic registry snapshot. This is most visible where a rename-blocking condition persists (a Windows `EPERM` from an antivirus or indexer holding a handle, `EACCES`, `EIO`, `ENOSPC`). Reclaiming it here also recovers temps orphaned by a crash, which no writer-side unwind can reach. Removal is fenced rather than age-only: the reaper parses the publisher PID out of the temp's own name and removes it only when that publisher is *provably dead*, so a live or slow publication keeps its staged temp however old it is, and an indeterminate liveness probe or an unparseable claim retains the file. A proven-dead temp is still bounded by the existing five-minute mtime grace window, and the deletion itself is bound to a no-follow identity capture (`dev`+`ino`+`size`+`mtime`+content digest, single-link regular files only) executed through the exact-unlink native, so a symlink is never followed and a temp replaced between capture and delete is refused instead of destroying the successor.
|
|
22
|
+
- The Telegram notification self-heal reaper now handles abandoned publication staging files in the agent `notifications/` directory. `writeJsonAtomic` stages a sibling `<name>.<pid>.<epoch-ms>.<suffix>.tmp` and renames it over the destination; a failed staging write or rename, or a process death between those steps, can leave an unreachable file. The reaper parses the publisher PID from the temp name and acts only when that publisher is provably dead and the existing five-minute mtime grace window has elapsed. Deletion is bound to a no-follow identity capture (`dev`+`ino`+`size`+`mtime`+content digest, single-link regular files only) through the exact-unlink native, so symlinks and same-name replacements are retained. A terminal native removal is reported as reclaimed; a typed `cleanup_pending` result is instead reported as skipped, leaves the bytes visible under a recognized exact-unlink placeholder, and later scans preserve that placeholder without pathname churn rather than claiming false removal.
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- Canonical wrapped first-event timeouts now continue the same clean turn through bounded retries and configured fallback rotation, while preserving replay-safety, cancellation, provider-terminal policies, exact attempt diagnostics, and task/subagent retry-status truth (#3553).
|
|
27
|
+
- Runtime skill discovery now preserves a candidate when its exact skill name appears as a query token, so additional task-specific terms no longer discard an explicitly named skill.
|
|
28
|
+
|
|
29
|
+
## [0.12.5] - 2026-07-30
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- ACP and SDK broker session deletion no longer promotes a non-empty retained artifact quarantine to transcript deletion. `cleanup_pending` keeps transcript and exact quarantine authority across retries and restarts while payload bytes survive; root-only transcript preauthorization remains replay-bound and is revalidated after ledger persistence immediately before mutation, while ordinary completion still requires an empty identity-bound root or `artifacts_removed`.
|
|
33
|
+
|
|
34
|
+
## [0.12.5] - 2026-07-30
|
|
35
|
+
|
|
5
36
|
## [0.12.4] - 2026-07-30
|
|
6
37
|
|
|
7
38
|
## [0.12.3] - 2026-07-30
|
|
@@ -30,12 +61,14 @@
|
|
|
30
61
|
- `gjc --worktree` / `gjc -w` launch no longer crashes with a raw uncaught `EEXIST` when the worktree bucket directory (`<repo>.gajae-code-worktrees`) is a broken symbolic link to unmounted or offloaded cold storage. The launch distinguishes dangling links and non-directory entries from valid directory symlinks or Windows junctions, reclassifies mkdir races, avoids disclosing raw link targets or unsafe shell commands, and never deletes or replaces an obstructing entry.
|
|
31
62
|
- POSIX parent identity reproof/fsync is now centralized before every promotable artifact-phase result, preventing a crash-window where a rename is lost after durable retirement is recorded (#3489).
|
|
32
63
|
- Artifact retirement, planned paths, retained authority, and transcript retry in both managed reconciliation and deletion now bind to the newest published `pendingEvidence` attempt, preventing stranded detached transcripts at paths absent from the newest receipt after a crash (#3489).
|
|
64
|
+
- Provider retry classification prefers the typed `stream_first_event_timeout` transport fact when present, falling back to error-message regex for message-only callers (#3496).
|
|
33
65
|
- Detached task receipts for in-memory parent sessions no longer advertise dead `agent://` output URIs. TaskTool allocates a session-lifetime durable artifact root under the process temp directory, persists child outputs there, authorizes parent and same-session descendants for scoped resolution, and omits the URI entirely when durable allocation fails (#3471).
|
|
34
66
|
- Managed-session replacement and cleanup now bind Windows destination mutation to exact native identity, keep lock acquisition/release retryable without reviving lost ownership, and report retained artifact payloads as `cleanup_pending` until only the verified root remains.
|
|
35
67
|
- Resuming a session no longer crashes with an unhandled rejection when another session transition is already running. The session picker dispatches resume through a void-returning callback, and `handleResumeSession` had no re-entrancy guard, so a second selection (or a resume issued while compaction, handoff, or a fork was in flight) reached `switchSession` and the `{ code: "busy" }` transition error rejected a promise nobody awaited. Resume now ignores an overlapping request with a status message, reports a busy transition as status, and still propagates every other failure. The progress lease is released on all paths.
|
|
36
68
|
- The interactive `Working…` indicator now remains visible and explicitly labels owner-scoped detached background work across foreground completion, provider errors, pending-submission aborts, and job completion, without resurrecting after TUI disposal (#3479).
|
|
37
69
|
- Activity-indicator suspension now detaches and restores the exact owned loader instead of stopping foreign transition UI; optimistic pre-init prompts still show and clear their spinner, context clear retains its eager teardown contract, and resume cancellation preserves transient state until session mutation actually begins.
|
|
38
70
|
- Activity-indicator stop and suspension helpers now fail safely for lightweight controller contexts with absent or partial status rails, while full interactive contexts retain exact loader detach/restore ownership.
|
|
71
|
+
- Bash now uses bounded core-to-native and N-API callback backpressure plus a 64 KiB terminal tail after the core 8 MiB stream budget, emits at most one typed aggregate loss marker, carries source-loss evidence through merged and raw stream cancellation/error paths, bounds ACP terminal lifecycle/output RPC settlement, cleans settled native sessions, labels every combined omission honestly through inline backstops and failure paths, omits false source ranges, and rejects malformed artifact IDs/counts.
|
|
39
72
|
|
|
40
73
|
## [0.12.1] - 2026-07-29
|
|
41
74
|
|
|
@@ -45,14 +78,17 @@
|
|
|
45
78
|
- Team Linux worker memory-guard replacement no longer holds the team task-mutation fence across the successor startup-ack wait, so concurrent `worker-startup-ack` can publish and selector-replacement no longer hangs under CI contention.
|
|
46
79
|
- Kitty/Ghostty inline images no longer remain visually pinned when transcript, pinned, or overlay rows are replaced, removed, scrolled, resized, or fully repainted. The TUI now parses only bounded named placements, soft-deletes overwritten placements from the previously committed physical frame, retains transmitted pixels, and restores placements from application scrollback without retransmitting image data.
|
|
47
80
|
- Reviewer `report_finding` evidence is no longer injected into caller-owned strict JTD completion data; full findings are published separately through a bounded artifact reference, and failed evidence publication now fails the task closed (#2893).
|
|
81
|
+
- Bash output-tail initialization now tolerates constrained `ToolSession` settings adapters that expose `get()` without `has()`, preserving the 1 KiB default and explicit head/tail overrides instead of crashing restricted and interceptor Bash execution.
|
|
48
82
|
- Managed-session startup failures now include their bounded preparation classification (and path-free native durability diagnostic when available), so Windows launch crashes no longer collapse to an unactionable generic error while filesystem paths and raw OS messages remain redacted (#3383).
|
|
49
83
|
- Single-model sessions now rotate immediately to another stored provider credential after a content-free quota or rate-limit failure, without requiring a synthetic model fallback chain. Credential rotation is replay-safe for content-free failures regardless of extension lifecycle participation, and traverses the full credential pool independent of `retry.maxRetries` (#3491).
|
|
50
84
|
- External credential discovery now follows `CLAUDE_CONFIG_DIR` and `CODEX_HOME` instead of always reading `~/.claude` and `~/.codex`, so importing from an account switcher (or any relocated Claude Code / Codex CLI config root) picks up the account the launching shell selected. Both variables resolve through the credential env trust boundary and must be absolute; redacted summaries name the variable, never the resolved path.
|
|
51
85
|
- The `acp_conformance` CI job runs again. The pinned upstream `acpx` checkout resolves its own imports (`@agentclientprotocol/sdk`, `zod`) from its own tree, but its dependencies were never installed, so the corpus runner aborted with `Cannot find module 'zod/v4'` before executing a single case. The checkout is now installed after provenance verification, and the reused warm cache still skips the reinstall.
|
|
86
|
+
- ACP prompt terminalization now binds each accepted execution handle to one immutable cancellation domain, reserves producer ownership before terminal publication, and quarantines only the exact run when settlement cannot be proven. The fixed 10-second fail-closed external error remains unchanged while internal diagnostics report only bounded resource kinds, hashed labels, clamped ages, and omitted counts.
|
|
52
87
|
|
|
53
88
|
### Added
|
|
54
89
|
|
|
55
90
|
- User-created Telegram forum topics can now start a GJC session by selecting the home folder, choosing a verified recent work folder, or entering an explicit folder path. The selected topic is adopted by the new session without creating or deleting a separate Telegram topic.
|
|
91
|
+
- The interactive terminal’s responsive IRC/todo work-lane contract now covers exact narrow/wide geometry, requested versus effective IRC visibility, direct-root pin ordering, todo lane bounds, remapped IRC toggles, and live composer shortcut hints.
|
|
56
92
|
|
|
57
93
|
### Fixed
|
|
58
94
|
|
package/README.md
CHANGED
|
@@ -33,7 +33,6 @@ gjc config set completion.notifyCommand 'powershell.exe -NoProfile -Command "[Co
|
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
`cmux notify` returning successfully means GJC handed the completion event to cmux. cmux may still suppress the native desktop banner when the app/window is focused, the emitting workspace is active, or the notification panel is open. In those cases, check cmux's notification panel or unread workspace state instead of treating the missing banner as a GJC delivery failure.
|
|
36
|
-
|
|
37
36
|
Recommended external mapping:
|
|
38
37
|
|
|
39
38
|
| Notification | Public event | Status guidance |
|
|
@@ -87,6 +86,10 @@ export default function lifecycleNotifier(pi: ExtensionAPI) {
|
|
|
87
86
|
|
|
88
87
|
This is the supported repo-native lifecycle notification path. It is not Claude Code hook compatibility, and it remains disabled unless the user configures an extension/hook handler and private delivery target.
|
|
89
88
|
|
|
89
|
+
## Windows psmux authority boundary
|
|
90
|
+
|
|
91
|
+
On native Windows, GJC-managed psmux sessions persist a per-owner `ProviderAuthority`: the exact resolved executable identity and an isolated tmux-compatible `-L` namespace. `GJC_TMUX_COMMAND` is an executable path/name only, never `psmux -L …`. Recover managed sessions through GJC so it reuses and re-proves that authority; do not fall back to ambient `tmux`/`psmux` or manually recreate a namespace. An unavailable, changed, or ambiguous authority fails closed.
|
|
92
|
+
|
|
90
93
|
## Memory backends
|
|
91
94
|
|
|
92
95
|
The agent supports three mutually-exclusive memory backends, selected via the `memory.backend` setting (Settings → Memory tab, or `~/.gjc/agent/config.yml`):
|
|
@@ -134,6 +134,8 @@ export interface SubagentRecord {
|
|
|
134
134
|
effectiveModel?: string;
|
|
135
135
|
/** True when the requested model lacked credentials and the subagent fell back to the parent model. */
|
|
136
136
|
modelFellBack?: boolean;
|
|
137
|
+
/** True when the effective subagent provider is in fast mode. */
|
|
138
|
+
fastMode?: boolean;
|
|
137
139
|
}
|
|
138
140
|
/** Lightweight, manager-owned resume payload. The async layer treats `data` as opaque. */
|
|
139
141
|
export interface ResumeDescriptor {
|
|
@@ -251,11 +253,17 @@ export declare class AsyncJobManager {
|
|
|
251
253
|
};
|
|
252
254
|
/** Register or replace the canonical record for a subagent. */
|
|
253
255
|
registerSubagentRecord(record: SubagentRecord): void;
|
|
254
|
-
/**
|
|
256
|
+
/**
|
|
257
|
+
* Patch model/runtime metadata onto an existing subagent record (best-effort; no-op if
|
|
258
|
+
* unknown). Every field is optional and omitting one preserves its current value, so a
|
|
259
|
+
* narrow patch like `{ fastMode: true }` cannot erase model identity recorded earlier.
|
|
260
|
+
* A field therefore cannot be cleared back to `undefined` through this method.
|
|
261
|
+
*/
|
|
255
262
|
updateSubagentModel(subagentId: string, model: {
|
|
256
263
|
requestedModel?: string;
|
|
257
264
|
effectiveModel?: string;
|
|
258
265
|
modelFellBack?: boolean;
|
|
266
|
+
fastMode?: boolean;
|
|
259
267
|
}): void;
|
|
260
268
|
getSubagentRecord(subagentId: string, filter?: AsyncJobFilter): SubagentRecord | undefined;
|
|
261
269
|
getSubagentRecords(filter?: AsyncJobFilter): SubagentRecord[];
|
|
@@ -10,8 +10,8 @@ export interface ExecutorBackendExecOptions {
|
|
|
10
10
|
session: ToolSession;
|
|
11
11
|
deadlineMs: number;
|
|
12
12
|
reset: boolean;
|
|
13
|
-
artifactPath
|
|
14
|
-
artifactId
|
|
13
|
+
artifactPath?: string;
|
|
14
|
+
artifactId?: string;
|
|
15
15
|
onChunk: (chunk: string) => void;
|
|
16
16
|
}
|
|
17
17
|
/** Result returned by a backend's execute(). */
|
|
@@ -6,7 +6,7 @@ export interface BashArtifactSaveSummary {
|
|
|
6
6
|
complete: boolean;
|
|
7
7
|
omittedBytes?: number;
|
|
8
8
|
}
|
|
9
|
-
export type BashMinimizedSaveReturn = BashArtifactSaveResult | BashArtifactSaveSummary |
|
|
9
|
+
export type BashMinimizedSaveReturn = BashArtifactSaveResult | BashArtifactSaveSummary | undefined;
|
|
10
10
|
export type BashArtifactSaveResult = {
|
|
11
11
|
status: "saved";
|
|
12
12
|
artifactId: string;
|
|
@@ -23,7 +23,7 @@ export type BashArtifactSaveResult = {
|
|
|
23
23
|
status: "failed";
|
|
24
24
|
diagnostic: string;
|
|
25
25
|
};
|
|
26
|
-
export declare function normalizeMinimizedSaveResultForTests(value:
|
|
26
|
+
export declare function normalizeMinimizedSaveResultForTests(value: unknown, _originalText?: string): BashArtifactSaveResult;
|
|
27
27
|
export interface BashExecutorOptions {
|
|
28
28
|
/**
|
|
29
29
|
* Invoked when the native minimizer rewrote the command's output, giving
|
|
@@ -80,16 +80,18 @@ export interface BashResult {
|
|
|
80
80
|
outputBytes: number;
|
|
81
81
|
artifactId?: string;
|
|
82
82
|
artifactTruncatedBytes?: number;
|
|
83
|
+
/** Bytes dropped before the Bash executor received the native output stream. */
|
|
84
|
+
sourceTruncatedBytes?: number;
|
|
85
|
+
/** Exact source capture completeness could not be proven. */
|
|
86
|
+
sourceCaptureIncomplete?: boolean;
|
|
83
87
|
artifactFailureDiagnostic?: string;
|
|
84
88
|
}
|
|
85
|
-
/** Number of persistent shell sessions currently retained (owner gauge). */
|
|
89
|
+
/** Number of persistent and retiring shell sessions currently retained (owner gauge). */
|
|
86
90
|
export declare function getShellSessionCount(): number;
|
|
87
91
|
/**
|
|
88
|
-
* Dispose all persistent shell sessions
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
* is registered as a postmortem cleanup so shutdown/signals release native
|
|
92
|
-
* shell resources, and is also callable directly (e.g. on owner teardown).
|
|
92
|
+
* Dispose all persistent shell sessions without waiting forever on a native
|
|
93
|
+
* abort that failed to settle. Quarantine entries are owner-scoped so a late
|
|
94
|
+
* finalizer cannot erase a successor shell's quarantine.
|
|
93
95
|
*/
|
|
94
96
|
export declare function disposeAllShellSessions(): Promise<void>;
|
|
95
97
|
/** Translate `ShellMinimizerSettings` into native `MinimizerOptions`, or `undefined` when disabled. */
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
* Extension runner - executes extensions and manages their lifecycle.
|
|
3
3
|
*/
|
|
4
4
|
import type { AgentMessage } from "@gajae-code/agent-core";
|
|
5
|
-
import type { CredentialDisabledEvent, ImageContent, Model, ProviderResponseMetadata } from "@gajae-code/ai";
|
|
5
|
+
import type { AttemptScopeRef, CredentialDisabledEvent, ImageContent, Model, ProviderResponseMetadata } from "@gajae-code/ai";
|
|
6
6
|
import type { KeyId } from "@gajae-code/tui";
|
|
7
7
|
import type { ModelRegistry } from "../../config/model-registry";
|
|
8
|
+
import type { AttemptRecordStore } from "../../session/attempt-record-store";
|
|
8
9
|
import { type SessionManager } from "../../session/session-manager";
|
|
9
10
|
import type { AfterProviderResponseEvent, BeforeAgentStartEvent, BeforeAgentStartEventResult, BeforeProviderRequestEvent, BeforeProviderRequestEventResult, ContextEvent, Extension, ExtensionActions, ExtensionCommandContext, ExtensionCommandContextActions, ExtensionContext, ExtensionContextActions, ExtensionError, ExtensionEvent, ExtensionFlag, ExtensionRuntime, ExtensionShortcut, ExtensionUIContext, InputEvent, InputEventResult, MessageRenderer, RegisteredCommand, RegisteredTool, ResourcesDiscoverEvent, SessionBeforeBranchResult, SessionBeforeCompactResult, SessionBeforeSwitchResult, SessionBeforeTreeResult, SessionCompactingResult, ToolCallEvent, ToolCallEventResult, ToolResultEvent, ToolResultEventResult, UserBashEvent, UserBashEventResult, UserPythonEvent, UserPythonEventResult } from "./types";
|
|
10
11
|
/** Combined result from all before_agent_start handlers */
|
|
@@ -91,6 +92,7 @@ export declare class ExtensionRunner {
|
|
|
91
92
|
onError(listener: ExtensionErrorListener): () => void;
|
|
92
93
|
emitError(error: ExtensionError): void;
|
|
93
94
|
hasHandlers(eventType: string): boolean;
|
|
95
|
+
setAttemptRecordStore(store: AttemptRecordStore): void;
|
|
94
96
|
getMessageRenderer(customType: string): MessageRenderer | undefined;
|
|
95
97
|
getRegisteredCommands(reserved?: Set<string>): RegisteredCommand[];
|
|
96
98
|
getCommandDiagnostics(): Array<{
|
|
@@ -105,9 +107,9 @@ export declare class ExtensionRunner {
|
|
|
105
107
|
*/
|
|
106
108
|
shutdown(): void;
|
|
107
109
|
createCommandContext(): ExtensionCommandContext;
|
|
108
|
-
emit<TEvent extends RunnerEmitEvent>(event: TEvent, continueWhile?: () => boolean): Promise<RunnerEmitResult<TEvent>>;
|
|
109
|
-
emitToolResult(event: ToolResultEvent): Promise<ToolResultEventResult | undefined>;
|
|
110
|
-
emitToolCall(event: ToolCallEvent): Promise<ToolCallEventResult | undefined>;
|
|
110
|
+
emit<TEvent extends RunnerEmitEvent>(event: TEvent, continueWhile?: () => boolean, scope?: AttemptScopeRef): Promise<RunnerEmitResult<TEvent>>;
|
|
111
|
+
emitToolResult(event: ToolResultEvent, scope?: AttemptScopeRef): Promise<ToolResultEventResult | undefined>;
|
|
112
|
+
emitToolCall(event: ToolCallEvent, scope?: AttemptScopeRef): Promise<ToolCallEventResult | undefined>;
|
|
111
113
|
emitUserBash(event: UserBashEvent): Promise<UserBashEventResult | undefined>;
|
|
112
114
|
emitUserPython(event: UserPythonEvent): Promise<UserPythonEventResult | undefined>;
|
|
113
115
|
private emitUserEvent;
|
|
@@ -127,9 +129,9 @@ export declare class ExtensionRunner {
|
|
|
127
129
|
}>;
|
|
128
130
|
/** Emit input event. Transforms chain, "handled" short-circuits. */
|
|
129
131
|
emitInput(text: string, images: ImageContent[] | undefined, source: "interactive" | "sdk" | "extension"): Promise<InputEventResult>;
|
|
130
|
-
emitContext(messages: AgentMessage[]): Promise<AgentMessage[]>;
|
|
131
|
-
emitBeforeProviderRequest(payload: unknown): Promise<BeforeProviderRequestEventResult>;
|
|
132
|
-
emitAfterProviderResponse(response: ProviderResponseMetadata, _model?: Model): Promise<void>;
|
|
132
|
+
emitContext(messages: AgentMessage[], scope?: AttemptScopeRef): Promise<AgentMessage[]>;
|
|
133
|
+
emitBeforeProviderRequest(payload: unknown, scope?: AttemptScopeRef): Promise<BeforeProviderRequestEventResult>;
|
|
134
|
+
emitAfterProviderResponse(response: ProviderResponseMetadata, _model?: Model, scope?: AttemptScopeRef): Promise<void>;
|
|
133
135
|
emitBeforeAgentStart(prompt: string, images: ImageContent[] | undefined, systemPrompt: string[]): Promise<BeforeAgentStartCombinedResult | undefined>;
|
|
134
136
|
}
|
|
135
137
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Args } from "../cli/args";
|
|
2
|
-
import { buildGjcTmuxExactSessionTarget, buildGjcTmuxProfileCommands, GJC_DEFAULT_TMUX_SESSION, GJC_TMUX_COMMAND_ENV, GJC_TMUX_MOUSE_ENV, GJC_TMUX_PROFILE_ENV, GJC_TMUX_SESSION_PREFIX, type GjcTmuxProfileCommand } from "./tmux-common";
|
|
3
|
-
import { type OwnerIsolationProbeSync } from "./tmux-owner-isolation";
|
|
2
|
+
import { buildGjcTmuxExactSessionTarget, buildGjcTmuxProfileCommands, GJC_DEFAULT_TMUX_SESSION, GJC_TMUX_COMMAND_ENV, GJC_TMUX_MOUSE_ENV, GJC_TMUX_PROFILE_ENV, GJC_TMUX_SESSION_PREFIX, type GjcTmuxProfileCommand, type ProviderAuthority } from "./tmux-common";
|
|
3
|
+
import { type OwnerGenerationBaseline, type OwnerIsolationProbeSync } from "./tmux-owner-isolation";
|
|
4
4
|
import { buildWindowsPowerShellInnerCommand, GJC_TMUX_LAUNCHED_ENV, type WindowsPowerShellInnerCommandOptions } from "./windows-powershell-command";
|
|
5
5
|
export type { WindowsPowerShellInnerCommandOptions };
|
|
6
6
|
export { buildGjcTmuxExactSessionTarget, buildGjcTmuxProfileCommands, buildWindowsPowerShellInnerCommand, GJC_DEFAULT_TMUX_SESSION, GJC_TMUX_COMMAND_ENV, GJC_TMUX_LAUNCHED_ENV, GJC_TMUX_MOUSE_ENV, GJC_TMUX_PROFILE_ENV, GJC_TMUX_SESSION_PREFIX, };
|
|
@@ -22,6 +22,23 @@ export interface TmuxLaunchContext {
|
|
|
22
22
|
platform?: NodeJS.Platform;
|
|
23
23
|
tty?: TtyState;
|
|
24
24
|
spawnSync?: TmuxSpawnSync;
|
|
25
|
+
/**
|
|
26
|
+
* Provider authority boundaries. Production resolves, persists, and asserts
|
|
27
|
+
* the durable psmux authority; tests may inject deterministic equivalents.
|
|
28
|
+
*/
|
|
29
|
+
providerAuthorityResolver?: (input: {
|
|
30
|
+
platform: NodeJS.Platform;
|
|
31
|
+
env: NodeJS.ProcessEnv;
|
|
32
|
+
command: string;
|
|
33
|
+
stateDir: string;
|
|
34
|
+
sessionId: string;
|
|
35
|
+
generation: string;
|
|
36
|
+
}) => ProviderAuthority;
|
|
37
|
+
providerAuthorityPersist?: (authority: ProviderAuthority) => void;
|
|
38
|
+
/** Re-proves an immutable staged authority before generation publication. */
|
|
39
|
+
providerAuthorityStagedAssert?: (authority: ProviderAuthority) => void;
|
|
40
|
+
/** Re-proves a current authority after generation publication. */
|
|
41
|
+
providerAuthorityAssert?: (authority: ProviderAuthority) => void;
|
|
25
42
|
tmuxAvailable?: boolean;
|
|
26
43
|
tmuxStatusLines?: number;
|
|
27
44
|
worktreeBranch?: string | null;
|
|
@@ -80,7 +97,7 @@ export interface TmuxLaunchPlan {
|
|
|
80
97
|
ownerRunId?: string;
|
|
81
98
|
ownerIncarnation?: string;
|
|
82
99
|
/** Generation state captured before owner-isolation planning; required for publication CAS. */
|
|
83
|
-
ownerGenerationBaseline?:
|
|
100
|
+
ownerGenerationBaseline?: OwnerGenerationBaseline;
|
|
84
101
|
/** Native tmux session identity emitted atomically by `new-session -P -F`. */
|
|
85
102
|
createdSessionId?: string;
|
|
86
103
|
/** Safe server identity proven immediately after creation. */
|
|
@@ -90,6 +107,7 @@ export interface TmuxLaunchPlan {
|
|
|
90
107
|
pidProven?: boolean;
|
|
91
108
|
};
|
|
92
109
|
isPsmux: boolean;
|
|
110
|
+
authority?: ProviderAuthority;
|
|
93
111
|
platform: NodeJS.Platform;
|
|
94
112
|
}
|
|
95
113
|
export interface GjcTmuxProfileResult {
|
|
@@ -114,6 +132,7 @@ export interface GjcTmuxProfileContext {
|
|
|
114
132
|
ownerGeneration?: string | null;
|
|
115
133
|
ownerServerKey?: string | null;
|
|
116
134
|
version?: string | null;
|
|
135
|
+
psmuxIncarnation?: string | null;
|
|
117
136
|
}
|
|
118
137
|
export declare function applyGjcTmuxProfile(context: GjcTmuxProfileContext): GjcTmuxProfileResult;
|
|
119
138
|
export declare function buildGjcTmuxWindowTitle(cwd: string, branch: string | null | undefined): string;
|
|
@@ -40,6 +40,9 @@ export type ExecutableIdentityResolver = (path: string) => string | null;
|
|
|
40
40
|
/** @internal Test-only seam; production code never calls this. */
|
|
41
41
|
export declare function __setExecutableIdentityResolverForTests(resolver: ExecutableIdentityResolver | null): void;
|
|
42
42
|
export declare function envDisabled(value: string | undefined): boolean;
|
|
43
|
+
/** Resolve through the same identity-aware seams used by Windows alias detection. */
|
|
44
|
+
export declare function resolveGjcTmuxExecutablePath(command: string): string | null;
|
|
45
|
+
export declare function resolveGjcTmuxExecutableIdentity(executablePath: string): string | null;
|
|
43
46
|
/**
|
|
44
47
|
* Decide whether command resolves to a psmux binary by probing its version
|
|
45
48
|
* output. The result is cached per process unless force is set or
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { GjcTeamConfig, GjcTeamSnapshot, GjcTeamStartOptions, GjcTeamTask, GjcTeamWorker, GjcTeamWorkerCli, GjcTeamWorkerLifecycle, GjcTeamWorktreeMode } from "./team-runtime";
|
|
2
|
+
import { type ProviderAuthority } from "./tmux-provider-context";
|
|
2
3
|
/** Launch-specific option wiring kept separate from runtime dispatch. */
|
|
3
4
|
export declare function withTeamLaunchTransport(options: GjcTeamStartOptions, mailboxDeliveryTransport: GjcTeamStartOptions["mailboxDeliveryTransport"]): GjcTeamStartOptions;
|
|
4
5
|
/** @internal Exported for unit tests. */
|
|
@@ -6,6 +7,7 @@ export declare function buildWorkerCommand(config: GjcTeamConfig, worker: GjcTea
|
|
|
6
7
|
interface GjcTmuxBinary {
|
|
7
8
|
command: string;
|
|
8
9
|
isPsmux: boolean;
|
|
10
|
+
viaExplicitOverride: boolean;
|
|
9
11
|
}
|
|
10
12
|
interface GjcTmuxLeaderContext {
|
|
11
13
|
sessionName: string;
|
|
@@ -25,7 +27,7 @@ export interface GjcTeamLaunchRuntime {
|
|
|
25
27
|
env: NodeJS.ProcessEnv;
|
|
26
28
|
platform: NodeJS.Platform;
|
|
27
29
|
}): GjcTmuxBinary;
|
|
28
|
-
readTmuxLeaderContext(tmuxCommand: string, env: NodeJS.ProcessEnv): GjcTmuxLeaderContext;
|
|
30
|
+
readTmuxLeaderContext(tmuxCommand: string, env: NodeJS.ProcessEnv, authority: ProviderAuthority): GjcTmuxLeaderContext;
|
|
29
31
|
buildWorkers(workerCount: number, agentType: string, stateRoot: string): GjcTeamWorker[];
|
|
30
32
|
buildInitialTasks(task: string, workers: GjcTeamWorker[]): GjcTeamTask[];
|
|
31
33
|
ensureWorkerWorktree(cwd: string, dir: string, teamName: string, worker: GjcTeamWorker, mode: GjcTeamWorktreeMode, platform: NodeJS.Platform, isPsmux: boolean): Promise<GjcTeamWorker>;
|
|
@@ -44,6 +44,12 @@ export type GjcTeamWorktreeMode = {
|
|
|
44
44
|
name: string;
|
|
45
45
|
};
|
|
46
46
|
export interface GjcTeamConfig {
|
|
47
|
+
/**
|
|
48
|
+
* Launch-time platform. Persisted so the monitor path resolves the same
|
|
49
|
+
* provider context the launch did instead of re-reading `process.platform`,
|
|
50
|
+
* which makes Windows-authority branches unreachable off Windows.
|
|
51
|
+
*/
|
|
52
|
+
platform?: NodeJS.Platform;
|
|
47
53
|
team_name: string;
|
|
48
54
|
display_name: string;
|
|
49
55
|
requested_name: string;
|
|
@@ -59,6 +65,9 @@ export interface GjcTeamConfig {
|
|
|
59
65
|
tmux_session: string;
|
|
60
66
|
tmux_session_name: string;
|
|
61
67
|
tmux_target: string;
|
|
68
|
+
tmux_provider_generation?: string;
|
|
69
|
+
tmux_provider_state_dir?: string;
|
|
70
|
+
tmux_provider_session_id?: string;
|
|
62
71
|
workspace_mode: "direct" | "worktree";
|
|
63
72
|
dry_run: boolean;
|
|
64
73
|
leader: GjcTeamLeader;
|
|
@@ -200,7 +209,7 @@ export interface GjcWorkerIntegrationAttemptRequestResult {
|
|
|
200
209
|
export interface GjcWorkerIntegrationAttemptOptions {
|
|
201
210
|
signal?: AbortSignal;
|
|
202
211
|
}
|
|
203
|
-
export declare const GJC_TEAM_API_OPERATIONS: readonly ["send-message", "broadcast", "mailbox-list", "mailbox-mark-delivered", "mailbox-mark-notified", "notification-list", "notification-read", "notification-replay", "notification-mark-pane-attempt", "worker-startup-ack", "create-task", "read-task", "list-tasks", "update-task", "claim-task", "transition-task-status", "transition-task", "release-task-claim", "read-config", "read-manifest", "read-worker-status", "update-worker-status", "read-worker-heartbeat", "recover-stale-claims", "update-worker-heartbeat", "read-worker-memory-guard", "update-worker-memory-guard", "apply-worker-memory-guard", "write-worker-inbox", "write-worker-identity", "append-event", "read-events", "read-traces", "await-event", "write-shutdown-request", "read-shutdown-ack", "read-monitor-snapshot", "write-monitor-snapshot", "read-task-approval", "write-task-approval"];
|
|
212
|
+
export declare const GJC_TEAM_API_OPERATIONS: readonly ["send-message", "broadcast", "mailbox-list", "mailbox-mark-delivered", "mailbox-mark-notified", "notification-list", "notification-read", "notification-replay", "notification-mark-pane-attempt", "worker-startup-ack", "worker-continuation-ack", "create-task", "read-task", "list-tasks", "update-task", "claim-task", "transition-task-status", "transition-task", "release-task-claim", "read-config", "read-manifest", "read-worker-status", "update-worker-status", "read-worker-heartbeat", "recover-stale-claims", "update-worker-heartbeat", "read-worker-memory-guard", "update-worker-memory-guard", "apply-worker-memory-guard", "write-worker-inbox", "write-worker-identity", "append-event", "read-events", "read-traces", "await-event", "write-shutdown-request", "read-shutdown-ack", "read-monitor-snapshot", "write-monitor-snapshot", "read-task-approval", "write-task-approval"];
|
|
204
213
|
export type GjcTeamApiOperation = (typeof GJC_TEAM_API_OPERATIONS)[number];
|
|
205
214
|
export declare class UnknownGjcTeamApiOperationError extends Error {
|
|
206
215
|
readonly code = "unknown_team_api_operation";
|
|
@@ -212,8 +221,11 @@ export interface GjcTeamRuntimeTestSeams {
|
|
|
212
221
|
nowMs?: () => number;
|
|
213
222
|
continuationTmuxDispatch?: (command: string, args: readonly string[]) => {
|
|
214
223
|
exitCode?: number;
|
|
215
|
-
}
|
|
224
|
+
} | Promise<{
|
|
225
|
+
exitCode?: number;
|
|
226
|
+
}>;
|
|
216
227
|
continuationBeforeDispatch?: () => Promise<void>;
|
|
228
|
+
continuationAckPoll?: () => Promise<void>;
|
|
217
229
|
}
|
|
218
230
|
/** @internal Test-only seam; production code leaves the real clock and tmux dispatch intact. */
|
|
219
231
|
export declare function __setGjcTeamRuntimeTestSeamsForTests(seams: GjcTeamRuntimeTestSeams | undefined): void;
|
|
@@ -129,10 +129,6 @@ type EventAppender = (event: {
|
|
|
129
129
|
/** The sole strict schema gate for persisted task and claim authority records. */
|
|
130
130
|
export declare function isCanonicalPersistedGjcTeamTaskClaim(value: unknown): value is GjcTeamTaskClaim;
|
|
131
131
|
export declare function isCanonicalPersistedGjcTeamTask(value: unknown, fileId?: string): value is GjcTeamTask;
|
|
132
|
-
/**
|
|
133
|
-
* Serializes mutable team facts across processes. Callers must not re-enter this
|
|
134
|
-
* fence; use unlocked helpers when composing operations under one transaction.
|
|
135
|
-
*/
|
|
136
132
|
export declare function withGjcTeamMutationFence<T>(dir: string, fn: () => Promise<T>): Promise<T>;
|
|
137
133
|
export declare function taskMetadataFromInput(input: Record<string, unknown>, includeOwner?: boolean): GjcTeamTaskMetadataInput;
|
|
138
134
|
export declare function normalizeGjcTeamTask(raw: GjcTeamTask): GjcTeamTask;
|
|
@@ -15,6 +15,7 @@ export interface GjcTeamWorkerRuntime {
|
|
|
15
15
|
workerDir(dir: string, worker: string): string;
|
|
16
16
|
readJson<T>(filePath: string): Promise<T | null>;
|
|
17
17
|
writeJson(filePath: string, value: unknown): Promise<void>;
|
|
18
|
+
withTaskMutation<T>(dir: string, fn: (capability: GjcTeamTaskMutationCapability) => Promise<T>): Promise<T>;
|
|
18
19
|
appendEvent(dir: string, event: {
|
|
19
20
|
type: string;
|
|
20
21
|
worker?: string;
|
|
@@ -67,9 +68,13 @@ export declare function updateGjcWorkerStatus(runtime: GjcTeamWorkerRuntime, tea
|
|
|
67
68
|
export declare function readGjcWorkerHeartbeat(runtime: GjcTeamWorkerRuntime, teamName: string, worker: string, cwd?: string, env?: NodeJS.ProcessEnv): Promise<WorkerHeartbeatFile | null>;
|
|
68
69
|
export declare function updateGjcWorkerHeartbeat(runtime: GjcTeamWorkerRuntime, teamName: string, worker: string, heartbeat: WorkerHeartbeatFile, cwd?: string, env?: NodeJS.ProcessEnv): Promise<WorkerHeartbeatFile>;
|
|
69
70
|
export declare function writeGjcWorkerStartupAck(runtime: GjcTeamWorkerRuntime, teamName: string, worker: string, cwd: string, env: NodeJS.ProcessEnv, input: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
71
|
+
export declare const GJC_TEAM_CONTINUATION_ACK_POLL_MS = 50;
|
|
72
|
+
export declare function isValidGjcContinuationAck(value: unknown, reservation: Record<string, unknown>, incident: string, attempt: number): value is Record<string, unknown>;
|
|
73
|
+
export declare function writeGjcWorkerContinuationAck(runtime: GjcTeamWorkerRuntime, teamName: string, worker: string, cwd: string, env: NodeJS.ProcessEnv, input: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
70
74
|
export declare function writeGjcShutdownRequest(runtime: GjcTeamWorkerRuntime, teamName: string, worker: string, requestedBy: string, cwd: string | undefined, env: NodeJS.ProcessEnv | undefined, requestId: string, mode?: GjcTeamShutdownMode, requestedAt?: string): Promise<Record<string, unknown>>;
|
|
71
75
|
export declare function readGjcShutdownAck(runtime: GjcTeamWorkerRuntime, teamName: string, worker: string, cwd?: string, env?: NodeJS.ProcessEnv): Promise<Record<string, unknown> | null>;
|
|
72
76
|
export declare const GJC_TEAM_CONTINUATION_PROMPT = "Continue only your current claimed GJC team task. Re-read current GJC team state; do not replay prior output; report status.";
|
|
77
|
+
export declare function buildGjcContinuationPrompt(reservation: Record<string, unknown>): string;
|
|
73
78
|
export declare function gjcContinuationReservationDigest(reservation: Record<string, unknown>): string;
|
|
74
79
|
export declare function isValidGjcContinuationReservation(value: unknown, incident: string, attempt: number, config: GjcTeamConfig, worker: string, task: GjcTeamTask, claim: GjcTeamTaskClaim, heartbeatAt: string, paneId: string): value is Record<string, unknown>;
|
|
75
80
|
export declare function isValidGjcContinuationOutcome(value: unknown, reservation: Record<string, unknown>, incident: string, attempt: number): value is Record<string, unknown>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ResolvedTmuxBinary } from "./psmux-detect";
|
|
2
|
+
export { assertGjcTmuxMutationAuthoritySync, bindGjcTmuxProviderAuthority, buildTmuxProviderCommand, hasGjcTmuxProviderAuthoritySync, type ProviderAuthority, type ProviderContext, persistGjcTmuxProviderAuthoritySync, readGjcTmuxProviderAuthoritySync, resolveGjcTmuxProviderContext, type TmuxProviderKind, } from "./tmux-provider-context";
|
|
2
3
|
export declare const GJC_DEFAULT_TMUX_SESSION = "gajae_code";
|
|
3
4
|
export declare const GJC_TMUX_SESSION_PREFIX = "gajae_code_";
|
|
4
5
|
export declare const GJC_TMUX_COMMAND_ENV = "GJC_TMUX_COMMAND";
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { type PsmuxSpawnRunner, type ResolvedTmuxBinary } from "./psmux-detect";
|
|
2
|
+
/** @internal Test-only seam for hermetic Windows authority storage tests. */
|
|
3
|
+
/**
|
|
4
|
+
* The platform that governs psmux authority decisions, honoring the test
|
|
5
|
+
* override. Every authority gate must read this rather than `process.platform`,
|
|
6
|
+
* or a pinned test platform is silently ignored on non-Windows hosts.
|
|
7
|
+
*/
|
|
8
|
+
export declare function gjcTmuxAuthorityPlatform(): NodeJS.Platform;
|
|
9
|
+
export declare function __setTmuxProviderAuthorityPlatformForTests(platform: NodeJS.Platform | null): void;
|
|
10
|
+
export type TmuxProviderKind = "native-tmux" | "windows-psmux";
|
|
11
|
+
/** A structured tmux provider. Native tmux intentionally has no prefix. */
|
|
12
|
+
export interface ProviderContext {
|
|
13
|
+
readonly kind: TmuxProviderKind;
|
|
14
|
+
readonly command: string;
|
|
15
|
+
readonly commandPrefix: readonly string[];
|
|
16
|
+
readonly namespace: string | null;
|
|
17
|
+
readonly executableIdentity: string | null;
|
|
18
|
+
readonly binary: ResolvedTmuxBinary;
|
|
19
|
+
readonly platform: NodeJS.Platform;
|
|
20
|
+
}
|
|
21
|
+
/** Durable authority binding for one owner generation. */
|
|
22
|
+
export interface ProviderAuthority extends ProviderContext {
|
|
23
|
+
readonly stateDir: string;
|
|
24
|
+
readonly sessionId: string;
|
|
25
|
+
readonly generation: string;
|
|
26
|
+
}
|
|
27
|
+
/** Resolve a structured provider. Native tmux remains byte-for-byte argv compatible. */
|
|
28
|
+
export declare function resolveGjcTmuxProviderContext(options?: {
|
|
29
|
+
env?: NodeJS.ProcessEnv;
|
|
30
|
+
platform?: NodeJS.Platform;
|
|
31
|
+
runner?: PsmuxSpawnRunner;
|
|
32
|
+
binary?: ResolvedTmuxBinary;
|
|
33
|
+
}): ProviderContext;
|
|
34
|
+
export declare function buildTmuxProviderCommand(context: ProviderContext, command: string, args?: readonly string[]): string[];
|
|
35
|
+
/** Returns whether an owner generation has a persisted Windows psmux authority. */
|
|
36
|
+
export declare function hasGjcTmuxProviderAuthoritySync(input: {
|
|
37
|
+
stateDir: string;
|
|
38
|
+
sessionId: string;
|
|
39
|
+
generation: string;
|
|
40
|
+
}): boolean;
|
|
41
|
+
export declare function bindGjcTmuxProviderAuthority(context: ProviderContext, input: {
|
|
42
|
+
stateDir: string;
|
|
43
|
+
sessionId: string;
|
|
44
|
+
generation: string;
|
|
45
|
+
}): ProviderAuthority;
|
|
46
|
+
export declare function persistGjcTmuxProviderAuthoritySync(authority: ProviderAuthority): void;
|
|
47
|
+
export declare function readGjcTmuxProviderAuthoritySync(input: {
|
|
48
|
+
stateDir: string;
|
|
49
|
+
sessionId: string;
|
|
50
|
+
generation: string;
|
|
51
|
+
}): ProviderAuthority;
|
|
52
|
+
/** Enumerates owner-secured, executable-validated psmux authorities in one durable state root. */
|
|
53
|
+
export declare function listGjcTmuxProviderAuthoritiesSync(stateDirInput: string): ProviderAuthority[];
|
|
54
|
+
/** Re-proves the staged immutable record and executable identity before generation publication. */
|
|
55
|
+
export declare function assertGjcTmuxStagedMutationAuthoritySync(authority: ProviderAuthority): void;
|
|
56
|
+
/** Re-proves the current pointer, exact executable identity, and native root before mutation. */
|
|
57
|
+
export declare function assertGjcTmuxMutationAuthoritySync(authority: ProviderAuthority): void;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ProviderAuthority } from "./tmux-common";
|
|
1
2
|
import { type OwnerIsolationProbeSync, type PlanResponse, type TmuxOwnerIsolationExecutionDependencies, type TmuxOwnerIsolationExecutionResult } from "./tmux-owner-isolation";
|
|
2
3
|
export interface GjcTmuxSessionStatus {
|
|
3
4
|
name: string;
|
|
@@ -14,6 +15,9 @@ export interface GjcTmuxSessionStatus {
|
|
|
14
15
|
version?: string;
|
|
15
16
|
ownerGeneration?: string;
|
|
16
17
|
nativeSessionId?: string;
|
|
18
|
+
psmuxIncarnation?: string;
|
|
19
|
+
/** Exact durable provider binding used to discover this psmux session. */
|
|
20
|
+
providerAuthority?: ProviderAuthority;
|
|
17
21
|
panePids: number[];
|
|
18
22
|
profile?: string;
|
|
19
23
|
}
|
|
@@ -27,6 +31,7 @@ export interface GjcTmuxSessionTagsForGc {
|
|
|
27
31
|
version?: string;
|
|
28
32
|
ownerGeneration?: string;
|
|
29
33
|
nativeSessionId?: string;
|
|
34
|
+
psmuxIncarnation?: string;
|
|
30
35
|
createdAt?: string;
|
|
31
36
|
attached?: boolean;
|
|
32
37
|
panePids?: number[];
|
|
@@ -39,6 +44,7 @@ export interface ProvenTmuxSessionIdentity {
|
|
|
39
44
|
nativeSessionId: string;
|
|
40
45
|
serverPid: number;
|
|
41
46
|
serverStartTime: string;
|
|
47
|
+
psmuxIncarnation?: string;
|
|
42
48
|
}
|
|
43
49
|
export interface ExpectedGjcTmuxSessionIdentity {
|
|
44
50
|
nativeSessionId: string;
|
|
@@ -47,6 +53,7 @@ export interface ExpectedGjcTmuxSessionIdentity {
|
|
|
47
53
|
sessionStateFile: string;
|
|
48
54
|
project: string;
|
|
49
55
|
createdAt: string;
|
|
56
|
+
psmuxIncarnation?: string;
|
|
50
57
|
}
|
|
51
58
|
export interface ExactOwnerIdentity {
|
|
52
59
|
sessionId: string;
|
|
@@ -85,7 +92,7 @@ export declare function findGjcTmuxSessionByScope(project: string, branch: strin
|
|
|
85
92
|
export declare function statusGjcTmuxSession(sessionName: string, env?: NodeJS.ProcessEnv): GjcTmuxSessionStatus;
|
|
86
93
|
export declare function createGjcTmuxSession(env?: NodeJS.ProcessEnv, options?: CreateGjcTmuxSessionOptions): GjcTmuxSessionStatus;
|
|
87
94
|
/** Proves a managed reusable name still resolves to one immutable session on one server. */
|
|
88
|
-
export declare function proveGjcTmuxSessionMutationTarget(sessionName: string, env?: NodeJS.ProcessEnv): ProvenTmuxSessionIdentity;
|
|
95
|
+
export declare function proveGjcTmuxSessionMutationTarget(sessionName: string, env?: NodeJS.ProcessEnv, provisionalAuthority?: ProviderAuthority): ProvenTmuxSessionIdentity;
|
|
89
96
|
/** @internal */
|
|
90
97
|
export declare function readTmuxSessionTagsForGc(sessionName: string, env?: NodeJS.ProcessEnv): GjcTmuxSessionTagsForGc;
|
|
91
98
|
export declare function removeGjcTmuxSession(sessionName: string, env?: NodeJS.ProcessEnv, expectedIdentity?: ExpectedGjcTmuxSessionIdentity): GjcTmuxSessionStatus;
|
|
@@ -9,5 +9,8 @@ export declare function spawnText(command: string[], options: {
|
|
|
9
9
|
}>;
|
|
10
10
|
export declare function resolveGitBase(cwd: string, branch?: string): Promise<string>;
|
|
11
11
|
export declare function parseGitNameStatus(output: string): UltragoalChangeSetPath[];
|
|
12
|
+
export declare function parseGitUntrackedPaths(output: string): UltragoalChangeSetPath[];
|
|
13
|
+
export declare function ciDevChangedPathRows(): UltragoalChangeSetPath[];
|
|
14
|
+
export declare function mergeChangeSetPaths(groups: UltragoalChangeSetPath[][]): UltragoalChangeSetPath[];
|
|
12
15
|
export declare function computeCheckpointChangeSet(cwd: string): Promise<UltragoalChangeSet | undefined>;
|
|
13
16
|
export declare function parseUnifiedDiffPaths(diff: string): UltragoalChangeSetPath[];
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { RepositoryBinding } from "./repository-binding";
|
|
2
|
+
export declare const REVIEW_SOURCE_COHORT_SCHEMA: "gjc.review_source_cohort.v1";
|
|
3
|
+
export type ReviewSourceWorkflow = "ultragoal" | "ralplan";
|
|
4
|
+
export type ReviewSourceLane = "cleaner" | "architect" | "qa" | "critic";
|
|
5
|
+
export type ReviewDeliveryDisposition = "current" | "stale_review_delivery" | "invalid_provenance";
|
|
6
|
+
export interface ReviewSourceDispatch {
|
|
7
|
+
schema: "gjc.review_source_dispatch.v1";
|
|
8
|
+
cohortId: string;
|
|
9
|
+
generation: number;
|
|
10
|
+
dispatchId: string;
|
|
11
|
+
taskId: string;
|
|
12
|
+
lane: ReviewSourceLane;
|
|
13
|
+
snapshotId: string;
|
|
14
|
+
repositoryBindingDigest: string;
|
|
15
|
+
stateRevision: number;
|
|
16
|
+
rerunCommand: string;
|
|
17
|
+
createdAt: string;
|
|
18
|
+
}
|
|
19
|
+
export interface ReviewSourceDelivery {
|
|
20
|
+
deliveryId: string;
|
|
21
|
+
taskId: string;
|
|
22
|
+
lane: ReviewSourceLane;
|
|
23
|
+
snapshotId: string;
|
|
24
|
+
disposition: ReviewDeliveryDisposition;
|
|
25
|
+
receivedAt: string;
|
|
26
|
+
rerunCommand?: string;
|
|
27
|
+
cohortId: string;
|
|
28
|
+
dispatchId: string;
|
|
29
|
+
}
|
|
30
|
+
export interface ReviewSourceCohort {
|
|
31
|
+
schema: typeof REVIEW_SOURCE_COHORT_SCHEMA;
|
|
32
|
+
cohortId: string;
|
|
33
|
+
workflow: ReviewSourceWorkflow;
|
|
34
|
+
generation: number;
|
|
35
|
+
snapshotId: string;
|
|
36
|
+
repositoryBindingDigest: string;
|
|
37
|
+
stateRevision: number;
|
|
38
|
+
createdAt: string;
|
|
39
|
+
status: "active" | "superseded";
|
|
40
|
+
supersededBy?: string;
|
|
41
|
+
dispatches: ReviewSourceDispatch[];
|
|
42
|
+
deliveries: ReviewSourceDelivery[];
|
|
43
|
+
}
|
|
44
|
+
interface CapturedReviewSource {
|
|
45
|
+
snapshotId: string;
|
|
46
|
+
repositoryBindingDigest: string;
|
|
47
|
+
}
|
|
48
|
+
export declare function captureReviewSourceSnapshot(cwd: string, repositoryBinding: RepositoryBinding): Promise<CapturedReviewSource>;
|
|
49
|
+
export declare function createReviewSourceCohort(input: {
|
|
50
|
+
workflow: ReviewSourceWorkflow;
|
|
51
|
+
generation: number;
|
|
52
|
+
snapshotId: string;
|
|
53
|
+
repositoryBindingDigest: string;
|
|
54
|
+
stateRevision: number;
|
|
55
|
+
now?: string;
|
|
56
|
+
}): ReviewSourceCohort;
|
|
57
|
+
export declare function createReviewSourceDispatch(input: {
|
|
58
|
+
cohort: ReviewSourceCohort;
|
|
59
|
+
taskId: string;
|
|
60
|
+
lane: ReviewSourceLane;
|
|
61
|
+
rerunCommand: string;
|
|
62
|
+
now?: string;
|
|
63
|
+
}): ReviewSourceDispatch;
|
|
64
|
+
export declare function normalizeReviewSourceCohorts(value: unknown): ReviewSourceCohort[];
|
|
65
|
+
export declare function reconcileReviewSourceDelivery(input: {
|
|
66
|
+
cwd: string;
|
|
67
|
+
repositoryBinding: RepositoryBinding;
|
|
68
|
+
reviewSource: {
|
|
69
|
+
schema: "gjc.review_source_dispatch.v1";
|
|
70
|
+
cohortId: string;
|
|
71
|
+
generation: number;
|
|
72
|
+
lane: ReviewSourceLane;
|
|
73
|
+
snapshotId: string;
|
|
74
|
+
repositoryBindingDigest: string;
|
|
75
|
+
stateRevision: number;
|
|
76
|
+
dispatchId: string;
|
|
77
|
+
rerunCommand: string;
|
|
78
|
+
};
|
|
79
|
+
}): Promise<{
|
|
80
|
+
disposition: ReviewDeliveryDisposition;
|
|
81
|
+
currentSnapshotId?: string;
|
|
82
|
+
}>;
|
|
83
|
+
export {};
|