@quantiya/codevibe-core 2.0.5 → 2.0.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.
Files changed (159) hide show
  1. package/README.md +7 -5
  2. package/dist/agy-cli-contract.d.ts +14 -0
  3. package/dist/appsync/appsync-client.d.ts +59 -31
  4. package/dist/appsync/event-throttle.d.ts +33 -0
  5. package/dist/appsync/index.d.ts +3 -2
  6. package/dist/appsync/queries.d.ts +4 -2
  7. package/dist/auth/auth-telemetry.d.ts +26 -0
  8. package/dist/auth/vendor-key-cli.d.ts +49 -0
  9. package/dist/companion-mode/index.d.ts +36 -22
  10. package/dist/companion-mode/persist-preference.d.ts +1 -5
  11. package/dist/companion-mode/resolve-agent.d.ts +5 -4
  12. package/dist/config/config.d.ts +0 -5
  13. package/dist/credential-broker/__tests__/upstream-result-helpers.d.ts +21 -0
  14. package/dist/credential-broker/broker.d.ts +196 -12
  15. package/dist/credential-broker/chatgpt-config.d.ts +40 -0
  16. package/dist/credential-broker/index.d.ts +4 -1
  17. package/dist/credential-broker/oauth-account-lock.d.ts +104 -0
  18. package/dist/credential-broker/oauth-refresh.d.ts +72 -0
  19. package/dist/credential-broker/types.d.ts +165 -17
  20. package/dist/credential-broker/upstream-client.d.ts +3 -2
  21. package/dist/credential-broker/vendor-key-store.d.ts +32 -1
  22. package/dist/crypto/__tests__/encrypt-for-emit.test.d.ts +1 -0
  23. package/dist/crypto/encrypt-for-emit.d.ts +39 -0
  24. package/dist/crypto/index.d.ts +2 -0
  25. package/dist/daemon/__tests__/process-guards.test.d.ts +1 -0
  26. package/dist/daemon/index.d.ts +2 -0
  27. package/dist/daemon/process-guards.d.ts +38 -0
  28. package/dist/index.d.ts +17 -2
  29. package/dist/index.js +308 -281
  30. package/dist/keychain/keychain-manager.d.ts +25 -4
  31. package/dist/local-executor/__tests__/reviewer-rationale-flag.test.d.ts +1 -0
  32. package/dist/local-executor/class-a-sign.d.ts +15 -0
  33. package/dist/local-executor/group-decision-outcome.d.ts +11 -0
  34. package/dist/local-executor/implementor-argv.d.ts +89 -7
  35. package/dist/local-executor/local-executor-impl.d.ts +18 -7
  36. package/dist/local-executor/merge-conflict-resolve.d.ts +19 -0
  37. package/dist/local-executor/revert-reconcile.d.ts +12 -0
  38. package/dist/local-executor/reviewer-rationale-flag.d.ts +10 -0
  39. package/dist/local-executor/types.d.ts +1 -0
  40. package/dist/local-model/manager.d.ts +1 -1
  41. package/dist/local-model/ollama.d.ts +40 -0
  42. package/dist/orchestration/__tests__/detect-agents.test.d.ts +1 -0
  43. package/dist/orchestration/detect-agents.d.ts +10 -30
  44. package/dist/orchestration/index.d.ts +1 -2
  45. package/dist/orchestration-shell/__tests__/a1a-planner-offers.test.d.ts +1 -0
  46. package/dist/orchestration-shell/__tests__/a6-cli-surface.test.d.ts +1 -0
  47. package/dist/orchestration-shell/__tests__/advisory-attachments-dir-race.test.d.ts +1 -0
  48. package/dist/orchestration-shell/__tests__/advisory-multi-mention-panel.test.d.ts +1 -0
  49. package/dist/orchestration-shell/__tests__/advisory-panel-attachments.test.d.ts +1 -0
  50. package/dist/orchestration-shell/__tests__/advisory-quota-stdout-result.test.d.ts +1 -0
  51. package/dist/orchestration-shell/__tests__/agent-turn-context-batch.test.d.ts +1 -0
  52. package/dist/orchestration-shell/__tests__/bounded-shutdown.test.d.ts +1 -0
  53. package/dist/orchestration-shell/__tests__/brainstorm-quorum-wiring.test.d.ts +1 -0
  54. package/dist/orchestration-shell/__tests__/brainstorm-quorum.test.d.ts +1 -0
  55. package/dist/orchestration-shell/__tests__/cli-team-session-key.test.d.ts +1 -0
  56. package/dist/orchestration-shell/__tests__/command-intent.test.d.ts +1 -0
  57. package/dist/orchestration-shell/__tests__/context-compaction.test.d.ts +1 -0
  58. package/dist/orchestration-shell/__tests__/context-items-hosted-sync.test.d.ts +1 -0
  59. package/dist/orchestration-shell/__tests__/context-items-wiring.test.d.ts +1 -0
  60. package/dist/orchestration-shell/__tests__/context-items.test.d.ts +1 -0
  61. package/dist/orchestration-shell/__tests__/cp8-full-team-events.test.d.ts +1 -0
  62. package/dist/orchestration-shell/__tests__/cp8-team-decomposed-zk.test.d.ts +1 -0
  63. package/dist/orchestration-shell/__tests__/explicit-tty-exit.test.d.ts +1 -0
  64. package/dist/orchestration-shell/__tests__/mention-suggest.test.d.ts +1 -0
  65. package/dist/orchestration-shell/__tests__/route-browse-summarize-recovery.test.d.ts +1 -0
  66. package/dist/orchestration-shell/attachments.d.ts +58 -2
  67. package/dist/orchestration-shell/bounded-shutdown.d.ts +16 -0
  68. package/dist/orchestration-shell/brainstorm-quorum.d.ts +118 -0
  69. package/dist/orchestration-shell/cli.d.ts +97 -70
  70. package/dist/orchestration-shell/cli.js +30990 -22426
  71. package/dist/orchestration-shell/command-intent.d.ts +56 -0
  72. package/dist/orchestration-shell/components/InputBar.d.ts +6 -0
  73. package/dist/orchestration-shell/components/OrchestrationApp.d.ts +2 -0
  74. package/dist/orchestration-shell/context-compaction.d.ts +264 -0
  75. package/dist/orchestration-shell/context-items-hosted-sync.d.ts +19 -0
  76. package/dist/orchestration-shell/context-items.d.ts +408 -0
  77. package/dist/orchestration-shell/context-store.d.ts +162 -0
  78. package/dist/orchestration-shell/emit-shell-event.d.ts +34 -13
  79. package/dist/orchestration-shell/explicit-tty-exit.d.ts +18 -0
  80. package/dist/orchestration-shell/gate-prompts.d.ts +3 -3
  81. package/dist/orchestration-shell/index.d.ts +306 -37
  82. package/dist/orchestration-shell/mention-suggest.d.ts +11 -0
  83. package/dist/orchestration-shell/mode-selection.d.ts +4 -22
  84. package/dist/orchestration-shell/quorum-loop.d.ts +336 -20
  85. package/dist/orchestration-shell/task-progress.d.ts +2 -0
  86. package/dist/orchestration-shell/team-decompose.d.ts +37 -19
  87. package/dist/orchestration-shell/types.d.ts +71 -4
  88. package/dist/planner/index.d.ts +1 -1
  89. package/dist/planner/local-advisory.d.ts +12 -0
  90. package/dist/planner/local-gemma.d.ts +27 -0
  91. package/dist/planner/types.d.ts +7 -0
  92. package/dist/reviewer/index.d.ts +0 -2
  93. package/dist/reviewer/provider.d.ts +9 -6
  94. package/dist/reviewer/providers/antigravity.d.ts +2 -3
  95. package/dist/reviewer/registry.d.ts +9 -4
  96. package/dist/reviewer/token-usage.d.ts +10 -0
  97. package/dist/session/__tests__/device-registration-lease.test.d.ts +1 -0
  98. package/dist/session/__tests__/pending-session-create.test.d.ts +1 -0
  99. package/dist/session/__tests__/session-rekey-fingerprint.test.d.ts +1 -0
  100. package/dist/session/__tests__/session-resume-key-reconciliation.test.d.ts +1 -0
  101. package/dist/session/__tests__/session-resume-pending-first.test.d.ts +1 -0
  102. package/dist/session/device-key-watcher.d.ts +1 -0
  103. package/dist/session/index.d.ts +4 -2
  104. package/dist/session/pending-session-create.d.ts +61 -0
  105. package/dist/session/register-device-key.d.ts +11 -1
  106. package/dist/session/session-rekey.d.ts +4 -5
  107. package/dist/session/session-resume.d.ts +21 -1
  108. package/dist/substrate/docker.d.ts +7 -0
  109. package/dist/substrate/sandbox-exec.d.ts +17 -3
  110. package/dist/substrate/types.d.ts +32 -3
  111. package/dist/substrate-launch/apikey-bootstrap.d.ts +24 -1
  112. package/dist/substrate-launch/engage-substrate.d.ts +17 -0
  113. package/dist/substrate-launch/sanitized-env.d.ts +5 -5
  114. package/dist/tool-activity/__tests__/consolidator.test.d.ts +1 -0
  115. package/dist/tool-activity/__tests__/digest.test.d.ts +1 -0
  116. package/dist/tool-activity/__tests__/flock-rollout-lock.test.d.ts +1 -0
  117. package/dist/tool-activity/__tests__/ledger.test.d.ts +1 -0
  118. package/dist/tool-activity/__tests__/outbox.test.d.ts +1 -0
  119. package/dist/tool-activity/__tests__/replay-cursor.test.d.ts +1 -0
  120. package/dist/tool-activity/__tests__/session-map.test.d.ts +1 -0
  121. package/dist/tool-activity/__tests__/socket-rollout-lock.test.d.ts +1 -0
  122. package/dist/tool-activity/atomic-file.d.ts +27 -0
  123. package/dist/tool-activity/consolidator.d.ts +253 -0
  124. package/dist/tool-activity/digest.d.ts +4 -0
  125. package/dist/tool-activity/flock-rollout-lock.d.ts +68 -0
  126. package/dist/tool-activity/index.d.ts +9 -0
  127. package/dist/tool-activity/ledger.d.ts +274 -0
  128. package/dist/tool-activity/outbox.d.ts +60 -0
  129. package/dist/tool-activity/replay-cursor.d.ts +156 -0
  130. package/dist/tool-activity/session-map.d.ts +133 -0
  131. package/dist/tool-activity/socket-rollout-lock.d.ts +57 -0
  132. package/dist/tool-activity/types.d.ts +368 -0
  133. package/dist/types/encryption.d.ts +4 -0
  134. package/dist/types/events.d.ts +24 -4
  135. package/dist/types/session.d.ts +32 -2
  136. package/package.json +6 -5
  137. package/dist/orchestration/orchestration-cli.d.ts +0 -12
  138. package/dist/orchestration/setup-bootstrap.d.ts +0 -146
  139. package/dist/orchestration/setup-failure-recourse.d.ts +0 -23
  140. package/dist/orchestration/setup-save.d.ts +0 -47
  141. package/dist/orchestration/setup-seat-picker.d.ts +0 -72
  142. package/dist/orchestration/setup-telemetry.d.ts +0 -54
  143. package/dist/orchestration/setup-test-agents.d.ts +0 -108
  144. package/dist/orchestration/setup-types.d.ts +0 -146
  145. package/dist/orchestration/setup-wizard.d.ts +0 -57
  146. package/dist/orchestration-shell/cohort-flag.d.ts +0 -16
  147. package/dist/reviewer/providers/gemini.d.ts +0 -109
  148. /package/dist/{companion-mode/__tests__/detect-parallel.test.d.ts → appsync/__tests__/appsync-client-context-items.test.d.ts} +0 -0
  149. /package/dist/{orchestration-shell/__tests__/cli-stub-session-adapter.test.d.ts → appsync/__tests__/heartbeat-active.test.d.ts} +0 -0
  150. /package/dist/{orchestration/__tests__/setup-bootstrap.test.d.ts → appsync/__tests__/orphan-sweep-null-heartbeat.test.d.ts} +0 -0
  151. /package/dist/{orchestration/__tests__/setup-failure-recourse.test.d.ts → auth/__tests__/vendor-key-cli.test.d.ts} +0 -0
  152. /package/dist/{orchestration/__tests__/setup-save.test.d.ts → companion-mode/__tests__/mode-selected-emit.test.d.ts} +0 -0
  153. /package/dist/{orchestration/__tests__/setup-seat-picker.test.d.ts → companion-mode/__tests__/private-launcher-detection.test.d.ts} +0 -0
  154. /package/dist/{orchestration/__tests__/setup-telemetry.test.d.ts → companion-mode/__tests__/private-launcher-path.test.d.ts} +0 -0
  155. /package/dist/{orchestration/__tests__/setup-test-agents.test.d.ts → credential-broker/__tests__/broker-c4.test.d.ts} +0 -0
  156. /package/dist/{orchestration/__tests__/setup-types.test.d.ts → credential-broker/__tests__/broker-streaming.test.d.ts} +0 -0
  157. /package/dist/{orchestration/__tests__/setup-wizard.test.d.ts → credential-broker/__tests__/chatgpt-config.test.d.ts} +0 -0
  158. /package/dist/{reviewer/providers/__tests__/gemini-live-smoke.test.d.ts → credential-broker/__tests__/oauth-account-lock.test.d.ts} +0 -0
  159. /package/dist/{reviewer/providers/__tests__/gemini.test.d.ts → credential-broker/__tests__/oauth-refresh.test.d.ts} +0 -0
