@quantiya/codevibe-claude-plugin 2.0.28 → 2.0.29

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 (24) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/node_modules/@quantiya/codevibe-core/dist/index.d.ts +5 -1
  3. package/node_modules/@quantiya/codevibe-core/dist/index.js +442 -419
  4. package/node_modules/@quantiya/codevibe-core/dist/local-executor/__tests__/local-executor-teams-summary.test.d.ts +1 -0
  5. package/node_modules/@quantiya/codevibe-core/dist/local-executor/hook-bridge.d.ts +2 -1
  6. package/node_modules/@quantiya/codevibe-core/dist/local-executor/index.d.ts +5 -0
  7. package/node_modules/@quantiya/codevibe-core/dist/local-executor/local-executor-impl.d.ts +16 -0
  8. package/node_modules/@quantiya/codevibe-core/dist/local-executor/team-summary.d.ts +151 -0
  9. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/audit-buffer-join.test.d.ts +1 -0
  10. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/audit-normalization.test.d.ts +1 -0
  11. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/audit-summary.test.d.ts +1 -0
  12. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/decision-map-lifecycle.test.d.ts +1 -0
  13. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/query_audit_tier_gate.test.d.ts +1 -0
  14. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/quorum-loop-fail-safe.test.d.ts +1 -0
  15. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/__tests__/quorum-loop-summary.test.d.ts +1 -0
  16. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/audit-runner.d.ts +25 -0
  17. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/audit-summary.d.ts +240 -0
  18. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/cli.d.ts +11 -3
  19. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/cli.js +3348 -678
  20. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/gate-decision-submit.d.ts +1 -1
  21. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/index.d.ts +23 -2
  22. package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/quorum-loop.d.ts +96 -1
  23. package/node_modules/@quantiya/codevibe-core/package.json +2 -2
  24. package/package.json +2 -2
@@ -62,7 +62,7 @@ export interface GateDecisionSubmitDeps {
62
62
  * 2026-06-11, option-4 "Reject and restart"). `undefined` when no shadow was
63
63
  * mapped at decision time (or no loop is wired).
64
64
  */
