@quantiya/codevibe-core 2.0.71 → 2.0.73

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 (58) hide show
  1. package/dist/appsync/appsync-client.d.ts +42 -10
  2. package/dist/appsync/queries.d.ts +4 -0
  3. package/dist/appsync/session-freshness.d.ts +12 -0
  4. package/dist/appsync/sync-operation-journal.d.ts +1 -0
  5. package/dist/appsync/sync-session-retirement.d.ts +1 -1
  6. package/dist/appsync/sync-source-pair.d.ts +1 -1
  7. package/dist/index.d.ts +1 -1
  8. package/dist/index.js +650 -569
  9. package/dist/orchestration/detect-agents.d.ts +20 -0
  10. package/dist/orchestration/index.d.ts +1 -1
  11. package/dist/orchestration-shell/audit-summary.d.ts +2 -0
  12. package/dist/orchestration-shell/brainstorm-context.d.ts +11 -0
  13. package/dist/orchestration-shell/cli.d.ts +15 -1
  14. package/dist/orchestration-shell/cli.js +55791 -53028
  15. package/dist/orchestration-shell/conductor-reply.d.ts +37 -0
  16. package/dist/orchestration-shell/context-items.d.ts +64 -0
  17. package/dist/orchestration-shell/doctor-cli.d.ts +2 -0
  18. package/dist/orchestration-shell/index.d.ts +44 -2
  19. package/dist/orchestration-shell/quorum-loop.d.ts +17 -3
  20. package/dist/orchestration-shell/resume-modal.d.ts +19 -0
  21. package/dist/orchestration-shell/slash-router.d.ts +2 -0
  22. package/dist/orchestration-shell/types.d.ts +48 -2
  23. package/dist/session/pending-session-create.d.ts +31 -0
  24. package/dist/session-resume/ResumePicker.d.ts +21 -0
  25. package/dist/session-resume/carry-over.d.ts +81 -0
  26. package/dist/session-resume/clean-exit.d.ts +33 -0
  27. package/dist/session-resume/cli-resume.d.ts +41 -0
  28. package/dist/session-resume/completeness-copy.d.ts +52 -0
  29. package/dist/session-resume/create-outcome.d.ts +43 -0
  30. package/dist/session-resume/e2e-fault.d.ts +28 -0
  31. package/dist/session-resume/hosted-loader.d.ts +88 -0
  32. package/dist/session-resume/local-completeness.d.ts +10 -0
  33. package/dist/session-resume/local-records.d.ts +121 -0
  34. package/dist/session-resume/picker-rows.d.ts +17 -0
  35. package/dist/session-resume/publish-retire.d.ts +40 -0
  36. package/dist/session-resume/relaunch.d.ts +72 -0
  37. package/dist/session-resume/restore-conversation.d.ts +27 -0
  38. package/dist/session-resume/resume-candidates.d.ts +52 -0
  39. package/dist/session-resume/resume-chosen.d.ts +103 -0
  40. package/dist/session-resume/resume-create.d.ts +121 -0
  41. package/dist/session-resume/resume-entry.d.ts +87 -0
  42. package/dist/session-resume/resume-header.d.ts +25 -0
  43. package/dist/session-resume/resume-io.d.ts +34 -0
  44. package/dist/session-resume/resume-ledger.d.ts +107 -0
  45. package/dist/session-resume/resume-messages.d.ts +68 -0
  46. package/dist/session-resume/resume-rows.d.ts +24 -0
  47. package/dist/session-resume/resume-target.d.ts +65 -0
  48. package/dist/session-resume/shell-resume-io.d.ts +25 -0
  49. package/dist/session-resume/shell-resume.d.ts +34 -0
  50. package/dist/session-resume/source-choice.d.ts +37 -0
  51. package/dist/session-resume/successor-carry-over.d.ts +54 -0
  52. package/dist/session-resume/will-retire.d.ts +24 -0
  53. package/dist/tool-activity/ledger.d.ts +5 -0
  54. package/dist/tool-activity/outbox.d.ts +3 -2
  55. package/dist/tool-activity/replay-cursor.d.ts +17 -3
  56. package/dist/tool-activity/sync-transport.d.ts +3 -0
  57. package/dist/types/session.d.ts +67 -0
  58. package/package.json +1 -1