@@ -1,3 +1,5 @@
1
+ import type * as http from "node:http";
2
+ import type { Readable } from "node:stream";
1
3
  /**
2
4
  * The vendor providers Rung 1 brokers. Claude + Codex (Anthropic +
3
5
  * OpenAI) only — Gemini stays out of the substrate (§6 Q4, agy is
@@ -13,13 +15,15 @@ export type BrokerRouteMethod = "POST" | "GET";
13
15
  */
14
16
  export interface BrokerRoute {
15
17
  method: BrokerRouteMethod;
16
- path: "/v1/messages" | "/v1/responses" | "/healthz";
18
+ path: "/v1/messages" | "/v1/responses" | "/healthz" | "/models" | "/v1/models";
17
19
  /** Whether the route requires a valid agent→broker token. */
18
20
  auth: "broker_token" | "none";
19
21
  }
20
22
  /**
21
- * The broker's locked route table — exactly three routes (§3.2). Any
22
- * other method+path → 403.
23
+ * The broker's locked route table (§3.2). Any other method+path → 403.
24
+ * `/models` and `/v1/models` are local compatibility metadata endpoints for
25
+ * Codex CLI provider preflight; they never forward to upstream or require a
26
+ * vendor credential.
23
27
  */
24
28
  export declare const BROKER_ROUTES: readonly BrokerRoute[];
