@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
package/README.md CHANGED
@@ -1,13 +1,15 @@
1
1
  # @quantiya/codevibe-core
2
2
 
3
- Core library for CodeVibe plugins — shared keychain, crypto, AppSync, authentication, session lifecycle, and network-resilience functionality. Used by [`@quantiya/codevibe-claude-plugin`](https://www.npmjs.com/package/@quantiya/codevibe-claude-plugin), [`@quantiya/codevibe-gemini-plugin`](https://www.npmjs.com/package/@quantiya/codevibe-gemini-plugin), and [`@quantiya/codevibe-codex-plugin`](https://www.npmjs.com/package/@quantiya/codevibe-codex-plugin).
3
+ Core library for CodeVibe plugins — shared keychain, crypto, AppSync,
4
+ authentication, session lifecycle, and network-resilience functionality. Used
5
+ by the Claude, Codex, and Antigravity Companion plugins.
4
6
 
5
- **Current version:** `1.0.3`
7
+ **Current 2.x candidate:** `2.0.7` (`next`; 1.x remains `latest` until promotion)
6
8
 
7
9
  ## Installation
8
10
 
9
11
  ```bash
10
- npm install @quantiya/codevibe-core
12
+ npm install @quantiya/codevibe-core@next
11
13
  ```
12
14
 
13
15
  ## Features
@@ -40,8 +42,8 @@ codevibe status
40
42
  # Reset device identity (destructive - old sessions become inaccessible)
41
43
  codevibe reset-device
42
44
 
43
- # Use specific environment
44
- codevibe --env development login
45
+ # Use a non-production development environment
46
+ ENVIRONMENT=development codevibe login
45
47
  ```
46
48
 
47
49
  ## API Usage
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Shared Antigravity 1.1.2 CLI constraints.
3
+ *
4
+ * Agy no longer accepts a one-shot prompt on stdin. The prompt must therefore
5
+ * be one argv value, which is both process-list-visible and subject to the
6
+ * platform's per-argument exec limit. Keep one conservative cross-platform
7
+ * ceiling for every Agy spawn surface and fail closed rather than truncating.
8
+ */
9
+ export declare const AGY_ARG_PROMPT_MAX_UTF8_BYTES: number;
10
+ export declare function validateAgyArgPrompt(prompt: string | undefined, context: string): string;
11
+ /** Redact every Agy `--print` value before audit, shell metadata, or logging. */
12
+ export declare function redactAgyPrintArgv(argv: readonly string[]): string[];
13
+ /** Remove Agy prompt values from an error detail before it crosses a boundary. */
14
+ export declare function redactAgyPrintValuesFromText(text: string, argv: readonly string[]): string;
@@ -76,6 +76,19 @@ export interface TaskGroupStatusResult {
76
76
  status: string;
77
77
  haltReason?: string;
78
78
  }
79
+ /**
80
+ * A1e hosted blind-hold upload input. These are the ONLY client-supplied
81
+ * plaintext fields permitted by the shared-context ZK boundary. `expiresAt`
82
+ * is intentionally absent: AppSync derives it from the authoritative Session
83
+ * row so a stale/offline desktop cannot extend retention.
84
+ */
85
+ export interface PutContextItemInput {
86
+ sessionId: string;
87
+ seq: string;
88
+ taskId?: string;
89
+ trackId?: string;
90
+ ciphertext: string;
91
+ }
79
92
  /**
80
93
  * PHASE-CP-1-F.1 Part A (LOCK L2) — tolerant `AWSJSON!` object read.
81
94
  *
@@ -186,6 +199,12 @@ export declare class AppSyncGraphQLError extends Error {
186
199
  path?: unknown;
187
200
  });
188
201
  }
202
+ export type AppSyncAuthenticationFailureKind = 'refresh_auth_rejected' | 'refresh_network';
203
+ /** A foreground GraphQL 401 that token refresh could not recover. */
204
+ export declare class AppSyncAuthenticationError extends Error {
205
+ readonly kind: AppSyncAuthenticationFailureKind;
206
+ constructor(kind: AppSyncAuthenticationFailureKind);
207
+ }
189
208
  /**
190
209
  * PHASE-CP-10-MIN (#585) §2.3 — the parsed cross-device applyUserDecision
191
210
  * echo. Mirrors the quorum-core SDK's `UserDecisionAppliedEvent`
@@ -225,19 +244,16 @@ export declare function shouldDeliverSubscribedEvent(event: Pick<Event, 'source'
225
244
  * Discriminator for the most recent `authenticateWithStoredTokens()`
226
245
  * failure. Lets callers distinguish a genuine "no tokens / refresh
227
246
  * rejected" outcome from a transient network failure during the
228
- * Cognito refresh-token POST.
247
+ * Cognito refresh-token POST, or a credential-store failure that prevented
248
+ * the token read from completing.
229
249
  *
230
250
  * Stage 2 round-1 Codex M1: the production refresh path returns
231
251
  * `false` on every error (including network blow-ups inside
232
- * `callCognitoRefresh`'s catch block), so the wizard's auth-vs-network
233
- * heuristic — which only ran on caught throws — never fired in
234
- * production. Recording the kind on every false-return path lets
235
- * `setup-bootstrap.ts:defaultClientFactory()` route network-shaped
236
- * refresh failures to `subscription_status_network` (per §6 row
237
- * "transient 5xx during refresh") instead of misleading the user with
238
- * a "not signed in" abort.
252
+ * `callCognitoRefresh`'s catch block). Recording the kind on every
253
+ * false-return path lets CLI callers distinguish a transient network
254
+ * failure from a genuine sign-in rejection.
239
255
  */
240
- export type AuthFailureKind = 'no_tokens' | 'refresh_auth_rejected' | 'refresh_network';
256
+ export type AuthFailureKind = 'no_tokens' | 'refresh_auth_rejected' | 'refresh_network' | 'credential_storage_unavailable';
241
257
  /**
242
258
  * AppSync GraphQL client with WebSocket subscriptions
243
259
  */
@@ -250,8 +266,7 @@ export declare class AppSyncClient {
250
266
  private activeSubscriptions;
251
267
  /**
252
268
  * Set by `authenticateWithStoredTokens()` on every false-return path
253
- * (and reset to `null` on success). Read by callers (e.g., the
254
- * wizard's `defaultClientFactory`) to discriminate auth-rejection
269
+ * (and reset to `null` on success). Read by callers to discriminate auth-rejection
255
270
  * vs network-failure without re-running the auth call. Stage 2
256
271
  * round-1 Codex M1.
257
272
  */
@@ -288,23 +303,16 @@ export declare class AppSyncClient {
288
303
  * `authenticateWithStoredTokens()` failure, or `null` if the call
289
304
  * succeeded (or has never been called).
290
305
  *
291
- * Stage 2 round-1 Codex M1. Callers (today: `setup-bootstrap.ts
292
- * :defaultClientFactory`) use this to distinguish network blow-ups
306
+ * Stage 2 round-1 Codex M1. Callers use this to distinguish network blow-ups
293
307
  * during the Cognito refresh-token POST from genuine auth
294
- * rejections. The wizard maps `'refresh_network'` to
295
- * `subscription_status_network` (don't tell a signed-in user to
296
- * re-login when their tokens are valid and the network is broken)
297
- * and the other two kinds to `not_signed_in` (preserves
298
- * pre-Codex-M1 behavior).
308
+ * Credential-storage failure remains distinct because re-authentication
309
+ * cannot repair a locked or unavailable keyring.
299
310
  */
300
311
  getLastAuthFailureKind(): AuthFailureKind | null;
301
312
  /**
302
313
  * Heuristic — does the error message look like a transient network
303
- * failure rather than an auth-token rejection? Mirrors
304
- * `setup-bootstrap.ts:isNetworkLikeError` byte-for-byte so the same
305
- * classifier runs both inside the client (for refresh-path
306
- * discrimination) and at the bootstrap boundary (for caught-throw
307
- * routing). Stage 2 round-1 Codex M1.
314
+ * failure rather than an auth-token rejection? Used for refresh-path
315
+ * discrimination. Stage 2 round-1 Codex M1.
308
316
  */
309
317
  private static isNetworkLikeMessage;
310
318
  /**
@@ -372,6 +380,13 @@ export declare class AppSyncClient {
372
380
  * Create a session
373
381
  */
374
382
  createSession(input: CreateSessionInput): Promise<Session>;
383
+ /**
384
+ * Blind-hold one canonical ContextItem. The mutation is idempotent only for
385
+ * an exact ciphertext+routing replay; a conflicting rewrite is rejected by
386
+ * the backend and therefore throws here, leaving the local durable outbox
387
+ * available for retry/diagnosis.
388
+ */
389
+ putContextItem(input: PutContextItemInput): Promise<void>;
375
390
  /**
376
391
  * Update a session
377
392
  */
@@ -402,6 +417,8 @@ export declare class AppSyncClient {
402
417
  agentType: string;
403
418
  status: string;
404
419
  lastHeartbeatAt: string | null;
420
+ createdAt: string | null;
421
+ updatedAt: string | null;
405
422
  }>>;
406
423
  /**
407
424
  * Mark stale ACTIVE sessions of a given agentType INACTIVE so they
@@ -409,19 +426,20 @@ export declare class AppSyncClient {
409
426
  * startup to clean up after daemons that died without running their
410
427
  * graceful shutdown (crash, auth-loop death, force-kill, power loss).
411
428
  *
412
- * Staleness rule: lastHeartbeatAt is older than `staleThresholdMs`
413
- * (default 15 min — a conservative ~7.5× the 2-min heartbeat
414
- * interval, giving legitimately-active daemons on other machines
415
- * ample margin before we consider their session abandoned).
429
+ * Staleness rule: the newest usable timestamp among lastHeartbeatAt,
430
+ * createdAt, and updatedAt is older than `staleThresholdMs` (default
431
+ * 15 min — a conservative ~7.5× the 2-min heartbeat interval, giving
432
+ * legitimately-active daemons on other machines ample margin before
433
+ * we consider their session abandoned). createdAt/updatedAt cover a
434
+ * creator that dies before its first heartbeat.
416
435
  *
417
436
  * Safety:
418
437
  * - Only sessions with status === 'ACTIVE' are candidates.
419
438
  * - Sessions explicitly listed in `excludeSessionIds` are skipped
420
439
  * (caller can pass the session the daemon is about to attach to
421
440
  * if the ID is known before the sweep).
422
- * - Absent `lastHeartbeatAt` (never-heartbeated sessions — should
423
- * only happen for rows created within the last few seconds)
424
- * treats the session as fresh and skips.
441
+ * - A row with no parseable heartbeat/create/update timestamp is
442
+ * skipped fail-safe; the sweeper never guesses its age.
425
443
  * - updateSession failures are logged as warnings and don't abort
426
444
  * the sweep — best-effort cleanup.
427
445
  *
@@ -922,6 +940,8 @@ export declare class AppSyncClient {
922
940
  */
923
941
  subscribeToEvents(sessionId: string, onEvent: (event: Event) => void, onError?: (error: Error) => void, options?: {
924
942
  receiveDesktopEvents?: boolean;
943
+ onSubscribed?: (isReconnect: boolean) => void;
944
+ onSessionRetired?: () => Promise<void> | void;
925
945
  }): () => void;
926
946
  /**
927
947
  * Build WebSocket URL
@@ -950,6 +970,7 @@ export declare class AppSyncClient {
950
970
  * Create WebSocket subscription
951
971
  */
952
972
  private createSubscription;
973
+ private handleSubscriptionStartAck;
953
974
  /**
954
975
  * Send subscription start message
955
976
  */
@@ -1059,11 +1080,17 @@ export declare class AppSyncClient {
1059
1080
  private handleApplyUserDecisionWatcherError;
1060
1081
  private cleanupApplyUserDecisionWatcherState;
1061
1082
  private heartbeatTimers;
1083
+ /** Identity tokens invalidate in-flight pulses when a session is stopped. */
1084
+ private heartbeatTokens;
1085
+ /** Shared initial confirmation makes duplicate start calls idempotent. */
1086
+ private heartbeatInitialPulses;
1087
+ private heartbeatInitialOutcomes;
1062
1088
  /**
1063
1089
  * Start periodic heartbeat for a session.
1064
1090
  * Updates lastHeartbeatAt on the session every intervalMs (default 2 minutes).
1065
1091
  */
1066
- startHeartbeat(sessionId: string, intervalMs?: number): void;
1092
+ startHeartbeat(sessionId: string, intervalMs?: number): Promise<boolean>;
1093
+ private startHeartbeatOutcome;
1067
1094
  /**
1068
1095
  * Stop heartbeat for a session.
1069
1096
  */
@@ -1072,6 +1099,7 @@ export declare class AppSyncClient {
1072
1099
  * Send a single heartbeat update.
1073
1100
  */
1074
1101
  private sendHeartbeat;
1102
+ private notifyRetiredSession;
1075
1103
  /**
1076
1104
  * Tear down the mobile-event subscription for a SINGLE session.
1077
1105
  *
@@ -1,3 +1,4 @@
1
+ import type { Event } from '../types/events';
1
2
  /** Exposed for the single log line in createEvent. */
2
3
  export declare const CLIENT_THROTTLE_EVENTS_PER_WINDOW: number;
3
4
  interface RateWindow {
@@ -21,6 +22,38 @@ export declare function shouldSuppressEvent(sessionId: string, type: string, now
21
22
  export declare function consumeThrottleLogOnce(sessionId: string): RateWindow | undefined;
22
23
  /** Test-only: clears the per-process rate map. */
23
24
  export declare function resetThrottleState(): void;
25
+ /**
26
+ * True iff a `createEvent` result is PROVEN durably persisted by the backend (a real
27
+ * stored Events row), as opposed to a NON-persisted synthetic acknowledgement that
28
+ * EITHER throttle layer returns over-cap:
29
+ * - the CLIENT throttle above (`createEvent` short-circuit) → `eventId` prefixed
30
+ * `local-throttled-`, no `writerAuthenticated`;
31
+ * - the BACKEND Lambda's per-SESSION guardrail → fresh `generateId()`, no
32
+ * `writerAuthenticated`;
33
+ * - the BACKEND per-ACCOUNT guardrail → fresh `generateId()`, no
34
+ * `writerAuthenticated` (its `rateLimitNotice` marker is not even in the
35
+ * `createEvent` selection set, so it never reaches the client);
36
+ * none of which stored a row.
37
+ *
38
+ * The single reliable POSITIVE persistence signal is `writerAuthenticated`: the
39
+ * backend stamps it (a boolean — `false` for a non-writer emit, `true` for a writer-
40
+ * attested one) on EVERY persisted Event and returns it in the `createEvent`
41
+ * selection set (queries.ts). No synthetic populates it — the client synthetic omits
42
+ * it (→ `undefined`) and every backend synthetic omits it (→ `null` through GraphQL).
43
+ * `emittedBy` (the other persist-only attribute) is `EventAuthor!` (non-null) in the
44
+ * schema, so it CANNOT be selected on a mutation whose resolver may return a
45
+ * synthetic — a non-null field resolving to null would error the whole response —
46
+ * which is exactly why `writerAuthenticated` (nullable) is the only persist marker
47
+ * safely in the selection set. The `local-throttled-` guard is belt-and-suspenders.
48
+ *
49
+ * Deliberately CONSERVATIVE: returns true ONLY on positive proof, so any
50
+ * unrecognized / partial shape is treated as NOT-persisted. Callers use this to
51
+ * decide whether to record a legacy `TOOL_USE` id as "legacy-owned" (§4.8) — being
52
+ * wrong toward "not persisted" only forgoes a dedup (a cosmetic duplicate render),
53
+ * whereas being wrong toward "persisted" on a synthetic would suppress the
54
+ * consolidator re-derive and permanently SKIP the tool (G2). Never the latter.
55
+ */
56
+ export declare function isPersistedEventResult(event: Pick<Event, 'eventId' | 'writerAuthenticated'> | null | undefined): boolean;
24
57
  /** Test-only: current size of the per-process rate map (eviction-bound check). */
25
58
  export declare function throttleMapSize(): number;
26
59
  /** Test-only: whether a session is currently tracked (eviction assertions). */
@@ -1,5 +1,6 @@
1
- export { AppSyncClient, AppSyncGraphQLError, DownloadUrlResponse } from './appsync-client';
1
+ export { AppSyncClient, AppSyncAuthenticationError, AppSyncGraphQLError, DownloadUrlResponse, } from './appsync-client';
2
2
  export { coerceAwsJsonObject } from './appsync-client';
3
3
  export type { ClassBPacketEnvelopeMeta } from './appsync-client';
4
- export type { TaskReviewSummary, TaskReviewSummaryRound, TaskReviewSummaryReviewer, TaskGroupStatusResult, } from './appsync-client';
4
+ export type { TaskReviewSummary, TaskReviewSummaryRound, TaskReviewSummaryReviewer, TaskGroupStatusResult, PutContextItemInput, } from './appsync-client';
5
5
  export { queries, mutations, subscriptions } from './queries';
6
+ export { isPersistedEventResult } from './event-throttle';
@@ -7,8 +7,9 @@ export declare const queries: {
7
7
  * Minimal session listing used by the orphan-sweep path. Only the
8
8
  * fields needed to decide whether a session row is stale — sessionId
9
9
  * for the INACTIVE mutation, agentType for the per-plugin filter,
10
- * status to skip non-ACTIVE rows, and lastHeartbeatAt for the age
11
- * check.
10
+ * status to skip non-ACTIVE rows, lastHeartbeatAt for the usual age
11
+ * check, and createdAt/updatedAt as the startup-age fallback for rows
12
+ * whose creator died before its first heartbeat.
12
13
  */
13
14
  listSessions: string;
14
15
  getSubscriptionStatus: string;
@@ -23,6 +24,7 @@ export declare const queries: {
23
24
  getTaskReviewSummary: string;
24
25
  };
25
26
  export declare const mutations: {
27
+ putContextItem: string;
26
28
  createSession: string;
27
29
  updateSession: string;
28
30
  createEvent: string;
@@ -23,6 +23,31 @@ export type AuthFailureReason = 'port_in_use' | 'port_range_exhausted' | 'server
23
23
  * not user AFK).
24
24
  */
25
25
  export type AuthStage = 'server_start' | 'browser_open' | 'awaiting_callback' | 'exchanging_code' | 'storing_tokens' | 'unknown';
26
+ /**
27
+ * Preserve the retired shell wrappers' exact activation-funnel identity.
28
+ * POSIX `echo` added a trailing newline before hashing, so omitting `\n` here
29
+ * would split the same machine across two GA4 client IDs after the A6 cutover.
30
+ */
31
+ declare function getLegacyWrapperClientId(): string;
32
+ /**
33
+ * Agent label used by the long-lived `wrapper_launched` activation-funnel
34
+ * event. Keep these values aligned with the historical public-wrapper event so
35
+ * the 2.x unified CLI continues the same GA4 series.
36
+ */
37
+ export type CompanionActivationAgent = 'claude' | 'codex' | 'antigravity';
38
+ declare function legacyWrapperBaseParams(): Record<string, string>;
39
+ /**
40
+ * Preserve the final activation-funnel event after A6 retires the public
41
+ * `codevibe-*` wrappers. The unified Companion route calls this exactly once
42
+ * after resolving the selected agent and before handing off to its private
43
+ * launcher. The caller awaits the bounded best-effort transport before its
44
+ * synchronous child handoff blocks the event loop.
45
+ */
46
+ export declare function fireWrapperLaunchedBeacon(agent: CompanionActivationAgent): Promise<void>;
47
+ export declare const __testing: {
48
+ getLegacyWrapperClientId: typeof getLegacyWrapperClientId;
49
+ legacyWrapperBaseParams: typeof legacyWrapperBaseParams;
50
+ };
26
51
  /**
27
52
  * Fire the `auth_completed` success beacon. Replaces the inline POST
28
53
  * previously duplicated in `auth-cli.ts`. Includes `user_id` so the
@@ -165,3 +190,4 @@ export declare function fireSessionEncryptionSelfRekeyTimeoutBeacon(params: {
165
190
  session_hash: string;
166
191
  attempt_count: number;
167
192
  }): Promise<void>;
193
+ export {};
@@ -0,0 +1,49 @@
1
+ import { type OAuthAccountLock } from "../credential-broker/oauth-account-lock";
2
+ import type { VendorKeyStore, VendorOAuthBundle } from "../credential-broker/types";
3
+ /** Injectable IO seam so the subcommands are unit-testable without a TTY. */
4
+ export interface VendorKeyCliIO {
5
+ print(line: string): void;
6
+ printErr(line: string): void;
7
+ /** Read a secret with NO echo (hidden). Never appears in argv/logs. */
8
+ readSecret(prompt: string): Promise<string>;
9
+ /** Read a visible yes/no consent answer. */
10
+ confirm(prompt: string): Promise<boolean>;
11
+ }
12
+ /** Injectable dependencies (production defaults wire the real store/keychain/lock). */
13
+ export interface VendorKeyCliDeps {
14
+ store: VendorKeyStore;
15
+ io: VendorKeyCliIO;
16
+ /** The §5 cross-process OAuth-account lock for C4 mutations. */
17
+ oauthLock: OAuthAccountLock;
18
+ /**
19
+ * Resolve (WITHOUT reading) the Codex auth file path — displayed in the consent
20
+ * prompt BEFORE any read (§4/§7: the prompt must authorize the read it names).
21
+ */
22
+ codexAuthPath: () => string;
23
+ /** Read `~/.codex/auth.json` raw contents (or null if missing) — ONLY AFTER consent. */
24
+ readCodexAuth: (authPath: string) => Promise<string | null>;
25
+ /**
26
+ * Content-BLIND existence check for the Codex auth file — used by the setup
27
+ * wizard for flow control WITHOUT reading token material before consent
28
+ * (§4/§7). Never opens/parses the file; existence only.
29
+ */
30
+ codexAuthExists: (authPath: string) => Promise<boolean>;
31
+ /** True iff the OS-native keychain is the active custody backend. */
32
+ custodyAvailable: () => boolean;
33
+ now: () => Date;
34
+ /**
35
+ * Run `claude setup-token` interactively with INHERITED stdio (the token is
36
+ * displayed by the claude CLI itself and pasted by the user — never captured
37
+ * from the subprocess). Resolves the exit code, or null when the `claude`
38
+ * binary is not on PATH.
39
+ */
40
+ runClaudeSetupToken: () => Promise<number | null>;
41
+ }
42
+ /** Parse a Codex `auth.json` into the C4 bundle. Never logs token material. */
43
+ export declare function parseCodexAuth(raw: string): VendorOAuthBundle | null;
44
+ /**
45
+ * Run the `vendor-key` subcommand group. Returns the process exit code (does NOT
46
+ * call `process.exit` — the caller does, keeping this unit-testable). `argv` is
47
+ * the full process argv (node, script, `vendor-key`, sub, …).
48
+ */
49
+ export declare function runVendorKeyCli(argv: string[], depsOverride?: Partial<VendorKeyCliDeps>): Promise<number>;
@@ -1,22 +1,22 @@
1
1
  import { DetectableAgent } from '../orchestration/detect-agents';
2
2
  import type { ShellEventEmit } from '../orchestration-shell/emit-shell-event';
3
3
  import type { Session } from '../types';
4
+ import { type CompanionActivationAgent } from '../auth/auth-telemetry';
5
+ type ActiveCompanionAgent = Exclude<DetectableAgent, 'GEMINI'>;
4
6
  export declare class NoAgentInstalledError extends Error {
5
7
  constructor(message: string);
6
8
  }
7
9
  export interface CompanionArgs {
8
10
  /** Optional `--agent <kind>` CLI override. */
9
- agent?: DetectableAgent;
10
- /** Args to pass through to the agent wrapper. */
11
+ agent?: ActiveCompanionAgent;
12
+ /** Args to pass through to the private Companion launcher. */
11
13
  passthrough: string[];
12
- /** When set, clears the persisted preference before resolving. */
13
- forgetAgent?: boolean;
14
14
  /**
15
15
  * Session context for §3 emitShellEvent fan-out. When provided
16
16
  * together with `emitter`, MODE_SELECTED is emitted before the exec
17
17
  * handoff. When either is omitted, the emit is skipped — Companion
18
- * Mode is functional without it because the cohort flag gates every
19
- * emit anyway (CP-1.a default OFF). Per Stage 1 r1 HIGH-3.
18
+ * Mode is functional without it because the MODE_SELECTED emit is a
19
+ * best-effort audit, not load-bearing for the mode. Per Stage 1 r1 HIGH-3.
20
20
  */
21
21
  session?: Session;
22
22
  /**
@@ -24,33 +24,47 @@ export interface CompanionArgs {
24
24
  * Required for the MODE_SELECTED emit when `session` is also set.
25
25
  */
26
26
  emitter?: (args: ShellEventEmit) => Promise<void>;
27
- /** Test seam — override the `execFileSync` handoff. */
28
- execFile?: (binPath: string, args: string[], options: {
27
+ /** Test seam — override the blocking private-launcher handoff. */
28
+ spawnFile?: (binPath: string, args: string[], options: {
29
29
  stdio: 'inherit';
30
- }) => void;
30
+ }) => CompanionProcessResult;
31
+ /** Test seam — production re-signals this process when the child dies by signal. */
32
+ signalSelf?: (signal: NodeJS.Signals) => void;
31
33
  /** Test seam — override `detectInstalledAgents`. */
32
34
  detect?: () => DetectableAgent[];
33
- /** Test seam — override bin-path resolver (real impl uses `command -v`). */
34
- resolveBinPath?: (kind: DetectableAgent) => string | null;
35
+ /** Test seam — override the plugin-private launcher resolver. */
36
+ resolveLauncherPath?: (kind: ActiveCompanionAgent) => string | null;
35
37
  /**
36
- * Test seam — override the `<wrapper> --version` health-probe
37
- * (§4 line 280; timeout AGENT_VERSION_PROBE_TIMEOUT_MS). Real impl
38
- * spawns the wrapper with a SIGKILL on timeout. Per Stage 2 r1 Codex
39
- * MEDIUM-2.
38
+ * Test seam — observe/suppress the best-effort activation-funnel beacon.
39
+ * The promise is awaited before the blocking launcher handoff so transport
40
+ * gets its bounded opportunity to complete.
40
41
  */
41
- versionProbe?: (binPath: string) => Promise<boolean>;
42
+ emitActivation?: (agent: CompanionActivationAgent) => void | Promise<void>;
42
43
  }
44
+ export interface CompanionProcessResult {
45
+ status: number | null;
46
+ signal: NodeJS.Signals | null;
47
+ error?: Error;
48
+ }
49
+ /**
50
+ * Resolve the launcher's package-owned private entrypoint. Package manifests
51
+ * declare `codevibe.companionLauncher`; the resolved real path must remain
52
+ * inside the real package root and be an executable regular file. This avoids
53
+ * both PATH alias dependency and a manifest path traversal/symlink escape.
54
+ */
55
+ export declare function resolveDeclaredCompanionLauncher(packageJsonPath: string): string | null;
43
56
  /**
44
57
  * §4 LOCK lines 232-273. Detect → resolve → persist → exec.
45
58
  *
46
59
  * On a TTY with multiple agents, this calls `pickAgent` for the
47
60
  * interactive readline picker. The function does NOT mount the Ink
48
61
  * TUI — Companion Mode does not need it (the picker hands terminal
49
- * control directly to the wrapper).
62
+ * control directly to the private launcher).
50
63
  *
51
- * NOTE: the function returns when the test seam `execFile` is
52
- * provided; in production the `execFileSync` call replaces the process
53
- * (`stdio: 'inherit'`) so `process.exit(0)` is unreachable but kept
54
- * as a defensive fallback (§4 line 273).
64
+ * The injected test seam and production `spawnSync` share the same contract.
65
+ * Production blocks while the private launcher owns the terminal, then
66
+ * returns its exact exit status or terminates this process with the same
67
+ * signal, preserving the former shell `exec` handoff semantics.
55
68
  */
56
- export declare function runCompanionMode(args: CompanionArgs): Promise<void>;
69
+ export declare function runCompanionMode(args: CompanionArgs): Promise<number>;
70
+ export {};
@@ -1,6 +1,6 @@
1
1
  export declare function companionPreferenceFilePath(): string;
2
2
  export interface CompanionPreference {
3
- lastAgent: 'CLAUDE' | 'GEMINI' | 'CODEX' | 'ANTIGRAVITY';
3
+ lastAgent: 'CLAUDE' | 'CODEX' | 'ANTIGRAVITY';
4
4
  lastUsedAt: string;
5
5
  }
6
6
  /**
@@ -18,7 +18,3 @@ export declare function readCompanionPreference(): Promise<CompanionPreference |
18
18
  * write).
19
19
  */
20
20
  export declare function persistCompanionPreference(pref: CompanionPreference): Promise<void>;
21
- /**
22
- * Clears the preference file (used by `--forget-agent` flag per §4).
23
- */
24
- export declare function clearCompanionPreference(): Promise<void>;
@@ -1,6 +1,7 @@
1
1
  import { DetectableAgent } from '../orchestration/detect-agents';
2
+ export type ActiveCompanionAgent = Exclude<DetectableAgent, 'GEMINI'>;
2
3
  export interface DetectedAgent {
3
- kind: DetectableAgent;
4
+ kind: ActiveCompanionAgent;
4
5
  binPath: string;
5
6
  healthy: boolean;
6
7
  }
@@ -8,9 +9,9 @@ export interface ResolveAgentArgs {
8
9
  /** Healthy agents detected on PATH. */
9
10
  healthy: DetectedAgent[];
10
11
  /** `--agent` CLI flag override (if any). */
11
- flag?: DetectableAgent;
12
+ flag?: ActiveCompanionAgent;
12
13
  /** Persisted preference from `readCompanionPreference()` (if any). */
13
- preferred?: DetectableAgent;
14
+ preferred?: ActiveCompanionAgent;
14
15
  }
15
16
  export interface ResolveAgentResult {
16
17
  /** When a single resolved agent exists. */
@@ -22,7 +23,7 @@ export interface ResolveAgentResult {
22
23
  };
23
24
  /** When the flag asked for an agent that's not healthy. */
24
25
  flagMissing?: {
25
- requested: DetectableAgent;
26
+ requested: ActiveCompanionAgent;
26
27
  };
27
28
  }
28
29
  /**
@@ -39,11 +39,6 @@ export interface Config {
39
39
  sessionsDir: string;
40
40
  approvalTimeoutMs: number;
41
41
  };
42
- gemini: {
43
- command: string;
44
- defaultTimeout: number;
45
- transcriptDir: string;
46
- };
47
42
  }
48
43
  /**
49
44
  * Get environment from process.env.ENVIRONMENT, defaults to 'production'
@@ -0,0 +1,21 @@
1
+ import type { UpstreamResult } from "../types";
2
+ /**
3
+ * The buffered SPEC a migrated stub stores (in place of the legacy
4
+ * `UpstreamResponse` shape). The stub wraps it via {@link bufferedResult} inside
5
+ * its own `post()`, producing a FRESH one-shot `UpstreamResult` per call (so a
6
+ * retry that posts twice never trips the one-shot guard).
7
+ */
8
+ export interface BufferedSpec {
9
+ status: number;
10
+ body?: unknown;
11
+ /** Optional response headers (defaults to `content-type: application/json`). */
12
+ headers?: Record<string, string>;
13
+ }
14
+ /**
15
+ * Build a one-shot buffered {@link UpstreamResult} from a status + JSON body,
16
+ * matching the real `FetchUpstreamClient` contract: `readText()` returns the
17
+ * exact serialized bytes (empty string for an absent body → the broker parses it
18
+ * to `undefined`), `bodyStream()` yields those same bytes once, and a second or
19
+ * mixed consumption THROWS (LOCK #643-1).
20
+ */
21
+ export declare function bufferedResult(status: number, body?: unknown, headers?: Record<string, string>): UpstreamResult;