@@ -0,0 +1,34 @@
1
+ import type { RelaunchRequest } from './relaunch';
2
+ import { type ResumeEntryDeps } from './resume-entry';
3
+ export declare const RESUME_DESKTOP_ONLY = "/resume works on the desktop only.";
4
+ export declare const RESUME_RUNNING_WORK = "Finish or cancel the running work first \u2014 /status shows it.";
5
+ export declare const RESUME_NEEDS_PAID_TIER = "Resuming a session needs CodeVibe Pro or Max.";
6
+ export declare const RESUME_CANCELLED = "Resume cancelled. This session continues.";
7
+ export type ShellResumeOutcome =
8
+ /** Print and keep this session running (an empty text prints nothing). */
9
+ {
10
+ kind: 'message';
11
+ text: string;
12
+ }
13
+ /** End this session through `/exit`, then relaunch as the resume of P. */
14
+ | {
15
+ kind: 'switch';
16
+ request: RelaunchRequest;
17
+ };
18
+ /** Step 1's first checks, before anything is read (a phone, Free, running work). */
19
+ export declare function shellResumePreCheck(args: {
20
+ origin: 'keyboard' | 'mobile';
21
+ paidTier: boolean;
22
+ hasRunningWork(): boolean;
23
+ }): string | null;
24
+ export declare function runShellResume(args: {
25
+ /** `/resume <id>`; null opens the picker (or lists without a terminal). */
26
+ id: string | null;
27
+ origin: 'keyboard' | 'mobile';
28
+ /** Pro or Max. */
29
+ paidTier: boolean;
30
+ hasRunningWork(): boolean;
31
+ ownSessionId: string;
32
+ /** Entry-point deps built for this shell (`ownSessionId` set; in-shell picker and choice). */
33
+ deps: ResumeEntryDeps;
34
+ }): Promise<ShellResumeOutcome>;
@@ -0,0 +1,37 @@
1
+ /**
2
+ * P61 §8.1 — which copy of P's context a resume reads, and whether this
3
+ * process may write P's directory. Pure over what the caller has already
4
+ * established: the resume lock, P's owner record here, a read-only read of
5
+ * P's local log, and whether P ran on this computer.
6
+ */
7
+ import type { ContextItem, ReadOnlyContextLogResult } from '../orchestration-shell/context-items';
8
+ import type { OwnerRecordState } from './local-records';
9
+ /** Why a resume on the computer where P ran uses the hosted copy (the §8.1 fallback-reason table). */
10
+ export type HostedFallbackReason = 'keychain-unavailable' | 'local-log-absent' | 'unreadable-local-log';
11
+ export type ResumeSourceChoice = {
12
+ source: 'local';
13
+ items: ContextItem[];
14
+ tail: {
15
+ seq: string;
16
+ itemSha256: string;
17
+ } | null;
18
+ /** P's owner is finished or dead: this resumer is P's sole post-mortem writer and drains P's outbox (best effort). */
19
+ postMortemWriter: boolean;
20
+ } | {
21
+ source: 'hosted';
22
+ /** Null when P ran on another computer. */
23
+ fallbackReason: HostedFallbackReason | null;
24
+ }
25
+ /** Every local line unsealed but the chain did not verify: refused, no fallback. */
26
+ | {
27
+ source: 'refuse-integrity';
28
+ }
29
+ /** P's own process is still closing here (§8.1 copy). */
30
+ | {
31
+ source: 'still-closing';
32
+ };
33
+ export declare function chooseResumeSource(args: {
34
+ ownerState: OwnerRecordState;
35
+ ranHere: boolean;
36
+ local: ReadOnlyContextLogResult;
37
+ }): ResumeSourceChoice;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * P61 INV-5 (design §8.5) for an interrupted resume found at a resume entry
3
+ * point (§6.2 step 2): S's shell starts, and S's create is replayed, only on a
4
+ * verified local carry-over that ends in its marker for P.
5
+ *
6
+ * S's log is first classified with the read-only reader (B-8), so nothing in
7
+ * S's directory changes on the way to a refusal. When the log cannot show the
8
+ * marker, the three INV-5 cases apply:
9
+ * - keychain unavailable: fail closed with the §8.1 keychain copy;
10
+ * - P still inside its window: S's log is set aside (exact-path rename to the
11
+ * shipped `log.jsonl.unrecoverable-<ms>` shape, never deleted) and the
12
+ * carry-over is rebuilt from P as a fresh log, re-verified and re-sealed;
13
+ * - otherwise: fail closed with the applicable §8.1 copy.
14
+ * The rebuild runs under P's resume lock, as S's recorded owner (INV-1).
15
+ */
16
+ import type { ContextItem, ReadOnlyContextLogResult } from '../orchestration-shell/context-items';
17
+ import { type ResumeChosenDeps } from './resume-chosen';
18
+ import { type ResumeLedgerRecord } from './resume-ledger';
19
+ /** Why S's log does not show a verified carry-over ending in its marker. */
20
+ export type SuccessorLogFailure = 'absent' | 'integrity' | 'unreadable' | 'no-marker';
21
+ export type SuccessorLogState = {
22
+ kind: 'verified';
23
+ items: ContextItem[];
24
+ marker: ContextItem;
25
+ } | {
26
+ kind: 'keychain-unavailable';
27
+ } | {
28
+ kind: 'unverifiable';
29
+ reason: SuccessorLogFailure;
30
+ };
31
+ /** Classify a read-only read of S's log against the ledger's sealed marker. */
32
+ export declare function classifySuccessorLog(read: ReadOnlyContextLogResult, marker: ResumeLedgerRecord['marker']): SuccessorLogState;
33
+ export type SuccessorRebuildResult = {
34
+ kind: 'rebuilt';
35
+ record: ResumeLedgerRecord;
36
+ items: ContextItem[];
37
+ marker: ContextItem;
38
+ warnings: string[];
39
+ } | {
40
+ kind: 'refused';
41
+ text: string;
42
+ } | {
43
+ kind: 'cancelled';
44
+ };
45
+ /** INV-5's second and third cases. The caller holds P's lock and has taken over S's owner record. */
46
+ export declare function rebuildSuccessorCarryOver(args: {
47
+ record: ResumeLedgerRecord;
48
+ reason: SuccessorLogFailure;
49
+ /** The targeted resume in a terminal; any other replay never prompts. */
50
+ interactive: boolean;
51
+ chosen: ResumeChosenDeps;
52
+ /** Rename S's log aside by exact path, if it exists. */
53
+ setAsideSuccessorLog(successorSessionId: string): Promise<void>;
54
+ }): Promise<SuccessorRebuildResult>;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * P61 `willRetire` (SESSION-RESUME-DESIGN.md §6.2 step 3): the shared
3
+ * definition of a row this launch retires. The `--continue` comparison and the
4
+ * pre-listing retire both evaluate it on the same step-1 `listSessions` read,
5
+ * so they can never disagree (C2-F5).
6
+ */
7
+ import { type SessionFreshnessFields } from '../appsync/session-freshness';
8
+ import type { OwnerRecordState } from './local-records';
9
+ /** The plain-launch orphan threshold the pre-listing sweep shares (`cli.ts` sweep). */
10
+ export declare const PRE_LISTING_STALE_THRESHOLD_MS: number;
11
+ export interface RetireCandidateRow extends SessionFreshnessFields {
12
+ sessionId: string;
13
+ agentType: string;
14
+ status: string;
15
+ }
16
+ export interface WillRetireContext {
17
+ nowMs: number;
18
+ /** The session running in this process, never retired. */
19
+ ownSessionId?: string;
20
+ /** This computer's owner-record state for the row's session. */
21
+ ownerState: OwnerRecordState;
22
+ staleThresholdMs?: number;
23
+ }
24
+ export declare function willRetire(row: RetireCandidateRow, ctx: WillRetireContext): boolean;
@@ -212,6 +212,11 @@ export declare class ToolActivityLedger {
212
212
  markTerminal(clientEventId: string, invocationIds?: string[]): Promise<void>;
213
213
  /** Retirement is permanent replay suppression, not delivery/quota settlement. */
214
214
  markRetired(clientEventId: string, invocationIds: string[]): Promise<void>;
215
+ /** One durable mutation per bounded retirement page, not per window. */
216
+ markRetiredWindows(windows: readonly {
217
+ clientEventId: string;
218
+ invocationIds: string[];
219
+ }[]): Promise<void>;
215
220
  /** R2 keeps a window settlement independently of occurrence remapping/pruning. */
216
221
  markSettled(clientEventId: string, invocationIds: string[], disposition: 'acked' | 'terminal', requireDirectorySync?: boolean): Promise<void>;
217
222
  /**
@@ -3,7 +3,7 @@ import type { DesktopSyncSessionScope } from '../appsync/sync-operation-journal'
3
3
  import type { ToolSyncRetirementLocation } from '../appsync/sync-session-retirement';
4
4
  import { ToolActivityOutboxEnvelope } from './types';
5
5
  export interface ToolActivityOutboxOptions {
6
- /** Plugin agent slug — `claude` | `codex` (the on-disk namespace). */
6
+ /** Plugin agent slug — `claude` | `codex` | `agy` (the on-disk namespace). */
7
7
  agent: string;
8
8
  logger: Logger;
9
9
  /** Override the root for tests; defaults to `~/.codevibe/<agent>/tool-activity-outbox`. */
@@ -17,7 +17,7 @@ export interface ListPendingResult {
17
17
  quarantined: string[];
18
18
  }
19
19
  /**
20
- * The durable outbox for ONE consolidated plugin (claude / codex). A pure
20
+ * The durable outbox for ONE consolidated plugin (claude / codex / agy). A pure
21
21
  * durability primitive: persist / list-and-validate / prune / enumerate. The
22
22
  * send orchestration (encrypt-at-send, retry, back-pressure, ack) lives in the
23
23
  * consolidator that owns this outbox.
@@ -60,6 +60,7 @@ export declare class ToolActivityOutbox {
60
60
  * No temp sweep, quarantine, generation rewrite or legacy window deletion. */
61
61
  withRetirementSources<T>(scope: DesktopSyncSessionScope, action: (sources: {
62
62
  windows: ToolActivityOutboxEnvelope[];
63
+ hasMore: boolean;
63
64
  markRetired(): Promise<void>;
64
65
  prune(): Promise<void>;
65
66
  }) => Promise<T>): Promise<T | null>;
@@ -57,6 +57,19 @@ export declare const ReplayCursorStateSchema: z.ZodObject<{
57
57
  carryover: string;
58
58
  }>;
59
59
  export type ReplayCursorState = z.infer<typeof ReplayCursorStateSchema>;
60
+ /** A first-host boundary captured before lifecycle/cloud awaits. This excludes
61
+ * pre-host history; it is NOT a delivery acknowledgement or a copied cursor. */
62
+ export interface ToolReplayInitialBoundary {
63
+ byteOffset: number;
64
+ fileIdentity: {
65
+ dev: number;
66
+ ino: number;
67
+ };
68
+ size: number;
69
+ }
70
+ /** Capture a native boundary synchronously before lifecycle/cloud awaits.
71
+ * Existing partial records remain unread. Memory and reverse lookup are bounded. */
72
+ export declare function captureToolReplayBoundary(filePath: string, initialOffset?: number): ToolReplayInitialBoundary;
60
73
  /** One framed transcript line with its byte span. */
61
74
  export interface ReplayFrame {
62
75
  line: string;
@@ -126,10 +139,11 @@ export declare class ToolReplayCursor {
126
139
  constructor(opts: ToolReplayCursorOptions);
127
140
  private filePath;
128
141
  /**
129
- * Load the persisted cursor. An absent / unreadable / invalid file yields a
130
- * FRESH cursor (rescan from 0) — losing it never skips an occurrence.
142
+ * Existing checkpoints win over a new hosting boundary. Without a boundary,
143
+ * the legacy recovery contract remains rescan-from0. A supplied boundary is
144
+ * used only for a truly absent cursor, never to hide existing corrupt state.
131
145
  */
132
- load(): Promise<void>;
146
+ load(initialBoundary?: ToolReplayInitialBoundary, requireExisting?: boolean): Promise<void>;
133
147
  /** The current durable checkpoint (0 when fresh). */
134
148
  byteOffset(): number;
135
149
  /**
@@ -23,9 +23,12 @@ export declare function retireToolActivityWindows(options: {
23
23
  writer: DurableDesktopSyncWriter;
24
24
  expectedSessionKeyGen: string;
25
25
  confirm(input: ConfirmDesktopSyncRetirementInput): Promise<SyncSessionRetirementReceipt>;
26
+ /** Terminal exit records the existing intent instead of pruning a backlog. */
27
+ deferIfPaged?: boolean;
26
28
  }): Promise<{
27
29
  windowsRemoved: number;
28
30
  operationsRemoved: number;
31
+ hasMore?: true;
29
32
  }>;
30
33
  /**
31
34
  * Shared metered tool transport. An existing ULID window maps deterministically
@@ -69,6 +69,8 @@ export interface Session {
69
69
  * which case the client stamps SESSION_KEY_GEN_ABSENT_SENTINEL.
70
70
  */
71
71
  sessionKeyGen?: string;
72
+ /** P61 — the predecessor this session resumed; selected only by the resume create. */
73
+ resumedFromSessionId?: string | null;
72
74
  }