25
29
  /**
@@ -34,8 +38,8 @@ export type BrokerStatus = 200 | 400 | 401 | 403 | 502 | 503;
34
38
  * the §3.2 contract is "everything else → 403", so the type MUST be able
35
39
  * to represent a *disallowed* route for the W1 gateway's `handle()` to be
36
40
  * conformance-testable (send `/v1/admin` / `DELETE` → assert 403). Only
37
- * the three `(method, path)` pairs in `BROKER_ROUTES` are forwarded; every
38
- * other request fails closed at 403.
41
+ * the model POST `(method, path)` pairs in `BROKER_ROUTES` are forwarded;
42
+ * every other request fails closed at 403, except local metadata/health routes.
39
43
  */
40
44
  export interface BrokerRequest {
41
45
  method: string;
@@ -62,7 +66,31 @@ export interface BrokerResponse {
62
66
  status: BrokerStatus;
63
67
  /** Upstream model-bound JSON body on 200; an error envelope otherwise. */
64
68
  body?: unknown;
69
+ /**
70
+ * Discriminant guard (PHASE-643 §3.0): a buffered `BrokerResponse` NEVER
71
+ * carries `kind`. A streamed 200-SSE forward that already wrote to the sink
72
+ * returns {@link BrokerHandled} (`{kind:"handled"}`) instead, so `"kind" in
73
+ * result` narrows the two apart in `handleHttp` (strict-TS valid).
74
+ */
75
+ kind?: never;
76
+ }
77
+ /**
78
+ * PHASE-643 §3.0 — the sentinel a 200-SSE forward returns AFTER it has streamed
79
+ * the response into the caller-provided sink (headers written + body piped). The
80
+ * HTTP adapter must NOT then write a second response; `"kind" in result` narrows
81
+ * this from a {@link BrokerResponse}.
82
+ */
83
+ export interface BrokerHandled {
84
+ readonly kind: "handled";
65
85
  }
86
+ /**
87
+ * PHASE-643 §3.0 — the minimal response surface the broker streams a 200-SSE
88
+ * forward into. `handleHttp` passes the node `http.ServerResponse`; non-HTTP
89
+ * callers pass nothing (buffered fallback). Restricted to the members the
90
+ * streaming write uses (`writeHead`/`headersSent`/`destroy`) plus the writable-
91
+ * stream surface `pipeline()` drives to completion.
92
+ */
93
+ export type ResponseSink = Pick<http.ServerResponse, "writeHead" | "headersSent" | "destroy"> & NodeJS.WritableStream;
66
94
  /**
67
95
  * The lifecycle surface of the per-session local broker daemon (§3.2).
68
96
  * The LE starts one broker per session on `127.0.0.1:<ephemeral>` and
@@ -77,14 +105,72 @@ export interface ModelGatewayBroker {
77
105
  healthz(): Promise<boolean>;
78
106
  /** Handle one model-gateway request (the §3.2 route surface). */
79
107
  handle(req: BrokerRequest): Promise<BrokerResponse>;
108
+ /**
109
+ * PHASE-643 §3.0 — the streaming overload: a 200 `text/event-stream` response
110
+ * is proxied incrementally into `sink` and resolves {@link BrokerHandled};
111
+ * every other disposition (and a 200-SSE WITHOUT a sink) resolves a buffered
112
+ * {@link BrokerResponse}.
113
+ */
114
+ handle(req: BrokerRequest, sink: ResponseSink): Promise<BrokerResponse | BrokerHandled>;
80
115
  /** Tear down; zeroize the in-process upstream credential (§3.3). */
81
116
  stop(): Promise<void>;
82
117
  }
