@quantiya/codevibe-core 2.0.0 → 2.0.1

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 (170) hide show
  1. package/dist/__tests__/cp-5-baseline-invariants.test.d.ts +1 -0
  2. package/dist/adapter/__tests__/capabilities.test.d.ts +1 -0
  3. package/dist/adapter/__tests__/contract-conformance.test.d.ts +1 -0
  4. package/dist/adapter/__tests__/packets.test.d.ts +1 -0
  5. package/dist/adapter/__tests__/progress.test.d.ts +1 -0
  6. package/dist/adapter/__tests__/registry.test.d.ts +1 -0
  7. package/dist/adapter/__tests__/smoke/claude.smoke.test.d.ts +1 -0
  8. package/dist/adapter/__tests__/smoke/codex.smoke.test.d.ts +1 -0
  9. package/dist/adapter/__tests__/smoke/gemini.smoke.test.d.ts +1 -0
  10. package/dist/adapter/capabilities.d.ts +68 -0
  11. package/dist/adapter/index.d.ts +7 -0
  12. package/dist/adapter/packets.d.ts +129 -0
  13. package/dist/adapter/progress.d.ts +93 -0
  14. package/dist/adapter/registry.d.ts +24 -0
  15. package/dist/adapter/types.d.ts +22 -0
  16. package/dist/appsync/__tests__/appsync-client-apply-user-decision.test.d.ts +1 -0
  17. package/dist/appsync/__tests__/appsync-client-classb.test.d.ts +1 -0
  18. package/dist/appsync/__tests__/appsync-client-planner.test.d.ts +1 -0
  19. package/dist/appsync/__tests__/appsync-client.test.d.ts +1 -0
  20. package/dist/appsync/appsync-client.d.ts +412 -0
  21. package/dist/appsync/index.d.ts +1 -1
  22. package/dist/appsync/queries.d.ts +15 -0
  23. package/dist/auth/__tests__/auth-telemetry.test.d.ts +1 -0
  24. package/dist/auth/auth-telemetry.d.ts +98 -5
  25. package/dist/companion-mode/__tests__/persist-preference.test.d.ts +1 -0
  26. package/dist/companion-mode/__tests__/resolve-agent.test.d.ts +1 -0
  27. package/dist/companion-mode/agent-picker.d.ts +9 -0
  28. package/dist/companion-mode/index.d.ts +55 -0
  29. package/dist/companion-mode/persist-preference.d.ts +24 -0
  30. package/dist/companion-mode/resolve-agent.d.ts +41 -0
  31. package/dist/index.d.ts +11 -3
  32. package/dist/index.js +243 -42
  33. package/dist/keychain/keychain-manager.d.ts +16 -2
  34. package/dist/local-executor/__tests__/authority-symlink-fixture.d.ts +15 -0
  35. package/dist/local-executor/__tests__/authority.test.d.ts +1 -0
  36. package/dist/local-executor/__tests__/class-a-emit.test.d.ts +1 -0
  37. package/dist/local-executor/__tests__/class-b-consumer.integration.test.d.ts +1 -0
  38. package/dist/local-executor/__tests__/class-b-consumer.test.d.ts +1 -0
  39. package/dist/local-executor/__tests__/hook-bridge.test.d.ts +1 -0
  40. package/dist/local-executor/__tests__/local-executor.integration.test.d.ts +1 -0
  41. package/dist/local-executor/__tests__/spawn.test.d.ts +1 -0
  42. package/dist/local-executor/__tests__/verification-runner.test.d.ts +1 -0
  43. package/dist/local-executor/authority.d.ts +29 -0
  44. package/dist/local-executor/class-a-emit.d.ts +138 -0
  45. package/dist/local-executor/class-b-consumer.d.ts +121 -0
  46. package/dist/local-executor/hook-bridge.d.ts +36 -0
  47. package/dist/local-executor/index.d.ts +8 -0
  48. package/dist/local-executor/local-executor-impl.d.ts +83 -0
  49. package/dist/local-executor/spawn.d.ts +6 -0
  50. package/dist/local-executor/types.d.ts +183 -0
  51. package/dist/local-executor/verification-gates/build.d.ts +6 -0
  52. package/dist/local-executor/verification-gates/deploy-preflight.d.ts +6 -0
  53. package/dist/local-executor/verification-gates/diff-sanity.d.ts +6 -0
  54. package/dist/local-executor/verification-gates/hostile-grep.d.ts +6 -0
  55. package/dist/local-executor/verification-gates/lint.d.ts +6 -0
  56. package/dist/local-executor/verification-gates/shell-runner.d.ts +40 -0
  57. package/dist/local-executor/verification-gates/source-traceability.d.ts +6 -0
  58. package/dist/local-executor/verification-gates/tests.d.ts +6 -0
  59. package/dist/local-executor/verification-gates/typecheck.d.ts +6 -0
  60. package/dist/local-executor/verification-runner.d.ts +28 -0
  61. package/dist/orchestration/__tests__/setup-bootstrap.test.d.ts +1 -0
  62. package/dist/orchestration/__tests__/setup-failure-recourse.test.d.ts +1 -0
  63. package/dist/orchestration/__tests__/setup-save.test.d.ts +1 -0
  64. package/dist/orchestration/__tests__/setup-seat-picker.test.d.ts +1 -0
  65. package/dist/orchestration/__tests__/setup-telemetry.test.d.ts +1 -0
  66. package/dist/orchestration/__tests__/setup-test-agents.test.d.ts +1 -0
  67. package/dist/orchestration/__tests__/setup-types.test.d.ts +1 -0
  68. package/dist/orchestration/__tests__/setup-wizard.test.d.ts +1 -0
  69. package/dist/orchestration/__tests__/v1-options.test.d.ts +1 -0
  70. package/dist/orchestration/detect-agents.d.ts +2 -1
  71. package/dist/orchestration/index.d.ts +1 -0
  72. package/dist/orchestration/orchestration-cli.d.ts +4 -1
  73. package/dist/orchestration/setup-bootstrap.d.ts +146 -0
  74. package/dist/orchestration/setup-failure-recourse.d.ts +23 -0
  75. package/dist/orchestration/setup-save.d.ts +47 -0
  76. package/dist/orchestration/setup-seat-picker.d.ts +72 -0
  77. package/dist/orchestration/setup-telemetry.d.ts +54 -0
  78. package/dist/orchestration/setup-test-agents.d.ts +108 -0
  79. package/dist/orchestration/setup-types.d.ts +140 -0
  80. package/dist/orchestration/setup-wizard.d.ts +57 -0
  81. package/dist/orchestration/v1-options.d.ts +97 -0
  82. package/dist/orchestration-shell/__tests__/cli-authority-bridge.test.d.ts +1 -0
  83. package/dist/orchestration-shell/__tests__/cli-planner-stack.test.d.ts +1 -0
  84. package/dist/orchestration-shell/__tests__/cli-singleton-enforcement.test.d.ts +1 -0
  85. package/dist/orchestration-shell/__tests__/cli-stub-session-adapter.test.d.ts +1 -0
  86. package/dist/orchestration-shell/__tests__/components.test.d.ts +1 -0
  87. package/dist/orchestration-shell/__tests__/emit-shell-event.test.d.ts +1 -0
  88. package/dist/orchestration-shell/__tests__/gate-prompts.test.d.ts +1 -0
  89. package/dist/orchestration-shell/__tests__/hostile-grep.test.d.ts +1 -0
  90. package/dist/orchestration-shell/__tests__/mode-selection.test.d.ts +1 -0
  91. package/dist/orchestration-shell/__tests__/process-markers.test.d.ts +1 -0
  92. package/dist/orchestration-shell/__tests__/reducer.test.d.ts +1 -0
  93. package/dist/orchestration-shell/__tests__/runOrchestrationShell-classify-dispatch.test.d.ts +1 -0
  94. package/dist/orchestration-shell/__tests__/runOrchestrationShell-planner-wiring.test.d.ts +1 -0
  95. package/dist/orchestration-shell/__tests__/runOrchestrationShell-signal.test.d.ts +1 -0
  96. package/dist/orchestration-shell/__tests__/runOrchestrationShell.test.d.ts +1 -0
  97. package/dist/orchestration-shell/__tests__/slash-router.test.d.ts +1 -0
  98. package/dist/orchestration-shell/__tests__/sticky-preference.test.d.ts +1 -0
  99. package/dist/orchestration-shell/cli.d.ts +96 -0
  100. package/dist/orchestration-shell/cli.js +8309 -0
  101. package/dist/orchestration-shell/cohort-flag.d.ts +16 -0
  102. package/dist/orchestration-shell/components/CodeVibeLogo.d.ts +2 -0
  103. package/dist/orchestration-shell/components/ConversationPane.d.ts +7 -0
  104. package/dist/orchestration-shell/components/GatePromptEntry.d.ts +9 -0
  105. package/dist/orchestration-shell/components/InputBar.d.ts +41 -0
  106. package/dist/orchestration-shell/components/OrchestrationApp.d.ts +63 -0
  107. package/dist/orchestration-shell/components/StatusBar.d.ts +7 -0
  108. package/dist/orchestration-shell/components/nodes/AdvisoryEntry.d.ts +8 -0
  109. package/dist/orchestration-shell/components/nodes/GateStatusNode.d.ts +8 -0
  110. package/dist/orchestration-shell/components/nodes/PlannerDecisionEntry.d.ts +8 -0
  111. package/dist/orchestration-shell/components/nodes/ReviewerQuorumStatusNode.d.ts +8 -0
  112. package/dist/orchestration-shell/components/nodes/SlashOutputEntry.d.ts +8 -0
  113. package/dist/orchestration-shell/components/nodes/SubagentEventEntry.d.ts +8 -0
  114. package/dist/orchestration-shell/components/nodes/UserMessageEntry.d.ts +8 -0
  115. package/dist/orchestration-shell/emit-shell-event.d.ts +64 -0
  116. package/dist/orchestration-shell/gate-prompts.d.ts +123 -0
  117. package/dist/orchestration-shell/index.d.ts +100 -0
  118. package/dist/orchestration-shell/ink-runtime.d.ts +64 -0
  119. package/dist/orchestration-shell/mode-selection.d.ts +46 -0
  120. package/dist/orchestration-shell/non-tty-fallback.d.ts +46 -0
  121. package/dist/orchestration-shell/process-markers.d.ts +12 -0
  122. package/dist/orchestration-shell/reducer.d.ts +8 -0
  123. package/dist/orchestration-shell/slash-router.d.ts +45 -0
  124. package/dist/orchestration-shell/sticky-preference.d.ts +24 -0
  125. package/dist/orchestration-shell/store.d.ts +17 -0
  126. package/dist/orchestration-shell/types.d.ts +417 -0
  127. package/dist/planner/__tests__/cache-clarification-bypass.test.d.ts +1 -0
  128. package/dist/planner/__tests__/cache.test.d.ts +1 -0
  129. package/dist/planner/__tests__/client.test.d.ts +1 -0
  130. package/dist/planner/__tests__/health-machine-transitions.test.d.ts +1 -0
  131. package/dist/planner/__tests__/types-zod.test.d.ts +1 -0
  132. package/dist/planner/adapter.d.ts +16 -0
  133. package/dist/planner/cache.d.ts +35 -0
  134. package/dist/planner/client.d.ts +103 -0
  135. package/dist/planner/health-state.d.ts +24 -0
  136. package/dist/planner/index.d.ts +5 -0
  137. package/dist/planner/types.d.ts +113 -0
  138. package/dist/session/__tests__/session-resume-service-keys.test.d.ts +1 -0
  139. package/dist/session/session-rekey.d.ts +40 -0
  140. package/dist/session/session-resume.d.ts +25 -0
  141. package/dist/structural-summary/__tests__/__fixtures__/fixture-helpers.d.ts +11 -0
  142. package/dist/structural-summary/__tests__/assembler.test.d.ts +1 -0
  143. package/dist/structural-summary/__tests__/generator.test.d.ts +1 -0
  144. package/dist/structural-summary/__tests__/language-detect.test.d.ts +1 -0
  145. package/dist/structural-summary/__tests__/manifest-parsers/cargo.test.d.ts +1 -0
  146. package/dist/structural-summary/__tests__/manifest-parsers/gomod.test.d.ts +1 -0
  147. package/dist/structural-summary/__tests__/manifest-parsers/gradle.test.d.ts +1 -0
  148. package/dist/structural-summary/__tests__/manifest-parsers/index.test.d.ts +1 -0
  149. package/dist/structural-summary/__tests__/manifest-parsers/npm.test.d.ts +1 -0
  150. package/dist/structural-summary/__tests__/manifest-parsers/podfile.test.d.ts +1 -0
  151. package/dist/structural-summary/__tests__/manifest-parsers/pyproject.test.d.ts +1 -0
  152. package/dist/structural-summary/__tests__/opt-in-store.test.d.ts +1 -0
  153. package/dist/structural-summary/__tests__/privacy-filter.test.d.ts +1 -0
  154. package/dist/structural-summary/__tests__/safe-file-read.test.d.ts +1 -0
  155. package/dist/structural-summary/__tests__/user-ignore-matcher.test.d.ts +1 -0
  156. package/dist/structural-summary/__tests__/walker.test.d.ts +1 -0
  157. package/dist/structural-summary/generator.d.ts +8 -0
  158. package/dist/structural-summary/index.d.ts +7 -0
  159. package/dist/structural-summary/manifest-parsers/cargo.d.ts +3 -0
  160. package/dist/structural-summary/manifest-parsers/index.d.ts +7 -0
  161. package/dist/structural-summary/manifest-parsers/npm.d.ts +3 -0
  162. package/dist/structural-summary/manifest-parsers/other.d.ts +17 -0
  163. package/dist/structural-summary/opt-in-store.d.ts +24 -0
  164. package/dist/structural-summary/privacy-filter.d.ts +110 -0
  165. package/dist/structural-summary/safe-file-read.d.ts +11 -0
  166. package/dist/structural-summary/types.d.ts +215 -0
  167. package/dist/structural-summary/user-ignore-matcher.d.ts +9 -0
  168. package/dist/structural-summary/walker.d.ts +20 -0
  169. package/dist/types/events.d.ts +17 -2
  170. package/package.json +17 -3