65
- onTerminalDecision?: (taskId: string, postAction: PostDecisionAction, expectedShadow?: unknown) => Promise<void> | void;
65
+ onTerminalDecision?: (taskId: string, postAction: PostDecisionAction, expectedShadow?: unknown, canonicalDecision?: string) => Promise<void> | void;
66
66
  /**
67
67
  * Optional — resolves the live shadow INSTANCE for a task at decision time. Read
68
68
  * ONCE at the TOP of `submitGateDecision` (BEFORE the `applyUserDecision` SDK
@@ -131,6 +131,10 @@ export interface RunOrchestrationShellArgs {
131
131
  teamShellEventTap?: {
132
132
  fn: (args: TeamTapEvent) => void;
133
133
  };
134
+ /** P36: Store-tap installed by cli.ts so team merge audit summaries are routed into this shell's store. */
135
+ teamMergeAuditSummaryTap?: {
136
+ fn: (summary: any) => void;
137
+ };
134
138
  /**
135
139
  * CP-1.f §3.C.20 — the desktop reviewer-quorum loop driver. Present for a
136
140
  * real Max session (constructed in `cli.ts` alongside the team LE). When
@@ -235,14 +239,20 @@ export { configureContextItemsHostedSync, wakeContextItemsHostedSync, drainConte
235
239
  export { compactSessionContext, maybeFireCompactionSafetyValve, rehydrateSessionContext, renderRehydratedSessionContext, distillItems, projectDistilledForRole, loadCompactionCache, compactionCachePath, onTaskBoundary, gcContextItemLogs, scheduleContextItemsGc, COMPACTION_SAFETY_VALVE_TAIL_BYTES, COMPACTION_KEEP_HOT_RECENT_ITEMS, CONTEXT_ITEMS_RETENTION_MS, SESSION_CONTEXT_SECTION_MAX_CHARS, type DistilledFact, type DistilledTaskSummary, type SessionCompactionCache, type CompactionResult, type RehydratedSessionContext, } from './context-compaction';
236
240
  export { routeSlashCommand, applySlashOutput, type SlashOutput, type ShellAction, } from './slash-router';
237
241
  export { buildAuditBrowserModel, routeAuditEntry, auditKindLabel, auditKindCopy, renderAuditBrowserText, renderAuditEntryText, ENTRY_DETAILS_UNAVAILABLE, NO_AUDIT_ENTRIES, AUDIT_LOG_TOO_LARGE, AUDIT_LOG_TITLE, AUDIT_BROWSER_MAX_HEADLINE, WIRE_PUBLIC_PLAINTEXT_KINDS, formatAuditExport, type AuditDetailRow, type AuditFilterOptions, type AuditExportFormat, type AuditExportPayload, type AuditBrowserModel, type AuditEntryModel, type AuditReviewerVerdictModel, type AuditTaskAuthorizedModel, type DecryptContentFn, } from './audit-browser';
238
- export { runAuditBrowser, renderAuditResultText, AUDIT_BROWSER_UPGRADE_HINT, type RunAuditBrowserResult, type RunAuditBrowserDeps, } from './audit-runner';
242
+ export { runAuditBrowser, renderAuditResultText, AUDIT_BROWSER_UPGRADE_HINT, type RunAuditBrowserResult, type RunAuditBrowserDeps, runAuditSummary, AUDIT_SUMMARY_PRO_MAX_HEADLINE, AUDIT_SUMMARY_UPGRADE_HINT, type RunAuditSummaryResult, type RunAuditSummaryDeps, } from './audit-runner';
243
+ export { compileAuditSummary, renderSummaryMarkdown, isTaskCompletionAuditSummary, type TaskAuditSummaryModel, type AuditSeatModel, type AuditFindingModel, type VerificationResultModel, type TaskCompletionOutcome, type UserDecisionRecord, type ReviewHistorySnapshot, } from './audit-summary';
244
+ export { atomicWriteJsonSync, FileDurableTeamDeliveryJournal, wireSnapshotMergeObserver, adaptSnapshotMergeResult, runSnapshotMergeWithObservedCleanup, emitTeamCompletionSummary, type AtomicWriteOptions, type TeamDeliveryJournalEntry, type TeamDeliveryRouting, type SnapshotCleanupObserver, type WireSnapshotMergeObserverResult, type AdaptedSnapshotMergeResult, type RunSnapshotMergeWithObservedCleanupOptions, type EmitTeamCompletionSummaryOptions, type EmitTeamCompletionSummaryResult, } from '../local-executor/team-summary';
239
245
  export { buildAuditFlagIndex, runFlagCommand, renderFlagResultText, FLAG_NO_INDEX_LINE, type RunFlagCommandResult, type RunFlagCommandDeps, type FlagAppSyncClient, } from './flag-command';
240
246
  export { AuditLogPanel } from './components/AuditLogPanel';
247
+ export { renderConversationEntry, ConversationPane } from './components/ConversationPane';
248
+ export { renderEntryAsLine, runLineLogFallback } from './non-tty-fallback';
249
+ export { initInkRuntime, getInkRuntime } from './ink-runtime';
241
250
  export { reducer } from './reducer';
242
251
  export { createOrchestrationStore, type OrchestrationStore } from './store';
243
252
  export type { Mode, Tier, PlannerDecision, AgentKind, PlannerHealthState, RunningTaskState, ReviewerSeatState, GateState, ExecutionEventEntry, RefusalEventEntry, BypassEventEntry, MobileEventEntry, EventStreamEntry, ConversationEntry, QueuedTask, PendingClarification, OrchestrationState, OrchestrationAction, LastModeFile, TeamState, TeamTrackEntry, TeamTrackState, TeamMergeGateStatus, LiveProgress, } from './types';
244
253
  export { formatElapsed, isSpinnerPhase, renderProgressLine, type TaskProgressEvent, type OnProgress, } from './task-progress';
245
254
  export { runDeclaredTestSurfaces, DECLARED_TEST_TIMEOUT_MS, type DeclaredTestResult, type DeclaredTestReason, type RunDeclaredTestSurfacesArgs, } from './declared-test-runner';
255
+ export { QuorumLoop, type QuorumLoopDeps } from './quorum-loop';
246
256
  /**
247
257
  * [A1g] Round-5 (Codex round-4 MEDIUM) — INVOCATION-OWNED conversation deltas.
248
258
  *
@@ -296,6 +306,13 @@ export declare const turnAuthoringContext: AsyncLocalStorage<TurnAuthoringSink>;
296
306
  * OUTERMOST diff — never double-pushed.
297
307
  */
298
308
  export declare function installTurnAuthoringDispatchWrapper(store: OrchestrationStore): void;