118
+ /**
119
+ * The C4 ChatGPT-subscription OAuth bundle (PHASE-626 §3/§5) — the token
120
+ * material copied out of Codex's `~/.codex/auth.json` `tokens` object plus
121
+ * `last_refresh`. Stored (as JSON) under the SEPARATE keychain account
122
+ * `vendor-oauth-openai`, deliberately distinct from the `vendor-key-openai`
123
+ * (C3) account. Structure pinned against Codex CLI 0.144.4 (§13 OQ-2):
124
+ * `{auth_mode, tokens:{id_token, access_token, refresh_token, account_id}, last_refresh}`.
125
+ */
126
+ export interface VendorOAuthBundle {
127
+ /** OAuth access token — `Authorization: Bearer <access_token>` upstream. */
128
+ access_token: string;
129
+ /** OAuth refresh token — the refresh-engine input; a SECOND secret (§5). */
130
+ refresh_token: string;
131
+ /** ChatGPT account id — the `ChatGPT-Account-Id` header (§13 OQ-1). */
132
+ account_id: string;
133
+ /**
134
+ * RFC3339 timestamp of the last successful refresh (advances on EVERY
135
+ * refresh success — §5 write-through merge rule). Gates the proactive-age
136
+ * threshold. NOT a secret.
137
+ */
138
+ last_refresh: string;
139
+ /** Optional id_token (carried through refreshes; not credential-bearing upstream). */
140
+ id_token?: string;
141
+ }
142
+ /**
143
+ * The credential class resolved by the broker's precedence engine (§5).
144
+ * The raw-string assumption of C1/C2/C3 does NOT extend to C4 — the bundle
145
+ * is a structured secret — so the resolved credential is DISCRIMINATED so
146
+ * every consumer (header builder, self-cred guard, fingerprint, upstream
147
+ * override) is class-aware (§5 "every consumer is class-aware").
148
+ *
149
+ * - `api_key` — C1 `sk-ant-api…` / C3 `sk-…` (raw string).
150
+ * - `subscription_token`— C2 `sk-ant-oat…` (raw string; Bearer-only + C2 beta).
151
+ * - `oauth_bundle` — C4 ChatGPT-subscription bundle (structured).
152
+ */
153
+ export type ResolvedCredential = {
154
+ readonly class: "api_key";
155
+ readonly material: string;
156
+ } | {
157
+ readonly class: "subscription_token";
158
+ readonly material: string;
159
+ } | {
160
+ readonly class: "oauth_bundle";
161
+ readonly material: VendorOAuthBundle;
162
+ };
83
163
  /**
84
164
  * The provider-scoped vendor-key storage API (§3.3) — [NEW], owner W1.
85
165
  * Reuses the existing keychain backend (OS keyring + file fallback).
86
166
  * Signatures only in W0; the implementation (keychain accounts
87
167
  * `vendor-key-<provider>`) lands in W1.
168
+ *
169
+ * PHASE-626 §5 widens this interface with the C4 OAuth-bundle methods +
170
+ * `clearVendorKey` (Stage-2 R1 Codex M-8 / R2 agy M-1). ALL apply the SAME
171
+ * keychain-only fail-closed gate as `get/setVendorKey`, factored through one
172
+ * shared gate helper so the two accounts (`vendor-key-*` / `vendor-oauth-*`)
173
+ * cannot drift.
88
174
  */