@@ -0,0 +1,103 @@
1
+ import type { PlannerInput, PlannerDecision, PlannerProbeResult, Tier } from './types';
2
+ import type { PlannerAdapter } from './adapter';
3
+ import type { PlannerCacheLayer } from './cache';
4
+ import type { PlannerHealthMachine } from './health-state';
5
+ /**
6
+ * AppSync transport interface. Minimal shape so unit tests can inject
7
+ * a stub without mounting the full @quantiya/codevibe-core AppSyncClient.
8
+ */
9
+ export interface PlannerAppSyncTransport {
10
+ classifyPlannerPrompt(input: {
11
+ sessionId: string;
12
+ prompt: string;
13
+ clarifications: string;
14
+ sessionContext: string;
15
+ budgetHint: string;
16
+ }): Promise<{
17
+ decision: string;
18
+ cacheHit: boolean;
19
+ cacheKind: string | null;
20
+ serverLatencyMs: number;
21
+ providerUsed: string;
22
+ }>;
23
+ pingPlanner(input: {
24
+ sessionId: string;
25
+ }): Promise<{
26
+ ok: boolean;
27
+ ms: number;
28
+ }>;
29
+ }
30
+ /**
31
+ * Crypto bridge — `encryptString` + `encryptJson` + `decryptJson`
32
+ * variants the adapter needs. Mirrors the existing
33
+ * codevibe-core CryptoService surface; injectable for tests.
34
+ */
35
+ export interface PlannerCryptoBridge {
36
+ /** Encrypt a UTF-8 string to base64 AES-GCM ciphertext. */
37
+ encryptString(plaintext: string, sessionKeyB64: string): string;
38
+ /** Decrypt base64 AES-GCM → UTF-8 string. */
39
+ decryptString(ciphertextB64: string, sessionKeyB64: string): string;
40
+ /** Encrypt JSON-serializable value → base64 ciphertext. */
41
+ encryptJson(obj: unknown, sessionKeyB64: string): string;
42
+ }
43
+ export interface SessionKeyResolver {
44
+ getSessionKey(sessionId: string): Promise<string | null>;
45
+ }
46
+ export interface ShellEventEmit {
47
+ sessionId: string;
48
+ type: 'PLANNER_DECISION' | 'PLANNER_CACHE_HIT' | 'PLANNER_DEGRADED' | 'PLANNER_OUTAGE' | 'PLANNER_RECOVERED';
49
+ metadata?: Record<string, unknown>;
50
+ }
51
+ export type EmitShellEventFn = (args: ShellEventEmit) => Promise<void>;
52
+ /**
53
+ * CP-1.b Stage 2 r2 M-3 — Typed errors that must NOT degrade health.
54
+ *
55
+ * The Lambda surfaces tier-gate / budget rejections as named-error
56
+ * GraphQL responses. Stage 2 r1's catch block recorded EVERY failure
57
+ * as a provider-health failure via `health.recordCall(elapsed, false)`,
58
+ * incorrectly driving the health machine toward Degraded/Outage on
59
+ * what are user-tier policy events (not provider outages). The
60
+ * client now classifies errors and ONLY records provider failures
61
+ * against health; tier/budget rejections emit NOTIFICATION events
62
+ * and throw without touching the machine.
63
+ */
64
+ export declare class PlannerBudgetExceededError extends Error {
65
+ constructor(msg: string);
66
+ }
67
+ export declare class PlannerTierGateRejectedError extends Error {
68
+ constructor(msg: string);
69
+ }
70
+ export declare class BackendPlannerClient implements PlannerAdapter {
71
+ private transport;
72
+ private cache;
73
+ private health;
74
+ private crypto;
75
+ private sessionKeyResolver;
76
+ private emitShellEvent;
77
+ /** Shell-side tier-change detection (LOCK #30). */
78
+ lastClassifyTier: Tier | null;
79
+ /**
80
+ * CP-1.b Stage 2 r2 M-4 — Active session for probe(). The probe
81
+ * mutation requires a sessionId for ownership check; carrying the
82
+ * session in client state lets callers use the canonical
83
+ * `PlannerAdapter.probe()` contract. Set via `setActiveSession()`
84
+ * by orchestration-shell on session start.
85
+ */
86
+ private activeSessionId;
87
+ constructor(transport: PlannerAppSyncTransport, cache: PlannerCacheLayer, health: PlannerHealthMachine, crypto: PlannerCryptoBridge, sessionKeyResolver: SessionKeyResolver, emitShellEvent: EmitShellEventFn);
88
+ /**
89
+ * CP-1.b Stage 2 r2 M-4 — Set the active session ID used by
90
+ * `probe()`. Called by the orchestration-shell on session start
91
+ * (and cleared to `null` on session end).
92
+ */
93
+ setActiveSession(sessionId: string | null): void;
94
+ classify(input: PlannerInput): Promise<PlannerDecision>;
95
+ /**
96
+ * CP-1.b Stage 2 r2 M-4 — Honor the `PlannerAdapter.probe()`
97
+ * contract by reading the session from client state (set via
98
+ * `setActiveSession()`). Stage 2 r1 threw unconditionally and
99
+ * required callers to use the now-removed `probeWithSession()`
100
+ * method, which violated the adapter interface.
101
+ */
102
+ probe(): Promise<PlannerProbeResult>;
103
+ }
@@ -0,0 +1,24 @@
1
+ import type { PlannerHealthState, PlannerHealthTransition } from './types';
2
+ export type { PlannerHealthState, PlannerHealthTransition };
3
+ export declare class PlannerHealthMachine {
4
+ private emitFn;
5
+ state: PlannerHealthState;
6
+ consecutiveFailures: number;
7
+ consecutiveSuccesses: number;
8
+ recentLatenciesMs: number[];
9
+ private readonly URGENT_FAILURE_FOR_DEGRADE;
10
+ private readonly P95_DEGRADE_THRESHOLD_MS;
11
+ private readonly P95_RECOVER_THRESHOLD_MS;
12
+ private readonly DEGRADED_TO_OUTAGE_FAILURES;
13
+ private readonly RECOVER_SUCCESSES_NEEDED;
14
+ private readonly RING_BUFFER_SIZE;
15
+ private readonly DEGRADED_PROBE_INTERVAL_MS;
16
+ private readonly OUTAGE_PROBE_INTERVAL_MS;
17
+ private lastProbeAt;
18
+ constructor(emitFn: (transition: PlannerHealthTransition) => void);
19
+ recordCall(latencyMs: number, success: boolean): PlannerHealthState;
20
+ shouldProbe(): boolean;
21
+ markProbeFired(): void;
22
+ private deriveNextState;
23
+ private p95Of;
24
+ }
@@ -0,0 +1,5 @@
1
+ export * from './types';
2
+ export * from './adapter';
3
+ export { PlannerCacheLayer } from './cache';
4
+ export { PlannerHealthMachine } from './health-state';
5
+ export { BackendPlannerClient, PlannerBudgetExceededError, PlannerTierGateRejectedError, type PlannerAppSyncTransport, type PlannerCryptoBridge, type SessionKeyResolver, type ShellEventEmit, type EmitShellEventFn, } from './client';
@@ -0,0 +1,113 @@
1
+ import { z } from 'zod';
2
+ export type Tier = 'FREE' | 'PRO' | 'MAX';
3
+ export interface SessionContext {
4
+ sessionId: string;
5
+ userId: string;
6
+ tier: Tier;
7
+ currentTaskState: 'none' | 'in_progress' | 'awaiting_user' | 'awaiting_review' | 'merge_gate_pending';
8
+ structuralSummaryDigest: string;
9
+ recentEventCount: number;
10
+ }
11
+ export declare const SessionContextSchema: z.ZodObject<{
12
+ sessionId: z.ZodString;
13
+ userId: z.ZodString;
14
+ tier: z.ZodEnum<["FREE", "PRO", "MAX"]>;
15
+ currentTaskState: z.ZodEnum<["none", "in_progress", "awaiting_user", "awaiting_review", "merge_gate_pending"]>;
16
+ structuralSummaryDigest: z.ZodString;
17
+ recentEventCount: z.ZodNumber;
18
+ }, "strip", z.ZodTypeAny, {
19
+ sessionId: string;
20
+ userId: string;
21
+ structuralSummaryDigest: string;
22
+ tier: "FREE" | "PRO" | "MAX";
23
+ currentTaskState: "none" | "merge_gate_pending" | "in_progress" | "awaiting_user" | "awaiting_review";
24
+ recentEventCount: number;
25
+ }, {
26
+ sessionId: string;
27
+ userId: string;
28
+ structuralSummaryDigest: string;
29
+ tier: "FREE" | "PRO" | "MAX";
30
+ currentTaskState: "none" | "merge_gate_pending" | "in_progress" | "awaiting_user" | "awaiting_review";
31
+ recentEventCount: number;
32
+ }>;
33
+ export interface BudgetHint {
34
+ wallClockMsRemaining: number;
35
+ reviseAttempts: number;
36
+ }
37
+ export declare const BudgetHintSchema: z.ZodObject<{
38
+ wallClockMsRemaining: z.ZodNumber;
39
+ reviseAttempts: z.ZodNumber;
40
+ }, "strip", z.ZodTypeAny, {
41
+ wallClockMsRemaining: number;
42
+ reviseAttempts: number;
43
+ }, {
44
+ wallClockMsRemaining: number;
45
+ reviseAttempts: number;
46
+ }>;
47
+ export interface Clarification {
48
+ question: string;
49
+ answer: string;
50
+ }
51
+ export declare const ClarificationSchema: z.ZodObject<{
52
+ question: z.ZodString;
53
+ answer: z.ZodString;
54
+ }, "strip", z.ZodTypeAny, {
55
+ question: string;
56
+ answer: string;
57
+ }, {
58
+ question: string;
59
+ answer: string;
60
+ }>;
61
+ export interface PlannerInput {
62
+ prompt: string;
63
+ clarifications: Clarification[];
64
+ sessionContext: SessionContext;
65
+ budgetHint: BudgetHint;
66
+ }
67
+ export interface PlannerDecision {
68
+ action: 'start_task' | 'summarize_current_status' | 'advisory_response' | 'ask_user' | 'refuse';
69
+ rationale: string;
70
+ clarifying_question?: string;
71
+ advisory_summary?: string;
72
+ /** Opaque per parent §6 lines 967-972; CP-1 NEVER inspects fields. */
73
+ gateRequest?: Record<string, unknown>;
74
+ }
75
+ export declare const PlannerDecisionSchema: z.ZodObject<{
76
+ action: z.ZodEnum<["start_task", "summarize_current_status", "advisory_response", "ask_user", "refuse"]>;
77
+ rationale: z.ZodString;
78
+ clarifying_question: z.ZodOptional<z.ZodString>;
79
+ advisory_summary: z.ZodOptional<z.ZodString>;
80
+ gateRequest: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
81
+ }, "strip", z.ZodTypeAny, {
82
+ action: "start_task" | "summarize_current_status" | "advisory_response" | "ask_user" | "refuse";
83
+ rationale: string;
84
+ clarifying_question?: string | undefined;
85
+ advisory_summary?: string | undefined;
86
+ gateRequest?: Record<string, unknown> | undefined;
87
+ }, {
88
+ action: "start_task" | "summarize_current_status" | "advisory_response" | "ask_user" | "refuse";
89
+ rationale: string;
90
+ clarifying_question?: string | undefined;
91
+ advisory_summary?: string | undefined;
92
+ gateRequest?: Record<string, unknown> | undefined;
93
+ }>;
94
+ export interface PlannerProbeResult {
95
+ ok: boolean;
96
+ latencyMs: number;
97
+ errorClass?: 'timeout' | 'rate_limited' | 'unreachable' | 'malformed_response' | 'auth_failed';
98
+ }
99
+ export type ClassificationKind = 'workflow_status_query' | 'workflow_audit_query' | 'workflow_review_query' | 'workflow_continuation_query' | 'advisory_response_safe' | 'ask_user_clarification';
100
+ export interface CachedClassification {
101
+ kind: ClassificationKind;
102
+ clarifyingQuestion?: string;
103
+ advisorySummary?: string;
104
+ }
105
+ export type PlannerHealthState = 'Available' | 'Degraded' | 'Outage';
106
+ export interface PlannerHealthTransition {
107
+ newState: PlannerHealthState;
108
+ fromState: PlannerHealthState;
109
+ reason: string;
110
+ consecutiveFailures: number;
111
+ consecutiveSuccesses: number;
112
+ p95Ms: number;
113
+ }
@@ -36,3 +36,43 @@ export interface RekeyOptions {
36
36
  * @returns The number of new grants that succeeded.
37
37
  */
38
38
  export declare function rekeySessionForNewDevices(sessionId: string, sessionKey: string, appSyncClient: AppSyncClient, options?: RekeyOptions): Promise<number>;
39
+ /**
40
+ * Options for {@link awaitOwnSessionKeyGrant}.
41
+ */
42
+ export interface AwaitOwnGrantOptions {
43
+ /** Poll interval in ms. Default 5000. */
44
+ pollIntervalMs?: number;
45
+ /** Max poll attempts. Default 6 (30s total at 5s intervals). */
46
+ maxAttempts?: number;
47
+ /** Authenticated AppSyncClient. */
48
+ appSyncClient: AppSyncClient;
49
+ /** Fired on successful decrypt. Telemetry-only — never thrown. */
50
+ onSuccess?: (attemptCount: number) => void;
51
+ /** Fired after maxAttempts exhausted. Telemetry-only — never thrown. */
52
+ onTimeout?: (attemptCount: number) => void;
53
+ }
54
+ /**
55
+ * Wait for this device's deviceId to appear in `session.encryptedKeys`.
56
+ *
57
+ * Triggered when {@link keychainManager.getSessionKey} returned null on
58
+ * resume AND at least one other device IS in encryptedKeys (so some other
59
+ * device can mint a grant for us via grantSessionKey). Caller must have
60
+ * already invoked {@link registerDeviceEncryptionKey} BEFORE this helper —
61
+ * that's what causes mobile's DeviceKeyWatcher subscription to fire and
62
+ * grant the session key to our (possibly rotated) pubKey.
63
+ *
64
+ * This helper deliberately bypasses {@link keychainManager.getSessionKey}
65
+ * (which has a cache short-circuit) and instead:
66
+ * 1. Calls {@link AppSyncClient.getSession} each poll for fresh
67
+ * `encryptedKeys`.
68
+ * 2. Looks for our `deviceId` in the fresh list.
69
+ * 3. If found, calls {@link cryptoService.decryptSessionKey} directly.
70
+ * 4. On success, populates the keychain cache (so subsequent
71
+ * `getSessionKey` calls hit the cache). The cache is NEVER populated
72
+ * on failure — there's no null sentinel.
73
+ *
74
+ * Returns the decrypted session key on success, or `null` after timeout.
75
+ * Errors are swallowed inside the loop (best-effort polling); telemetry
76
+ * surfaces success vs timeout via the optional callbacks.
77
+ */
78
+ export declare function awaitOwnSessionKeyGrant(sessionId: string, options: AwaitOwnGrantOptions): Promise<string | null>;
@@ -24,6 +24,30 @@ export interface ResumeOrCreateSessionResult {
24
24
  /** The E2E session key (for encrypting/decrypting events), or null if no encryption */
25
25
  sessionKey: string | null;
26
26
  }
27
+ /**
28
+ * CP-1.b IMPL r5 H-2 — Typed error thrown by `prepareSessionEncryption()`
29
+ * when `listServiceDeviceKeys()` returns an empty array across all
30
+ * attempts. Contract per r6/r7 fix: 4 fetch attempts, 3 backoff sleeps:
31
+ * 1s/2s/4s (total ~7s wall on full-failure path). Per CP-1.b design
32
+ * §6.1 lifecycle bullet "Fail-safe:
33
+ * shell-side createSession retries with 1s + 2s + 4s backoff" + LOCK
34
+ * #32 (prewarm custom-resource closes the first-cold-start window
35
+ * structurally; this retry is the disaster-recovery fail-safe).
36
+ *
37
+ * Surfacing this as a typed error (rather than the previous
38
+ * best-effort behavior which built sessions WITHOUT the planner-proxy
39
+ * grant — guaranteeing every subsequent Lambda decrypt would fail)
40
+ * lets the plugin / CLI wrappers display an actionable banner to the
41
+ * user instead of producing a half-broken session.
42
+ *
43
+ * The Lambda emits a matching `PlannerProxyServiceKeyMissing`
44
+ * CloudWatch metric in its `handleClassify` decrypt-failure path; the
45
+ * shell-side typed error closes the funnel at session-create time so
46
+ * the user never reaches a session that can't be decrypted.
47
+ */
48
+ export declare class PlannerProxyServiceKeyMissingError extends Error {
49
+ constructor(msg: string);
50
+ }
27
51
  /**
28
52
  * Prepare E2E encryption for a new session.
29
53
  *
@@ -36,6 +60,7 @@ export interface ResumeOrCreateSessionResult {
36
60
  export declare function prepareSessionEncryption(sessionId: string, appSyncClient: AppSyncClient, logger: Logger): Promise<{
37
61
  sessionKey: string;
38
62
  encryptedKeys: EncryptedSessionKey[];
63
+ skippedDeviceIds: string[];
39
64
  } | null>;
40
65
  /**
41
66
  * Resume an existing session or create a new one.
@@ -0,0 +1,11 @@
1
+ export declare function makeTmpDir(prefix?: string): Promise<string>;
2
+ export declare function git(cwd: string, ...args: string[]): Promise<string>;
3
+ export declare function writeFile(file: string, content: string): Promise<void>;
4
+ /**
5
+ * Initialises a git repo at `dir`, commits initial empty-tree marker so
6
+ * `git status --porcelain` works.
7
+ */
8
+ export declare function initGitRepo(dir: string): Promise<void>;
9
+ export declare function gitAdd(cwd: string, file: string): Promise<void>;
10
+ export declare function gitCommit(cwd: string, msg?: string): Promise<void>;
11
+ export declare function cleanup(dir: string): Promise<void>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ import { type ExclusionState, type StructuralSummaryGenerator } from './types';
2
+ export declare function createStructuralSummaryGenerator(): StructuralSummaryGenerator;
3
+ export interface ReadmeCounters {
4
+ excludedAsUntracked: number;
5
+ excludedByGitignore: number;
6
+ excludedByIgnoreFile: number;
7
+ }
8
+ export declare function readReadmePreview(rootPath: string, exclusionState: ExclusionState, countedExactPaths: Set<string>, countedPrunedPrefixes: Set<string>, counters: ReadmeCounters): Promise<string>;
@@ -0,0 +1,7 @@
1
+ export { createStructuralSummaryGenerator, readReadmePreview, } from './generator';
2
+ export { walk as walkRepoTree } from './walker';
3
+ export { isPathAdmissible, isPathInIgnoredPrefixes, isPathAccountedFor, matchesSecretDenyList, SECRET_DENY_LIST, } from './privacy-filter';
4
+ export { readOptIn, addBodyPath, removeBodyPath, optInFilePath, } from './opt-in-store';
5
+ export { compileUserIgnore, emptyUserIgnoreMatcher, } from './user-ignore-matcher';
6
+ export type { DirectoryNode, RepoSummary, StructuralSummary, StructuralSummaryGenerator, GenerateOpts, PrivacyEnvelope, WalkResult, ExclusionState, UserIgnoreMatcher, ParsedManifest, ManifestType, OptInFile, StructuralSummaryErrorKind, } from './types';
7
+ export { StructuralSummaryError } from './types';
@@ -0,0 +1,3 @@
1
+ import { type ParsedManifest } from '../types';
2
+ export declare function findManifest(rootPath: string): Promise<string | null>;
3
+ export declare function parse(file: string): Promise<ParsedManifest>;
@@ -0,0 +1,7 @@
1
+ import type { ExclusionState, ParsedManifest } from '../types';
2
+ export interface ManifestCounters {
3
+ excludedAsUntracked: number;
4
+ excludedByGitignore: number;
5
+ excludedByIgnoreFile: number;
6
+ }
7
+ export declare function parse(rootPath: string, exclusionState: ExclusionState, countedExactPaths: Set<string>, countedPrunedPrefixes: Set<string>, counters: ManifestCounters): Promise<ParsedManifest>;
@@ -0,0 +1,3 @@
1
+ import { type ParsedManifest } from '../types';
2
+ export declare function findManifest(rootPath: string): Promise<string | null>;
3
+ export declare function parse(file: string): Promise<ParsedManifest>;
@@ -0,0 +1,17 @@
1
+ import { type ParsedManifest } from '../types';
2
+ export declare const pyproject: {
3
+ findManifest(rootPath: string): Promise<string | null>;
4
+ parse(file: string): Promise<ParsedManifest>;
5
+ };
6
+ export declare const gomod: {
7
+ findManifest(rootPath: string): Promise<string | null>;
8
+ parse(file: string): Promise<ParsedManifest>;
9
+ };
10
+ export declare const podfile: {
11
+ findManifest(rootPath: string): Promise<string | null>;
12
+ parse(file: string): Promise<ParsedManifest>;
13
+ };
14
+ export declare const gradle: {
15
+ findManifest(rootPath: string): Promise<string | null>;
16
+ parse(file: string): Promise<ParsedManifest>;
17
+ };
@@ -0,0 +1,24 @@
1
+ import { type OptInFile } from './types';
2
+ import type { Tier } from '../orchestration-shell/types';
3
+ export declare function optInFilePath(): string;
4
+ /**
5
+ * Per Stage 2 r1 Gemini M-1: reader takes `currentTier`. If
6
+ * `parsed.tierAtOptIn !== currentTier`, returns `null` (graceful tier-
7
+ * downgrade invalidation — no error throw).
8
+ */
9
+ export declare function readOptIn(currentTier: Tier): Promise<OptInFile | null>;
10
+ /**
11
+ * Per Stage 2 r1 Gemini H-3 option (a): widen to `Tier` so callers can
12
+ * pass `args.tier` directly without an unsafe type narrow. Runtime gate
13
+ * inside the function is authoritative; non-MAX throws `tier_gate`.
14
+ *
15
+ * Stage 2 r2 fix (H-1, Codex): validates that `bodyPath` is absolute
16
+ * BEFORE any persistence work. Normalises via `path.resolve()`
17
+ * (defense-in-depth — strips any residual `..` segments) and resolves
18
+ * symlinks via `fs.realpath()`. The realpath result is what gets
19
+ * persisted, so a future `cd` that lands the user in a different repo
20
+ * cannot trip a relative-path match. Throws `StructuralSummaryError(
21
+ * 'invalid_path')` for non-absolute or unresolvable inputs.
22
+ */
23
+ export declare function addBodyPath(bodyPath: string, currentTier: Tier): Promise<OptInFile>;
24
+ export declare function removeBodyPath(bodyPath: string): Promise<OptInFile>;
@@ -0,0 +1,110 @@
1
+ import type { ExclusionState } from './types';
2
+ /**
3
+ * Stage 2 IMPL r2 fix (H-3, Codex H-2): strict path-containment helper.
4
+ *
5
+ * Returns true iff `rel` (the output of `path.relative(root, target)`)
6
+ * denotes a path OUTSIDE `root` via parent-directory traversal. Required
7
+ * because the naive `rel.startsWith('..')` form falsely classifies valid
8
+ * child names that happen to BEGIN with `..` (e.g., `..scratch/file.ts`,
9
+ * `..hidden`, `..foo/bar`) as outside the root.
10
+ *
11
+ * Correct semantics:
12
+ * rel === '..' → outside (parent of root)
13
+ * rel === '..' + path.sep + 'sib' → outside (sibling of root)
14
+ * rel === '..' + '/' + 'sib' → outside (POSIX form, used by
15
+ * git output / forward-slash
16
+ * callers on Windows)
17
+ * rel === '..foo' → INSIDE (child whose name
18
+ * starts with `..`)
19
+ *
20
+ * Used in: walker.ts `buildExclusionState` (realRootPath outside-repo
21
+ * check + untracked subtree filter) and privacy-filter.ts
22
+ * `isPathAdmissible` (relative-to-realRootPath admission).
23
+ */
24
+ export declare function isOutsideRoot(rel: string): boolean;
25
+ /**
26
+ * Static secret-file deny-list. Matches `.env`, `.env.*`, `.aws/credentials`,
27
+ * and assorted private-key formats. Matched against absolute-path basename
28
+ * and a few suffix patterns. Per §4.3 step 2 first match.
29
+ */
30
+ export declare const SECRET_DENY_LIST: readonly string[];
31
+ /**
32
+ * Pure path test — returns true if `absolutePath` matches any secret
33
+ * deny-list pattern. The walker uses this to skip secret files silently
34
+ * (no counter increment per §4.3 hard-caps audit-quality note).
35
+ */
36
+ export declare function matchesSecretDenyList(absolutePath: string): boolean;
37
+ /**
38
+ * Helper exported alongside `isPathAdmissible`: returns true if
39
+ * `absolutePath` is either:
40
+ * (a) an exact entry in `exactPaths` — file-level gitignore match,
41
+ * O(1) `Set.has(p)`; OR
42
+ * (b) equal to OR a descendant of an entry in `dirPrefixes` —
43
+ * directory-level gitignore match, implemented via check-then-step
44
+ * ancestor-walk:
45
+ *
46
+ * let p = absolutePath;
47
+ * while (true) {
48
+ * if (dirPrefixes.has(p)) return true;
49
+ * const parent = path.dirname(p);
50
+ * if (parent === p) return false; // filesystem root reached
51
+ * p = parent;
52
+ * }
53
+ *
54
+ * Key properties (per round-7 revision Codex r6 H-1 + Gemini r6 H-1/M-2):
55
+ *
56
+ * 1. **Signature is 3-arg** `(absolutePath, exactPaths, dirPrefixes)`.
57
+ * The helper does NOT receive `realRootPath`. The walk MUST proceed
58
+ * past `realRootPath` because `git ls-files --directory` may report
59
+ * an ignored ancestor ABOVE the launch root (e.g., parent
60
+ * `.gitignore` ignores `sub/` when launch root is `repo/sub/inner`).
61
+ * 2. **Check-then-step semantics**: check `dirPrefixes.has(p)` BEFORE
62
+ * advancing `p`. This handles the case where `absolutePath` is
63
+ * itself an entry in `dirPrefixes` (e.g., Step 0.5 root admission
64
+ * tests `realRootPath` directly when it is itself ignored).
65
+ * 3. **Loop termination**: when `path.dirname(p) === p` (POSIX `/`,
66
+ * Windows `C:\`). NO early termination at `realRootPath`.
67
+ *
68
+ * Lookup cost is O(absolute filesystem depth) (typically <30 on any sane
69
+ * mount tree), independent of `|dirPrefixes|`.
70
+ */
71
+ export declare function isPathInIgnoredPrefixes(absolutePath: string, exactPaths: Set<string>, dirPrefixes: Set<string>): boolean;
72
+ /**
73
+ * INTERNAL helper (not exported from the module index, but exported here
74
+ * so the manifest dispatcher + README reader can import it). Returns true
75
+ * iff `realFile` is already accounted for in the walker's two-set ledger
76
+ * (exact match OR equal-to-or-descendant-of an entry in pruned prefixes).
77
+ *
78
+ * Same canonical algorithm as `isPathInIgnoredPrefixes` — 3-arg signature,
79
+ * check-then-step, filesystem-root termination. Per round-7 revision
80
+ * Gemini r6 M-1 + Codex r6 H-1 + Gemini r6 M-2.
81
+ */
82
+ export declare function isPathAccountedFor(realFile: string, countedExactPaths: Set<string>, countedPrunedPrefixes: Set<string>): boolean;
83
+ /**
84
+ * Order of checks (mirrors §4.3 step 2, first match wins):
85
+ * 1. secret (deny-list path-glob match — operates on basename + suffix).
86
+ * 2. untracked (`state.untrackedSet.has(absolutePath)`; SKIPPED if
87
+ * notInGitRepo).
88
+ * 3. gitignore (`isPathInIgnoredPrefixes(...)`; SKIPPED if notInGitRepo).
89
+ * 4. userIgnore (`state.userIgnoreMatcher.ignores(path.relative(
90
+ * realRootPath, absolutePath), isDir)`).
91
+ *
92
+ * Pure in-memory check; consults only the pre-built `state`. No I/O.
93
+ *
94
+ * `isDir` (Stage 2 r2 fix, M-2 Gemini M-1): walker passes
95
+ * `entry.isDirectory()` here. File-only callers (manifest dispatcher,
96
+ * README reader) accept the default `false`. The flag is consumed by
97
+ * `userIgnoreMatcher.ignores()` to honour trailing-slash `dir/` rules.
98
+ *
99
+ * Caller is responsible for incrementing the appropriate counter on
100
+ * `privacyEnvelope` when `admissible === false` (so audit signal is
101
+ * preserved). `reason === 'secret'` is silent (no counter — per §4.3
102
+ * hard-caps audit-quality note).
103
+ */
104
+ export declare function isPathAdmissible(absolutePath: string, state: ExclusionState, isDir?: boolean): {
105
+ admissible: true;
106
+ } | {
107
+ admissible: false;
108
+ reason: 'secret' | 'untracked' | 'gitignore' | 'userIgnore';
109
+ };
110
+ export type { ExclusionState } from './types';
@@ -0,0 +1,11 @@
1
+ /**
2
+ * TOCTOU-safe text file read. Returns the file contents as UTF-8 or
3
+ * `null` on any refusal / error. See module JSDoc for the syscall
4
+ * sequence + threat model.
5
+ *
6
+ * @param absPath Absolute filesystem path. Caller is responsible for
7
+ * path absolutism + admission-oracle checks BEFORE
8
+ * invoking this function; this helper only guards the
9
+ * lstat→open transition.
10
+ */
11
+ export declare function safeReadTextFile(absPath: string): Promise<string | null>;