@gajae-code/coding-agent 0.12.21 → 0.13.0

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.
Files changed (222) hide show
  1. package/CHANGELOG.md +67 -2
  2. package/dist/types/cli/args.d.ts +5 -2
  3. package/dist/types/cli/root-flags.d.ts +246 -0
  4. package/dist/types/cli.d.ts +11 -19
  5. package/dist/types/commands/daemon.d.ts +0 -30
  6. package/dist/types/commands/launch.d.ts +11 -19
  7. package/dist/types/commands/quick-lane.d.ts +32 -0
  8. package/dist/types/commands/sdk.d.ts +21 -15
  9. package/dist/types/config/file-lock-gc.d.ts +2 -0
  10. package/dist/types/config/model-equivalence.d.ts +20 -0
  11. package/dist/types/config/model-profile-activation.d.ts +62 -17
  12. package/dist/types/config/model-profiles.d.ts +10 -0
  13. package/dist/types/config/model-registry.d.ts +68 -1
  14. package/dist/types/config/model-resolver.d.ts +15 -4
  15. package/dist/types/config/models-config-schema.d.ts +7 -2
  16. package/dist/types/config/provider-selection-policy.d.ts +62 -0
  17. package/dist/types/config/settings-schema.d.ts +36 -78
  18. package/dist/types/config/settings.d.ts +2 -0
  19. package/dist/types/edit/renderer.d.ts +5 -2
  20. package/dist/types/edit/streaming.d.ts +13 -0
  21. package/dist/types/extensibility/custom-tools/types.d.ts +2 -0
  22. package/dist/types/extensibility/extensions/compact-handler.d.ts +2 -1
  23. package/dist/types/extensibility/extensions/types.d.ts +3 -0
  24. package/dist/types/gjc-runtime/gc-runtime.d.ts +19 -5
  25. package/dist/types/internal-urls/local-protocol.d.ts +1 -0
  26. package/dist/types/modes/components/model-selector.d.ts +0 -2
  27. package/dist/types/modes/components/provider-order-context.d.ts +45 -0
  28. package/dist/types/modes/components/provider-order-editor.d.ts +24 -0
  29. package/dist/types/modes/components/settings-defs.d.ts +5 -1
  30. package/dist/types/modes/components/settings-selector.d.ts +2 -0
  31. package/dist/types/quick-lane/classify.d.ts +40 -0
  32. package/dist/types/runtime/stt-settings-setup.d.ts +18 -0
  33. package/dist/types/sdk/broker/broker.d.ts +56 -2
  34. package/dist/types/sdk/broker/operation-receipt-ledger.d.ts +25 -0
  35. package/dist/types/sdk/broker/session-index.d.ts +83 -2
  36. package/dist/types/sdk/broker/state-version.d.ts +1 -1
  37. package/dist/types/sdk/bus/notification-service.d.ts +6 -0
  38. package/dist/types/sdk/bus/prompt-reconciliation.d.ts +8 -1
  39. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +4 -1
  40. package/dist/types/sdk/bus/telegram-daemon.d.ts +26 -0
  41. package/dist/types/sdk/cli/rows.d.ts +98 -0
  42. package/dist/types/sdk/cli/session-cli.d.ts +35 -3
  43. package/dist/types/sdk/elevation/allowlist.d.ts +20 -0
  44. package/dist/types/sdk/elevation/audit.d.ts +93 -0
  45. package/dist/types/sdk/elevation/capability.d.ts +3 -0
  46. package/dist/types/sdk/elevation/digest.d.ts +72 -0
  47. package/dist/types/sdk/elevation/dispatch-receipt.d.ts +85 -0
  48. package/dist/types/sdk/elevation/grant-ledger.d.ts +163 -0
  49. package/dist/types/sdk/elevation/owner.d.ts +48 -0
  50. package/dist/types/sdk/guides/cache.d.ts +98 -0
  51. package/dist/types/sdk/guides/catalog.d.ts +156 -0
  52. package/dist/types/sdk/guides/cli.d.ts +39 -0
  53. package/dist/types/sdk/guides/manifest.d.ts +66 -0
  54. package/dist/types/sdk/guides/verify.d.ts +66 -0
  55. package/dist/types/sdk/host/control/dispatch.d.ts +8 -0
  56. package/dist/types/sdk/host/control/index.d.ts +1 -1
  57. package/dist/types/sdk/host/control/operations.d.ts +3 -2
  58. package/dist/types/sdk/host/query/cursor.d.ts +10 -0
  59. package/dist/types/sdk/host/query/handlers.d.ts +21 -0
  60. package/dist/types/sdk/host/session-runtime.d.ts +9 -0
  61. package/dist/types/sdk/mcp/server.d.ts +2 -2
  62. package/dist/types/sdk/prompt-status.d.ts +11 -0
  63. package/dist/types/sdk/session.d.ts +4 -0
  64. package/dist/types/sdk/transport/index.d.ts +1 -0
  65. package/dist/types/sdk/transport/relay.d.ts +1 -0
  66. package/dist/types/sdk/transport/serve-cli.d.ts +20 -1
  67. package/dist/types/session/agent-session.d.ts +32 -18
  68. package/dist/types/session/blob-store.d.ts +13 -7
  69. package/dist/types/session/fallback-chain-controller.d.ts +15 -0
  70. package/dist/types/session/internal/managed-session-storage.d.ts +25 -1
  71. package/dist/types/session/internal/session-memory-sidecar.d.ts +5 -5
  72. package/dist/types/session/session-manager.d.ts +139 -10
  73. package/dist/types/session/session-storage.d.ts +48 -0
  74. package/dist/types/setup/provider-onboarding.d.ts +7 -1
  75. package/dist/types/slash-commands/builtin-registry.d.ts +14 -0
  76. package/dist/types/stt/setup.d.ts +2 -0
  77. package/dist/types/task/executor.d.ts +10 -2
  78. package/dist/types/tools/browser/runtime-diagnostics.d.ts +65 -0
  79. package/dist/types/tools/browser/tab-protocol.d.ts +4 -0
  80. package/dist/types/tools/browser/tab-supervisor.d.ts +2 -0
  81. package/dist/types/tools/browser/tab-worker.d.ts +2 -0
  82. package/dist/types/tools/browser.d.ts +2 -0
  83. package/dist/types/tools/image-gen.d.ts +14 -18
  84. package/dist/types/tools/index.d.ts +2 -0
  85. package/dist/types/tools/resource-gc.d.ts +2 -0
  86. package/dist/types/utils/pasted-image-path.d.ts +6 -0
  87. package/package.json +9 -9
  88. package/scripts/generate-sdk-operation-inventory.ts +8 -0
  89. package/scripts/run-test-manifest.ts +61 -21
  90. package/scripts/verify-gjc-sdk-canonicalization.ts +9 -4
  91. package/src/cli/args.ts +62 -9
  92. package/src/cli/completion-cli.ts +1 -0
  93. package/src/cli/fast-help.ts +1 -0
  94. package/src/cli/root-flags.ts +100 -0
  95. package/src/cli/setup-cli.ts +6 -2
  96. package/src/cli.ts +42 -65
  97. package/src/commands/acp.ts +1 -1
  98. package/src/commands/daemon.ts +2 -31
  99. package/src/commands/gc.ts +1 -1
  100. package/src/commands/launch.ts +8 -129
  101. package/src/commands/quick-lane.ts +51 -0
  102. package/src/commands/sdk.ts +200 -26
  103. package/src/commands/setup.ts +4 -2
  104. package/src/config/file-lock-gc.ts +4 -1
  105. package/src/config/model-equivalence.ts +76 -7
  106. package/src/config/model-profile-activation.ts +1115 -265
  107. package/src/config/model-profiles.ts +134 -2
  108. package/src/config/model-registry.ts +352 -50
  109. package/src/config/model-resolver.ts +289 -38
  110. package/src/config/models-config-schema.ts +11 -4
  111. package/src/config/provider-selection-policy.ts +146 -0
  112. package/src/config/settings-schema.ts +50 -77
  113. package/src/config/settings.ts +40 -0
  114. package/src/coordinator-mcp/server.ts +32 -2
  115. package/src/edit/renderer.ts +175 -223
  116. package/src/edit/streaming.ts +108 -1
  117. package/src/export/html/index.ts +57 -7
  118. package/src/extensibility/custom-tools/types.ts +2 -0
  119. package/src/extensibility/extensions/compact-handler.ts +3 -2
  120. package/src/extensibility/extensions/runner.ts +6 -0
  121. package/src/extensibility/extensions/types.ts +3 -0
  122. package/src/gjc-runtime/gc-runtime.ts +379 -20
  123. package/src/gjc-runtime/launch-worktree.ts +5 -1
  124. package/src/gjc-runtime/team-runtime.ts +59 -2
  125. package/src/gjc-runtime/tmux-owner-isolation.ts +19 -0
  126. package/src/gjc-runtime/ultragoal-receipt-freshness.ts +16 -1
  127. package/src/internal-urls/docs-index.generated.ts +17 -13
  128. package/src/internal-urls/local-protocol.ts +1 -0
  129. package/src/main.ts +40 -3
  130. package/src/memories/index.ts +4 -2
  131. package/src/modes/acp/acp-agent.ts +235 -91
  132. package/src/modes/components/model-selector.ts +206 -42
  133. package/src/modes/components/provider-order-context.ts +197 -0
  134. package/src/modes/components/provider-order-editor.ts +441 -0
  135. package/src/modes/components/settings-defs.ts +21 -1
  136. package/src/modes/components/settings-selector.ts +45 -2
  137. package/src/modes/components/tool-execution.ts +47 -15
  138. package/src/modes/controllers/command-controller.ts +6 -3
  139. package/src/modes/controllers/extension-ui-controller.ts +2 -0
  140. package/src/modes/controllers/input-controller.ts +73 -2
  141. package/src/modes/controllers/selector-controller.ts +260 -153
  142. package/src/modes/prompt-suggestion-controller.ts +1 -1
  143. package/src/modes/runtime-init.ts +1 -0
  144. package/src/modes/utils/ui-helpers.ts +18 -0
  145. package/src/prompts/tools/browser.md +1 -0
  146. package/src/quick-lane/classify.ts +257 -0
  147. package/src/rlm/index.ts +1 -1
  148. package/src/runtime/stt-settings-setup.ts +57 -0
  149. package/src/sdk/acp/adapter.ts +2 -1
  150. package/src/sdk/broker/broker.ts +780 -12
  151. package/src/sdk/broker/lifecycle.ts +70 -29
  152. package/src/sdk/broker/operation-receipt-ledger.ts +144 -0
  153. package/src/sdk/broker/session-index.ts +463 -48
  154. package/src/sdk/broker/state-version.ts +13 -9
  155. package/src/sdk/broker/transport.ts +14 -1
  156. package/src/sdk/bus/index.ts +34 -13
  157. package/src/sdk/bus/kind-aware-reconciliation.ts +21 -2
  158. package/src/sdk/bus/notification-service.ts +47 -1
  159. package/src/sdk/bus/prompt-reconciliation.ts +22 -3
  160. package/src/sdk/bus/telegram-daemon-contract.ts +4 -1
  161. package/src/sdk/bus/telegram-daemon.ts +54 -3
  162. package/src/sdk/cli/rows.ts +247 -0
  163. package/src/sdk/cli/session-cli.ts +930 -79
  164. package/src/sdk/elevation/allowlist.ts +54 -0
  165. package/src/sdk/elevation/audit.ts +208 -0
  166. package/src/sdk/elevation/capability.ts +41 -0
  167. package/src/sdk/elevation/digest.ts +129 -0
  168. package/src/sdk/elevation/dispatch-receipt.ts +184 -0
  169. package/src/sdk/elevation/grant-ledger.ts +1142 -0
  170. package/src/sdk/elevation/owner.ts +109 -0
  171. package/src/sdk/guides/cache.ts +363 -0
  172. package/src/sdk/guides/catalog.ts +554 -0
  173. package/src/sdk/guides/cli.ts +235 -0
  174. package/src/sdk/guides/manifest.ts +152 -0
  175. package/src/sdk/guides/verify.ts +178 -0
  176. package/src/sdk/host/control/dispatch.ts +49 -1
  177. package/src/sdk/host/control/index.ts +1 -0
  178. package/src/sdk/host/control/operations.ts +8 -1
  179. package/src/sdk/host/query/cursor.ts +47 -3
  180. package/src/sdk/host/query/handlers.ts +155 -2
  181. package/src/sdk/host/sdk-surface-parity.test.ts +1 -0
  182. package/src/sdk/host/session-runtime.test.ts +391 -1
  183. package/src/sdk/host/session-runtime.ts +308 -73
  184. package/src/sdk/host/surface-policy.ts +3 -0
  185. package/src/sdk/host/websocket-transport.ts +7 -1
  186. package/src/sdk/mcp/server.ts +88 -15
  187. package/src/sdk/prompt-status.ts +8 -0
  188. package/src/sdk/protocol/operation-inventory.generated.json +62 -0
  189. package/src/sdk/protocol/operation-registry.ts +3 -2
  190. package/src/sdk/session.ts +87 -39
  191. package/src/sdk/transport/index.ts +1 -0
  192. package/src/sdk/transport/relay.ts +3 -0
  193. package/src/sdk/transport/serve-cli.ts +111 -24
  194. package/src/secrets/obfuscator.ts +92 -12
  195. package/src/session/agent-session.ts +322 -93
  196. package/src/session/blob-store.ts +60 -8
  197. package/src/session/fallback-chain-controller.ts +35 -0
  198. package/src/session/internal/managed-session-scope.ts +25 -3
  199. package/src/session/internal/managed-session-storage.ts +574 -73
  200. package/src/session/internal/session-memory-sidecar.ts +19 -29
  201. package/src/session/session-manager.ts +2166 -743
  202. package/src/session/session-storage.ts +715 -48
  203. package/src/setup/provider-onboarding.ts +19 -3
  204. package/src/setup/provider-presets.json +3 -1
  205. package/src/slash-commands/builtin-registry.ts +85 -3
  206. package/src/stt/downloader.ts +2 -3
  207. package/src/stt/setup.ts +29 -4
  208. package/src/task/executor.ts +22 -18
  209. package/src/task/index.ts +24 -1
  210. package/src/tools/archive-reader.ts +11 -2
  211. package/src/tools/browser/runtime-diagnostics.ts +249 -0
  212. package/src/tools/browser/tab-protocol.ts +4 -0
  213. package/src/tools/browser/tab-supervisor.ts +5 -0
  214. package/src/tools/browser/tab-worker.ts +36 -1
  215. package/src/tools/browser.ts +7 -0
  216. package/src/tools/image-gen.ts +110 -166
  217. package/src/tools/index.ts +2 -0
  218. package/src/tools/read.ts +1 -1
  219. package/src/tools/resource-gc.ts +6 -1
  220. package/src/tools/tool-catalog.generated.ts +5 -1
  221. package/src/utils/pasted-image-path.ts +93 -0
  222. package/src/web/search/index.ts +3 -3