89
175
  export interface VendorKeyStore {
90
176
  /**
@@ -96,6 +182,25 @@ export interface VendorKeyStore {
96
182
  getVendorKey(provider: VendorProvider): Promise<string | null>;
97
183
  /** Persist the user's vendor key for `provider` (one-time setup step). */
98
184
  setVendorKey(provider: VendorProvider, key: string): Promise<void>;
185
+ /**
186
+ * Delete the user's C3-class vendor key for `provider` (Stage-2 R1 Codex
187
+ * M-8). Behind the SAME keychain-only gate as `setVendorKey` so `clear
188
+ * --class api-key` has a store-owned, gate-respecting deletion rather than
189
+ * a CLI-side keychain reach-around. Returns true iff a key was removed.
190
+ */
191
+ clearVendorKey(provider: VendorProvider): Promise<boolean>;
192
+ /**
193
+ * Read the C4 OAuth bundle for `provider` (§5). Same keychain-only gate as
194
+ * `getVendorKey`: `null` on the file backend (fail closed, no plaintext read).
195
+ */
196
+ getVendorOAuthBundle(provider: VendorProvider): Promise<VendorOAuthBundle | null>;
197
+ /**
198
+ * Persist the C4 OAuth bundle for `provider` as ONE atomic whole-bundle
199
+ * `setPassword` (§7 no torn tuple). Same keychain-only gate as `setVendorKey`.
200
+ */
201
+ setVendorOAuthBundle(provider: VendorProvider, bundle: VendorOAuthBundle): Promise<void>;
202
+ /** Delete the C4 OAuth bundle for `provider`. Returns true iff one was removed. */
203
+ clearVendorOAuthBundle(provider: VendorProvider): Promise<boolean>;
99
204
  }
100
205
  /**
101
206
  * The agent→broker token (§3.3): per-session, broker-minted, opaque,
@@ -109,17 +214,47 @@ export interface BrokerToken {
109
214
  readonly expiresAtMs: number;
110
215
  }
111
216
  /**
112
- * The result of a broker→vendor upstream call. The broker maps upstream
113
- * status to the agent-facing `BrokerStatus` (§3.2): an upstream 401/403
114
- * (bad/expired vendor key) → 502 (NOT a pass-through), every other status
115
- * carries through.
217
+ * The result of a broker→vendor upstream call (PHASE-643 §3.1). The client
218
+ * resolves at HEADERS — `status` + lowercased `headers` are known before the
219
+ * body is read — and the body is then consumed EXACTLY ONCE: either incrementally
220
+ * as a stream (the 200-SSE forward, §3.3) OR fully-buffered as text (every other
221
+ * disposition, §3.2). Both consumers are abortable by `stop()` (LOCK #643-2). The
222
+ * broker maps upstream status to the agent-facing `BrokerStatus` (§3.2): an
223
+ * upstream 401/403 (bad/expired vendor key) → 502 (NOT a pass-through), every
224
+ * other status carries through.
225
+ *
226
+ * LOCK #643-1 — one-shot body: `bodyStream()` and `readText()` are mutually
227
+ * exclusive AND single-use; a second or mixed call THROWS. This eliminates the
228
+ * dual-model ambiguity (a buffered `.body` alongside a stream) the phase closes.
116
229
  */
