@quantiya/codevibe-claude-plugin 2.0.42 → 2.0.43
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.
- package/.claude-plugin/plugin.json +1 -1
- package/node_modules/@quantiya/codevibe-core/dist/index.js +446 -437
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/class-b-consumer.d.ts +5 -5
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/hook-bridge.d.ts +1 -1
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/local-executor-impl.d.ts +52 -20
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/types.d.ts +7 -2
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/workspace-shadow.d.ts +16 -0
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/cli.js +1190 -359
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/components/InputBar.d.ts +1 -0
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/gate-decision-submit.d.ts +26 -5
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/index.d.ts +17 -0
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/non-tty-fallback.d.ts +1 -1
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/quorum-loop.d.ts +223 -51
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/reducer.d.ts +7 -0
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/slash-routes/continuation.d.ts +5 -0
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/task-label.d.ts +25 -0
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/types.d.ts +83 -0
- package/node_modules/@quantiya/codevibe-core/package.json +1 -1
- package/package.json +2 -2
package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/gate-decision-submit.d.ts
CHANGED
|
@@ -89,13 +89,34 @@ type GatePromptEntry = Extract<ConversationEntry, {
|
|
|
89
89
|
kind: 'gate-prompt';
|
|
90
90
|
}>;
|
|
91
91
|
/**
|
|
92
|
-
* §5.1 + #C8M-11 active-gate-prompt scan
|
|
93
|
-
*
|
|
92
|
+
* §5.1 + #C8M-11 active-gate-prompt scan: the OLDEST `kind:'gate-prompt'`
|
|
93
|
+
* entry with `final === false` (head-to-tail). Pure; safe to call from a
|
|
94
94
|
* render path. Returns the entry verbatim so callers can pattern-match the
|
|
95
|
-
* discriminated union directly. (Shared so the TTY component
|
|
96
|
-
* the identical scan.)
|
|
95
|
+
* discriminated union directly. (Shared so the TTY component, the mobile
|
|
96
|
+
* reply route and the non-TTY loop use the identical scan.)
|
|
97
|
+
*
|
|
98
|
+
* P46a (F-P46a-5): this used to be tail-to-head (the NEWEST open gate). With
|
|
99
|
+
* several tasks in flight, gates arrive in bursts, and the newest-wins rule
|
|
100
|
+
* moved the target under the user's fingers — the composer read `Task #2`,
|
|
101
|
+
* a gate for `#3` arrived, and the `1` that was typed for #2 approved #3
|
|
102
|
+
* (E2E r3 q1). Oldest-first keeps the active gate — its pinned card, the
|
|
103
|
+
* composer label `Type a number 1..N · Task #n`, and the gate a digit
|
|
104
|
+
* resolves — stable until the user answers it; newer gates wait their turn.
|
|
105
|
+
*
|
|
106
|
+
* Stage 1 r1 F2(b): an older open gate that is NOT answerable — stuck in
|
|
107
|
+
* `confirming` / `submitting` (the F-P46a-1 wedge) or `claimed` elsewhere —
|
|
108
|
+
* must not block every newer gate: the active gate is the oldest open gate in
|
|
109
|
+
* an ANSWERABLE phase (`awaiting-number` / `awaiting-notes`); when no open gate
|
|
110
|
+
* is answerable, the oldest open one (so the UI still shows its state).
|
|
111
|
+
*
|
|
112
|
+
* Stage 1 r2 F1: that choice is STICKY. Callers holding the store state pass
|
|
113
|
+
* `state.activeGatePromptId` (reducer-owned, see `normalizeActiveGatePrompt`):
|
|
114
|
+
* while that entry is open it stays the active gate, so an older gate whose
|
|
115
|
+
* submit rolled back to `awaiting-number` never takes the digits (or a
|
|
116
|
+
* half-typed note) back from the gate the user is answering. Without an id the
|
|
117
|
+
* scan above applies (pure callers and tests).
|
|
97
118
|
*/
|
|
98
|
-
export declare function findActiveGatePromptEntry(conversation: ReadonlyArray<ConversationEntry
|
|
119
|
+
export declare function findActiveGatePromptEntry(conversation: ReadonlyArray<ConversationEntry>, activeGatePromptId?: string | null): GatePromptEntry | null;
|
|
99
120
|
/**
|
|
100
121
|
* Submit a gate decision: dispatch SUBMIT_STARTED, fire the SDK, dispatch
|
|
101
122
|
* RESOLVED on success (and notify `onTerminalDecision`) or SUBMIT_FAILED on
|
|
@@ -48,6 +48,23 @@ import { contextItemOccurrence, type ContextDurabilityReceipt } from './context-
|
|
|
48
48
|
import { renderRehydratedSessionContext } from './context-compaction';
|
|
49
49
|
import type { AgentKind as LocalExecutorAgentKind } from '../local-executor/types';
|
|
50
50
|
import { type TaskProgressEvent } from './task-progress';
|
|
51
|
+
import { taskLabel } from './task-label';
|
|
52
|
+
/**
|
|
53
|
+
* P46a (Stage 1 r1 F2a) — the oldest unresolved continuation-offer gate
|
|
54
|
+
* prompt, whatever other gates are open. Pure.
|
|
55
|
+
*/
|
|
56
|
+
export declare function findActiveContinuationOfferEntry(conversation: ReadonlyArray<ConversationEntry>): (ConversationEntry & {
|
|
57
|
+
kind: 'gate-prompt';
|
|
58
|
+
}) | null;
|
|
59
|
+
/**
|
|
60
|
+
* P46a (Stage 1 r1 F2c) — a typed digit from the phone cannot choose between
|
|
61
|
+
* several open review gates (the phone shows no task label until P46b): the
|
|
62
|
+
* advisory to send back instead of answering the oldest gate, or null when the
|
|
63
|
+
* reply is not a bare digit or at most one gate is answerable. Pure.
|
|
64
|
+
*/
|
|
65
|
+
export declare function mobileGateReplyAmbiguity(state: Parameters<typeof taskLabel>[0] & {
|
|
66
|
+
conversation: ReadonlyArray<ConversationEntry>;
|
|
67
|
+
}, text: string): string | null;
|
|
51
68
|
export declare class OrchestrationShellStartupError extends Error {
|
|
52
69
|
readonly cause?: unknown;
|
|
53
70
|
constructor(message: string, cause?: unknown);
|
|
@@ -48,7 +48,7 @@ export declare function plannerDecisionRenderEnabled(env?: NodeJS.ProcessEnv): b
|
|
|
48
48
|
* Renders a single `ConversationEntry` as a line-prefixed text string.
|
|
49
49
|
* Strict text only — no ANSI escapes, no colors, no `\r` rewrites.
|
|
50
50
|
*/
|
|
51
|
-
export declare function renderEntryAsLine(entry: ConversationEntry): string;
|
|
51
|
+
export declare function renderEntryAsLine(entry: ConversationEntry, labelFor?: (taskId: string) => string | undefined): string;
|
|
52
52
|
/**
|
|
53
53
|
* Subscribes to the store and prints new conversation entries as
|
|
54
54
|
* line-prefixed text. Returns a promise that resolves on `EXIT` action
|
|
@@ -325,19 +325,6 @@ export interface QuorumLoopDeps {
|
|
|
325
325
|
* unset (see {@link resolveTeamExecution}).
|
|
326
326
|
*/
|
|
327
327
|
teamExecution?: TeamExecution;
|
|
328
|
-
/**
|
|
329
|
-
* CP-7 Stage-2 r3 (Codex) HIGH — ARM the LE's current/authorized task id so
|
|
330
|
-
* the round-0 (and revise) implementor spawn engages the CP-7 trusted-execution
|
|
331
|
-
* substrate instead of the pre-TaskAuthorized reduced-trust path. `startTask`
|
|
332
|
-
* threads the minted taskId here BEFORE the round-0 spawn drains (and rolls it
|
|
333
|
-
* back to `null` on a START rejection); production wires it to
|
|
334
|
-
* `LocalExecutorImpl.setActiveTaskId`. ABSENT (legacy/tests) → the LE's task id
|
|
335
|
-
* is unchanged (the pre-fix behavior); production MUST wire it so the
|
|
336
|
-
* implementor never spawns unbadged/unsandboxed. The same state
|
|
337
|
-
* (`LocalExecutorImpl.taskId`) drives `engageSubstrateForSpawn` (local-executor-
|
|
338
|
-
* impl.ts:566) to call `substrateEngager` rather than emit a `tier:'none'` badge.
|
|
339
|
-
*/
|
|
340
|
-
armLeTaskId?: (taskId: string | null) => void;
|
|
341
328
|
/**
|
|
342
329
|
* CP-7 §8 (Stage-1-resolved) — engage the CP-7 trusted-execution substrate +
|
|
343
330
|
* broker for ONE reviewer seat. When wired (production via cli.ts →
|
|
@@ -599,12 +586,59 @@ interface TeamRunAuthority {
|
|
|
599
586
|
* here closes packet-order races without extending or weakening the wire.
|
|
600
587
|
*/
|
|
601
588
|
export declare function teamRound0GateId(taskId: string, taskGroupId: string, trackIndex: number, dispatchGeneration: number): string;
|
|
589
|
+
/**
|
|
590
|
+
* P46a D1 — the reducer-owned in-session task numbering, reachable from the
|
|
591
|
+
* loop through this sink (installed by the shell after the store exists).
|
|
592
|
+
* `assign` returns the number the store assigned (undefined when unwired);
|
|
593
|
+
* `label` renders `#n` / `#n retry` / the short-id fallback for any task id.
|
|
594
|
+
*/
|
|
595
|
+
export interface TaskOrdinalSink {
|
|
596
|
+
assign(taskId: string, opts: {
|
|
597
|
+
kind: 'single' | 'group';
|
|
598
|
+
retryOf?: string;
|
|
599
|
+
}): number | undefined;
|
|
600
|
+
label(taskId: string): string;
|
|
601
|
+
}
|
|
602
|
+
/** P46a C3 — the desktop-local "could not apply" menu the loop asks the shell to present. */
|
|
603
|
+
export interface ApplyConflictMenu {
|
|
604
|
+
taskId: string;
|
|
605
|
+
taskLabel: string;
|
|
606
|
+
conflicts: Array<{
|
|
607
|
+
path: string;
|
|
608
|
+
cause: 'session-task' | 'external' | 'write-error';
|
|
609
|
+
byTaskLabel?: string;
|
|
610
|
+
}>;
|
|
611
|
+
autoRetried: boolean;
|
|
612
|
+
retryBrief: string;
|
|
613
|
+
/** The ROOT user request (Stage 1 r3 F1) — the menu's retry carries it (web-access decision, `/status`). */
|
|
614
|
+
request: string;
|
|
615
|
+
agent: AgentKind;
|
|
616
|
+
}
|
|
602
617
|
export declare class QuorumLoop {
|
|
603
618
|
private readonly deps;
|
|
604
619
|
private readonly sleep;
|
|
605
620
|
private workspaceOutcomeSink?;
|
|
606
|
-
/**
|
|
607
|
-
|
|
621
|
+
/**
|
|
622
|
+
* P46a B1 — the FOCUSED single task: the task the UI means when a command
|
|
623
|
+
* names none (`/continue`, `/review-reset`, the status "starting" row).
|
|
624
|
+
* Default = the most recently CONFIRMED START; `/task focus <n>` sets it
|
|
625
|
+
* explicitly; it advances to the newest remaining single task when the
|
|
626
|
+
* focused task ends; a rejected START never moves it. It replaces the three
|
|
627
|
+
* P45 singletons (`activeTaskId` / `activeBrief` / `activeImplementorAgent`):
|
|
628
|
+
* every reader now resolves through the task's OWN record
|
|
629
|
+
* (`singleTaskContextByTask`), never through "the latest task".
|
|
630
|
+
*/
|
|
631
|
+
private focusedTaskId;
|
|
632
|
+
/** P46a B1 — confirmed single tasks in START-confirmation order (focus fallback). */
|
|
633
|
+
private readonly confirmedSingleOrder;
|
|
634
|
+
/**
|
|
635
|
+
* P46a B1 — the most recent START still in flight (or null). A legacy
|
|
636
|
+
* GATE_DISPATCH with an EMPTY envelope task id can only belong to it (the P45
|
|
637
|
+
* rule); with no START in flight such a packet is a no-op left to recovery.
|
|
638
|
+
*/
|
|
639
|
+
private latestInFlightStart;
|
|
640
|
+
/** Stage 1 r1 F13 — every START still in flight, in issue order; `latestInFlightStart` is its last entry. */
|
|
641
|
+
private readonly startOrderInFlight;
|
|
608
642
|
/** Tasks whose next automatic revise round must start a fresh review baseline. */
|
|
609
643
|
private readonly reviewScopeResetTasks;
|
|
610
644
|
/** Non-terminal tasks for which `/review-reset` may arm the next revise round. */
|
|
@@ -613,16 +647,9 @@ export declare class QuorumLoop {
|
|
|
613
647
|
private readonly epochByTaskId;
|
|
614
648
|
private readonly tokensByTaskId;
|
|
615
649
|
private readonly tokensCountedGates;
|
|
616
|
-
/**
|
|
617
|
-
* The implementor brief for the active task (set at start_task). The
|
|
618
|
-
* GATE_DISPATCH consumer reads this to drive the round-0 implementor spawn —
|
|
619
|
-
* the brief is no longer threaded inline through the spawn call (the spawn
|
|
620
|
-
* moved out of `startTask` into the GATE_DISPATCH consumer, §3.C.20 FIX).
|
|
621
|
-
*/
|
|
622
|
-
private activeBrief;
|
|
623
650
|
/**
|
|
624
651
|
* IMAGE-ATTACHMENT-DESIGN.md §5 — TASK-SCOPED image attachments (parallel to
|
|
625
|
-
* `
|
|
652
|
+
* `singleTaskContextByTask`/`activeBriefByTask`). The single-impl path uses `activeAttachments`;
|
|
626
653
|
* the team path keys by the child `taskId` in `activeAttachmentsByTask` (armed at
|
|
627
654
|
* `registerTeamTaskBrief`, before its buffered GATE_DISPATCH drains). Re-copied
|
|
628
655
|
* into EACH round's shadow at `runImplementorRound` (round-0, revise, continuation,
|
|
@@ -677,20 +704,50 @@ export declare class QuorumLoop {
|
|
|
677
704
|
private readonly recoveredBriefsByAuthority;
|
|
678
705
|
private readonly activeBriefByTask;
|
|
679
706
|
/**
|
|
680
|
-
* P45 D1 (M7 E2E step 8, 2026-09-14) — the brief + agent of EVERY
|
|
681
|
-
* implementor task this loop started, keyed by task id.
|
|
682
|
-
*
|
|
683
|
-
*
|
|
684
|
-
*
|
|
685
|
-
*
|
|
686
|
-
*
|
|
687
|
-
*
|
|
688
|
-
* continuation context resolve through this map first; the singletons stay
|
|
689
|
-
* as the legacy fallback (an empty envelope task id, the test seam). Entries
|
|
690
|
-
* are removed with the task's other per-task state at its terminal cleanup.
|
|
707
|
+
* P45 D1 (M7 E2E step 8, 2026-09-14) / P46a B1 — the brief + agent of EVERY
|
|
708
|
+
* LIVE single-implementor task this loop started, keyed by task id. P45 added
|
|
709
|
+
* it beside the three "latest task" singletons (a second single task's
|
|
710
|
+
* request had replaced the first task's in its revise round); P46a deletes
|
|
711
|
+
* the singletons — round-0 spawns, revise rounds, the continuation context and
|
|
712
|
+
* every other reader resolve ONLY through this map. An entry exists from the
|
|
713
|
+
* START call (in flight) until the task's terminal cleanup; `retryOf` links a
|
|
714
|
+
* `#n retry` task to its `apply_failed` original (P46a C2/C3).
|
|
691
715
|
*/
|
|
692
716
|
private readonly singleTaskContextByTask;
|
|
717
|
+
/** Agent web browsing (upstream 2.0.37) — whether a task's ORIGINAL request needs web access; ends with the task (`forgetSingleTask`, team cleanup). */
|
|
693
718
|
private readonly webAccessByTask;
|
|
719
|
+
/**
|
|
720
|
+
* P46a D2 — append-only per-loop-life record of every single task this loop
|
|
721
|
+
* started (confirmed or in flight) with its terminal outcome once known, for
|
|
722
|
+
* `/status` (`describeTasks`). Never deleted (bounded by the session's tasks).
|
|
723
|
+
*/
|
|
724
|
+
private readonly singleTaskHistory;
|
|
725
|
+
/**
|
|
726
|
+
* P46a C1 — every single-task promote THIS session landed, by workspace-
|
|
727
|
+
* relative path: the promoting task + the post-image hash/mode the promote
|
|
728
|
+
* compare-and-set reads (`readRealMetadata`; `null` hash = a deletion). Used
|
|
729
|
+
* to attribute a later collision to a `session-task` (the path's current
|
|
730
|
+
* metadata equals a recorded post-image) or `external` (anything else —
|
|
731
|
+
* including a session-promoted file the user edited afterwards, and every
|
|
732
|
+
* promote by another session). In-memory, fail-safe: empty after a desktop
|
|
733
|
+
* restart, so every collision then classifies as `external`.
|
|
734
|
+
*/
|
|
735
|
+
private readonly promotedByPath;
|
|
736
|
+
/** P46a C2 — originals whose ONE automatic retry has been issued (never a second). */
|
|
737
|
+
private readonly autoRetryIssuedFor;
|
|
738
|
+
/**
|
|
739
|
+
* P46a C2 — retry STARTs planned inside the promote critical section and
|
|
740
|
+
* issued only after it (and the durable `apply_failed` record) completed:
|
|
741
|
+
* `startTask` runs the round-0 spawn before returning, so it must never run
|
|
742
|
+
* inside `promoteShadowLocked`.
|
|
743
|
+
*/
|
|
744
|
+
private readonly pendingPromoteRetries;
|
|
745
|
+
/** P46a D1 — the store-owned ordinal sink (installed by the shell after construction). */
|
|
746
|
+
private taskOrdinalSink?;
|
|
747
|
+
/** P46a C3 — the desktop-local apply-conflict menu sink (installed by the shell). */
|
|
748
|
+
private applyConflictSink?;
|
|
749
|
+
/** P46a C2 — notified when an automatic retry task started (the shell records its lifecycle row). */
|
|
750
|
+
private retryStartedSink?;
|
|
694
751
|
/**
|
|
695
752
|
* CP-1.f revise-context fix (dogfood task 2ac68708, 2026-06-11) — the BINDING
|
|
696
753
|
* user-requested changes for a task, accumulated across ALL revise rounds.
|
|
@@ -1245,10 +1302,67 @@ export declare class QuorumLoop {
|
|
|
1245
1302
|
setWorkspaceOutcomeSink(sink: WorkspaceOutcomeSink | undefined): void;
|
|
1246
1303
|
isWorkspaceTaskTerminallyRetired(taskId: string): boolean;
|
|
1247
1304
|
isTaskTerminallyRetired(taskId: string): boolean;
|
|
1248
|
-
/**
|
|
1305
|
+
/**
|
|
1306
|
+
* P46a B1 — the FOCUSED single task (null when no single task is live). The
|
|
1307
|
+
* P45 `activeTask` name is kept for the shell's readers; it now means the
|
|
1308
|
+
* focused task, never "the latest task".
|
|
1309
|
+
*/
|
|
1249
1310
|
get activeTask(): string | null;
|
|
1250
|
-
/**
|
|
1251
|
-
|
|
1311
|
+
/** P46a B1 — every LIVE single task this loop started (in flight or confirmed). */
|
|
1312
|
+
knownSingleTasks(): string[];
|
|
1313
|
+
/**
|
|
1314
|
+
* P46a B1 — `/task focus <n>`: make `taskId` the focused task. Refused (false)
|
|
1315
|
+
* for a task this loop does not know as a live single task.
|
|
1316
|
+
*/
|
|
1317
|
+
setFocusedTask(taskId: string): boolean;
|
|
1318
|
+
/** P46a D1 — install the store-owned ordinal sink (the shell, after construction). */
|
|
1319
|
+
setTaskOrdinalSink(sink: TaskOrdinalSink | undefined): void;
|
|
1320
|
+
/** P46a C3 — install the desktop-local apply-conflict menu sink. */
|
|
1321
|
+
setApplyConflictSink(sink: ((menu: ApplyConflictMenu) => void) | undefined): void;
|
|
1322
|
+
/** P46a C2 — install the retry-started notifier (the shell records the lifecycle row). */
|
|
1323
|
+
setRetryStartedSink(sink: ((info: {
|
|
1324
|
+
taskId: string;
|
|
1325
|
+
retryOf: string;
|
|
1326
|
+
agent: AgentKind;
|
|
1327
|
+
}) => void) | undefined): void;
|
|
1328
|
+
/** P46a D1 — `#n` / `#n retry` / short id for any task id (never throws). */
|
|
1329
|
+
labelFor(taskId: string): string;
|
|
1330
|
+
/**
|
|
1331
|
+
* P46a D2 — every single task this loop started, for `/status`: its label,
|
|
1332
|
+
* agent, request (desktop-local plaintext — the user's own words), link to an
|
|
1333
|
+
* `apply_failed` original, loop state and whether it is the focused task.
|
|
1334
|
+
*/
|
|
1335
|
+
describeTasks(): Array<{
|
|
1336
|
+
taskId: string;
|
|
1337
|
+
label: string;
|
|
1338
|
+
agent: AgentKind;
|
|
1339
|
+
brief: string;
|
|
1340
|
+
retryOf?: string;
|
|
1341
|
+
outcome: 'running' | 'applied' | 'discarded' | 'apply_failed' | 'unresolved' | 'rejected';
|
|
1342
|
+
implementorActive: boolean;
|
|
1343
|
+
focused: boolean;
|
|
1344
|
+
}>;
|
|
1345
|
+
/** Stage 1 r1 F13 — a START confirmed or rejected: the newest START still in flight (if any) becomes the empty-envelope target. */
|
|
1346
|
+
private dropInFlightStart;
|
|
1347
|
+
/**
|
|
1348
|
+
* P46a B1 — a single task ended (promote, terminal discard, rejected START):
|
|
1349
|
+
* drop its live record and, when it was the focused task, advance the focus
|
|
1350
|
+
* to the newest remaining confirmed single task (or none).
|
|
1351
|
+
*/
|
|
1352
|
+
private forgetSingleTask;
|
|
1353
|
+
/**
|
|
1354
|
+
* Arm an explicit, one-shot comprehensive baseline for the FOCUSED task
|
|
1355
|
+
* (P46a B1). Refused with the candidate list when the focused task has no
|
|
1356
|
+
* eligible gate (or no single task is focused) — the shell renders the
|
|
1357
|
+
* `#n` candidates so the user can `/task focus <n>` first.
|
|
1358
|
+
*/
|
|
1359
|
+
requestReviewScopeReset(): {
|
|
1360
|
+
armed: true;
|
|
1361
|
+
taskId: string;
|
|
1362
|
+
} | {
|
|
1363
|
+
armed: false;
|
|
1364
|
+
candidates: string[];
|
|
1365
|
+
};
|
|
1252
1366
|
/**
|
|
1253
1367
|
* Audited-path fix (Fix 5) — the host's detected implementor agents
|
|
1254
1368
|
* (UPPERCASE `AgentKind`), as threaded into the loop at construction. Used by
|
|
@@ -1369,6 +1483,16 @@ export declare class QuorumLoop {
|
|
|
1369
1483
|
agent: AgentKind;
|
|
1370
1484
|
/** IMAGE-ATTACHMENT-DESIGN.md §5 — task-scoped image attachments, armed before the drain. */
|
|
1371
1485
|
attachments?: ImageAttachment[];
|
|
1486
|
+
/** P46a C2/C3 — the `apply_failed` original this task retries (renders `#n retry`). */
|
|
1487
|
+
retryOf?: string;
|
|
1488
|
+
/**
|
|
1489
|
+
* P46a C2/C3 (Stage 1 r3 F1) — the ROOT user request a retry carries. A
|
|
1490
|
+
* retry's `brief` is the COMPOSED retry brief (diffs + reviewed contents that
|
|
1491
|
+
* can hold any text — URLs included); decisions that must follow the user's
|
|
1492
|
+
* own words (the agent-web access decision, the next retry brief, `/status`)
|
|
1493
|
+
* read this instead. Omitted for an ordinary task (its brief IS the request).
|
|
1494
|
+
*/
|
|
1495
|
+
request?: string;
|
|
1372
1496
|
}): Promise<{
|
|
1373
1497
|
taskId: string;
|
|
1374
1498
|
} | null>;
|
|
@@ -1821,6 +1945,27 @@ export declare class QuorumLoop {
|
|
|
1821
1945
|
* half-applied tree.
|
|
1822
1946
|
*/
|
|
1823
1947
|
promoteShadow(taskId: string): Promise<void>;
|
|
1948
|
+
/** P46a C2 — start every planned automatic retry as a new linked task. */
|
|
1949
|
+
private drainPromoteRetries;
|
|
1950
|
+
/** P46a D2 — correct a task's recorded outcome after its terminal cleanup ran. */
|
|
1951
|
+
private markTaskOutcome;
|
|
1952
|
+
/**
|
|
1953
|
+
* P46a C1 — classify each conflicting path: `session-task` when its current
|
|
1954
|
+
* real-tree metadata equals a post-image a single-task promote of THIS
|
|
1955
|
+
* session recorded (`promotedByPath`), else `external`.
|
|
1956
|
+
*/
|
|
1957
|
+
private attributeConflicts;
|
|
1958
|
+
/**
|
|
1959
|
+
* P46a C2 — the retry brief: the original request, a "Files changed since
|
|
1960
|
+
* your first attempt" section (a unified diff from the failed task's REVIEWED
|
|
1961
|
+
* contents to the CURRENT real contents, per conflicting path, naming the
|
|
1962
|
+
* session task that changed it), and the reviewed contents themselves. Every
|
|
1963
|
+
* section is capped (`RETRY_BRIEF_SECTION_CAP` per path,
|
|
1964
|
+
* `RETRY_BRIEF_TOTAL_CAP` overall — the brief becomes the retry task's
|
|
1965
|
+
* durable `task_spec`, whose write is fire-and-forget) and secret-scrubbed
|
|
1966
|
+
* (`redactSecretShapesInText`) before insertion.
|
|
1967
|
+
*/
|
|
1968
|
+
private buildRetryBrief;
|
|
1824
1969
|
/**
|
|
1825
1970
|
* CP-12 W2.b (§3.C.2b (d) / H3-4) — promote-quiescence BARRIER for `taskId`.
|
|
1826
1971
|
* Enqueues an EMPTY critical section behind any in-flight shadow lifecycle op
|
|
@@ -2143,9 +2288,12 @@ export declare class QuorumLoop {
|
|
|
2143
2288
|
private submitVerdict;
|
|
2144
2289
|
/**
|
|
2145
2290
|
* On WS (re)connect/startup, poll for the seats assigned to this desktop for
|
|
2146
|
-
* any in_review gate of
|
|
2147
|
-
*
|
|
2148
|
-
*
|
|
2291
|
+
* any in_review gate of EVERY in-flight task (P46a B3: the live single tasks,
|
|
2292
|
+
* the tasks with an active implementor, and the registered team tracks — one
|
|
2293
|
+
* query each) and spawn any seat NEITHER already running-in-memory NOR already
|
|
2294
|
+
* verdict-submitted (double-guard). Without this, a REVIEWER_DISPATCH dropped
|
|
2295
|
+
* during a WS gap hangs the gate forever. Residual (unchanged): after a full
|
|
2296
|
+
* desktop restart the in-memory maps are empty.
|
|
2149
2297
|
*/
|
|
2150
2298
|
recoverInReviewAssignments(): Promise<void>;
|
|
2151
2299
|
/**
|
|
@@ -2333,17 +2481,37 @@ export declare class QuorumLoop {
|
|
|
2333
2481
|
*/
|
|
2334
2482
|
private reconstructRound0GateDispatch;
|
|
2335
2483
|
private handleReviseFeedback;
|
|
2336
|
-
/** The implementor agent the loop spawns (set at start_task). */
|
|
2337
|
-
private activeImplementorAgent;
|
|
2338
|
-
setActiveImplementorAgent(agent: AgentKind): void;
|
|
2339
2484
|
/**
|
|
2340
|
-
*
|
|
2341
|
-
*
|
|
2342
|
-
*
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2485
|
+
* P46a B1 — set a single task's implementor agent on ITS record (the only
|
|
2486
|
+
* caller is `resumeFromContinuation`, after the user chose a target agent).
|
|
2487
|
+
* Replaces the session-wide `setActiveImplementorAgent` singleton.
|
|
2488
|
+
*/
|
|
2489
|
+
private setTaskImplementorAgent;
|
|
2490
|
+
/**
|
|
2491
|
+
* #585 #C10M-9 / P46a B1 (OQ-1, decided) — resolve WHICH single task a
|
|
2492
|
+
* `/continue request` means: the FOCUSED task if it has an active implementor
|
|
2493
|
+
* round; else the single task that has one; else refuse — `ambiguous` lists
|
|
2494
|
+
* the candidates (the shell renders their `#n` so the user can
|
|
2495
|
+
* `/task focus <n>` first), `none` means no task is running a round. The
|
|
2496
|
+
* `gateId`/`roundNumber` come from the ACTIVE implementor registry (the round
|
|
2497
|
+
* currently running); the brief + source agent from the task's own record.
|
|
2346
2498
|
*/
|
|
2499
|
+
resolveContinuationRequest(): {
|
|
2500
|
+
kind: 'ok';
|
|
2501
|
+
ctx: {
|
|
2502
|
+
taskId: string;
|
|
2503
|
+
gateId: string;
|
|
2504
|
+
roundNumber: number;
|
|
2505
|
+
brief: string;
|
|
2506
|
+
sourceAgent: AgentKind;
|
|
2507
|
+
};
|
|
2508
|
+
} | {
|
|
2509
|
+
kind: 'ambiguous';
|
|
2510
|
+
candidates: string[];
|
|
2511
|
+
} | {
|
|
2512
|
+
kind: 'none';
|
|
2513
|
+
};
|
|
2514
|
+
/** The `ok` projection of {@link resolveContinuationRequest} (null otherwise). */
|
|
2347
2515
|
getActiveContinuationRequestContext(): {
|
|
2348
2516
|
taskId: string;
|
|
2349
2517
|
gateId: string;
|
|
@@ -2605,8 +2773,12 @@ export declare class QuorumLoop {
|
|
|
2605
2773
|
get _runningSeatsForTests(): ReadonlySet<string>;
|
|
2606
2774
|
/** @internal — test introspection. */
|
|
2607
2775
|
get _submittedSeatsForTests(): ReadonlySet<string>;
|
|
2608
|
-
/**
|
|
2609
|
-
|
|
2776
|
+
/**
|
|
2777
|
+
* @internal — test seam to register a single task (its record + focus)
|
|
2778
|
+
* without start_task. P46a B1: the record is what every reader resolves, so
|
|
2779
|
+
* the seam always creates one (an empty brief when none is given).
|
|
2780
|
+
*/
|
|
2781
|
+
_setActiveTaskForTests(taskId: string, brief?: string, agent?: AgentKind, gateIds?: string[]): void;
|
|
2610
2782
|
/** @internal — read a task's accumulated binding user notes. */
|
|
2611
2783
|
_userNotesForTests(taskId: string): readonly string[];
|
|
2612
2784
|
/** @internal — A1b: read a task's accumulated structured findings history. */
|
|
@@ -14,3 +14,10 @@ export declare function reducer(state: OrchestrationState, action: Orchestration
|
|
|
14
14
|
* task-start size heuristic.
|
|
15
15
|
*/
|
|
16
16
|
export declare function hasRunningSingleTask(state: OrchestrationState): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* P46a C3 — the apply-conflict menu's reply hint. A digit answers it only while
|
|
19
|
+
* no review gate is awaiting a number (the gate composer takes digits first);
|
|
20
|
+
* `/task retry <n>` / `/task discard <n>` answer it unambiguously at any time.
|
|
21
|
+
* Slash commands keep the menu open; any other text closes it (Stage 1 r1 F3).
|
|
22
|
+
*/
|
|
23
|
+
export declare const APPLY_CONFLICT_MENU_HINT = "Reply with a number 1-2 (or /task retry <n> / /task discard <n> while another review is open); other text closes this menu.";
|
package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/slash-routes/continuation.d.ts
CHANGED
|
@@ -52,6 +52,11 @@ export interface ContinuationCliDeps {
|
|
|
52
52
|
} | null>;
|
|
53
53
|
/** Resolve the active-task request context (loop state). `null` if no active task. */
|
|
54
54
|
getActiveRequestContext?: () => ActiveContinuationRequestContext | null;
|
|
55
|
+
/**
|
|
56
|
+
* P46a B1 — the refusal text when `getActiveRequestContext` is null (several
|
|
57
|
+
* tasks running a round → the `#n` candidates; none → the plain message).
|
|
58
|
+
*/
|
|
59
|
+
explainNoActiveRequest?: () => string;
|
|
55
60
|
/**
|
|
56
61
|
* PHASE-CP-10-MIN (#585) #C10M-9/11 — `/continue accept <target>`: the
|
|
57
62
|
* rescue/headless path. The entrypoint wires this to call
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { OrchestrationState } from './types';
|
|
2
|
+
export declare function shortTaskId(taskId: string): string;
|
|
3
|
+
/**
|
|
4
|
+
* The label for `taskId` (a single task id, a team child task id, a
|
|
5
|
+
* `taskGroupId`, or a `group:<id>` gate id).
|
|
6
|
+
*/
|
|
7
|
+
export declare function taskLabel(state: Pick<OrchestrationState, 'taskOrdinals' | 'team'>, taskId: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Resolve `#n` / `n` (a single task or a team group number) back to the id
|
|
10
|
+
* that holds it, or null. Used by `/task focus <n>`.
|
|
11
|
+
*/
|
|
12
|
+
export declare function taskIdForOrdinal(state: Pick<OrchestrationState, 'taskOrdinals'>, ordinal: number): string | null;
|
|
13
|
+
/**
|
|
14
|
+
* P46a (F-P46a-6) — the advisory the shell prints under a gate prompt whose
|
|
15
|
+
* task already ENDED on this side as `discarded` (its implementor round failed
|
|
16
|
+
* here — typically the result's submit lost its response in a network cut —
|
|
17
|
+
* while the engine still had the result, reviewed it and raised the gate).
|
|
18
|
+
* Accepting such a gate applies nothing; the user must know before deciding.
|
|
19
|
+
* Returns null for a live task or any other outcome.
|
|
20
|
+
*/
|
|
21
|
+
export declare function endedTaskAdvisory(described: ReadonlyArray<{
|
|
22
|
+
taskId: string;
|
|
23
|
+
label: string;
|
|
24
|
+
outcome: string;
|
|
25
|
+
}>, taskId: string): string | null;
|
|
@@ -427,6 +427,7 @@ export type ConversationEntry = {
|
|
|
427
427
|
panel: {
|
|
428
428
|
variant: 'prompt';
|
|
429
429
|
envelope: GatePromptEnvelope;
|
|
430
|
+
taskLabel?: string;
|
|
430
431
|
} | {
|
|
431
432
|
variant: 'summary';
|
|
432
433
|
reviewSummary: ReviewSummaryPanelModel;
|
|
@@ -522,6 +523,51 @@ export interface PendingPlannerOffer {
|
|
|
522
523
|
/** §13 Option-2 — ordered-with-dups carried paths for the number-based chip rewrite. */
|
|
523
524
|
attachmentPaths?: string[];
|
|
524
525
|
}
|
|
526
|
+
/**
|
|
527
|
+
* P46a D1 — one in-session task number. Assigned by the reducer from ONE
|
|
528
|
+
* per-session counter (`nextTaskOrdinal`) at the START-confirmed point of a
|
|
529
|
+
* single task (`QuorumLoop.startTask`) or when `createTaskGroup` returns for a
|
|
530
|
+
* team (`launchTeamFromWorkItems`), so both paths share the numbering. A team
|
|
531
|
+
* group is one number (its child tasks render `#n.1`, `#n.2` via `state.team`).
|
|
532
|
+
* `retryOf` links a `#n retry` task (P46a C2/C3) to the `apply_failed` original.
|
|
533
|
+
* In-memory only: production has no session resume (design §2.4/A8), so every
|
|
534
|
+
* launch is a new session with its own numbering; nothing is persisted.
|
|
535
|
+
*/
|
|
536
|
+
export interface TaskOrdinalRecord {
|
|
537
|
+
readonly ordinal: number;
|
|
538
|
+
readonly kind: 'single' | 'group';
|
|
539
|
+
readonly retryOf?: string;
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* P46a C3 — the desktop-local "could not apply" menu. Modeled on
|
|
543
|
+
* `pendingPlannerOffer` (a local numbered reply resolves it; free text clears
|
|
544
|
+
* it) but NEVER mirrored to mobile — the durable, mobile-answerable form is
|
|
545
|
+
* P46b A5 (HD-10). Not durable: a desktop relaunch drops it with its session
|
|
546
|
+
* (the failed task's shadow is already discarded; the durable `apply_failed`
|
|
547
|
+
* outcome stands).
|
|
548
|
+
*/
|
|
549
|
+
export interface PendingApplyConflict {
|
|
550
|
+
/** The `apply_failed` task the menu is about. */
|
|
551
|
+
readonly taskId: string;
|
|
552
|
+
/** Its rendered label (`#n`, `#n retry`, or the short-id fallback). */
|
|
553
|
+
readonly taskLabel: string;
|
|
554
|
+
/** Workspace-relative paths + their attribution (paths only — never content). */
|
|
555
|
+
readonly conflicts: ReadonlyArray<{
|
|
556
|
+
readonly path: string;
|
|
557
|
+
readonly cause: 'session-task' | 'external' | 'write-error';
|
|
558
|
+
/** Rendered label of the session task whose promote changed the path. */
|
|
559
|
+
readonly byTaskLabel?: string;
|
|
560
|
+
}>;
|
|
561
|
+
/** True when this menu follows the one automatic retry's own promote failure. */
|
|
562
|
+
readonly autoRetried: boolean;
|
|
563
|
+
/** The `advisory` conversation entry that rendered the numbered options. */
|
|
564
|
+
readonly conversationEntryId: string;
|
|
565
|
+
/** The composed retry brief (original request + files changed since + reviewed contents). */
|
|
566
|
+
readonly retryBrief: string;
|
|
567
|
+
/** The ROOT user request the retry carries (Stage 1 r3 F1: web access and `/status` follow the user's own words). */
|
|
568
|
+
readonly request: string;
|
|
569
|
+
readonly agent: AgentKind;
|
|
570
|
+
}
|
|
525
571
|
/**
|
|
526
572
|
* [ADDITIVE WIDENING — CP-12 W3, per PHASE-CP-12-DESIGN.md §3.5 "minimal
|
|
527
573
|
* multi-track status node; rich UX is #469"]. Per-track lifecycle state as the
|
|
@@ -679,6 +725,32 @@ export interface OrchestrationState {
|
|
|
679
725
|
* source of truth.
|
|
680
726
|
*/
|
|
681
727
|
pendingPlannerOffer: PendingPlannerOffer | null;
|
|
728
|
+
/**
|
|
729
|
+
* `[ADDITIVE WIDENING — P46a D1]` The in-session task numbers, keyed by
|
|
730
|
+
* single-task id or team `taskGroupId`. Reducer-owned (`TASK_ORDINAL_ASSIGNED`)
|
|
731
|
+
* from the single per-session `nextTaskOrdinal` counter; never persisted.
|
|
732
|
+
*/
|
|
733
|
+
taskOrdinals: Map<string, TaskOrdinalRecord>;
|
|
734
|
+
/** `[ADDITIVE WIDENING — P46a D1]` The next number to assign (starts at 1). */
|
|
735
|
+
nextTaskOrdinal: number;
|
|
736
|
+
/**
|
|
737
|
+
* `[ADDITIVE WIDENING — P46a C3]` The OPEN desktop-local apply-conflict menus,
|
|
738
|
+
* keyed by the failed task's id, in presentation order (empty by default).
|
|
739
|
+
* Set by `APPLY_CONFLICT_PRESENTED` (a second task's menu never replaces the
|
|
740
|
+
* first — Stage 1 r2 F2); `/task retry|discard <n>` answers one by number, a
|
|
741
|
+
* bare digit only when exactly one is open; other desktop text closes them
|
|
742
|
+
* (`CLEAR_PENDING_APPLY_CONFLICT`). Never mirrored to mobile (P46b A5).
|
|
743
|
+
*/
|
|
744
|
+
pendingApplyConflicts: ReadonlyMap<string, PendingApplyConflict>;
|
|
745
|
+
/**
|
|
746
|
+
* `[ADDITIVE WIDENING — P46a D1]` The gate-prompt entry the desktop composer,
|
|
747
|
+
* its pinned card and a typed digit currently target (null when no open gate
|
|
748
|
+
* is answerable). Reducer-owned and STICKY (Stage 1 r2 F1): it stays on the
|
|
749
|
+
* current gate while that gate is answerable; only when it leaves the
|
|
750
|
+
* answerable phases does the oldest answerable open gate take over — a
|
|
751
|
+
* rolled-back older gate waits its turn instead of taking the digits back.
|
|
752
|
+
*/
|
|
753
|
+
activeGatePromptId: string | null;
|
|
682
754
|
inputHistory: string[];
|
|
683
755
|
/**
|
|
684
756
|
* `[ADDITIVE WIDENING — CP-1.d]` per `PHASE-CP-1-D-DESIGN.md` §4.8
|
|
@@ -884,6 +956,17 @@ export type OrchestrationAction = {
|
|
|
884
956
|
offer: PendingPlannerOffer;
|
|
885
957
|
} | {
|
|
886
958
|
type: 'CLEAR_PENDING_PLANNER_OFFER';
|
|
959
|
+
} | {
|
|
960
|
+
type: 'TASK_ORDINAL_ASSIGNED';
|
|
961
|
+
taskId: string;
|
|
962
|
+
kind: 'single' | 'group';
|
|
963
|
+
retryOf?: string;
|
|
964
|
+
} | {
|
|
965
|
+
type: 'APPLY_CONFLICT_PRESENTED';
|
|
966
|
+
menu: Omit<PendingApplyConflict, 'conversationEntryId'>;
|
|
967
|
+
} | {
|
|
968
|
+
type: 'CLEAR_PENDING_APPLY_CONFLICT';
|
|
969
|
+
taskId?: string;
|
|
887
970
|
} | {
|
|
888
971
|
type: 'STRUCTURAL_SUMMARY_GENERATED';
|
|
889
972
|
summary: StructuralSummary;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quantiya/codevibe-claude-plugin",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.43",
|
|
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.
|
|
51
|
+
"@quantiya/codevibe-core": "^2.0.38",
|
|
52
52
|
"@quantiya/quorum-core": "^1.0.1",
|
|
53
53
|
"dotenv": "^16.6.1",
|
|
54
54
|
"express": "^5.1.0",
|