309
+ /**
310
+ * P36 / R7-F1: Wire team merge audit summary dispatch to desktop conversation store.
311
+ */
312
+ export declare function wireTeamMergeAuditSummary(store: OrchestrationStore, target: {
313
+ fn?: (summary: any) => void;
314
+ onTeamMergeAuditSummary?: (summary: any) => void;
315
+ }): void;
299
316
  /**
300
317
  * §5 lines 336-365 LOCK + §16 LOCK #14. Single entrypoint that wires
301
318
  * the store + emit chokepoint + slash router and either mounts the
@@ -364,7 +381,11 @@ export declare const TASK_REVIEW_SUMMARY_FETCH_TIMEOUT_MS = 5000;
364
381
  * dispatcher stays decoupled from the SDK + session-key plumbing (and is
365
382
  * unit-testable with a mock).
366
383
  */
367
- export type ReviewSummaryFetcher = (taskId: string, gateId: string, sessionId: string) => Promise<DecryptedReviewSummaryInput | null>;
384
+ export type ReviewSummaryFetcher = (taskId: string, gateId: string, sessionId: string, options?: {
385
+ isAbandoned?: () => boolean;
386
+ expectedGeneration?: number;
387
+ expectedFence?: number;
388
+ }) => Promise<DecryptedReviewSummaryInput | null>;
368
389
  export declare function handleSubscribedEvent(event: Event, store: OrchestrationStore, sessionKeyResolver?: (sessionId: string) => Promise<string | null>, reviewSummaryFetcher?: ReviewSummaryFetcher, maybeAutoContinue?: (envelope: GatePromptEnvelope) => boolean, onDurableGateResolution?: (resolution: DurableGateResolution) => Promise<void> | void): void;
369
390
  /**
370
391
  * Route a `USER_PROMPT` sent from the paired MOBILE companion into the shell's
@@ -3,6 +3,9 @@ import type { Session } from '../types';
3
3
  import type { LocalExecutor } from '../local-executor';
4
4
  import type { ClassBInbound } from '../local-executor/types';
5
5
  import type { ImageAttachment } from './types';
6
+ import { type TaskAuditSummaryModel, type ReviewHistorySnapshot, type UserDecisionRecord } from './audit-summary';
7
+ import type { DecryptedReviewSummaryInput } from './gate-prompts';
8
+ import type { ShellEventEmit, ShellEventEmitResult } from './emit-shell-event';
6
9
  import { type ImplementorMode } from '../local-executor/implementor-argv';
7
10
  import { type FallbackLadderDeps } from '../substrate-launch/fallback-ladder';
8
11
  import type { ConflictModelCaller } from '../local-executor/class2-resolver';
@@ -160,13 +163,23 @@ export interface RoundFindingRecord {
160
163
  seatId: string;
161
164
  role: ReviewerRole;
162
165
  reviewerAgent: ReviewerAgentKind;
163
- verdict: VerdictKind;
166
+ verdict: VerdictKind | string;
164
167
  /** Capped to HISTORY_SUGGESTION_MAX_CHARS each at capture. */
165
168
  suggestedChanges: string[];
166
169
  /** Capped to HISTORY_REASONING_MAX_CHARS at capture. Stored for audit /
167
170
  * bounded reuse; NOT rendered into the brief (the brief carries verdict +
168
171
  * suggested changes only). */
169
172
  reasoning: string;
173
+ /** P36: Optional review metadata preserved for task audit summary. */
174
+ modelUsed?: string | null;
175
+ tokensUsed?: number | null;
176
+ latencyMs?: number | null;
177
+ durationSeconds?: number | null;
178
+ residualObservations?: string[];
179
+ /** P36 / R1-F9: Preserved degradation metadata when history budget is exceeded. */
180
+ historyDegraded?: boolean;
181
+ omittedFindingsCount?: number;
182
+ omittedResidualsCount?: number;
170
183
  }
171
184
  /**
172
185
  * A1b — ONE implementor rationale entry (Stage-2 R1 Codex LOW-4: the round is
@@ -529,6 +542,15 @@ export interface QuorumLoopDeps {
529
542
  * `expiresAt = now + TTL`. ABSENT → the default `CONTINUATION_EXPIRES_TTL_MS`.
530
543
  */
531
544
  continuationTtlMs?: number;
545
+ /**
546
+ * P36: Task-completion audit summary local store callback.
547
+ * Dispatched directly to desktop store upon task completion.
548
+ */
549
+ onTaskAuditSummary?: (summary: TaskAuditSummaryModel, markdown: string) => void;
550
+ /**
551
+ * P36: Emitter for companion notification event.
552
+ */
553
+ emitShellEvent?: (args: ShellEventEmit) => Promise<ShellEventEmitResult>;
532
554
  }
533
555
  /**
534
556
  * Map the lowercase wire `AgentKind` (`"claude"`) used by the engine dispatch
@@ -670,6 +692,30 @@ export declare class QuorumLoop {
670
692
  * exactly: cleared on promote / discard / round-0 restart replacement.
671
693
  */