117
- export interface UpstreamResponse {
118
- /** Raw upstream HTTP status. */
230
+ export interface UpstreamResult {
231
+ /** Raw upstream HTTP status (known at headers, before the body is read). */
119
232
  status: number;
120
- /** Parsed JSON body (model-bound). */
121
- body?: unknown;
233
+ /** Upstream response headers with LOWERCASED keys (e.g. `content-type`). */
234
+ headers: Readonly<Record<string, string>>;
235
+ /**
236
+ * Consume the body ONCE as a Node stream — the 200-SSE incremental-forward
237
+ * path (§3.3). Destroying the returned stream cancels the upstream fetch. XOR
238
+ * with {@link readText} (LOCK #643-1).
239
+ */
240
+ bodyStream(): Readable;
241
+ /**
242
+ * Consume the body ONCE as fully-buffered text — every non-streamed
243
+ * disposition (non-SSE 200, any non-200, a 401 drain; §3.2). Has its OWN
244
+ * full-read timeout AND composes the broker abort signal, so a stalled read
245
+ * cancels immediately. XOR with {@link bodyStream} (LOCK #643-1).
246
+ */
247
+ readText(): Promise<string>;
122
248
  }
249
+ /**
250
+ * @deprecated PHASE-643 renamed `UpstreamResponse` → {@link UpstreamResult}. The
251
+ * alias preserves the exported SYMBOL for type importers, but NOT the legacy
252
+ * `{status, body?}` SHAPE — implementors of {@link UpstreamClient.post} MUST
253
+ * migrate to the one-shot body surface (a TS implementor of the old shape fails
254
+ * to compile; a declared SemVer-major break — core 2.0 ships on the `@next`
255
+ * channel and every implementor is in-repo).
256
+ */
257
+ export type UpstreamResponse = UpstreamResult;
123
258
  /**
124
259
  * The broker→vendor upstream HTTP client (§3.3/§3.4). INJECTED so W1 tests
125
260
  * use a stub (no real network). The real fetch-backed client lands when
@@ -129,13 +264,26 @@ export interface UpstreamClient {
129
264
  /**
130
265
  * POST the canonical request upstream. `headers` already includes the
131
266
  * synthesized vendor/version headers AND the injected upstream
132
- * credential (the caller adds the credential header). Resolves with the
133
- * upstream status + body; rejects only on a transport/network error
134
- * (which the broker maps to its forward-error path).
267
+ * credential (the caller adds the credential header). Resolves at HEADERS
268
+ * with the upstream status + lowercased headers; the body is consumed ONCE
269
+ * via {@link UpstreamResult.bodyStream}/{@link UpstreamResult.readText}
270
+ * (PHASE-643 §3.1). Rejects only on a transport/network error (which the
271
+ * broker maps to its forward-error path).
272
+ *
273
+ * PHASE-626 §5 stop-lifecycle (Stage-2 R4 Codex #1): `signal` is the
274
+ * SECOND pinned-interface widening (alongside the new `VendorKeyStore`
275
+ * methods). The broker owns the outer credential-bearing frame, so it
276
+ * MUST be able to abort the in-flight model-forward on `stop()` drain-
277
+ * timeout — registering only `FetchUpstreamClient`'s PRIVATE timeout
278
+ * controller is unreachable from the broker. `FetchUpstreamClient`
279
+ * composes this broker signal with its internal timeout controller so
280
+ * either can abort the request. Optional so the W1 stub + older callers
281
+ * still satisfy the interface.
135
282
  */
136
283
  post(args: {
137
284
  url: string;
138
285
  headers: Readonly<Record<string, string>>;
139
286
  body: unknown;
140
- }): Promise<UpstreamResponse>;
287
+ signal?: AbortSignal;
288
+ }): Promise<UpstreamResult>;
141
289
  }
@@ -1,4 +1,4 @@
1
- import type { UpstreamClient, UpstreamResponse } from "./types";
1
+ import type { UpstreamClient, UpstreamResult } from "./types";
2
2
  /**
3
3
  * The production fetch-backed {@link UpstreamClient}. Constructed once per
4
4
  * broker session by the LE and injected into `LocalModelGatewayBroker`
@@ -16,5 +16,6 @@ export declare class FetchUpstreamClient implements UpstreamClient {
16
16
  url: string;
17
17
  headers: Readonly<Record<string, string>>;
18
18
  body: unknown;
19
- }): Promise<UpstreamResponse>;
19
+ signal?: AbortSignal;
20
+ }): Promise<UpstreamResult>;
20
21
  }
@@ -1,4 +1,4 @@
1
- import type { VendorKeyStore, VendorProvider } from "./types";
1
+ import type { VendorKeyStore, VendorOAuthBundle, VendorProvider } from "./types";
2
2
  /**
3
3
  * Keychain-backed implementation of {@link VendorKeyStore} (§3.3). Reads
4
4
  * the same keychain service the rest of CodeVibe uses (`getConfig()
@@ -51,4 +51,35 @@ export declare class KeychainVendorKeyStore implements VendorKeyStore {
51
51
  * per-session into broker memory.
52
52
  */
53
53
  setVendorKey(provider: VendorProvider, key: string): Promise<void>;