73
75
  /**
74
76
  * GraphQL input for creating sessions
@@ -91,6 +93,19 @@ export interface CreateSessionInput {
91
93
  * User.orchestrationEnabledDefault (option 6a auto-populate).
92
94
  */
93
95
  orchestrationEnabled?: boolean;
96
+ /**
97
+ * P61 session resume: the ended CODEVIBE session this create continues.
98
+ * Idempotent (creationRequestId) CODEVIBE creates only; the backend claims
99
+ * the predecessor atomically with admission. Absent on every plain create.
100
+ */
101
+ resumedFromSessionId?: string;
102
+ }
103
+ /** P61 clean-exit tail of the context log (design §9.4). */
104
+ export interface ContextTailInput {
105
+ /** The tail item's seq (canonical Crockford ULID). */
106
+ seq: string;
107
+ /** Lowercase SHA-256 hex of the tail item's plaintext JSON. */
108
+ itemSha256: string;
94
109
  }
95
110
  /**
96
111
  * GraphQL input for updating sessions
@@ -105,4 +120,56 @@ export interface UpdateSessionInput {
105
120
  * were retired by A6; current clients do not set this from the CLI.
106
121
  */
107
122
  orchestrationEnabled?: boolean;
123
+ /**
124
+ * P61 clean-exit fields (design §9.4). The backend stores them only on the
125
+ * owner's live→INACTIVE transition of a CODEVIBE session, write-once.
126
+ */
127
+ contextTail?: ContextTailInput;
128
+ contextTailIsResumeMarker?: boolean;
129
+ encryptedLastPrompt?: string;
130
+ }
131
+ /** P61 refusal reasons on ResumeDetails (design §9.2). */
132
+ export type ResumeRefusalReason = 'NOT_ORCHESTRATION' | 'STILL_ACTIVE' | 'ALREADY_RESUMED' | 'WINDOW_CLOSED';
133
+ /** P61 owner-only resume read contract (design §9.2). */
134
+ export interface ResumeDetails {
135
+ sessionId: string;
136
+ agentType: AgentType;
137
+ status: SessionStatus;
138
+ createdAt: string;
139
+ lastHeartbeatAt: string | null;
140
+ /** Epoch seconds; null while live. */
141
+ expiresAt: number | null;
142
+ /** Epoch seconds; null until the live→INACTIVE transition. */
143
+ resumableUntil: number | null;
144
+ resumedFromSessionId: string | null;
145
+ resumedAs: {
146
+ successorSessionId: string;
147
+ claimedAt: string;
148
+ } | null;
149
+ resumable: boolean;
150
+ notResumableReason: ResumeRefusalReason | null;
151
+ /** Ciphertext, as on Session. */
152
+ projectPath: string;
153
+ encryptedLastPrompt: string | null;
154
+ encryptedKeys: EncryptedSessionKey[] | null;
155
+ sessionKeyGen: string | null;
156
+ creatorDeviceId: string | null;
157
+ contextTailSeq: string | null;
158
+ contextTailSha256: string | null;
159
+ contextTailIsResumeMarker: boolean | null;
160
+ }
161
+ export interface ResumableSessionPage {
162
+ items: ResumeDetails[];
163
+ nextToken: string | null;
164
+ }
165
+ /** A hosted ContextItem row: routing ids and ciphertext only (design §9.3). */
166
+ export interface ContextItemRowWire {
167
+ seq: string;
168
+ taskId: string | null;
169
+ trackId: string | null;
170
+ ciphertext: string;
171
+ }
172
+ export interface ContextItemPage {
173
+ items: ContextItemRowWire[];
174
+ nextToken: string | null;
108
175
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quantiya/codevibe-core",
3
- "version": "2.0.71",
3
+ "version": "2.0.73",
4
4
  "description": "Core library for CodeVibe plugins - shared keychain, crypto, AppSync, and auth functionality",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",