@quantiya/codevibe-claude-plugin 2.0.44 → 2.0.46
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/appsync/appsync-client.d.ts +124 -3
- package/node_modules/@quantiya/codevibe-core/dist/appsync/queries.d.ts +6 -0
- package/node_modules/@quantiya/codevibe-core/dist/index.js +578 -461
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/class-b-consumer.d.ts +10 -1
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/descendant-reaper.d.ts +81 -0
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/local-executor-impl.d.ts +15 -1
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/process-tree.d.ts +6 -0
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/snapshot-merge.d.ts +10 -0
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/spawn.d.ts +1 -1
- package/node_modules/@quantiya/codevibe-core/dist/local-executor/types.d.ts +16 -0
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/cli.js +2291 -824
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/components/LiveProgressLine.d.ts +4 -0
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/components/OrchestrationApp.d.ts +13 -0
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/context-compaction.d.ts +7 -5
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/index.d.ts +77 -18
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/prompt-reply-router.d.ts +53 -0
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/quorum-loop.d.ts +138 -7
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/task-lifecycle-lines.d.ts +29 -0
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/task-progress.d.ts +1 -0
- package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/types.d.ts +48 -1
- package/node_modules/@quantiya/codevibe-core/dist/substrate/command-runner.d.ts +2 -0
- package/node_modules/@quantiya/codevibe-core/dist/substrate/types.d.ts +5 -0
- package/node_modules/@quantiya/codevibe-core/dist/substrate-launch/engage-substrate.d.ts +2 -0
- package/node_modules/@quantiya/codevibe-core/package.json +1 -1
- package/package.json +2 -2
|
@@ -2,6 +2,10 @@ import * as React from 'react';
|
|
|
2
2
|
import { LiveProgress } from '../types';
|
|
3
3
|
export interface LiveProgressLineProps {
|
|
4
4
|
progress: LiveProgress | null;
|
|
5
|
+
/** P46b §3.7 — the task's label (`#2`) when several task lines render. */
|
|
6
|
+
label?: string;
|
|
7
|
+
/** P46b §3.7 — how many more busy tasks are not shown (last line only). */
|
|
8
|
+
moreCount?: number;
|
|
5
9
|
/** Test seam; otherwise derived from the live terminal width, then 80 (mirrors StatusBar). */
|
|
6
10
|
columns?: number;
|
|
7
11
|
}
|
|
@@ -4,6 +4,19 @@ import { ConversationEntry, PostDecisionAction, Tier } from '../types';
|
|
|
4
4
|
import type { PlannerRuntimeKind } from '../status-format';
|
|
5
5
|
import type { UpdateReviewerPolicyInput, UserReviewerPolicySnapshot } from '../../types/reviewer';
|
|
6
6
|
import { type ApplyUserDecisionClient as SharedApplyUserDecisionClient, type GroupDecisionSubmitDeps } from '../gate-decision-submit';
|
|
7
|
+
/**
|
|
8
|
+
* Stable empty list passed to <InputBar> to SUPPRESS slash autocomplete unless
|
|
9
|
+
* it fits (Stage-1 MEDIUM + Stage-2 — #469): the dropdown lives in the live
|
|
10
|
+
* region below the input, so an open dropdown while the live region is tall
|
|
11
|
+
* could push total output over the terminal height and re-trigger Ink's
|
|
12
|
+
* whole-scrollback reprint. P46b §3.7 — the dropdown is offered while tasks run
|
|
13
|
+
* (progress lines no longer suppress it); a pinned gate-prompt card or the
|
|
14
|
+
* reviewer wizard still does, and while it can be open we reserve
|
|
15
|
+
* DROPDOWN_MAX_ROWS plus every progress line beyond the first in the height cap
|
|
16
|
+
* (below) so it always fits. Module-scope constant → stable identity.
|
|
17
|
+
*/
|
|
18
|
+
/** P46b §3.7 — at most this many per-task progress lines render (`+n more` after). */
|
|
19
|
+
export declare const MAX_TASK_PROGRESS_LINES = 3;
|
|
7
20
|
/**
|
|
8
21
|
* Minimal SDK contract for the applyUserDecision wire. Structurally
|
|
9
22
|
* compatible with the full `AppSyncClient.applyUserDecision` signature
|
package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/context-compaction.d.ts
CHANGED
|
@@ -127,11 +127,9 @@ export interface SessionCompactionCache {
|
|
|
127
127
|
sessionId: string;
|
|
128
128
|
/**
|
|
129
129
|
* High-watermark `seq` — every item with `seq <= compactedThroughSeq` is
|
|
130
|
-
* covered by `distilled`. `null` = nothing compacted yet. This is
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
* hosted upload path, which does not exist yet; flagged in the A1f
|
|
134
|
-
* report).
|
|
130
|
+
* covered by `distilled`. `null` = nothing compacted yet. This is the LOCAL
|
|
131
|
+
* watermark; hosted blind-hold upload (shipped in A1e via `putContextItem`)
|
|
132
|
+
* tracks its own upload watermark in `hosted-sync.json`.
|
|
135
133
|
*/
|
|
136
134
|
compactedThroughSeq: string | null;
|
|
137
135
|
/**
|
|
@@ -238,6 +236,8 @@ export declare function projectDistilledForRole(entry: DistilledTaskSummary, rol
|
|
|
238
236
|
*
|
|
239
237
|
* LOSSLESS: the log is never touched — only the sidecar cache advances.
|
|
240
238
|
* Fail-closed: an unverifiable chain compacts nothing. Never throws.
|
|
239
|
+
* Mutex-held per session: `onTaskBoundary` and `maybeFireCompactionSafetyValve`
|
|
240
|
+
* serialize strictly so a valve run never overwrites a boundary distillation.
|
|
241
241
|
*/
|
|
242
242
|
export declare function compactSessionContext(deps: {
|
|
243
243
|
sessionId: string;
|
|
@@ -402,3 +402,5 @@ export declare function gcContextItemLogs(deps: {
|
|
|
402
402
|
export declare function onTaskBoundary(sessionId: string): Promise<void>;
|
|
403
403
|
/** Test seam — reset module state (vitest-gated, the established pattern). */
|
|
404
404
|
export declare function resetContextCompactionProcessStateForTests(): void;
|
|
405
|
+
/** Test seam — inspect compactionChains size to verify prompt cleanup upon settlement. */
|
|
406
|
+
export declare function getCompactionChainsSizeForTests(): number;
|
|
@@ -49,7 +49,7 @@ import { renderRehydratedSessionContext } from './context-compaction';
|
|
|
49
49
|
import type { AgentKind as LocalExecutorAgentKind } from '../local-executor/types';
|
|
50
50
|
import type { OrchestrationState as OrchestrationStateType } from './types';
|
|
51
51
|
import { type TaskProgressEvent } from './task-progress';
|
|
52
|
-
import {
|
|
52
|
+
import { type PromptReplyOrigin } from './prompt-reply-router';
|
|
53
53
|
/**
|
|
54
54
|
* Gathers the implementor agents currently active across single-implementor running tasks
|
|
55
55
|
* and multi-track Agent Teams tracks. Used for multi-track priority allocation.
|
|
@@ -63,14 +63,37 @@ export declare function findActiveContinuationOfferEntry(conversation: ReadonlyA
|
|
|
63
63
|
kind: 'gate-prompt';
|
|
64
64
|
}) | null;
|
|
65
65
|
/**
|
|
66
|
-
* P46a (Stage 1 r1 F2c) — a
|
|
67
|
-
* several open
|
|
68
|
-
*
|
|
69
|
-
*
|
|
66
|
+
* P46a (Stage 1 r1 F2c) / P46b §3.7 — a bare digit from the phone cannot choose
|
|
67
|
+
* between several open prompts: every prompt the phone can answer counts (gate
|
|
68
|
+
* prompts awaiting a number or a note, the retry prompt, a pending planner
|
|
69
|
+
* offer). Returns the advisory naming them, or null when the reply is not a bare
|
|
70
|
+
* digit or at most one prompt is open. Pure.
|
|
70
71
|
*/
|
|
71
|
-
export declare function mobileGateReplyAmbiguity(state:
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
export declare function mobileGateReplyAmbiguity(state: Pick<OrchestrationStateType, 'conversation' | 'taskOrdinals' | 'team' | 'pendingApplyConflicts' | 'pendingPlannerOffer'>, text: string): string | null;
|
|
73
|
+
/**
|
|
74
|
+
* P46b §3.13 item 3 — route a reply that names or must choose among the open
|
|
75
|
+
* prompts. Returns true when the line was consumed (answered, or refused with
|
|
76
|
+
* an advisory); false sends it down today's paths (the keyboard's active
|
|
77
|
+
* prompt, slash commands, the planner).
|
|
78
|
+
*
|
|
79
|
+
* 1. While any prompt is open, `#n <rest>` / `#offer <rest>` is always
|
|
80
|
+
* consumed, from either origin: naming an open prompt it answers it
|
|
81
|
+
* (making a gate the active prompt), otherwise an advisory.
|
|
82
|
+
* 2. Keyboard lines without `#` → today's paths (never refused).
|
|
83
|
+
* 3. Phone lines without `#`: a bare digit with several open prompts is
|
|
84
|
+
* refused; with one it answers it. With several prompts awaiting a note a
|
|
85
|
+
* plain line or bare `/cancel` is refused; with exactly one it is that
|
|
86
|
+
* prompt's note (or leaves its notes entry). Anything else → today's paths.
|
|
87
|
+
*/
|
|
88
|
+
export declare function routeOpenPromptReply(deps: {
|
|
89
|
+
store: OrchestrationStore;
|
|
90
|
+
args: RunOrchestrationShellArgs;
|
|
91
|
+
emitShellEventBound: ReturnType<typeof createShellEventEmitter>;
|
|
92
|
+
generator: StructuralSummaryGenerator;
|
|
93
|
+
gateDecisionDeps: GateDecisionSubmitDeps | null;
|
|
94
|
+
origin: PromptReplyOrigin;
|
|
95
|
+
text: string;
|
|
96
|
+
}): Promise<boolean>;
|
|
74
97
|
export declare class OrchestrationShellStartupError extends Error {
|
|
75
98
|
readonly cause?: unknown;
|
|
76
99
|
constructor(message: string, cause?: unknown);
|
|
@@ -380,6 +403,8 @@ export declare function runOrchestrationShell(args: RunOrchestrationShellArgs):
|
|
|
380
403
|
* simply renders with no review panel (fail-open).
|
|
381
404
|
*/
|
|
382
405
|
export declare const TASK_REVIEW_SUMMARY_FETCH_TIMEOUT_MS = 5000;
|
|
406
|
+
/** P46b §3.9 — the engine's phone retry prompt kind (core-rs `apply_retry.rs`). */
|
|
407
|
+
export declare const APPLY_RETRY_PROMPT_KIND = "orchestration_apply_retry";
|
|
383
408
|
/**
|
|
384
409
|
* Plaintext-first dispatcher per #C8M-7 (Stage 1 R1 M6 lock):
|
|
385
410
|
* 1. If `event.metadata` is an object, use it directly. Otherwise try
|
|
@@ -508,18 +533,48 @@ export declare function createSubscribedEventDispatcher(deps: {
|
|
|
508
533
|
onDurableGateResolution?: (resolution: DurableGateResolution) => Promise<void> | void;
|
|
509
534
|
updateEventStatus?: (input: UpdateEventStatusInput) => Promise<unknown>;
|
|
510
535
|
}): (event: Event) => void;
|
|
536
|
+
export declare function registerTeamTrackStarts(taskGroupId: string, initialRunning: number): void;
|
|
537
|
+
export declare function routeTeamShellEventToStore(store: OrchestrationStore, evt: TeamTapEvent, postLine?: (text: string) => void): void;
|
|
538
|
+
/**
|
|
539
|
+
* CP-12 W3 — minimal `/team <json>` arg parse. Accepts a JSON `WorkItemInput[]`
|
|
540
|
+
* (≥2 items). Shallow structural validation only — the backend
|
|
541
|
+
* `validate_create_input` (#C12-2 disjointness) is authoritative; we just need
|
|
542
|
+
* a well-formed array to drive `createTaskGroup`. Polished ergonomics
|
|
543
|
+
* (file-path-set shorthand, interactive builder) are [DEFERRED → CP-8 #469].
|
|
544
|
+
*/
|
|
511
545
|
/**
|
|
512
|
-
*
|
|
513
|
-
*
|
|
514
|
-
* `
|
|
515
|
-
*
|
|
516
|
-
*
|
|
517
|
-
*
|
|
546
|
+
* Audited-path fix (Fix 4 + Fix 5) — parse a `/task` invocation into an optional
|
|
547
|
+
* implementor-agent override + the remaining brief. Supports a LEADING `--agent
|
|
548
|
+
* codex|claude|antigravity|agy` flag (case-insensitive value, space or '=' separated); everything after it (or the
|
|
549
|
+
* whole arg list when absent) is the brief, re-joined verbatim. The override is
|
|
550
|
+
* returned even when not detected on this host — `selectImplementorAgent` decides
|
|
551
|
+
* whether to honor it (fail-closed to the default with a user-facing note).
|
|
518
552
|
*
|
|
519
|
-
*
|
|
520
|
-
*
|
|
553
|
+
* Tolerant: an unknown `--agent <value>` is IGNORED (the `--agent` token is dropped,
|
|
554
|
+
* the unrecognized value becomes part of the brief) rather than erroring — keeps the shortcut
|
|
555
|
+
* forgiving. When using the composite `--agent=<value>` form, the entire token including
|
|
556
|
+
* any unrecognized value is dropped so it does not pollute the brief. `--agent` with no
|
|
557
|
+
* following value is dropped (no brief consumed).
|
|
521
558
|
*/
|
|
522
|
-
export declare function
|
|
559
|
+
export declare function parseTaskCommand(text: string): {
|
|
560
|
+
agent: LocalExecutorAgentKind | null;
|
|
561
|
+
brief: string;
|
|
562
|
+
/** P46a B1 — `/task focus <n>` (or `#n`): the task number to focus, else null. */
|
|
563
|
+
focus: number | null;
|
|
564
|
+
/** P46a C3 (Stage 1 r1 F3) — `/task retry <n>` / `/task discard <n>`: answer the apply-conflict menu of task #n. */
|
|
565
|
+
conflictChoice: {
|
|
566
|
+
choice: 1 | 2;
|
|
567
|
+
ordinal: number;
|
|
568
|
+
} | null;
|
|
569
|
+
/**
|
|
570
|
+
* P46b §3.7 — `/task cancel <n>`: `{ ordinal }`, or `{ ordinal: null }` for a
|
|
571
|
+
* `/task cancel` without a valid number (usage). Matched before the brief
|
|
572
|
+
* fallback, so it never starts a task with the brief "cancel …".
|
|
573
|
+
*/
|
|
574
|
+
cancel: {
|
|
575
|
+
ordinal: number | null;
|
|
576
|
+
} | null;
|
|
577
|
+
};
|
|
523
578
|
export declare function readOnlyAgentPrompt(args: {
|
|
524
579
|
agent: LocalExecutorAgentKind;
|
|
525
580
|
intent: AgentMentionIntent;
|
|
@@ -656,6 +711,8 @@ export declare function launchTeamFromWorkItems(deps: {
|
|
|
656
711
|
* rewrite resolves each chip to the right ref. Retained for REJECT_RESTART reissue.
|
|
657
712
|
*/
|
|
658
713
|
attachmentPaths?: string[];
|
|
714
|
+
/** P46b §3.10 — the failed group this launch retries (the new group is `#m retry`). */
|
|
715
|
+
retryOf?: string;
|
|
659
716
|
}): Promise<LaunchTeamOutcome>;
|
|
660
717
|
/**
|
|
661
718
|
* PHASE-589/469 W3.2 RESIDUAL 1 — re-dispatch the WHOLE team for a
|
|
@@ -679,7 +736,9 @@ export declare function reissueTeamFromRetainedSpec(deps: {
|
|
|
679
736
|
quorumLoop?: QuorumLoop;
|
|
680
737
|
sessionId: string;
|
|
681
738
|
durableStore: RevertManifestStore;
|
|
682
|
-
}, taskGroupId: string
|
|
739
|
+
}, taskGroupId: string, options?: {
|
|
740
|
+
retryOf?: string;
|
|
741
|
+
}): Promise<void>;
|
|
683
742
|
/**
|
|
684
743
|
* PHASE-590 §3.D — the `team_decompose` routing path. Runs the local decomposer,
|
|
685
744
|
* shape-checks (the schema is applied inside the decomposer parse) +
|
package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/prompt-reply-router.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { ConversationEntry, OrchestrationState, PendingApplyConflict, PendingPlannerOffer } from './types';
|
|
2
|
+
export type PromptReplyOrigin = 'keyboard' | 'mobile';
|
|
3
|
+
type GatePromptEntry = Extract<ConversationEntry, {
|
|
4
|
+
kind: 'gate-prompt';
|
|
5
|
+
}>;
|
|
6
|
+
export type OpenPrompt = {
|
|
7
|
+
kind: 'gate';
|
|
8
|
+
/** `#3`, `#5.2`, or the short-id fallback of an unnumbered task. */
|
|
9
|
+
label: string;
|
|
10
|
+
entry: GatePromptEntry;
|
|
11
|
+
awaiting: 'number' | 'note';
|
|
12
|
+
optionCount: number;
|
|
13
|
+
} | {
|
|
14
|
+
kind: 'apply';
|
|
15
|
+
label: string;
|
|
16
|
+
menu: PendingApplyConflict;
|
|
17
|
+
awaiting: 'number';
|
|
18
|
+
optionCount: 2;
|
|
19
|
+
} | {
|
|
20
|
+
kind: 'offer';
|
|
21
|
+
label: 'offer';
|
|
22
|
+
offer: PendingPlannerOffer;
|
|
23
|
+
awaiting: 'number';
|
|
24
|
+
optionCount: number;
|
|
25
|
+
};
|
|
26
|
+
/** The reference a reply uses for `prompt`: `3`, `5.2` or `offer`. */
|
|
27
|
+
export declare function promptReference(prompt: OpenPrompt): string;
|
|
28
|
+
/** How advisories name `prompt`: `Task #3`, `Task #5.2`, `#offer`. */
|
|
29
|
+
export declare function promptName(prompt: OpenPrompt): string;
|
|
30
|
+
/** Every open prompt in presentation order (gates, then menus, then the offer). */
|
|
31
|
+
export declare function listOpenPrompts(state: Pick<OrchestrationState, 'conversation' | 'taskOrdinals' | 'team' | 'pendingApplyConflicts' | 'pendingPlannerOffer'>, origin: PromptReplyOrigin): OpenPrompt[];
|
|
32
|
+
/**
|
|
33
|
+
* `#2 1` → `{ reference: '2', rest: '1' }`; `#5.2 note text` → `{ '5.2', 'note text' }`;
|
|
34
|
+
* `#offer 3` → `{ 'offer', '3' }`; a bare `#2` → rest `''`. Null when the line
|
|
35
|
+
* does not start with a reference followed by whitespace or the end.
|
|
36
|
+
*/
|
|
37
|
+
export declare function parsePromptReference(text: string): {
|
|
38
|
+
reference: string;
|
|
39
|
+
rest: string;
|
|
40
|
+
} | null;
|
|
41
|
+
/** The open prompt a reference names, or null. */
|
|
42
|
+
export declare function findPromptByReference(open: ReadonlyArray<OpenPrompt>, reference: string): OpenPrompt | null;
|
|
43
|
+
/** §3.7 — a bare digit from the phone while several prompts are open. */
|
|
44
|
+
export declare function severalPromptsAdvisory(open: ReadonlyArray<OpenPrompt>): string;
|
|
45
|
+
/** §3.13 item 3.3.2 — a plain phone line while several prompts await a note. */
|
|
46
|
+
export declare function severalNotesAdvisory(notes: ReadonlyArray<OpenPrompt>): string;
|
|
47
|
+
/** §3.13 item 3.1 — a `#n` reply the named prompt cannot take. */
|
|
48
|
+
export declare function expectedReplyAdvisory(prompt: OpenPrompt): string;
|
|
49
|
+
/** §3.13 item 3.1 — a `#n` reply naming no open prompt. */
|
|
50
|
+
export declare function noOpenPromptAdvisory(reference: string): string;
|
|
51
|
+
/** §3.13 item 3 — the phone hint when a numbered answer opens a gate's notes entry. */
|
|
52
|
+
export declare function notesHint(prompt: OpenPrompt): string;
|
|
53
|
+
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AppSyncClient, TeamTrackRecoveryRow } from '../appsync/appsync-client';
|
|
2
2
|
import type { Session } from '../types';
|
|
3
3
|
import type { LocalExecutor } from '../local-executor';
|
|
4
|
-
import type { ClassBInbound } from '../local-executor/types';
|
|
4
|
+
import type { ClassBInbound, QueuedWorkEndedPayload } from '../local-executor/types';
|
|
5
5
|
import type { ImageAttachment } from './types';
|
|
6
6
|
import { type TaskAuditSummaryModel, type ReviewHistorySnapshot, type UserDecisionRecord } from './audit-summary';
|
|
7
7
|
import type { DecryptedReviewSummaryInput } from './gate-prompts';
|
|
@@ -596,6 +596,51 @@ export interface TaskOrdinalSink {
|
|
|
596
596
|
}): number | undefined;
|
|
597
597
|
label(taskId: string): string;
|
|
598
598
|
}
|
|
599
|
+
/**
|
|
600
|
+
* P46a D2 / P46b §3.7 — a single task's recorded state for `/status`. `queued`
|
|
601
|
+
* waits for a running-track slot; `cancelled` ended before it started
|
|
602
|
+
* (`QUEUED_WORK_ENDED`, or a `cancelled` START replay); `already_finished` is a
|
|
603
|
+
* START replay of work that already ended.
|
|
604
|
+
*/
|
|
605
|
+
export type SingleTaskOutcome = 'running' | 'queued' | 'applied' | 'discarded' | 'apply_failed' | 'unresolved' | 'rejected' | 'cancelled' | 'already_finished';
|
|
606
|
+
/** P46b §3.3 — what a confirmed START did. */
|
|
607
|
+
export interface StartTaskResultInfo {
|
|
608
|
+
taskId: string;
|
|
609
|
+
outcome: 'running' | 'queued' | 'already_finished' | 'cancelled';
|
|
610
|
+
/** Present when queued: 1-based position in the account's queue. */
|
|
611
|
+
queuePosition?: number;
|
|
612
|
+
runningTracks?: number;
|
|
613
|
+
trackBudget?: number;
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* P46b §3.13 item 1 — a single task's lifecycle change the shell turns into a
|
|
617
|
+
* store update and a phone line: queued at START, started (immediately or when
|
|
618
|
+
* a slot freed), or cancelled before it started.
|
|
619
|
+
*/
|
|
620
|
+
export type TaskLifecycleEvent = {
|
|
621
|
+
kind: 'queued';
|
|
622
|
+
taskId: string;
|
|
623
|
+
agent: AgentKind;
|
|
624
|
+
queuePosition?: number;
|
|
625
|
+
runningTracks?: number;
|
|
626
|
+
trackBudget?: number;
|
|
627
|
+
} | {
|
|
628
|
+
kind: 'started';
|
|
629
|
+
taskId: string;
|
|
630
|
+
agent: AgentKind;
|
|
631
|
+
fromQueue: boolean;
|
|
632
|
+
retryOf?: string;
|
|
633
|
+
} | {
|
|
634
|
+
kind: 'cancelled';
|
|
635
|
+
taskId: string;
|
|
636
|
+
reason: string;
|
|
637
|
+
};
|
|
638
|
+
/** P46b §3.6 — the desktop's slot-lease capability sent on every START. */
|
|
639
|
+
export declare const SLOT_LEASE_PROTOCOL = 1;
|
|
640
|
+
/** P46b §3.6 — one task lease heartbeat per held task every 2 minutes (the engine lease is 600 s). */
|
|
641
|
+
export declare const TASK_LEASE_HEARTBEAT_INTERVAL_MS: number;
|
|
642
|
+
/** P46b §3.3 — map the START answer's state label onto what the START did. */
|
|
643
|
+
export declare function startOutcomeFor(workflowState: string): StartTaskResultInfo['outcome'];
|
|
599
644
|
/** P46a C3 — the desktop-local "could not apply" menu the loop asks the shell to present. */
|
|
600
645
|
export interface ApplyConflictMenu {
|
|
601
646
|
taskId: string;
|
|
@@ -606,6 +651,14 @@ export interface ApplyConflictMenu {
|
|
|
606
651
|
byTaskLabel?: string;
|
|
607
652
|
}>;
|
|
608
653
|
autoRetried: boolean;
|
|
654
|
+
/** P46b §3.10 — `group` for a team promote (`taskId` is the taskGroupId). */
|
|
655
|
+
kind?: 'single' | 'group';
|
|
656
|
+
/** P46b §3.9 — counts only, per cause (the retry prompt's content). */
|
|
657
|
+
counts?: {
|
|
658
|
+
sessionTask: number;
|
|
659
|
+
external: number;
|
|
660
|
+
writeErrors: number;
|
|
661
|
+
};
|
|
609
662
|
retryBrief: string;
|
|
610
663
|
/** The ROOT user request (Stage 1 r3 F1) — the menu's retry carries it (web-access decision, `/status`). */
|
|
611
664
|
request: string;
|
|
@@ -636,6 +689,19 @@ export declare class QuorumLoop {
|
|
|
636
689
|
private latestInFlightStart;
|
|
637
690
|
/** Stage 1 r1 F13 — every START still in flight, in issue order; `latestInFlightStart` is its last entry. */
|
|
638
691
|
private readonly startOrderInFlight;
|
|
692
|
+
/**
|
|
693
|
+
* P46b §3.7 — a queued task's START answer (position, running tracks, budget)
|
|
694
|
+
* and, once it ended before starting, the reason. Kept for `/status`.
|
|
695
|
+
*/
|
|
696
|
+
private readonly queueInfoByTask;
|
|
697
|
+
/** P46b §3.7 — single tasks whose implementor has been spawned at least once (`starting` ends). */
|
|
698
|
+
private readonly spawnedSingleTasks;
|
|
699
|
+
/** P46b §3.13 item 1 — the shell's lifecycle sink (store update + phone line). */
|
|
700
|
+
private taskLifecycleSink?;
|
|
701
|
+
/** P46b §3.6 — the one per-session task lease heartbeat timer (null while stopped). */
|
|
702
|
+
private taskLeaseHeartbeatTimer;
|
|
703
|
+
/** P46b §3.6 — tasks whose heartbeat request is still in flight (one at a time per task). */
|
|
704
|
+
private readonly taskLeaseHeartbeatsInFlight;
|
|
639
705
|
/** Tasks whose next automatic revise round must start a fresh review baseline. */
|
|
640
706
|
private readonly reviewScopeResetTasks;
|
|
641
707
|
/** Non-terminal tasks for which `/review-reset` may arm the next revise round. */
|
|
@@ -1117,8 +1183,22 @@ export declare class QuorumLoop {
|
|
|
1117
1183
|
*/
|
|
1118
1184
|
private recoverySeedingDepth;
|
|
1119
1185
|
/**
|
|
1120
|
-
*
|
|
1121
|
-
*
|
|
1186
|
+
* P46b (E2E T-3) — how many barrier holders are in their PASS-2 relaunch (each
|
|
1187
|
+
* counted within `recoverySeedingDepth`), and the tracks they relaunch
|
|
1188
|
+
* (refcounted task ids and brief slots). While EVERY holder is relaunching (none
|
|
1189
|
+
* is still querying, seeding briefs or binding a `/team` create), only packets
|
|
1190
|
+
* for a relaunched track keep buffering — the relaunch-before-drain dedup order
|
|
1191
|
+
* is unchanged for them. A packet for any other track (a queued track promoted
|
|
1192
|
+
* meanwhile, whose brief PASS 1 already seeded) is consumed live instead of
|
|
1193
|
+
* waiting for every relaunched implementor round to finish, which can outlast
|
|
1194
|
+
* its 15-minute lease.
|
|
1195
|
+
*/
|
|
1196
|
+
private recoveryRelaunchPhaseDepth;
|
|
1197
|
+
private readonly recoveryRelaunchTaskIds;
|
|
1198
|
+
private readonly recoveryRelaunchSlots;
|
|
1199
|
+
/**
|
|
1200
|
+
* Recovery B.1 and B.2 can overlap. A per-call batch is therefore
|
|
1201
|
+
* insufficient: two concurrent calls could each launch a full batch.
|
|
1122
1202
|
* These permits are owned by the QuorumLoop/session and cover the complete
|
|
1123
1203
|
* `launchRecoveredTrack` operation across every recovery entry path.
|
|
1124
1204
|
*/
|
|
@@ -1322,6 +1402,43 @@ export declare class QuorumLoop {
|
|
|
1322
1402
|
retryOf: string;
|
|
1323
1403
|
agent: AgentKind;
|
|
1324
1404
|
}) => void) | undefined): void;
|
|
1405
|
+
/**
|
|
1406
|
+
* P46b §3.10 — a team promote could not be applied (the team promote has no
|
|
1407
|
+
* per-path session attribution, so every changed path is `external`). A team
|
|
1408
|
+
* gets no automatic retry: it always offers the menu (retry reissues the
|
|
1409
|
+
* whole team from its retained launch spec).
|
|
1410
|
+
*/
|
|
1411
|
+
reportTeamApplyConflict(info: {
|
|
1412
|
+
taskGroupId: string;
|
|
1413
|
+
conflicts: readonly string[];
|
|
1414
|
+
writeErrors: readonly string[];
|
|
1415
|
+
}): void;
|
|
1416
|
+
/** P46b §3.13 item 1 — install the task lifecycle sink (the shell). */
|
|
1417
|
+
setTaskLifecycleSink(sink: ((event: TaskLifecycleEvent) => void) | undefined): void;
|
|
1418
|
+
/** P46b — notify the lifecycle sink; a throwing sink never breaks the loop. */
|
|
1419
|
+
private emitTaskLifecycle;
|
|
1420
|
+
/**
|
|
1421
|
+
* P46b §3.6 — the first change of a queued task to `cancelled (reason)`. Shared
|
|
1422
|
+
* by the `QUEUED_WORK_ENDED` packet, the `/status` catch-up and a `cancelled`
|
|
1423
|
+
* answer to `/task cancel`, so whichever arrives first acts and the others do
|
|
1424
|
+
* nothing. Returns true only on that first change.
|
|
1425
|
+
*/
|
|
1426
|
+
markQueuedTaskCancelled(taskId: string, reason: string): boolean;
|
|
1427
|
+
/** P46b §3.6 — the `QUEUED_WORK_ENDED` Class-B packet. */
|
|
1428
|
+
private handleQueuedWorkEnded;
|
|
1429
|
+
/** P46b §3.6 — start the per-session task lease heartbeat (idempotent). */
|
|
1430
|
+
private ensureTaskLeaseHeartbeat;
|
|
1431
|
+
/** P46b §3.6 — stop the task lease heartbeat (terminal: shutdown or no task left). */
|
|
1432
|
+
private stopTaskLeaseHeartbeat;
|
|
1433
|
+
/**
|
|
1434
|
+
* P46b §3.6 — one heartbeat for every single task this desktop holds in the
|
|
1435
|
+
* implement–review loop (queued, starting, implementing, in review, awaiting
|
|
1436
|
+
* you): `recordExecutionEvent(PROGRESS_EVENT, {kind: TASK_LEASE_HEARTBEAT,
|
|
1437
|
+
* taskId})`, which RENEWs the task's slot lease. A START still in flight is
|
|
1438
|
+
* skipped (its holder may not exist yet); a beat still in flight is not
|
|
1439
|
+
* doubled. Work this desktop no longer knows stops renewing and lapses.
|
|
1440
|
+
*/
|
|
1441
|
+
sendTaskLeaseHeartbeats(): Promise<void>;
|
|
1325
1442
|
/** P46a D1 — `#n` / `#n retry` / short id for any task id (never throws). */
|
|
1326
1443
|
labelFor(taskId: string): string;
|
|
1327
1444
|
/**
|
|
@@ -1335,9 +1452,15 @@ export declare class QuorumLoop {
|
|
|
1335
1452
|
agent: AgentKind;
|
|
1336
1453
|
brief: string;
|
|
1337
1454
|
retryOf?: string;
|
|
1338
|
-
outcome:
|
|
1455
|
+
outcome: SingleTaskOutcome;
|
|
1339
1456
|
implementorActive: boolean;
|
|
1340
1457
|
focused: boolean;
|
|
1458
|
+
/** P46b §3.7 — START confirmed or dispatched, implementor not spawned yet. */
|
|
1459
|
+
starting?: boolean;
|
|
1460
|
+
/** P46b §3.7 — queue position from the START answer (queued tasks). */
|
|
1461
|
+
queuePosition?: number;
|
|
1462
|
+
/** P46b §3.6 — why a queued task ended before it started. */
|
|
1463
|
+
cancelReason?: string;
|
|
1341
1464
|
}>;
|
|
1342
1465
|
/** Stage 1 r1 F13 — a START confirmed or rejected: the newest START still in flight (if any) becomes the empty-envelope target. */
|
|
1343
1466
|
private dropInFlightStart;
|
|
@@ -1441,6 +1564,7 @@ export declare class QuorumLoop {
|
|
|
1441
1564
|
gateDispatch: (payload: GateDispatchPayload, envelopeTaskId?: string) => Promise<void>;
|
|
1442
1565
|
spawnReviewers: (payload: ReviewerDispatchPayload) => Promise<void>;
|
|
1443
1566
|
runReviseRound: (payload: ReviseFeedbackPayload) => Promise<void>;
|
|
1567
|
+
queuedWorkEnded: (payload: QueuedWorkEndedPayload) => Promise<void>;
|
|
1444
1568
|
};
|
|
1445
1569
|
private cachedSigningKey;
|
|
1446
1570
|
private verifySignature;
|
|
@@ -1490,9 +1614,7 @@ export declare class QuorumLoop {
|
|
|
1490
1614
|
* read this instead. Omitted for an ordinary task (its brief IS the request).
|
|
1491
1615
|
*/
|
|
1492
1616
|
request?: string;
|
|
1493
|
-
}): Promise<
|
|
1494
|
-
taskId: string;
|
|
1495
|
-
} | null>;
|
|
1617
|
+
}): Promise<StartTaskResultInfo | null>;
|
|
1496
1618
|
/**
|
|
1497
1619
|
* CP-1.f Wave 3 FIX — consume a GATE_DISPATCH packet. The engine emits this
|
|
1498
1620
|
* after `startTask` creates the round-0 `reviewer_quorum` gate; its
|
|
@@ -2366,6 +2488,15 @@ export declare class QuorumLoop {
|
|
|
2366
2488
|
* here; single-impl / non-team packets bypass this entirely.
|
|
2367
2489
|
*/
|
|
2368
2490
|
bufferTeamPacketDuringSeeding(kind: 'trackAssigned' | 'gateDispatch', payload: unknown, envelopeTaskId?: string): boolean;
|
|
2491
|
+
/**
|
|
2492
|
+
* P46b (E2E T-3) — whether a live team packet belongs to a track a recovery is
|
|
2493
|
+
* relaunching right now. A packet that names no track this can match (no
|
|
2494
|
+
* envelope task id and no TrackAssigned ids) counts as one, so it keeps
|
|
2495
|
+
* buffering exactly as before.
|
|
2496
|
+
*/
|
|
2497
|
+
private isRecoveryRelaunchPacket;
|
|
2498
|
+
private enterRecoveryRelaunchPhase;
|
|
2499
|
+
private leaveRecoveryRelaunchPhase;
|
|
2369
2500
|
/**
|
|
2370
2501
|
* §4.3 — drain the buffered live TEAM packets through the normal live handlers
|
|
2371
2502
|
* AFTER the recovery seed barrier lifts (`recoverySeedingDepth === 0`). Each
|
package/node_modules/@quantiya/codevibe-core/dist/orchestration-shell/task-lifecycle-lines.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** The never-started halt reasons of `QUEUED_WORK_ENDED` (engine `halted_reason`). */
|
|
2
|
+
export type QueuedTaskEndReason = 'user_cancelled_queued_task' | 'tier_changed' | 'queued_task_expired';
|
|
3
|
+
/** `#4` → `4`, `#4 retry` → `4`, `#5.2` → `5.2`; anything else unchanged. */
|
|
4
|
+
export declare function labelNumber(label: string): string;
|
|
5
|
+
/** Desktop answer to a queued START (§3.7). */
|
|
6
|
+
export declare function queuedDesktopLine(label: string, info: {
|
|
7
|
+
runningTracks?: number;
|
|
8
|
+
trackBudget?: number;
|
|
9
|
+
}): string;
|
|
10
|
+
/** Phone line for a queued START (§3.13 item 1). */
|
|
11
|
+
export declare function queuedPhoneLine(label: string, info: {
|
|
12
|
+
runningTracks?: number;
|
|
13
|
+
trackBudget?: number;
|
|
14
|
+
}): string;
|
|
15
|
+
/** Phone line for every single-task start, immediate or from the queue. */
|
|
16
|
+
export declare function startedPhoneLine(label: string, agent: string): string;
|
|
17
|
+
/** Desktop line when a queued task starts because a slot freed. */
|
|
18
|
+
export declare function startedFromQueueDesktopLine(label: string, agent: string): string;
|
|
19
|
+
/** Phone line when a team starts (§3.13 item 1). */
|
|
20
|
+
export declare function teamStartedPhoneLine(label: string, running: number, waiting: number): string;
|
|
21
|
+
/** Phone line when a team track that waited starts later (`#5.4`). */
|
|
22
|
+
export declare function trackStartedPhoneLine(trackLabel: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* The line (desktop and phone) for a task that never started and was halted.
|
|
25
|
+
* An unknown reason renders the neutral form.
|
|
26
|
+
*/
|
|
27
|
+
export declare function cancelledLine(label: string, reason: string): string;
|
|
28
|
+
/** `/status` phase for a cancelled task: `cancelled (reason)`. */
|
|
29
|
+
export declare function cancelledStatusLabel(reason?: string): string;
|
|
@@ -177,7 +177,8 @@ export interface SessionTaskRecord {
|
|
|
177
177
|
/** 'single' = TASK_LIFECYCLE-tracked; 'team' = Agent Teams track. */
|
|
178
178
|
origin: 'single' | 'team';
|
|
179
179
|
/**
|
|
180
|
-
* Singles: the lifecycle status — '
|
|
180
|
+
* Singles: the lifecycle status — 'queued' while a START waits for a
|
|
181
|
+
* running-track slot (P46b), 'running' at dispatch, flipped terminal
|
|
181
182
|
* by the task-end CLOSER progress events (promoted → 'completed',
|
|
182
183
|
* discarded → 'cancelled', round_failed → 'failed'; Stage-2 r1 Codex
|
|
183
184
|
* MED-2 — no production TASK_LIFECYCLE dispatch ever carries a terminal
|
|
@@ -589,6 +590,24 @@ export interface PendingApplyConflict {
|
|
|
589
590
|
}>;
|
|
590
591
|
/** True when this menu follows the one automatic retry's own promote failure. */
|
|
591
592
|
readonly autoRetried: boolean;
|
|
593
|
+
/**
|
|
594
|
+
* P46b §3.10 — `group` when the failed promote was a team's (`taskId` is then
|
|
595
|
+
* the `taskGroupId`; retry reissues the team from its retained launch spec).
|
|
596
|
+
* Absent = a single task (P46a).
|
|
597
|
+
*/
|
|
598
|
+
readonly kind?: 'single' | 'group';
|
|
599
|
+
/** P46b §3.9 — counts only: how many paths each cause failed. */
|
|
600
|
+
readonly counts?: {
|
|
601
|
+
readonly sessionTask: number;
|
|
602
|
+
readonly external: number;
|
|
603
|
+
readonly writeErrors: number;
|
|
604
|
+
};
|
|
605
|
+
/**
|
|
606
|
+
* P46b §3.9 (ID-20) — the engine retry prompt's gate id once
|
|
607
|
+
* `openApplyRetryOffer` succeeded: the phone can answer this menu, and it is
|
|
608
|
+
* resolved with the user's choice. Absent = the desktop-local menu only.
|
|
609
|
+
*/
|
|
610
|
+
readonly offerGateId?: string;
|
|
592
611
|
/** The `advisory` conversation entry that rendered the numbered options. */
|
|
593
612
|
readonly conversationEntryId: string;
|
|
594
613
|
/** The composed retry brief (original request + files changed since + reviewed contents). */
|
|
@@ -709,6 +728,11 @@ export interface LiveProgress {
|
|
|
709
728
|
updatedAt: string;
|
|
710
729
|
/** ISO — when THIS busy window opened; the wall-clock timer anchor. */
|
|
711
730
|
startedAt: string;
|
|
731
|
+
/**
|
|
732
|
+
* P46b §3.7 — the task this line belongs to (from `emitProgressForTask`);
|
|
733
|
+
* undefined for a classify/familiarize/advisory window.
|
|
734
|
+
*/
|
|
735
|
+
taskId?: string;
|
|
712
736
|
/**
|
|
713
737
|
* The per-TASK origin epoch of the event that opened/last-refreshed this window
|
|
714
738
|
* (§2/§3). Undefined ONLY for the direct-dispatched classify/familiarize windows
|
|
@@ -810,6 +834,13 @@ export interface OrchestrationState {
|
|
|
810
834
|
* Companion sessions never dispatch `TASK_PROGRESS`, so this stays null.
|
|
811
835
|
*/
|
|
812
836
|
progress: LiveProgress | null;
|
|
837
|
+
/**
|
|
838
|
+
* `[ADDITIVE WIDENING — P46b §3.7]` One live line per single task that is
|
|
839
|
+
* busy right now, keyed by task id, under the same epoch/closer rules as
|
|
840
|
+
* `progress` applied per task. Team tracks are excluded (their rows live in
|
|
841
|
+
* `MultiTrackStatusNode`). Optional so pre-P46b state literals stay valid.
|
|
842
|
+
*/
|
|
843
|
+
progressByTask?: Map<string, LiveProgress>;
|
|
813
844
|
/**
|
|
814
845
|
* `[ADDITIVE WIDENING — /reviewer-setup wizard, 2026-06-29]` The active
|
|
815
846
|
* interactive reviewer-panel setup modal, or `null` when no wizard is open
|
|
@@ -1010,6 +1041,22 @@ export type OrchestrationAction = {
|
|
|
1010
1041
|
} | {
|
|
1011
1042
|
type: 'CLEAR_PENDING_APPLY_CONFLICT';
|
|
1012
1043
|
taskId?: string;
|
|
1044
|
+
} | {
|
|
1045
|
+
type: 'APPLY_CONFLICT_OFFER_OPENED';
|
|
1046
|
+
taskId: string;
|
|
1047
|
+
gateId: string;
|
|
1048
|
+
} | {
|
|
1049
|
+
type: 'SINGLE_TASK_QUEUED';
|
|
1050
|
+
taskId: string;
|
|
1051
|
+
agentKind: string;
|
|
1052
|
+
queuedAt: string;
|
|
1053
|
+
} | {
|
|
1054
|
+
type: 'SINGLE_TASK_QUEUE_ENDED';
|
|
1055
|
+
taskId: string;
|
|
1056
|
+
reason: string;
|
|
1057
|
+
} | {
|
|
1058
|
+
type: 'GATE_PROMPT_ACTIVATED';
|
|
1059
|
+
promptEntryId: string;
|
|
1013
1060
|
} | {
|
|
1014
1061
|
type: 'STRUCTURAL_SUMMARY_GENERATED';
|
|
1015
1062
|
summary: StructuralSummary;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CommandResult, CommandRunner, RunnerProc } from './types';
|
|
2
2
|
import type { WorkspaceRootAuthority } from '../local-executor/workspace-authority';
|
|
3
|
+
import type { HostDescendantReap } from '../local-executor/descendant-reaper';
|
|
3
4
|
/**
|
|
4
5
|
* The production `CommandRunner` — runs `docker` / `sandbox-exec` via
|
|
5
6
|
* `node:child_process`. No shell is used (argv is passed directly to
|
|
@@ -18,5 +19,6 @@ export declare class ChildProcessCommandRunner implements CommandRunner {
|
|
|
18
19
|
cwd?: string;
|
|
19
20
|
cwdAuthority?: WorkspaceRootAuthority;
|
|
20
21
|
launchPathAuthorities?: readonly WorkspaceRootAuthority[];
|
|
22
|
+
descendantReap?: HostDescendantReap;
|
|
21
23
|
}): RunnerProc;
|
|
22
24
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Readable, Writable } from "node:stream";
|
|
2
2
|
import type { WorkspaceRootAuthority } from "../local-executor/workspace-authority";
|
|
3
|
+
import type { HostDescendantReap } from "../local-executor/descendant-reaper";
|
|
3
4
|
/**
|
|
4
5
|
* Isolation backend for a substrate. `firecracker` is [DEF →
|
|
5
6
|
* A3-after-C2] — declared so the union admits the hosted runner without
|
|
@@ -173,6 +174,8 @@ export interface SubstrateHandle {
|
|
|
173
174
|
stdinTty: boolean;
|
|
174
175
|
timeoutMs?: number;
|
|
175
176
|
signal?: AbortSignal;
|
|
177
|
+
/** P46b ID-31 — the descendant sweep the process host runs if the desktop dies first. */
|
|
178
|
+
descendantReap?: HostDescendantReap;
|
|
176
179
|
}): Promise<SubstrateProc>;
|
|
177
180
|
/** Idempotent; MUST destroy the sandbox + its fs view. */
|
|
178
181
|
teardown(): Promise<void>;
|
|
@@ -276,5 +279,7 @@ export interface CommandRunner {
|
|
|
276
279
|
* they are not its cwd (for example Claude's private scratch root).
|
|
277
280
|
*/
|
|
278
281
|
launchPathAuthorities?: readonly WorkspaceRootAuthority[];
|
|
282
|
+
/** P46b ID-31 — the descendant sweep the process host runs if the desktop dies first. */
|
|
283
|
+
descendantReap?: HostDescendantReap;
|
|
279
284
|
}): RunnerProc;
|
|
280
285
|
}
|
|
@@ -41,6 +41,8 @@ export interface EngageSubstrateInput {
|
|
|
41
41
|
* legacy behavior for every existing caller.
|
|
42
42
|
*/
|
|
43
43
|
requireConfined?: boolean;
|
|
44
|
+
/** F-P46a-4 — the implementor spawn's process-tree id (descendant reaping marker). */
|
|
45
|
+
processTreeId?: string;
|
|
44
46
|
/** Ladder deps (injectable for tests). */
|
|
45
47
|
ladderDeps?: FallbackLadderDeps;
|
|
46
48
|
/** Broker upstream client override (tests inject a stub; default real fetch). */
|