54
+ /**
55
+ * Delete the C3-class vendor key (Stage-2 R1 Codex M-8). Behind the SAME
56
+ * keychain-only gate as `setVendorKey`: on the file backend it FAILS CLOSED
57
+ * (throws, does NOT delete from `~/.codevibe`) rather than silently touching
58
+ * the plaintext store. Returns true iff a key was actually removed.
59
+ */
60
+ clearVendorKey(provider: VendorProvider): Promise<boolean>;
61
+ /**
62
+ * Read the C4 OAuth bundle (§5). KEYCHAIN-ONLY on the read side exactly like
63
+ * `getVendorKey`: on the file backend returns `null` (fail closed, no
64
+ * plaintext read) so a legacy / manually-placed bundle is never sourced.
65
+ * A corrupted (non-JSON) stored value is treated as absent (`null`) — the
66
+ * broker then fails closed rather than trusting a torn value.
67
+ */
68
+ getVendorOAuthBundle(provider: VendorProvider): Promise<VendorOAuthBundle | null>;
69
+ /**
70
+ * Persist the C4 OAuth bundle as ONE atomic whole-bundle `setPassword`
71
+ * (§7 — no torn tuple: access/refresh/account_id/last_refresh are written
72
+ * together or not at all). Same keychain-only gate as `setVendorKey`: FAILS
73
+ * CLOSED on the file backend. The token material is never logged.
74
+ */
75
+ setVendorOAuthBundle(provider: VendorProvider, bundle: VendorOAuthBundle): Promise<void>;
76
+ /**
77
+ * Delete the C4 OAuth bundle. Behind the SAME keychain-only gate: on the
78
+ * file backend it FAILS CLOSED (throws). Returns true iff one was removed.
79
+ * Clearing the bundle is a revocation — the broker must hold the §5 cross-
80
+ * process OAuth-account lock around this call so a concurrent refresh can
81
+ * not resurrect it (revocation wins); the store method itself is the
82
+ * gate-respecting primitive the locked caller uses.
83
+ */
84
+ clearVendorOAuthBundle(provider: VendorProvider): Promise<boolean>;
54
85
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,39 @@
1
+ /**
2
+ * The on-wire shape a companion emits to AppSync `createEvent`.
3
+ */
4
+ export interface EncryptedEmitPayload {
5
+ content: string;
6
+ metadata: any;
7
+ isEncrypted: boolean;
8
+ }
9
+ /**
10
+ * (#638) Decide how a mobile-visible event should be emitted.
11
+ *
12
+ * Returns the on-wire `{ content, metadata, isEncrypted }`:
13
+ * - encryption state UNRESOLVED (`encryptionResolved === false`) → returns `null`:
14
+ * the caller MUST drop the event (FAIL-CLOSED). Until resumeOrCreateSession has
15
+ * set the session's encryption state we do NOT yet know whether the session is
16
+ * encrypted, and `sessionKey` may still be a STALE prior-session key — so
17
+ * treat unknown as encrypted and never emit plaintext. (#638 F1: closes the
18
+ * plaintext-for-encrypted RACE where a hook event landing during the bootstrap
19
+ * await, or a transient/generic resume error, left `sessionIsEncrypted=false`
20
+ * and leaked cleartext.)
21
+ * - `sessionKey` present → AES-256-GCM ciphertext + `{ encrypted: <meta> }`
22
+ * (isEncrypted=true). A `null`/`undefined` `plainMetadata` passes through
23
+ * untouched (some hook events carry none) — matching the shape mobile expects.
24
+ * - CONFIRMED unencrypted/legacy session (resolved, no key AND `sessionIsEncrypted`
25
+ * false) → plaintext (isEncrypted=false).
26
+ * - session IS encrypted but keyless (`sessionIsEncrypted && !sessionKey`) →
27
+ * returns `null`: the caller MUST drop the event (FAIL-CLOSED). Emitting
28
+ * cleartext for an encrypted session is the confidentiality regression #638
29
+ * exists to close. Routing every emit site through this ONE chokepoint means a
30
+ * newly-added site cannot silently regress it.
31
+ *
32
+ * `encryptionResolved` defaults to `true` so existing 4-arg call sites (and every
33
+ * emit path whose session identity is already resolved) behave exactly as before;
34
+ * only a caller that can emit DURING session bootstrap needs to thread the flag.
35
+ *
36
+ * Pure: no logging, no I/O, no side effects. Callers own the drop log so the
37
+ * fail-closed decision is never silent.
38
+ */
39
+ export declare function encryptForEmit(sessionKey: string | null, sessionIsEncrypted: boolean, plaintext: string, plainMetadata: any, encryptionResolved?: boolean): EncryptedEmitPayload | null;
@@ -1 +1,3 @@
1
1
  export { CryptoService, cryptoService, CryptoError, ENCRYPTION_VERSION } from './crypto-service';
2
+ export { encryptForEmit } from './encrypt-for-emit';
3
+ export type { EncryptedEmitPayload } from './encrypt-for-emit';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export { installDaemonProcessGuards, isNetworkClass, } from './process-guards';
2
+ export type { DaemonGuardLogger, DaemonProcessGuardOptions, } from './process-guards';
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Minimal structural logger — every plugin's `createLogger(...)` Logger satisfies
3
+ * it, and so does any object with an `error(message, data?)` method.
4
+ */
5
+ export interface DaemonGuardLogger {
6
+ error(message: string, data?: any): void;
7
+ }
8
+ export interface DaemonProcessGuardOptions {
9
+ /**
10
+ * Invoked for a genuinely fatal (non-network-class) `uncaughtException`. A
11
+ * plugin passes its existing graceful-shutdown fn here. When omitted, the guard
12
+ * falls back to `process.exit(1)` so a fatal fault still terminates the daemon.
13
+ */
14
+ onFatal?: (error: Error) => void;
15
+ }
16
+ /**
17
+ * True when `err`'s `code` or `message` matches a known transient network-class
18
+ * signature.
19
+ */
20
+ export declare function isNetworkClass(err: unknown): boolean;
21
+ /**
22
+ * Install the shared daemon process guards.
23
+ *
24
+ * Both handlers are SYMMETRIC (#638 F6): a network-class fault is transient — the
25
+ * AppSync two-phase reconnect heals it — so log and CONTINUE; anything else is a
26
+ * genuinely-unexpected (programmer/app) fault that could leave a corrupted daemon
27
+ * lying ACTIVE (a2's heartbeat re-asserts `status: ACTIVE`), so treat it as fatal
28
+ * and hand off to `opts.onFatal` (a clean shutdown incl. INACTIVE) or `process.exit(1)`.
29
+ *
30
+ * - `unhandledRejection` → network-class → log + CONTINUE; otherwise fatal. EXPECTED
31
+ * transient app/GraphQL rejections are handled AT their emit source with `.catch()`
32
+ * (audited across the plugins), so they never reach here — only a truly-unhandled
33
+ * programmer-bug rejection is fatal. This is intentionally symmetric with
34
+ * `uncaughtException`: before #638 an unhandledRejection was ALWAYS non-fatal, which
35
+ * masked a corrupted daemon that kept advertising connected.
36
+ * - `uncaughtException` → network-class → log + CONTINUE; otherwise fatal.
37
+ */
38
+ export declare function installDaemonProcessGuards(logger: DaemonGuardLogger, opts?: DaemonProcessGuardOptions): void;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,13 @@
1
1
  export { KeychainManager, keychainManager, KeychainError } from './keychain';