672
694
  private readonly roundHistoryByTask;
695
+ /**
696
+ * P36: Bounded FIFO map (max 500) of the most recent user decision per task,
697
+ * recorded by `recordUserDecision` and evicted on task promotion.
698
+ */
699
+ private readonly lastUserDecisionByTask;
700
+ /**
701
+ * P36: Bounded cache of recently completed task summary metadata (max 100).
702
+ * Enables reconciliation if a user decision arrives or is replayed after promotion.
703
+ */
704
+ private readonly completedTaskSummaries;
705
+ private readonly expectedRosterByTask;
706
+ private readonly taskDegradedMetadataByTask;
707
+ private getCompletedSummariesPath;
708
+ private shouldUnlinkAbandonedTmpLockFile;
709
+ private withCompletedSummariesLock;
710
+ private loadCompletedSummariesFromDisk;
711
+ private recordCompletedTaskSummary;
712
+ getCompletedTaskSummary(taskId: string): {
713
+ historySnapshot?: ReviewHistorySnapshot | null;
714
+ filesApplied: number;
715
+ completedAt: string;
716
+ originEpoch?: number;
717
+ workspaceApplicationStatus?: "pending_merge_gate" | "applied" | "unobserved";
718
+ } | undefined;
673
719
  /**
674
720
  * A1b — the implementor's own per-round stdout rationale (the
675
721
  * `extractAgentSummary` text), recorded as `{ round, text }` (LOW-4: labels
@@ -826,6 +872,11 @@ export declare class QuorumLoop {
826
872
  * cardinality is bounded by those same dedup sets).
827
873
  */
828
874
  private readonly taskByGateId;
875
+ private readonly activeGateByTaskId;
876
+ private readonly conflictedSeatsByTask;
877
+ private readonly nonApprovedSeatsByTask;
878
+ private readonly restartFenceByTaskId;
879
+ private readonly gateFenceByGateId;
829
880
  /** Exact immutable team generation that authored each team gate. */
830
881
  private readonly teamAuthorityByGateId;
831
882
  /**
@@ -1158,6 +1209,7 @@ export declare class QuorumLoop {
1158
1209
  /** Installed by the session-owning shell after both objects are constructed. */
1159
1210
  setWorkspaceOutcomeSink(sink: WorkspaceOutcomeSink | undefined): void;
1160
1211
  isWorkspaceTaskTerminallyRetired(taskId: string): boolean;
1212
+ isTaskTerminallyRetired(taskId: string): boolean;
1161
1213
  /** The current active task id (for the recovery poll). */
1162
1214
  get activeTask(): string | null;
1163
1215
  /** Arm an explicit, one-shot comprehensive baseline for the active task. */
