@gajae-code/coding-agent 0.12.5 → 0.12.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/README.md +4 -1
- package/dist/types/async/job-manager.d.ts +36 -1
- 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-runtime.d.ts +21 -4
- 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 +2 -3
- package/dist/types/sdk/bus/index.d.ts +4 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +2 -2
- 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/session/agent-session.d.ts +5 -4
- package/dist/types/session/attempt-record-store.d.ts +19 -0
- package/dist/types/session/session-manager.d.ts +1 -0
- package/dist/types/session/session-storage.d.ts +8 -0
- package/dist/types/task/receipt.d.ts +1 -0
- package/dist/types/task/types.d.ts +43 -0
- package/dist/types/tools/subagent.d.ts +15 -0
- package/dist/types/tools/todo-write.d.ts +3 -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 +430 -46
- package/src/config/model-profiles.ts +8 -0
- package/src/config/settings-schema.ts +17 -3
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +2 -0
- 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-runtime.ts +360 -156
- package/src/internal-urls/docs-index.generated.ts +4 -4
- package/src/internal-urls/local-protocol.ts +39 -18
- package/src/modes/acp/acp-agent.ts +27 -13
- 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/monitor.md +4 -4
- package/src/sdk/broker/broker.ts +93 -10
- package/src/sdk/broker/lifecycle-ledger.ts +227 -11
- package/src/sdk/broker/lifecycle.ts +691 -92
- package/src/sdk/bus/chat-daemon-control.ts +30 -6
- package/src/sdk/bus/index.ts +23 -6
- package/src/sdk/bus/telegram-daemon-contract.ts +2 -2
- package/src/sdk/bus/telegram-daemon.ts +283 -44
- package/src/sdk/bus/topic-registry.ts +133 -10
- package/src/sdk/session.ts +7 -6
- package/src/session/agent-session.ts +752 -339
- package/src/session/attempt-record-store.ts +106 -0
- package/src/session/internal/managed-session-scope.ts +252 -67
- package/src/session/internal/managed-session-storage.ts +1 -0
- package/src/session/session-manager.ts +7 -0
- package/src/session/session-storage.ts +146 -24
- package/src/task/index.ts +230 -19
- package/src/task/provider-retry-status.ts +4 -1
- package/src/task/receipt.ts +2 -0
- package/src/task/types.ts +10 -0
- package/src/tools/monitor.ts +7 -1
- package/src/tools/output-meta.ts +10 -2
- package/src/tools/subagent.ts +97 -75
- package/src/tools/todo-write.ts +47 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,38 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.12.7] - 2026-07-31
|
|
6
|
+
|
|
7
|
+
## [0.12.6] - 2026-07-31
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- 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.
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- 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).
|
|
15
|
+
- `todo_write` now rejects unsupported operation keys and treats a bare `done` or `drop` as an error instead of completing or abandoning every task (#3640).
|
|
16
|
+
- 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.
|
|
17
|
+
- 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).
|
|
18
|
+
- 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).
|
|
19
|
+
- 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).
|
|
20
|
+
- 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).
|
|
21
|
+
- 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).
|
|
22
|
+
- 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.
|
|
23
|
+
- 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.
|
|
24
|
+
- 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.
|
|
25
|
+
- 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.
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- 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).
|
|
30
|
+
- 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.
|
|
31
|
+
|
|
32
|
+
## [0.12.5] - 2026-07-30
|
|
33
|
+
### Fixed
|
|
34
|
+
|
|
35
|
+
- 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`.
|
|
36
|
+
|
|
5
37
|
## [0.12.5] - 2026-07-30
|
|
6
38
|
|
|
7
39
|
## [0.12.4] - 2026-07-30
|
|
@@ -48,10 +80,12 @@
|
|
|
48
80
|
- 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.
|
|
49
81
|
- 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.
|
|
50
82
|
- 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).
|
|
83
|
+
- 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.
|
|
51
84
|
- 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).
|
|
52
85
|
- 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).
|
|
53
86
|
- 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.
|
|
54
87
|
- 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.
|
|
88
|
+
- 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.
|
|
55
89
|
|
|
56
90
|
### Added
|
|
57
91
|
|
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`):
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AgentProgress, AgentSource } from "../task/types";
|
|
2
2
|
export interface AsyncJob {
|
|
3
3
|
id: string;
|
|
4
|
+
readonly generation: string;
|
|
4
5
|
type: "bash" | "task";
|
|
5
6
|
status: "running" | "completed" | "failed" | "cancelled" | "paused";
|
|
6
7
|
startTime: number;
|
|
@@ -41,6 +42,8 @@ export interface AsyncJobMetadata {
|
|
|
41
42
|
agentSource: AgentSource;
|
|
42
43
|
description?: string;
|
|
43
44
|
assignment?: string;
|
|
45
|
+
duplicateIdentity?: string;
|
|
46
|
+
duplicateDisposition?: "warned" | "superseded";
|
|
44
47
|
};
|
|
45
48
|
/** True when this bash job was started by the `monitor` tool (vs plain async bash). */
|
|
46
49
|
monitor?: boolean;
|
|
@@ -136,6 +139,11 @@ export interface SubagentRecord {
|
|
|
136
139
|
modelFellBack?: boolean;
|
|
137
140
|
/** True when the effective subagent provider is in fast mode. */
|
|
138
141
|
fastMode?: boolean;
|
|
142
|
+
duplicateIdentity?: string;
|
|
143
|
+
duplicateDisposition?: "warned" | "superseded";
|
|
144
|
+
terminalGeneration?: string;
|
|
145
|
+
/** Generation of currentJobId, preventing stale ID reuse from mutating this record. */
|
|
146
|
+
currentJobGeneration?: string;
|
|
139
147
|
}
|
|
140
148
|
/** Lightweight, manager-owned resume payload. The async layer treats `data` as opaque. */
|
|
141
149
|
export interface ResumeDescriptor {
|
|
@@ -200,6 +208,31 @@ export interface AsyncJobRegisterOptions {
|
|
|
200
208
|
export interface AsyncJobFilter {
|
|
201
209
|
ownerId?: string;
|
|
202
210
|
}
|
|
211
|
+
export type AsyncJobWaitCondition = "all_terminal" | "any_terminal";
|
|
212
|
+
export type AsyncJobWaitOutcome = "completed" | "timed_out_wait" | "interrupted";
|
|
213
|
+
export interface AsyncJobWaitTarget {
|
|
214
|
+
targetId: string;
|
|
215
|
+
jobId: string | null;
|
|
216
|
+
subagentId?: string;
|
|
217
|
+
generation: string;
|
|
218
|
+
ownerId?: string;
|
|
219
|
+
initialStatus: AsyncJob["status"] | "queued" | "not_found";
|
|
220
|
+
}
|
|
221
|
+
export interface AsyncJobWaitResult {
|
|
222
|
+
outcome: AsyncJobWaitOutcome;
|
|
223
|
+
condition: AsyncJobWaitCondition;
|
|
224
|
+
terminalJobIds: string[];
|
|
225
|
+
pendingJobIds: string[];
|
|
226
|
+
}
|
|
227
|
+
export interface AsyncJobWaitHandle {
|
|
228
|
+
readonly token: string;
|
|
229
|
+
readonly result: Promise<AsyncJobWaitResult>;
|
|
230
|
+
acknowledge(targetIds?: readonly string[]): {
|
|
231
|
+
acknowledged: boolean;
|
|
232
|
+
jobIds: string[];
|
|
233
|
+
};
|
|
234
|
+
close(): void;
|
|
235
|
+
}
|
|
203
236
|
/**
|
|
204
237
|
* A slice of process-stream output for a background job, as recorded by
|
|
205
238
|
* `appendOutput` / read by `readOutputSince`.
|
|
@@ -229,6 +262,8 @@ export declare class AsyncJobManager {
|
|
|
229
262
|
static setInstance(value: AsyncJobManager | undefined): void;
|
|
230
263
|
/** Reset the process-global instance. Test-only. */
|
|
231
264
|
static resetForTests(): void;
|
|
265
|
+
resolveSubagentWaitTarget(id: string, filter?: AsyncJobFilter): AsyncJobWaitTarget | undefined;
|
|
266
|
+
subscribeTerminalWait(targets: readonly AsyncJobWaitTarget[], condition?: AsyncJobWaitCondition): AsyncJobWaitHandle;
|
|
232
267
|
constructor(options: AsyncJobManagerOptions);
|
|
233
268
|
/**
|
|
234
269
|
* Subscribe to live-job-set change events. Returns an unsubscribe function.
|
|
@@ -385,5 +420,5 @@ export declare class AsyncJobManager {
|
|
|
385
420
|
dispose(options?: {
|
|
386
421
|
timeoutMs?: number;
|
|
387
422
|
}): Promise<boolean>;
|
|
388
|
-
isDeliverySuppressed(jobId: string): boolean;
|
|
423
|
+
isDeliverySuppressed(jobId: string, generation?: string): boolean;
|
|
389
424
|
}
|
|
@@ -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[];
|
|
@@ -303,11 +303,12 @@ export interface UltragoalChangeSet extends JsonObject {
|
|
|
303
303
|
paths: UltragoalChangeSetPath[];
|
|
304
304
|
rawDiffStat?: string;
|
|
305
305
|
rawDiff?: string;
|
|
306
|
+
captureIncomplete?: boolean;
|
|
306
307
|
trusted: true;
|
|
307
308
|
}
|
|
308
309
|
export declare function normalizeRepoPath(value: string): string;
|
|
310
|
+
export declare function normalizeChangeSetPath(value: string): string;
|
|
309
311
|
export declare function categorizeComputerChangePath(value: string): UltragoalChangeCategory;
|
|
310
|
-
export declare function isSettingsSchemaPath(value: string): boolean;
|
|
311
312
|
export declare function normalizeSurfaceToken(value: string): string;
|
|
312
313
|
export declare function surfaceFamily(value: string): SurfaceFamily;
|
|
313
314
|
export declare function isLiveSurfaceFamily(family: SurfaceFamily): boolean;
|
|
@@ -380,7 +381,10 @@ export declare function recordUltragoalReviewBlockers(input: {
|
|
|
380
381
|
title: string;
|
|
381
382
|
objective: string;
|
|
382
383
|
evidence: string;
|
|
383
|
-
}): Promise<
|
|
384
|
+
}): Promise<{
|
|
385
|
+
plan: UltragoalPlan;
|
|
386
|
+
blockerGoalId: string;
|
|
387
|
+
}>;
|
|
384
388
|
export type UltragoalBlockerClassification = "human_blocked" | "resolvable";
|
|
385
389
|
/**
|
|
386
390
|
* Record an audited blocker triage classification in the durable ledger. Pause
|
|
@@ -422,7 +426,20 @@ interface UltragoalReviewResult extends JsonObject {
|
|
|
422
426
|
weakContractCapApplied: boolean;
|
|
423
427
|
blockerGoalIds?: string[];
|
|
424
428
|
}
|
|
425
|
-
import { computeCheckpointChangeSet, parseGitNameStatus, parseUnifiedDiffPaths, resolveGitBase, spawnText } from "./ultragoal-change-set";
|
|
426
|
-
export { computeCheckpointChangeSet, parseGitNameStatus, parseUnifiedDiffPaths, resolveGitBase, spawnText };
|
|
429
|
+
import { ciDevChangedPathRows, computeCheckpointChangeSet, mergeChangeSetPaths, parseGitNameStatus, parseGitUntrackedPaths, parseUnifiedDiffPaths, resolveGitBase, spawnText } from "./ultragoal-change-set";
|
|
430
|
+
export { ciDevChangedPathRows, computeCheckpointChangeSet, mergeChangeSetPaths, parseGitNameStatus, parseGitUntrackedPaths, parseUnifiedDiffPaths, resolveGitBase, spawnText, };
|
|
431
|
+
/**
|
|
432
|
+
* Typed terminal handoff thrown when {@link recordUltragoalReviewBlockers} would
|
|
433
|
+
* exceed {@link MAX_REVIEW_BLOCKER_DESCENTS} unresolved review_blocker descents
|
|
434
|
+
* off a single blocked goal (#3613). Never silently marks unresolved technical
|
|
435
|
+
* findings complete; the operator/leader must pause and escalate.
|
|
436
|
+
*/
|
|
437
|
+
export declare class UltragoalReviewBlockerRecursionCapError extends Error {
|
|
438
|
+
readonly code: "review_blocker_recursion_cap";
|
|
439
|
+
readonly blockedGoalId: string;
|
|
440
|
+
readonly unresolvedDescents: number;
|
|
441
|
+
readonly cap: number;
|
|
442
|
+
constructor(blockedGoalId: string, unresolvedDescents: number, cap?: number);
|
|
443
|
+
}
|
|
427
444
|
export declare function runUltragoalReview(cwd: string, args: readonly string[]): Promise<UltragoalReviewResult>;
|
|
428
445
|
export declare function runNativeUltragoalCommand(args: string[], cwd?: string): Promise<UltragoalCommandResult>;
|
|
@@ -19,6 +19,7 @@ export interface GjcBundleSettingsDependencies {
|
|
|
19
19
|
export interface GjcBundleSettingsCallbacks {
|
|
20
20
|
onClose: () => void;
|
|
21
21
|
onBundlesChanged?: () => void;
|
|
22
|
+
onRenderRequested?: () => void;
|
|
22
23
|
}
|
|
23
24
|
export type GjcBundleSettingsState = "loading" | "error" | "empty" | "list" | "detail" | "unsupported-source" | "update-review" | "update-confirm" | "update-running" | "update-result" | "stale-result" | "quarantined-blocked" | "mutation-in-flight-locked";
|
|
24
25
|
/** Scope-qualified, lifecycle-backed Settings UI for installed GJC bundles. */
|
|
@@ -35,6 +35,7 @@ export interface PluginDetailCallbacks {
|
|
|
35
35
|
onFeatureChange: (feature: string, enabled: boolean) => void;
|
|
36
36
|
onConfigChange: (key: string, value: unknown) => void;
|
|
37
37
|
onBack: () => void;
|
|
38
|
+
onRenderRequested?: () => void;
|
|
38
39
|
}
|
|
39
40
|
/**
|
|
40
41
|
* Shows detail settings for a single plugin:
|
|
@@ -53,6 +54,7 @@ export declare class PluginDetailComponent extends Container {
|
|
|
53
54
|
export interface PluginSettingsCallbacks {
|
|
54
55
|
onClose: () => void;
|
|
55
56
|
onPluginChanged: () => void;
|
|
57
|
+
onRenderRequested?: () => void;
|
|
56
58
|
}
|
|
57
59
|
/**
|
|
58
60
|
* Top-level plugin settings component.
|
|
@@ -67,6 +67,8 @@ export interface SettingsCallbacks {
|
|
|
67
67
|
getStatusLinePreview?: (width?: number) => string;
|
|
68
68
|
/** Called when plugins change */
|
|
69
69
|
onPluginsChanged?: () => void;
|
|
70
|
+
/** Called when asynchronously rebuilt settings content needs a repaint. */
|
|
71
|
+
onRenderRequested?: () => void;
|
|
70
72
|
/** Called when an interactive setting cannot be committed. */
|
|
71
73
|
onError?: (message: string) => void;
|
|
72
74
|
/** Called when settings panel is closed */
|