2
2
  export { CryptoService, cryptoService, CryptoError, ENCRYPTION_VERSION } from './crypto';
3
+ export { encryptForEmit } from './crypto';
4
+ export type { EncryptedEmitPayload } from './crypto';
5
+ export { installDaemonProcessGuards, isNetworkClass } from './daemon';
6
+ export type { DaemonGuardLogger, DaemonProcessGuardOptions } from './daemon';
3
7
  export { AppSyncClient, AppSyncGraphQLError, DownloadUrlResponse } from './appsync';
4
8
  export { queries, mutations, subscriptions } from './appsync';
9
+ export { isPersistedEventResult } from './appsync';
10
+ export type { PutContextItemInput } from './appsync';
5
11
  export { AuthService, authService } from './auth';
6
12
  export { bindOAuthServer, PRIMARY_PORT, PORT_RANGE_SIZE } from './auth';
7
13
  export { runAuthCli } from './auth';
@@ -14,7 +20,7 @@ export { parseInteractivePrompt, normalizeSnapshot, } from './prompt-parser';
14
20
  export type { ParsedInteractivePrompt, PromptKind, InteractivePromptOption, } from './prompt-parser';
15
21
  export { resumeOrCreateSession, prepareSessionEncryption, rekeySessionForNewDevices, startDeviceKeyWatcher, registerDeviceEncryptionKey, prepareEventTimestamp, _resetPrepareEventTimestampForTesting, } from './session';
16
22
  export type { ResumeOrCreateSessionInput, ResumeOrCreateSessionResult } from './session';
17
- export { detectInstalledAgents, pushDetectedAgents, applyPerSessionOrchestrationOverride, runOrchestrationCli, V1_ORCHESTRATION_PROMPT_KIND, V1_ORCHESTRATION_OPTIONS, mapOptionNumberToUserDecisionKind, mapOptionToUserDecisionKind, } from './orchestration';
23
+ export { detectInstalledAgents, pushDetectedAgents, V1_ORCHESTRATION_PROMPT_KIND, V1_ORCHESTRATION_OPTIONS, mapOptionNumberToUserDecisionKind, mapOptionToUserDecisionKind, } from './orchestration';
18
24
  export type { DetectableAgent, V1OrchestrationOption, V1UserDecisionKind, } from './orchestration';
19
25
  export * as Reviewer from './reviewer';
20
26
  export * as AuditKeys from './audit-keys';
@@ -27,7 +33,16 @@ export * as Continuation from './continuation';
27
33
  export * as StructuralSummary from './structural-summary';
28
34
  export { runOrchestrationShell } from './orchestration-shell';
29
35
  export { runCompanionMode } from './companion-mode';
30
- export { pickMode, TierError } from './orchestration-shell';
36
+ export { pickMode } from './orchestration-shell';
31
37
  export { emitShellEvent, createShellEventEmitter } from './orchestration-shell';
32
38
  export { processMarkers, withRoleMarker } from './orchestration-shell';
39
+ export { ToolActivityOutbox, type ToolActivityOutboxOptions, type ListPendingResult, } from './tool-activity';
40
+ export { ToolActivityLedger, LedgerEntrySchema, LedgerFileSchema, LegacyOwnedFileSchema, type LedgerEntry, type LedgerFile, type LegacyOwnedFile, type OccurrenceRef, type ToolActivityLedgerOptions, } from './tool-activity';
41
+ export { ToolReplayCursor, ReplayCursorStateSchema, type ReplayCursorState, type ReplayFrame, type ReadFramesResult, type ToolReplayCursorOptions, } from './tool-activity';
42
+ export { ToolActivitySessionMap, InProcessRolloutLock, SessionMapRecordSchema, type RolloutLock, type RolloutOwnership, type SessionMapRecord, type ToolActivitySessionMapOptions, } from './tool-activity';
43
+ export { ToolActivityConsolidator, isSessionKeyStaleError, type ObservedOccurrence, type ObserveDisposition, type ToolActivityTransport, type ToolActivityConsolidatorOptions, } from './tool-activity';
44
+ export { SocketRolloutLock, type SocketRolloutLockOptions, FlockRolloutLock, type FlockRolloutLockOptions, type FlockSyncFn, type FlockFlag, createRolloutLock, type CreateRolloutLockOptions, } from './tool-activity';
45
+ export { ToolActivityOccurrenceSchema, ToolActivityDetailSchema, ToolActivityGroupSchema, ToolActivityManifestSchema, ToolActivityOutboxEnvelopeSchema, type ToolActivityOccurrence, type ToolActivityDetail, type ToolActivityGroup, type ToolActivityManifest, type ToolActivityOutboxEnvelope, } from './tool-activity';
46
+ export { digestOf, stableStringify } from './tool-activity';
47
+ export { CONTEXT_SESSION_PSEUDO_TASK_NAMESPACE, deriveSessionPseudoTaskId, auditPartitionTaskIdFor, buildContextItemWireRow, decryptContextItemWireRow, type ContextItem, type ContextItemWireRow, } from './orchestration-shell';
33
48
  export type { Mode, Tier, PlannerDecision, AgentKind, PlannerHealthState, OrchestrationState, OrchestrationAction, ConversationEntry, RunningTaskState, ReviewerSeatState, GateState, ExecutionEventEntry, RefusalEventEntry, BypassEventEntry, MobileEventEntry, EventStreamEntry, QueuedTask, PendingClarification, LastModeFile, } from './orchestration-shell';