@@ -1605,6 +1657,49 @@ export declare class QuorumLoop {
1605
1657
  * taskId (SECURITY INVARIANT: no user content, mirrors `discarded`).
1606
1658
  */
1607
1659
  reportFinalApprovalCancelled(taskId: string, postAction: PostDecisionAction): void;
1660
+ /**
1661
+ * P36: Record a user decision for task audit summary compilation.
1662
+ * Evicts the oldest entry if size exceeds 500 (FIFO).
1663
+ */
1664
+ recordUserDecision(taskId: string, decision: UserDecisionRecord): void;
1665
+ /**
1666
+ * P36: Snapshot in-memory round findings history before eviction at promote.
1667
+ */
1668
+ captureReviewHistorySnapshot(taskId: string): ReviewHistorySnapshot;
1669
+ /**
1670
+ * R18-F4: Sanitize history record for snapshot so internal raw caches and scratch fields
1671
+ * are never copied into the serialized snapshot or persistence layer.
1672
+ */
1673
+ private sanitizeHistoryRecordForSnapshot;
1674
+ /**
1675
+ * P36: Wire or replace the desktop task-completion audit summary callback.
1676
+ */
1677
+ setOnTaskAuditSummary(fn: (summary: TaskAuditSummaryModel, markdown: string) => void): void;
1678
+ /**
1679
+ * P36 / R13-F1 / R14-F2 / R14-F3 / R14-F4 / R14-F5:
1680
+ * Ingest wire review summary fetched from AppSync (getTaskReviewSummary)
1681
+ * into the in-memory roundHistoryByTask map so post-promotion task audit summary
1682
+ * generation has full reviewer provenance without requiring preloaded disk fixtures.
1683
+ *
1684
+ * Reconciles idempotently by (roundNum, seatIdStr), preserving local high-fidelity telemetry,
1685
+ * enforces fail-closed roster declaration from reviewQuorum.seats, parses verdicts strictly
1686
+ * (never defaulting missing/invalid decisions to APPROVE), tracks degradation metadata,
1687
+ * and rejects late fetches for terminally retired or completed tasks.
1688
+ */
1689
+ ingestReviewSummary(taskId: string, summary: DecryptedReviewSummaryInput): void;
1690
+ /**
1691
+ * Public helper to retrieve the task's current restart generation fence.
1692
+ */
1693
+ getRestartFence(taskId: string): number;
1694
+ /**
1695
+ * Statically/externally register an active gate mapping for a task (e.g., prompt arrival or test fixture).
1696
+ */
1697
+ registerActiveGate(taskId: string, gateId: string, roundNumber?: number, generationFence?: number): void;
1698
+ /**
1699
+ * Check whether an incoming gate review summary is still relevant for the specified task.
1700
+ * Rejects requests if task is retired, summary is completed, or gate does not match active task gate and restart fence.
1701
+ */
1702
+ isGateRelevantForTask(taskId: string, gateId: string, expectedGeneration?: number, expectedFence?: number): boolean;
1608
1703
  /**
1609
1704
  * Authoritative TaskGroupHalted bridge from LocalExecutor. Calling this async
1610
1705
  * method publishes the terminal group fence synchronously (before its first
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quantiya/codevibe-core",
3
- "version": "2.0.24",
3
+ "version": "2.0.25",
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",
@@ -17,7 +17,7 @@
17
17
  "typecheck": "tsc --noEmit",
18
18
  "emit-types": "tsc --emitDeclarationOnly",
19
19
  "build": "rm -rf dist && npm run emit-types && esbuild src/index.ts --bundle --platform=node --target=node18 --minify --packages=external --define:__CODEVIBE_TEST_BUILD__=false --outfile=dist/index.js && esbuild src/orchestration-shell/cli.ts --bundle --platform=node --target=node18 --minify-syntax --packages=external --define:__CODEVIBE_TEST_BUILD__=false --outfile=dist/orchestration-shell/cli.js --banner:js=\"#!/usr/bin/env node\" && npm run verify-no-test-hooks",
20
- "verify-no-test-hooks": "if grep -ERl 'CODEVIBE_TEST_FORCE_QUOTA_FAIL|CODEVIBE_TEST_FORCE_IMPLEMENTOR_AGENT|CODEVIBE_ANCHORED_PUBLICATION_AUTHORITY_ROOT|codevibe-anchored-publications-|cv-publication-authority-vitest-|codevibe\\.test\\.publication-authority-|setPublicationAuthorityRootForTestBuild|__CODEVIBE_TEST_BUILD__' dist; then echo 'ERROR: a test-only hook leaked into a published artifact (prod-unreachability invariant)'; exit 1; fi; echo 'OK — no test-only hooks in published artifacts'",
20
+ "verify-no-test-hooks": "if grep -ERl 'CODEVIBE_TEST_FORCE_QUOTA_FAIL|CODEVIBE_TEST_FORCE_IMPLEMENTOR_AGENT|CODEVIBE_ANCHORED_PUBLICATION_AUTHORITY_ROOT|codevibe-anchored-publications-|cv-publication-authority-vitest-|codevibe\\.test\\.publication-authority-|setPublicationAuthorityRootForTestBuild|__CODEVIBE_TEST_BUILD__|_onBeforeLinkForTesting|_onBeforeSummariesLockForTesting|__codevibe_test_on_before_link|__codevibe_test_on_before_summaries_lock' dist; then echo 'ERROR: a test-only hook leaked into a published artifact (prod-unreachability invariant)'; exit 1; fi; echo 'OK — no test-only hooks in published artifacts'",
21
21
  "clean": "rm -rf dist",
22
22
  "prepublishOnly": "npm run build",
23
23
  "test": "vitest run",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quantiya/codevibe-claude-plugin",
3
- "version": "2.0.28",
3
+ "version": "2.0.29",
4
4
  "description": "Control Claude Code from your iPhone and Android — real-time sync, approve file edits, send prompts by voice. Part of CodeVibe.",
5
5
  "main": "dist/server.js",
6
6
  "codevibe": {
@@ -48,7 +48,7 @@
48
48
  "node": ">=22.0.0"
49
49
  },
50
50
  "dependencies": {
51
- "@quantiya/codevibe-core": "^2.0.24",
51
+ "@quantiya/codevibe-core": "^2.0.25",
52
52
  "@quantiya/quorum-core": "^1.0.1",
53
53
  "dotenv": "^16.6.1",
54
54
  "express": "^5.1.0",