@@ -0,0 +1,163 @@
1
+ import { SDK_STATE_VERSION } from "../broker/state-version";
2
+ import { type ElevationOperation } from "./digest";
3
+ import { type ElevationAnswerAuthority, type ElevationClaimIdentity, type ElevationDispatchOutcome, type ElevationDispatchReceipt } from "./dispatch-receipt";
4
+ import { type BrokerOwnerPrincipal, classifyProcessIncarnationLiveness } from "./owner";
5
+ /**
6
+ * Broker-owned elevation grant ledger.
7
+ *
8
+ * Durable state machine (per elevation request):
9
+ * `requested -> granted -> claimed -> dispatched(outcome)`; terminal
10
+ * `denied`/`expired`/`misused`/`target_unavailable`; crash truth
11
+ * `consumed` (claimed but outcome unknown). Grants are single-use: the claim
12
+ * CAS consumes the grant before dispatch, and a crash between consume and
13
+ * dispatch is replayed truthfully as `consumed` with outcome `unknown`
14
+ * (retry requires a new grant — fail closed).
15
+ *
16
+ * All mutations and reads serialize on one elevation-local
17
+ * `withFileLock` transaction covering grants (`grants.jsonl`), dispatch
18
+ * receipts (`receipts.jsonl`), the issue index (`index.json`), and the
19
+ * audit trail (`audit.jsonl`), so a claim, its receipt, and the issue
20
+ * sequence commit together.
21
+ *
22
+ * The answer boundary is internal operator-only: there is no public
23
+ * `elevation.answer` operation; answers are admitted only from the internal
24
+ * operator attestation, so requester self-approval is impossible by
25
+ * construction.
26
+ */
27
+ export type ElevationGrantState = "requested" | "granted" | "claimed" | "dispatched" | "consumed" | "denied" | "expired" | "misused" | "target_unavailable";
28
+ export interface ElevationSessionIdentity {
29
+ sessionId: string;
30
+ /** Exact endpoint state root bound at issue time; never the repo root. */
31
+ endpointStateRoot: string;
32
+ endpointGeneration: number;
33
+ endpointIncarnation: string;
34
+ }
35
+ /** Audit-only requester binding; never an identity claim. */
36
+ export interface ElevationRequester {
37
+ source: "broker_connection";
38
+ connectionId: string;
39
+ }
40
+ export interface ElevationGrantRecord {
41
+ version: typeof SDK_STATE_VERSION;
42
+ /** Durable correlation ID; UUID, path-safe. */
43
+ elevationRequestId: string;
44
+ /** Monotonic path-safe issue sequence, allocated under the ledger lock. */
45
+ issueIndex: number;
46
+ state: ElevationGrantState;
47
+ operation: ElevationOperation;
48
+ requestDigest: string;
49
+ sessionIdentity: ElevationSessionIdentity;
50
+ principal: BrokerOwnerPrincipal;
51
+ requester: ElevationRequester;
52
+ requestedAt: number;
53
+ expiresAt: number;
54
+ outcome?: ElevationDispatchOutcome;
55
+ ts: number;
56
+ }
57
+ export type ElevationErrorCode = "not_found" | "invalid_input" | "idempotency_conflict" | "grant_spent" | "elevation_claim_in_progress" | "elevation_required" | "elevation_unavailable" | "elevation_not_required" | "endpoint_stale" | "target_unavailable" | "expired" | "misused" | "duplicate_answer" | "terminal_uncertain" | (string & {});
58
+ export type ElevationResult<T> = {
59
+ ok: true;
60
+ value: T;
61
+ } | {
62
+ ok: false;
63
+ error: {
64
+ code: ElevationErrorCode;
65
+ message: string;
66
+ };
67
+ };
68
+ export interface ElevationIssueParams {
69
+ /** Optional caller-supplied correlation ID for idempotent retry; the broker generates a UUID otherwise. */
70
+ elevationRequestId?: string;
71
+ operation: ElevationOperation;
72
+ input: Record<string, unknown>;
73
+ sessionIdentity: ElevationSessionIdentity;
74
+ principal: BrokerOwnerPrincipal;
75
+ requester: ElevationRequester;
76
+ expiresInMs?: number;
77
+ }
78
+ export interface ElevationIssueValue {
79
+ replay: boolean;
80
+ elevationRequestId: string;
81
+ issueIndex: number;
82
+ requestDigest: string;
83
+ state: ElevationGrantState;
84
+ requestedAt: number;
85
+ expiresAt: number;
86
+ grant: ElevationGrantRecord;
87
+ }
88
+ export interface ElevationAnswerParams {
89
+ elevationRequestId: string;
90
+ answer: "approve" | "deny";
91
+ /** Digest the answering surface presented from the gate payload. */
92
+ presentedDigest: string;
93
+ /** Broker-owner principal attesting the answer authority. */
94
+ principal: BrokerOwnerPrincipal;
95
+ answerer: ElevationAnswerAuthority;
96
+ /** Current broker-resolved target identity; undefined means the session is unreachable. */
97
+ currentSessionIdentity?: ElevationSessionIdentity;
98
+ }
99
+ export type ElevationAnswerOutcome = "granted" | "denied" | "expired" | "misused" | "target_unavailable" | "duplicate_answer";
100
+ export interface ElevationAnswerValue {
101
+ outcome: ElevationAnswerOutcome;
102
+ grant: ElevationGrantRecord;
103
+ }
104
+ export interface ElevationClaimParams {
105
+ elevationRequestId: string;
106
+ claimIdentity: ElevationClaimIdentity;
107
+ /** Current broker-resolved target identity; undefined means the session is unreachable. */
108
+ currentSessionIdentity?: ElevationSessionIdentity;
109
+ }
110
+ export interface ElevationClaimValue {
111
+ grant: ElevationGrantRecord;
112
+ receipt: ElevationDispatchReceipt;
113
+ }
114
+ export interface ElevationDispatchParams {
115
+ elevationRequestId: string;
116
+ dispatchIdentity: ElevationClaimIdentity;
117
+ outcome: ElevationDispatchOutcome;
118
+ }
119
+ export interface ElevationDispatchValue {
120
+ grant: ElevationGrantRecord;
121
+ receipt: ElevationDispatchReceipt;
122
+ }
123
+ export interface ElevationReadValue {
124
+ grant: ElevationGrantRecord;
125
+ receipt?: ElevationDispatchReceipt;
126
+ }
127
+ export interface ElevationListValue {
128
+ grants: ElevationReadValue[];
129
+ }
130
+ export interface ElevationLedgerOptions {
131
+ /** Defaults to the GJC_SDK_ELEVATION_ENABLED environment flag. */
132
+ enabled?: boolean;
133
+ /** Request lifetime before the grant expires. */
134
+ ttlMs?: number;
135
+ /** Injectable clock. */
136
+ now?: () => number;
137
+ /**
138
+ * Injectable tri-state process-incarnation liveness classifier (defaults to
139
+ * `classifyProcessIncarnationLiveness`). Test seam for crash-state replay:
140
+ * "unknown" must always fail closed as `elevation_claim_in_progress`.
141
+ */
142
+ classifyLiveness?: typeof classifyProcessIncarnationLiveness;
143
+ }
144
+ declare function isElevationOperation(value: unknown): value is ElevationOperation;
145
+ declare function isElevationGrantRecord(value: unknown): value is ElevationGrantRecord;
146
+ export declare class ElevationLedger {
147
+ #private;
148
+ constructor(agentDir: string, options?: ElevationLedgerOptions);
149
+ get warnings(): readonly string[];
150
+ open(): Promise<this>;
151
+ assertSupportedStateVersions(): Promise<void>;
152
+ issue(params: ElevationIssueParams): Promise<ElevationResult<ElevationIssueValue>>;
153
+ answer(params: ElevationAnswerParams): Promise<ElevationResult<ElevationAnswerValue>>;
154
+ claim(params: ElevationClaimParams): Promise<ElevationResult<ElevationClaimValue>>;
155
+ dispatch(params: ElevationDispatchParams): Promise<ElevationResult<ElevationDispatchValue>>;
156
+ /** Pure read without reconciliation writes; used before actions. */
157
+ get(elevationRequestId: string): Promise<ElevationResult<ElevationReadValue>>;
158
+ /** Truthful read: reconciles expiry and crash-state claims before returning. */
159
+ resolve(elevationRequestId: string, claimIdentity: ElevationClaimIdentity): Promise<ElevationResult<ElevationReadValue>>;
160
+ /** Truthful listing: reconciles every grant before returning. */
161
+ list(claimIdentity: ElevationClaimIdentity): Promise<ElevationResult<ElevationListValue>>;
162
+ }
163
+ export { isElevationGrantRecord, isElevationOperation };
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Broker-owner principal.
3
+ *
4
+ * The elevation authority is the broker itself under the existing loopback
5
+ * trust model: one local OS-user/broker authority derived entirely from
6
+ * broker-owned state, never from caller input. `agentDirUid` is the uid that
7
+ * owns the agent directory, `brokerPid`/`brokerIncarnation` identify the
8
+ * broker process tenure so a restarted broker cannot attest the same
9
+ * authority.
10
+ */
11
+ export interface BrokerOwnerPrincipal {
12
+ kind: "broker_owner";
13
+ owner: {
14
+ agentDirUid: number;
15
+ brokerPid: number;
16
+ brokerIncarnation: string;
17
+ };
18
+ }
19
+ export declare function isBrokerOwnerPrincipal(value: unknown): value is BrokerOwnerPrincipal;
20
+ export declare function sameBrokerOwnerPrincipal(left: BrokerOwnerPrincipal, right: BrokerOwnerPrincipal): boolean;
21
+ /**
22
+ * Reads the broker-owner principal from broker-owned state. Throws when the
23
+ * broker cannot attest a canonical process incarnation (the broker refuses to
24
+ * start in that case anyway), so callers treat a throw as "authority
25
+ * unavailable".
26
+ */
27
+ export declare function readBrokerOwnerPrincipal(agentDir: string, brokerPid: number, brokerIncarnation: string): Promise<BrokerOwnerPrincipal>;
28
+ export type ProcessIncarnationLiveness = "alive" | "dead" | "unknown";
29
+ /**
30
+ * Tri-state liveness of a process incarnation.
31
+ *
32
+ * - `alive`: the pid is running and its current incarnation matches the
33
+ * stored one, so the original process tenure is still live.
34
+ * - `dead`: ESRCH (the pid is provably gone — independent of any persisted
35
+ * incarnation text), or the pid is running under a *different* canonical
36
+ * incarnation (PID reuse), which provably means the original process
37
+ * ended.
38
+ * - `unknown`: the pid is malformed, the persisted or observed incarnation
39
+ * is malformed/undefined, or the current incarnation cannot be read.
40
+ * Unknown never implies death: elevation claims must fail closed with
41
+ * `elevation_claim_in_progress` instead of terminalizing state on
42
+ * unprovable liveness.
43
+ *
44
+ * ESRCH is independent positive death proof: a pid that provably does not
45
+ * exist is dead regardless of the persisted incarnation text, so a corrupt
46
+ * persisted incarnation can never stall recovery forever.
47
+ */
48
+ export declare function classifyProcessIncarnationLiveness(pid: unknown, incarnation: unknown): ProcessIncarnationLiveness;
@@ -0,0 +1,98 @@
1
+ import { SDK_STATE_VERSION } from "../broker/state-version";
2
+ import { type GuideEntryV1, type GuideManifestV1 } from "./manifest";
3
+ import { type GuideVerificationErrorCode } from "./verify";
4
+ /**
5
+ * Verified on-disk cache for trusted advisory guides.
6
+ *
7
+ * Layout under `<agentDir>/sdk/guides/cache/` (mode 0700):
8
+ * meta.json — atomic commit pointer {version, manifestId, sequence, generation, installedAt}
9
+ * meta.json.lock — cross-process install lock (project `withFileLock` convention)
10
+ * generations/<generation>/manifest.json — canonical manifest bytes
11
+ * generations/<generation>/manifest.sig — detached Ed25519 signature
12
+ * generations/<generation>/guides/<sha256> — immutable advisory text
13
+ *
14
+ * A complete generation is written and fsynced before `meta.json` is atomically
15
+ * replaced under the install lock. Readers follow only the committed
16
+ * generation, so an interrupted install cannot expose a new manifest with
17
+ * stale metadata or disturb the previously valid cache.
18
+ */
19
+ export interface GuideCacheMetaV1 {
20
+ version: typeof SDK_STATE_VERSION;
21
+ manifestId: string;
22
+ sequence: number;
23
+ installedAt: number;
24
+ generation: string;
25
+ }
26
+ export interface GuideCacheGuideV1 {
27
+ id: string;
28
+ title: string;
29
+ sha256: string;
30
+ text: string;
31
+ }
32
+ export interface VerifiedGuideCache {
33
+ manifest: GuideManifestV1;
34
+ signatureBytes: Uint8Array;
35
+ meta: GuideCacheMetaV1;
36
+ guides: GuideCacheGuideV1[];
37
+ }
38
+ export type GuideCacheReadResult = {
39
+ ok: true;
40
+ value: VerifiedGuideCache;
41
+ } | {
42
+ ok: false;
43
+ error: {
44
+ code: "missing_cache" | "corrupt_cache" | "expired_cache" | "unsupported_state_version";
45
+ message: string;
46
+ };
47
+ };
48
+ export type GuideCacheInstallResult = {
49
+ ok: true;
50
+ value: VerifiedGuideCache;
51
+ } | {
52
+ ok: false;
53
+ error: {
54
+ code: GuideVerificationErrorCode | "invalid_input" | "io_error";
55
+ message: string;
56
+ };
57
+ };
58
+ export declare function guideCacheDir(agentDir: string): string;
59
+ /**
60
+ * Reads and re-verifies the cache end to end: manifest parse, meta commit
61
+ * record, detached signature, expiry against `now`, and every advisory hash.
62
+ * Any failure is reported as `corrupt_cache` (or `expired_cache` when the
63
+ * signature is valid but stale) and the cache is left untouched — a corrupt
64
+ * entry never destroys the data a future, still-valid install may replace.
65
+ */
66
+ export declare function readGuideCache(params: {
67
+ agentDir: string;
68
+ now: number;
69
+ }): Promise<GuideCacheReadResult>;
70
+ /**
71
+ * Installs a verified manifest plus its advisory content into the cache.
72
+ *
73
+ * Order of operations:
74
+ * 1. Verify the manifest signature, expiry, and every advisory hash before
75
+ * any write — a tampered or expired payload never touches disk.
76
+ * 2. Under the cache's cross-process install lock, enforce the monotonic
77
+ * version floor against the committed meta record (`rollback` when the
78
+ * candidate does not advance the channel).
79
+ * 3. Write and fsync a complete immutable generation, then atomically replace
80
+ * `meta.json` as the only commit pointer.
81
+ *
82
+ * Steps 2–3 are serialized with `<cacheDir>/meta.json.lock` (the project's
83
+ * `withFileLock` convention): the floor is re-read under the same lock that
84
+ * guards the commit pointer replacement, so a concurrent install can never
85
+ * read an older floor, observe a newer commit, and then downgrade the channel.
86
+ * Any failure aborts before the commit, leaving the prior valid cache fully
87
+ * intact and readable.
88
+ */
89
+ export declare function installGuideCache(params: {
90
+ agentDir: string;
91
+ manifest: GuideManifestV1;
92
+ signatureBytes: Uint8Array;
93
+ advisories: readonly {
94
+ entry: GuideEntryV1;
95
+ text: Uint8Array;
96
+ }[];
97
+ now: number;
98
+ }): Promise<GuideCacheInstallResult>;
@@ -0,0 +1,156 @@
1
+ import { type VerifiedGuideCache } from "./cache";
2
+ import { type GuideManifestV1 } from "./manifest";
3
+ /**
4
+ * HTTPS-only, allowlisted, credential-free fetch boundary for advisory guides.
5
+ *
6
+ * The catalog refuses any URL that is not https, whose host is not in the
7
+ * allowlist, whose path is outside the allowlisted prefix, or that carries
8
+ * userinfo. Every request uses `credentials: "omit"`, no authorization or
9
+ * cookie headers, and `redirect: "error"` so a redirect can never escape the
10
+ * allowlist. Responses are bounded by byte caps and a timeout. This boundary
11
+ * is the only network surface of the guide subsystem — advisories are fetched
12
+ * as data, verified against the signed manifest, and never executed.
13
+ */
14
+ export interface GuideFetchAllowlistEntry {
15
+ host: string;
16
+ /** Every fetched path must start with this prefix. */
17
+ pathPrefix: string;
18
+ }
19
+ export declare const GUIDE_FETCH_ALLOWLIST: readonly GuideFetchAllowlistEntry[];
20
+ export declare const GUIDE_FETCH_TIMEOUT_MS = 10000;
21
+ export declare const GUIDE_FETCH_MAX_MANIFEST_BYTES: number;
22
+ export declare const GUIDE_FETCH_MAX_SIGNATURE_BYTES = 1024;
23
+ export declare const GUIDE_FETCH_USER_AGENT = "gajae-code-sdk-guides/1";
24
+ export interface GuideFetchPolicy {
25
+ httpsOnly: true;
26
+ credentials: "omit";
27
+ redirect: "error";
28
+ allowlist: readonly GuideFetchAllowlistEntry[];
29
+ maxManifestBytes: number;
30
+ maxSignatureBytes: number;
31
+ timeoutMs: number;
32
+ userAgent: string;
33
+ }
34
+ export declare function guideFetchPolicy(): GuideFetchPolicy;
35
+ /** True when a URL satisfies the HTTPS allowlist boundary. */
36
+ export declare function isGuideFetchUrlAllowed(url: string): boolean;
37
+ export type GuideFetchErrorCode = "fetch_forbidden" | "fetch_failed" | "oversize" | "timeout" | "network_error" | "invalid_manifest" | "unsupported_version" | (string & {});
38
+ export interface GuideOnlineManifest {
39
+ url: string;
40
+ manifest: GuideManifestV1;
41
+ signatureBytes: Uint8Array;
42
+ fetchedAt: number;
43
+ }
44
+ export type GuideFetchResult = {
45
+ ok: true;
46
+ value: GuideOnlineManifest;
47
+ } | {
48
+ ok: false;
49
+ error: {
50
+ code: GuideFetchErrorCode;
51
+ message: string;
52
+ status?: number;
53
+ };
54
+ };
55
+ /**
56
+ * Fetches the manifest at `url` and its detached signature at `<url>.sig`,
57
+ * bounded by the HTTPS allowlist policy. The manifest is parsed and shape
58
+ * validated here; signature verification and advisory hash checks happen in
59
+ * the caller so a rejected refresh can fall back to cache/bundled.
60
+ */
61
+ export declare function fetchGuideManifestOnline(params: {
62
+ url: string;
63
+ timeoutMs?: number;
64
+ fetchImpl?: typeof fetch;
65
+ now?: number;
66
+ }): Promise<GuideFetchResult>;
67
+ /**
68
+ * Trusted-by-compilation bundled manifests. The seed manifest is signed by the
69
+ * bundled pinned key (`verify.ts`), and every bundled advisory ships its text
70
+ * so fresh-install `list`/`show` work offline with no cache. The seed is
71
+ * selected only when no valid online or cached manifest exists; because the
72
+ * bundled manifest is itself signature-verified at module load, bundling the
73
+ * signature here preserves the normal verify path for bundled content.
74
+ */
75
+ export declare const BUNDLED_GUIDE_MANIFESTS: readonly GuideManifestV1[];
76
+ export type GuideCatalogSource = "online" | "cache" | "bundled";
77
+ export interface GuideCatalogGuideV1 {
78
+ id: string;
79
+ title: string;
80
+ sha256: string;
81
+ /** Advisory text; undefined when the bundled manifest does not ship content for this guide. */
82
+ text: string | undefined;
83
+ }
84
+ export interface GuideCatalogSelection {
85
+ source: GuideCatalogSource;
86
+ manifest: GuideManifestV1;
87
+ guides: GuideCatalogGuideV1[];
88
+ /** Present when the selection is served from (or was installed into) the verified cache. */
89
+ cache?: VerifiedGuideCache;
90
+ /** Online provenance. */
91
+ url?: string;
92
+ fetchedAt?: number;
93
+ /** Non-fatal provenance notes (e.g. an online refresh was rejected and selection fell back). */
94
+ warnings: string[];
95
+ }
96
+ export type GuideCatalogResult = {
97
+ ok: true;
98
+ value: GuideCatalogSelection;
99
+ } | {
100
+ ok: false;
101
+ error: {
102
+ code: string;
103
+ message: string;
104
+ };
105
+ };
106
+ export interface GuideCatalogOptions {
107
+ agentDir: string;
108
+ /** Online manifest URL; undefined disables the network entirely. */
109
+ onlineUrl?: string;
110
+ now?: () => number;
111
+ fetchImpl?: typeof fetch;
112
+ timeoutMs?: number;
113
+ /** Trusted-by-compilation bundled manifests; defaults to `BUNDLED_GUIDE_MANIFESTS`. */
114
+ disableBundled?: boolean;
115
+ }
116
+ /**
117
+ * Advisory guide catalog service.
118
+ *
119
+ * Selection precedence is `valid online -> valid cache -> bundled`: a freshly
120
+ * fetched, verified manifest wins; otherwise the verified cache; otherwise the
121
+ * bundled seed. Verification failures never throw — they surface as warnings
122
+ * (for online) or as selection fallback, and the cache is never destroyed.
123
+ */
124
+ export declare class GuideCatalog {
125
+ #private;
126
+ constructor(options: GuideCatalogOptions);
127
+ /**
128
+ * Fetches, verifies, and installs the online manifest when `onlineUrl` is
129
+ * configured, then selects per the online/cache/bundled precedence. The
130
+ * verified cache is always the source of advisory text for online and
131
+ * cached selections, so a single verified read path serves both.
132
+ */
133
+ refresh(): Promise<GuideCatalogResult>;
134
+ /** Offline selection: verified cache first, then bundled. Never touches the network. */
135
+ load(): Promise<GuideCatalogResult>;
136
+ /**
137
+ * Returns the advisory text for a guide in the currently selected
138
+ * manifest. Advisory text is data only: it is rendered and never executed
139
+ * or applied as configuration.
140
+ */
141
+ advisory(guideId: string): Promise<{
142
+ ok: true;
143
+ value: {
144
+ source: GuideCatalogSource;
145
+ guideId: string;
146
+ title: string;
147
+ text: string;
148
+ };
149
+ } | {
150
+ ok: false;
151
+ error: {
152
+ code: string;
153
+ message: string;
154
+ };
155
+ }>;
156
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * `gjc sdk guides` command family (routing lives in `src/commands/sdk.ts`).
3
+ *
4
+ * Verbs:
5
+ * refresh --url <https url> fetch + verify the online manifest and advisory
6
+ * text, install the verified cache, report selection.
7
+ * Fails operationally (exit 1) whenever the online
8
+ * manifest is not selected: fallback cache/bundled
9
+ * content is reported as a failure, never as a
10
+ * successful refresh
11
+ * list offline selection: verified cache, else bundled
12
+ * show <guideId> render the advisory text for one guide (data only)
13
+ * status selection provenance, cache health, fetch policy
14
+ * trust pinned key ids and the no-credential fetch boundary
15
+ *
16
+ * The subsystem is advisory-text only: it never executes guide content, never
17
+ * mutates configuration, and never accepts or emits credentials. The only
18
+ * state it writes is the verified guide cache during `refresh`.
19
+ */
20
+ export type SdkGuidesCliAction = "refresh" | "list" | "show" | "status" | "trust";
21
+ export interface SdkGuidesCliArgs {
22
+ action?: string;
23
+ /** Guide id for `show`. */
24
+ guideId?: string;
25
+ /** Online manifest URL for `refresh`; must satisfy the HTTPS allowlist. */
26
+ url?: string;
27
+ agentDir?: string;
28
+ /** Bounded fetch timeout for `refresh`. */
29
+ timeoutMs?: number;
30
+ /** Fetch implementation override for `refresh` (test seam); defaults to the global fetch. */
31
+ fetchImpl?: typeof fetch;
32
+ }
33
+ /**
34
+ * Runs the `gjc sdk guides` command family. Exported for command routing from
35
+ * `src/commands/sdk.ts` and for direct service use; the injected `write` /
36
+ * `setExitCode` hooks keep the surface testable without touching stdout or
37
+ * the process exit code.
38
+ */
39
+ export declare function runSdkGuidesCli(args: SdkGuidesCliArgs, writeOutput?: (value: unknown) => void, setExitCode?: (exitCode: 1 | 2) => void): Promise<void>;
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Trusted advisory guide manifest: types, canonical encoding, and parsing.
3
+ *
4
+ * A manifest is a signed, time-boxed bundle of advisory guide bindings. Each
5
+ * entry binds a stable guide id to the SHA-256 digest of its advisory text, so
6
+ * the advisory content can be fetched separately and verified against the
7
+ * signed manifest. Manifests are advisory text only: they never carry
8
+ * instructions to execute or configuration to apply.
9
+ */
10
+ export declare const GUIDES_MANIFEST_VERSION = 1;
11
+ /** Maximum byte length of a single advisory text file. */
12
+ export declare const GUIDE_ADVISORY_MAX_BYTES: number;
13
+ /** Maximum number of guides bound by a single manifest. */
14
+ export declare const GUIDE_MANIFEST_MAX_ENTRIES = 256;
15
+ /** Maximum manifest JSON byte length (enforced at fetch and cache read time). */
16
+ export declare const GUIDE_MANIFEST_MAX_BYTES: number;
17
+ export declare const GUIDE_ID_MAX_LENGTH = 128;
18
+ export declare const GUIDE_TITLE_MAX_LENGTH = 256;
19
+ export interface GuideEntryV1 {
20
+ /** Path-safe, stable guide id, e.g. "troubleshooting/socket". */
21
+ id: string;
22
+ /** Human-readable advisory title. */
23
+ title: string;
24
+ /** Hex SHA-256 of the advisory text bytes; binds content to the signed manifest. */
25
+ sha256: string;
26
+ }
27
+ export interface GuideManifestV1 {
28
+ version: 1;
29
+ /** Stable channel identity the signature binds to; the rollback floor is per manifestId. */
30
+ manifestId: string;
31
+ /** Key id of the pinned Ed25519 public key that detached-signed the canonical manifest bytes. */
32
+ keyId: string;
33
+ /** Monotonic per-manifestId sequence; the cache refuses installs at or below the floor. */
34
+ sequence: number;
35
+ /** Milliseconds since epoch; the manifest is not authoritative before this instant. */
36
+ issuedAt: number;
37
+ /** Milliseconds since epoch; the manifest is not authoritative after this instant. */
38
+ expiresAt: number;
39
+ /** Minimum SDK advisory client version required to consume this manifest. */
40
+ minimumSdkVersion: number;
41
+ guides: GuideEntryV1[];
42
+ }
43
+ /**
44
+ * Deterministic UTF-8 encoding of a guide manifest. Object keys are sorted,
45
+ * separators are compact, and the output is byte-identical for semantically
46
+ * equal manifests regardless of the original JSON formatting. The detached
47
+ * Ed25519 signature is verified over exactly these bytes, so a re-formatted
48
+ * manifest file still verifies while any semantic change breaks the signature.
49
+ */
50
+ export declare function canonicalGuideManifestBytes(manifest: GuideManifestV1): Buffer;
51
+ export type GuideManifestParseResult = {
52
+ ok: true;
53
+ manifest: GuideManifestV1;
54
+ } | {
55
+ ok: false;
56
+ error: {
57
+ code: "invalid_manifest" | "unsupported_version";
58
+ message: string;
59
+ };
60
+ };
61
+ /**
62
+ * Strict shape validation for a parsed manifest value. Fails closed on any
63
+ * out-of-bounds field; a manifest for a newer format version is refused with
64
+ * `unsupported_version` so callers can distinguish "too new" from "malformed".
65
+ */
66
+ export declare function parseGuideManifest(value: unknown): GuideManifestParseResult;
@@ -0,0 +1,66 @@
1
+ import { type GuideEntryV1, type GuideManifestV1 } from "./manifest";
2
+ /**
3
+ * Version of the SDK advisory guide client. Manifests carry a
4
+ * `minimumSdkVersion` compatibility floor; a manifest that requires a newer
5
+ * client is refused (`incompatible`) instead of being partially understood.
6
+ */
7
+ export declare const GUIDE_CLIENT_VERSION = 1;
8
+ /** Ed25519 detached signatures are always exactly 64 bytes. */
9
+ export declare const GUIDE_SIGNATURE_BYTES = 64;
10
+ export interface GuidePinnedKey {
11
+ keyId: string;
12
+ /** DER-encoded SPKI public key, hex. */
13
+ spkiDerHex: string;
14
+ source: "bundled";
15
+ }
16
+ export declare const GUIDE_PINNED_KEYS: readonly GuidePinnedKey[];
17
+ export declare const GUIDE_PINNED_KEY_IDS: readonly string[];
18
+ export type GuideVerificationErrorCode = "invalid_manifest" | "unsupported_version" | "unknown_key" | "corrupt_signature" | "invalid_signature" | "not_yet_valid" | "expired" | "incompatible" | "rollback" | "hash_mismatch" | (string & {});
19
+ export type GuideVerificationResult<T> = {
20
+ ok: true;
21
+ value: T;
22
+ } | {
23
+ ok: false;
24
+ error: {
25
+ code: GuideVerificationErrorCode;
26
+ message: string;
27
+ };
28
+ };
29
+ /** Test-only override: installs an additional trusted key for deterministic tests. */
30
+ export declare function addTestGuidePinnedKey(key: GuidePinnedKey): void;
31
+ /** Test-only override: removes a previously installed test key. */
32
+ export declare function removeTestGuidePinnedKey(keyId: string): void;
33
+ /**
34
+ * Verifies a guide manifest end to end and fails closed on the first broken
35
+ * property. Order matters: identity and tamper checks (unknown key, malformed
36
+ * or mismatched signature) run before temporal and compatibility checks, so a
37
+ * tampered or untrusted manifest is never masked by an expiry message.
38
+ */
39
+ export declare function verifyGuideManifest(params: {
40
+ manifest: GuideManifestV1;
41
+ signatureBytes: Uint8Array;
42
+ now: number;
43
+ }): GuideVerificationResult<{
44
+ keyId: string;
45
+ }>;
46
+ /**
47
+ * Monotonic floor check: a candidate manifest for a channel must strictly
48
+ * advance that channel's sequence, otherwise an older (but still validly
49
+ * signed) manifest is refused as a rollback.
50
+ */
51
+ export declare function guideRollbackCheck(previous: {
52
+ manifestId: string;
53
+ sequence: number;
54
+ } | undefined, candidate: GuideManifestV1): GuideVerificationResult<{
55
+ monotonic: boolean;
56
+ }>;
57
+ export declare function guideAdvisoryDigest(text: Uint8Array): string;
58
+ /**
59
+ * Per-guide SHA-256 binding: the advisory text must match the digest the
60
+ * signed manifest binds for that guide id. This is the tamper check for the
61
+ * advisory payload itself — the manifest signature cannot cover content that
62
+ * is fetched separately, so every advisory is hash-verified against it.
63
+ */
64
+ export declare function verifyGuideAdvisoryText(entry: GuideEntryV1, text: Uint8Array): GuideVerificationResult<{
65
+ sha256: string;
66
+ }>;
@@ -7,6 +7,8 @@ export interface ControlRequest {
7
7
  expectedRevision?: string;
8
8
  idempotencyKey?: string;
9
9
  confirm?: boolean;
10
+ /** Top-level elevation claim selector, preserved from the control frame. */
11
+ elevationRequestId?: string;
10
12
  }
11
13
  export type ControlErrorCode = string;
12
14
  export interface ControlError {
@@ -30,5 +32,11 @@ export declare class TypedControlError extends Error {
30
32
  export declare class BusyError extends TypedControlError {
31
33
  constructor(message?: string);
32
34
  }
35
+ /**
36
+ * Build the typed control request from a wire frame. Every runtime transport
37
+ * mapper uses this helper so the top-level elevation claim selector cannot
38
+ * drift between callsites.
39
+ */
40
+ export declare function controlRequestFromFrame(frame: Record<string, unknown>): ControlRequest;
33
41
  /** Dispatches a registry-defined per-session control operation. */
34
42
  export declare function dispatchControl(surface: ControlSurface, registryRow: Operation | undefined, request: ControlRequest): Promise<ControlResponse>;
@@ -1,2 +1,2 @@
1
- export { BusyError, type ControlError, type ControlErrorCode, type ControlRequest, type ControlResponse, dispatchControl, TypedControlError, } from "./dispatch";
1
+ export { BusyError, type ControlError, type ControlErrorCode, type ControlRequest, type ControlResponse, controlRequestFromFrame, dispatchControl, TypedControlError, } from "./dispatch";
2
2
  export type { ControlInput, ControlSurface, ControlValue } from "./operations";