@diousk/pi-subagents-fast 0.20.0
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/CHANGELOG.md +808 -0
- package/CONTRIBUTING.md +72 -0
- package/LICENSE +21 -0
- package/README.md +1034 -0
- package/SECURITY.md +95 -0
- package/dist/abortable.d.ts +12 -0
- package/dist/abortable.js +42 -0
- package/dist/agent-color.d.ts +35 -0
- package/dist/agent-color.js +123 -0
- package/dist/agent-file-toggle.d.ts +125 -0
- package/dist/agent-file-toggle.js +260 -0
- package/dist/agent-manager.d.ts +472 -0
- package/dist/agent-manager.js +1338 -0
- package/dist/agent-runner.d.ts +312 -0
- package/dist/agent-runner.js +1034 -0
- package/dist/agent-types.d.ts +119 -0
- package/dist/agent-types.js +286 -0
- package/dist/child-context.d.ts +2 -0
- package/dist/child-context.js +12 -0
- package/dist/context.d.ts +12 -0
- package/dist/context.js +56 -0
- package/dist/cross-extension-rpc.d.ts +66 -0
- package/dist/cross-extension-rpc.js +138 -0
- package/dist/custom-agents.d.ts +54 -0
- package/dist/custom-agents.js +316 -0
- package/dist/default-agents.d.ts +7 -0
- package/dist/default-agents.js +122 -0
- package/dist/enabled-models.d.ts +49 -0
- package/dist/enabled-models.js +145 -0
- package/dist/env.d.ts +6 -0
- package/dist/env.js +28 -0
- package/dist/group-join.d.ts +32 -0
- package/dist/group-join.js +116 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.js +3682 -0
- package/dist/invocation-config.d.ts +107 -0
- package/dist/invocation-config.js +83 -0
- package/dist/memory.d.ts +53 -0
- package/dist/memory.js +165 -0
- package/dist/mention-clone.d.ts +87 -0
- package/dist/mention-clone.js +153 -0
- package/dist/mention.d.ts +81 -0
- package/dist/mention.js +131 -0
- package/dist/model-resolver.d.ts +36 -0
- package/dist/model-resolver.js +95 -0
- package/dist/model-scope.d.ts +49 -0
- package/dist/model-scope.js +48 -0
- package/dist/nested-tools.d.ts +55 -0
- package/dist/nested-tools.js +299 -0
- package/dist/output-file.d.ts +43 -0
- package/dist/output-file.js +142 -0
- package/dist/prompts.d.ts +55 -0
- package/dist/prompts.js +91 -0
- package/dist/schedule-store.d.ts +38 -0
- package/dist/schedule-store.js +155 -0
- package/dist/schedule.d.ts +109 -0
- package/dist/schedule.js +359 -0
- package/dist/settings.d.ts +360 -0
- package/dist/settings.js +251 -0
- package/dist/skill-loader.d.ts +24 -0
- package/dist/skill-loader.js +93 -0
- package/dist/status-note.d.ts +61 -0
- package/dist/status-note.js +85 -0
- package/dist/structured-output.d.ts +61 -0
- package/dist/structured-output.js +112 -0
- package/dist/types.d.ts +371 -0
- package/dist/types.js +5 -0
- package/dist/ui/agent-mention.d.ts +82 -0
- package/dist/ui/agent-mention.js +187 -0
- package/dist/ui/agent-widget.d.ts +219 -0
- package/dist/ui/agent-widget.js +592 -0
- package/dist/ui/conversation-viewer.d.ts +120 -0
- package/dist/ui/conversation-viewer.js +578 -0
- package/dist/ui/fleet-list.d.ts +195 -0
- package/dist/ui/fleet-list.js +471 -0
- package/dist/ui/schedule-menu.d.ts +16 -0
- package/dist/ui/schedule-menu.js +94 -0
- package/dist/ui/select-item.d.ts +27 -0
- package/dist/ui/select-item.js +34 -0
- package/dist/ui/viewer-keys.d.ts +20 -0
- package/dist/ui/viewer-keys.js +17 -0
- package/dist/ui/workflow-card.d.ts +175 -0
- package/dist/ui/workflow-card.js +332 -0
- package/dist/ui/workflow-dialog.d.ts +305 -0
- package/dist/ui/workflow-dialog.js +843 -0
- package/dist/ui/workflow-menu.d.ts +60 -0
- package/dist/ui/workflow-menu.js +147 -0
- package/dist/usage.d.ts +135 -0
- package/dist/usage.js +120 -0
- package/dist/workflow/collisions.d.ts +95 -0
- package/dist/workflow/collisions.js +88 -0
- package/dist/workflow/entry.d.ts +32 -0
- package/dist/workflow/entry.js +29 -0
- package/dist/workflow/host.d.ts +62 -0
- package/dist/workflow/host.js +362 -0
- package/dist/workflow/journal.d.ts +97 -0
- package/dist/workflow/journal.js +120 -0
- package/dist/workflow/json-schema.d.ts +51 -0
- package/dist/workflow/json-schema.js +111 -0
- package/dist/workflow/meta.d.ts +67 -0
- package/dist/workflow/meta.js +317 -0
- package/dist/workflow/progress.d.ts +224 -0
- package/dist/workflow/progress.js +361 -0
- package/dist/workflow/runtime.d.ts +334 -0
- package/dist/workflow/runtime.js +830 -0
- package/dist/workflow/saved.d.ts +90 -0
- package/dist/workflow/saved.js +203 -0
- package/dist/workflow/task.d.ts +136 -0
- package/dist/workflow/task.js +207 -0
- package/dist/workflow/tool-description.d.ts +38 -0
- package/dist/workflow/tool-description.js +199 -0
- package/dist/workflow/worker-source.d.ts +47 -0
- package/dist/workflow/worker-source.js +778 -0
- package/dist/worktree.d.ts +52 -0
- package/dist/worktree.js +164 -0
- package/dist/xml.d.ts +10 -0
- package/dist/xml.js +12 -0
- package/docs/rpc.md +183 -0
- package/docs/workflows.md +437 -0
- package/examples/agent-tool-description.md +42 -0
- package/examples/workflows/compose.js +51 -0
- package/examples/workflows/fan-out-audit.js +47 -0
- package/examples/workflows/gated-fix.js +60 -0
- package/examples/workflows/lib/count-child.js +27 -0
- package/examples/workflows/review-panel.js +63 -0
- package/examples/workflows/structured-findings.js +78 -0
- package/package.json +68 -0
- package/src/abortable.ts +43 -0
- package/src/agent-color.ts +161 -0
- package/src/agent-file-toggle.ts +270 -0
- package/src/agent-manager.ts +1581 -0
- package/src/agent-runner.ts +1286 -0
- package/src/agent-types.ts +346 -0
- package/src/child-context.ts +15 -0
- package/src/context.ts +58 -0
- package/src/cross-extension-rpc.ts +198 -0
- package/src/custom-agents.ts +333 -0
- package/src/default-agents.ts +126 -0
- package/src/enabled-models.ts +180 -0
- package/src/env.ts +33 -0
- package/src/group-join.ts +141 -0
- package/src/index.ts +3991 -0
- package/src/invocation-config.ts +155 -0
- package/src/memory.ts +179 -0
- package/src/mention-clone.ts +196 -0
- package/src/mention.ts +141 -0
- package/src/model-resolver.ts +118 -0
- package/src/model-scope.ts +70 -0
- package/src/nested-tools.ts +422 -0
- package/src/output-file.ts +155 -0
- package/src/prompts.ts +142 -0
- package/src/schedule-store.ts +153 -0
- package/src/schedule.ts +386 -0
- package/src/settings.ts +587 -0
- package/src/skill-loader.ts +102 -0
- package/src/status-note.ts +90 -0
- package/src/structured-output.ts +130 -0
- package/src/types.ts +384 -0
- package/src/ui/agent-mention.ts +216 -0
- package/src/ui/agent-widget.ts +664 -0
- package/src/ui/conversation-viewer.ts +589 -0
- package/src/ui/fleet-list.ts +543 -0
- package/src/ui/schedule-menu.ts +105 -0
- package/src/ui/select-item.ts +45 -0
- package/src/ui/viewer-keys.ts +39 -0
- package/src/ui/workflow-card.ts +470 -0
- package/src/ui/workflow-dialog.ts +1115 -0
- package/src/ui/workflow-menu.ts +193 -0
- package/src/usage.ts +167 -0
- package/src/workflow/collisions.ts +123 -0
- package/src/workflow/entry.ts +47 -0
- package/src/workflow/host.ts +403 -0
- package/src/workflow/journal.ts +164 -0
- package/src/workflow/json-schema.ts +128 -0
- package/src/workflow/meta.ts +325 -0
- package/src/workflow/progress.ts +550 -0
- package/src/workflow/runtime.ts +1219 -0
- package/src/workflow/saved.ts +217 -0
- package/src/workflow/task.ts +302 -0
- package/src/workflow/tool-description.ts +200 -0
- package/src/workflow/worker-source.ts +781 -0
- package/src/worktree.ts +205 -0
- package/src/xml.ts +13 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* schedule-menu.ts — `/agents → Scheduled jobs` submenu.
|
|
3
|
+
*
|
|
4
|
+
* Minimal v1 surface: list scheduled jobs, select one to inspect details +
|
|
5
|
+
* confirm cancellation. No create wizard (the `Agent` tool's `schedule` param
|
|
6
|
+
* is the canonical creation path), no toggle/cleanup (cancel is enough for
|
|
7
|
+
* "I scheduled something dumb, get rid of it"). Add management surfaces here
|
|
8
|
+
* if real demand emerges.
|
|
9
|
+
*/
|
|
10
|
+
import { selectItem } from "./select-item.js";
|
|
11
|
+
/** Format an ISO timestamp as relative time ("in 4h", "2d ago", "—"). */
|
|
12
|
+
function relTime(iso, now = Date.now()) {
|
|
13
|
+
if (!iso)
|
|
14
|
+
return "—";
|
|
15
|
+
const t = new Date(iso).getTime();
|
|
16
|
+
if (Number.isNaN(t))
|
|
17
|
+
return "—";
|
|
18
|
+
const diff = t - now;
|
|
19
|
+
const abs = Math.abs(diff);
|
|
20
|
+
const future = diff > 0;
|
|
21
|
+
if (abs < 60_000)
|
|
22
|
+
return future ? "in <1m" : "<1m ago";
|
|
23
|
+
const m = Math.round(abs / 60_000);
|
|
24
|
+
if (m < 60)
|
|
25
|
+
return future ? `in ${m}m` : `${m}m ago`;
|
|
26
|
+
const h = Math.round(abs / 3_600_000);
|
|
27
|
+
if (h < 24)
|
|
28
|
+
return future ? `in ${h}h` : `${h}h ago`;
|
|
29
|
+
const d = Math.round(abs / 86_400_000);
|
|
30
|
+
return future ? `in ${d}d` : `${d}d ago`;
|
|
31
|
+
}
|
|
32
|
+
/** One-line status icon. */
|
|
33
|
+
function statusIcon(j) {
|
|
34
|
+
if (!j.enabled)
|
|
35
|
+
return "✗";
|
|
36
|
+
if (j.lastStatus === "error")
|
|
37
|
+
return "!";
|
|
38
|
+
if (j.lastStatus === "running")
|
|
39
|
+
return "⋯";
|
|
40
|
+
return "✓";
|
|
41
|
+
}
|
|
42
|
+
/** Compact selectable row — name, schedule, agent type, next/last run, count. */
|
|
43
|
+
function formatJob(j, scheduler) {
|
|
44
|
+
const next = scheduler.getNextRun(j.id);
|
|
45
|
+
return [
|
|
46
|
+
statusIcon(j),
|
|
47
|
+
j.name.padEnd(18).slice(0, 18),
|
|
48
|
+
j.schedule.padEnd(14).slice(0, 14),
|
|
49
|
+
`[${j.subagent_type}]`,
|
|
50
|
+
`next ${relTime(next)}`,
|
|
51
|
+
`last ${relTime(j.lastRun)}`,
|
|
52
|
+
`runs ${j.runCount}`,
|
|
53
|
+
].join(" ");
|
|
54
|
+
}
|
|
55
|
+
/** Multi-line details block for the cancel confirm. */
|
|
56
|
+
function formatDetails(j, scheduler) {
|
|
57
|
+
const next = scheduler.getNextRun(j.id) ?? "—";
|
|
58
|
+
return [
|
|
59
|
+
`name: ${j.name}`,
|
|
60
|
+
`schedule: ${j.schedule} (${j.scheduleType})`,
|
|
61
|
+
`agent: ${j.subagent_type}`,
|
|
62
|
+
`prompt: ${j.prompt.slice(0, 200)}${j.prompt.length > 200 ? "…" : ""}`,
|
|
63
|
+
`created: ${j.createdAt}`,
|
|
64
|
+
`last run: ${j.lastRun ?? "—"} (${j.lastStatus ?? "—"})`,
|
|
65
|
+
`next run: ${next}`,
|
|
66
|
+
`runs: ${j.runCount}`,
|
|
67
|
+
].join("\n");
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* List scheduled jobs; selecting one opens a cancel-confirm with details.
|
|
71
|
+
* Returns when the user backs out or after a cancellation.
|
|
72
|
+
*/
|
|
73
|
+
export async function showSchedulesMenu(ctx, scheduler) {
|
|
74
|
+
if (!scheduler.isActive()) {
|
|
75
|
+
ctx.ui.notify("Scheduler is not active in this session.", "warning");
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const jobs = scheduler.list();
|
|
79
|
+
if (jobs.length === 0) {
|
|
80
|
+
ctx.ui.notify("No scheduled jobs.", "info");
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
// Numbered + item-paired: two jobs whose names agree in the first 18
|
|
84
|
+
// characters format identically, and matching the returned string back
|
|
85
|
+
// against a parallel label array cancelled whichever came first.
|
|
86
|
+
const job = await selectItem(ctx.ui, `Scheduled jobs (${jobs.length}) — select to cancel`, jobs, j => formatJob(j, scheduler));
|
|
87
|
+
if (!job)
|
|
88
|
+
return;
|
|
89
|
+
const ok = await ctx.ui.confirm(`Cancel "${job.name}"?`, formatDetails(job, scheduler));
|
|
90
|
+
if (!ok)
|
|
91
|
+
return;
|
|
92
|
+
scheduler.removeJob(job.id);
|
|
93
|
+
ctx.ui.notify(`Cancelled "${job.name}".`, "info");
|
|
94
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* select-item.ts — pick an item from a list via `ctx.ui.select`, safely.
|
|
3
|
+
*
|
|
4
|
+
* Pi's dialog API is `select(title, options: string[]) => Promise<string | undefined>`:
|
|
5
|
+
* strings in, string out, with no index or value form. Callers therefore have to
|
|
6
|
+
* map the returned string back to the item it came from, and the obvious way —
|
|
7
|
+
* `labels.indexOf(choice)` over a parallel array — silently resolves to the
|
|
8
|
+
* FIRST match whenever two rows format identically. Row formatters here truncate
|
|
9
|
+
* (job names to 18 chars, agent descriptions to whatever fits), and the text they
|
|
10
|
+
* truncate is LLM-authored, so collisions are ordinary rather than exotic.
|
|
11
|
+
*
|
|
12
|
+
* This numbers every row, which makes the labels unique by construction — no
|
|
13
|
+
* data-dependent branch that only executes in the case nobody exercises — and
|
|
14
|
+
* keeps each label paired with its item so a later edit that sorts or filters
|
|
15
|
+
* between building and resolving cannot desync them.
|
|
16
|
+
*/
|
|
17
|
+
/** Minimal shape of the `ctx.ui` surface this needs. */
|
|
18
|
+
export interface SelectUI {
|
|
19
|
+
select(title: string, options: string[]): Promise<string | undefined>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Show a numbered picker and return the chosen item (not its label).
|
|
23
|
+
*
|
|
24
|
+
* Returns undefined when the user escapes, or when the returned string is not
|
|
25
|
+
* one we offered.
|
|
26
|
+
*/
|
|
27
|
+
export declare function selectItem<T>(ui: SelectUI, title: string, items: readonly T[], format: (item: T, index: number) => string): Promise<T | undefined>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* select-item.ts — pick an item from a list via `ctx.ui.select`, safely.
|
|
3
|
+
*
|
|
4
|
+
* Pi's dialog API is `select(title, options: string[]) => Promise<string | undefined>`:
|
|
5
|
+
* strings in, string out, with no index or value form. Callers therefore have to
|
|
6
|
+
* map the returned string back to the item it came from, and the obvious way —
|
|
7
|
+
* `labels.indexOf(choice)` over a parallel array — silently resolves to the
|
|
8
|
+
* FIRST match whenever two rows format identically. Row formatters here truncate
|
|
9
|
+
* (job names to 18 chars, agent descriptions to whatever fits), and the text they
|
|
10
|
+
* truncate is LLM-authored, so collisions are ordinary rather than exotic.
|
|
11
|
+
*
|
|
12
|
+
* This numbers every row, which makes the labels unique by construction — no
|
|
13
|
+
* data-dependent branch that only executes in the case nobody exercises — and
|
|
14
|
+
* keeps each label paired with its item so a later edit that sorts or filters
|
|
15
|
+
* between building and resolving cannot desync them.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Show a numbered picker and return the chosen item (not its label).
|
|
19
|
+
*
|
|
20
|
+
* Returns undefined when the user escapes, or when the returned string is not
|
|
21
|
+
* one we offered.
|
|
22
|
+
*/
|
|
23
|
+
export async function selectItem(ui, title, items, format) {
|
|
24
|
+
// Pad the number so a 10+ item list keeps its columns aligned.
|
|
25
|
+
const width = String(items.length).length;
|
|
26
|
+
const rows = items.map((item, i) => ({
|
|
27
|
+
item,
|
|
28
|
+
label: `${String(i + 1).padStart(width)}. ${format(item, i)}`,
|
|
29
|
+
}));
|
|
30
|
+
const choice = await ui.select(title, rows.map(r => r.label));
|
|
31
|
+
if (!choice)
|
|
32
|
+
return undefined;
|
|
33
|
+
return rows.find(r => r.label === choice)?.item;
|
|
34
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* viewer-keys.ts — Scroll key matchers for the conversation viewer.
|
|
3
|
+
*
|
|
4
|
+
* Resolves `tui.select.*` through the user's keybindings when pi provides a
|
|
5
|
+
* manager, falling back to the previous hardcoded keys otherwise. The viewer's
|
|
6
|
+
* k/j and shift+arrow aliases always work alongside whatever is bound.
|
|
7
|
+
*/
|
|
8
|
+
/** The `tui.select.*` keybinding ids the viewer resolves. */
|
|
9
|
+
export type ViewerScrollKeybinding = "tui.select.up" | "tui.select.down" | "tui.select.pageUp" | "tui.select.pageDown";
|
|
10
|
+
/** Structural subset of pi-tui's `KeybindingsManager` (which satisfies it). */
|
|
11
|
+
export interface ViewerKeybindings {
|
|
12
|
+
matches(data: string, keybinding: ViewerScrollKeybinding): boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface ViewerKeys {
|
|
15
|
+
scrollUp(data: string): boolean;
|
|
16
|
+
scrollDown(data: string): boolean;
|
|
17
|
+
pageUp(data: string): boolean;
|
|
18
|
+
pageDown(data: string): boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare function createViewerKeys(keybindings?: ViewerKeybindings): ViewerKeys;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* viewer-keys.ts — Scroll key matchers for the conversation viewer.
|
|
3
|
+
*
|
|
4
|
+
* Resolves `tui.select.*` through the user's keybindings when pi provides a
|
|
5
|
+
* manager, falling back to the previous hardcoded keys otherwise. The viewer's
|
|
6
|
+
* k/j and shift+arrow aliases always work alongside whatever is bound.
|
|
7
|
+
*/
|
|
8
|
+
import { matchesKey } from "@earendil-works/pi-tui";
|
|
9
|
+
export function createViewerKeys(keybindings) {
|
|
10
|
+
const matches = (data, id, fallback) => keybindings ? keybindings.matches(data, id) : matchesKey(data, fallback);
|
|
11
|
+
return {
|
|
12
|
+
scrollUp: (data) => matches(data, "tui.select.up", "up") || matchesKey(data, "k"),
|
|
13
|
+
scrollDown: (data) => matches(data, "tui.select.down", "down") || matchesKey(data, "j"),
|
|
14
|
+
pageUp: (data) => matches(data, "tui.select.pageUp", "pageUp") || matchesKey(data, "shift+up"),
|
|
15
|
+
pageDown: (data) => matches(data, "tui.select.pageDown", "pageDown") || matchesKey(data, "shift+down"),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* workflow-card.ts — the inline transcript card for a running workflow.
|
|
3
|
+
*
|
|
4
|
+
* ```
|
|
5
|
+
* ▸ Workflow review-changes 3/7 agents · 1m12s
|
|
6
|
+
* Review changed files across dimensions, verify each finding
|
|
7
|
+
* ╭─ Review
|
|
8
|
+
* │ ├─ ✔ review:bugs · Explore · haiku · 18.4k · 12 tool calls · 42s
|
|
9
|
+
* │ ├─ ⟳ review:perf · Explore · 8 tool calls · 21s
|
|
10
|
+
* │ └─ ⟳ review:security
|
|
11
|
+
* ╰─ Verify
|
|
12
|
+
* └─ ⟳ verify:auth.ts · Plan · 3 tool calls · 9s
|
|
13
|
+
* ⎿ scanned 41 changed files
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* Two things about this file are easy to get wrong.
|
|
17
|
+
*
|
|
18
|
+
* **The glyphs are not the dialog's glyphs.** The inline row keys off the *raw*
|
|
19
|
+
* entry `state` (start | progress | done | error), not the derived display
|
|
20
|
+
* state, so a skipped or blocked agent renders as a plain ✘ here while the
|
|
21
|
+
* workflows dialog distinguishes them. `displayState` is deliberately not
|
|
22
|
+
* consulted below.
|
|
23
|
+
*
|
|
24
|
+
* **The layout is pure.** `layoutWorkflowCard` returns coloured segments and
|
|
25
|
+
* never touches a theme or a terminal, so the same layout drives the `Workflow`
|
|
26
|
+
* tool's `renderResult` and a standalone session entry (a workflow launched from
|
|
27
|
+
* a CLI flag has no tool call to attach to). Theme application is the thin
|
|
28
|
+
* `styleWorkflowCardLines` wrapper on top.
|
|
29
|
+
*
|
|
30
|
+
* All state derivation lives in `src/workflow/progress.ts`; this file only
|
|
31
|
+
* arranges what that module returns.
|
|
32
|
+
*/
|
|
33
|
+
import { Text } from "@earendil-works/pi-tui";
|
|
34
|
+
import type { WorkflowEntryData } from "../workflow/entry.js";
|
|
35
|
+
import type { WorkflowMeta } from "../workflow/meta.js";
|
|
36
|
+
import { type WorkflowAgentEntry, type WorkflowEntry, type WorkflowRunStatus } from "../workflow/progress.js";
|
|
37
|
+
import type { Theme } from "./agent-widget.js";
|
|
38
|
+
/**
|
|
39
|
+
* Header re-render cadence. Claude Code ticks the workflow clock once a second,
|
|
40
|
+
* not at the 80ms spinner cadence — the running glyph is static, so there is
|
|
41
|
+
* nothing to animate faster than the elapsed time changes.
|
|
42
|
+
*/
|
|
43
|
+
export declare const WORKFLOW_TICK_MS = 1000;
|
|
44
|
+
export interface WorkflowGlyphs {
|
|
45
|
+
/** Tool-title pointer, matching the Agent tool's `▸`. */
|
|
46
|
+
pointer: string;
|
|
47
|
+
tick: string;
|
|
48
|
+
cross: string;
|
|
49
|
+
/** Running/queued. A static glyph, hence no spinner inline. */
|
|
50
|
+
running: string;
|
|
51
|
+
/** First and subsequent phase groups. */
|
|
52
|
+
groupTop: string;
|
|
53
|
+
/** A group that is neither the first nor the last. */
|
|
54
|
+
groupMid: string;
|
|
55
|
+
/** The last phase group. */
|
|
56
|
+
groupBottom: string;
|
|
57
|
+
/** Continuation rail under a non-final group. */
|
|
58
|
+
vertical: string;
|
|
59
|
+
branch: string;
|
|
60
|
+
lastBranch: string;
|
|
61
|
+
/** Log-line prefix, matching the Agent tool's result lines. */
|
|
62
|
+
log: string;
|
|
63
|
+
warning: string;
|
|
64
|
+
}
|
|
65
|
+
export declare const UNICODE_GLYPHS: WorkflowGlyphs;
|
|
66
|
+
/**
|
|
67
|
+
* The `figures` ASCII tier, for terminals that cannot draw the box set. Every
|
|
68
|
+
* glyph keeps its unicode counterpart's column width so the tree stays aligned
|
|
69
|
+
* either way.
|
|
70
|
+
*/
|
|
71
|
+
export declare const ASCII_GLYPHS: WorkflowGlyphs;
|
|
72
|
+
/**
|
|
73
|
+
* pi theme keys. Claude Code's palette maps as success→success, error→error,
|
|
74
|
+
* subtle→dim, permission→warning for a blocked row and accent for selection;
|
|
75
|
+
* an undefined colour means "leave it at the terminal default", which is what
|
|
76
|
+
* the recovered inline mapping asks for on a running row.
|
|
77
|
+
*
|
|
78
|
+
* `accent` is unused by the card and exists for the workflows dialog, which
|
|
79
|
+
* shares these segment types.
|
|
80
|
+
*/
|
|
81
|
+
export type WorkflowCardColor = "success" | "error" | "warning" | "dim" | "muted" | "toolTitle" | "accent";
|
|
82
|
+
export interface WorkflowCardSegment {
|
|
83
|
+
text: string;
|
|
84
|
+
color?: WorkflowCardColor;
|
|
85
|
+
bold?: boolean;
|
|
86
|
+
}
|
|
87
|
+
export type WorkflowCardLine = WorkflowCardSegment[];
|
|
88
|
+
/** The subset of the task record the card reads. */
|
|
89
|
+
export interface WorkflowCardTask {
|
|
90
|
+
status: WorkflowRunStatus;
|
|
91
|
+
workflowName?: string;
|
|
92
|
+
summary?: string;
|
|
93
|
+
description?: string;
|
|
94
|
+
startTime: number;
|
|
95
|
+
endTime?: number;
|
|
96
|
+
totalPausedMs?: number;
|
|
97
|
+
}
|
|
98
|
+
export interface WorkflowCardInput {
|
|
99
|
+
progress: readonly WorkflowEntry[];
|
|
100
|
+
task: WorkflowCardTask;
|
|
101
|
+
meta?: WorkflowMeta;
|
|
102
|
+
/** Agents the runtime has scheduled, which can exceed those that have reported. */
|
|
103
|
+
agentCount?: number;
|
|
104
|
+
/** Total tokens for the size warning; summed from the entries when omitted. */
|
|
105
|
+
totalTokens?: number;
|
|
106
|
+
agentCap?: number;
|
|
107
|
+
tokenCap?: number;
|
|
108
|
+
now?: number;
|
|
109
|
+
width?: number;
|
|
110
|
+
/** Swap in the ASCII glyph tier for terminals without unicode. */
|
|
111
|
+
ascii?: boolean;
|
|
112
|
+
/**
|
|
113
|
+
* Lead with `▸ SubagentWorkflow`.
|
|
114
|
+
*
|
|
115
|
+
* True where the card stands alone — the session entry a flag-launched run
|
|
116
|
+
* writes, which has no tool call above it to say what it is. False as a tool
|
|
117
|
+
* result, where the call line directly above already does.
|
|
118
|
+
*/
|
|
119
|
+
showToolTitle?: boolean;
|
|
120
|
+
}
|
|
121
|
+
/** `18.4k` / `1.2M` — bare magnitude, since the row already reads as a stat. */
|
|
122
|
+
export declare function formatCompactTokens(count: number): string;
|
|
123
|
+
/**
|
|
124
|
+
* One label for the model pair. A fallback that never differed from the primary
|
|
125
|
+
* would just be noise, so it only shows when the run actually has two models in
|
|
126
|
+
* play.
|
|
127
|
+
*/
|
|
128
|
+
export declare function formatModel(entry: WorkflowAgentEntry, opts?: {
|
|
129
|
+
canonical?: boolean;
|
|
130
|
+
}): string | undefined;
|
|
131
|
+
/**
|
|
132
|
+
* The thinking level, and what was asked for when it was not honoured.
|
|
133
|
+
*
|
|
134
|
+
* Separate from {@link formatModel} because a row can have one without the
|
|
135
|
+
* other: an `agent()` that named no model still runs at some level, and a level
|
|
136
|
+
* pi clamped is worth saying so about even when the model is unremarkable.
|
|
137
|
+
*/
|
|
138
|
+
export declare function formatThinking(entry: WorkflowAgentEntry): string | undefined;
|
|
139
|
+
/**
|
|
140
|
+
* What a row replayed from a resume journal says instead of a duration.
|
|
141
|
+
*
|
|
142
|
+
* Shared with the dialog so both views name the same thing the same way — the
|
|
143
|
+
* card shows it inline while the run happens, the dialog on the agent's row.
|
|
144
|
+
*/
|
|
145
|
+
export declare const REPLAYED_ANNOTATION = "from resume journal";
|
|
146
|
+
/**
|
|
147
|
+
* The `·`-separated tail of an agent row, in the recovered order: agentType,
|
|
148
|
+
* model, tokens, toolCalls, durationMs. Absent values drop out entirely rather
|
|
149
|
+
* than rendering a placeholder.
|
|
150
|
+
*/
|
|
151
|
+
export declare function agentStatSegments(entry: WorkflowAgentEntry): string[];
|
|
152
|
+
/** Trim a line to `width`, cutting inside whichever segment crosses the edge. */
|
|
153
|
+
export declare function clampLine(line: WorkflowCardLine, width: number): WorkflowCardLine;
|
|
154
|
+
/**
|
|
155
|
+
* Build the card.
|
|
156
|
+
*
|
|
157
|
+
* Everything derived — the phase tree, the header counts, the logs, the size
|
|
158
|
+
* warning — comes from `progress.ts`; what happens here is purely arrangement.
|
|
159
|
+
*/
|
|
160
|
+
export declare function layoutWorkflowCard(input: WorkflowCardInput): WorkflowCardLine[];
|
|
161
|
+
/** The card as plain text — what the layout tests assert against. */
|
|
162
|
+
export declare function plainWorkflowCardLines(lines: readonly WorkflowCardLine[]): string[];
|
|
163
|
+
/** Apply the theme. Nothing here changes the layout, only its colours. */
|
|
164
|
+
export declare function styleWorkflowCardLines(lines: readonly WorkflowCardLine[], theme: Theme): string[];
|
|
165
|
+
/** The card as a component, for a tool result or a session entry renderer. */
|
|
166
|
+
export declare function renderWorkflowCard(input: WorkflowCardInput, theme: Theme): Text;
|
|
167
|
+
/**
|
|
168
|
+
* The card for a session entry, from the JSON a flag-launched run persisted.
|
|
169
|
+
*
|
|
170
|
+
* The same layout the tool result uses, not a second one — the only difference
|
|
171
|
+
* is `showToolTitle`, because a session entry stands alone and nothing above it
|
|
172
|
+
* says what it is. Returns undefined for an entry with no data, which is what
|
|
173
|
+
* pi's renderer contract wants for "nothing to draw".
|
|
174
|
+
*/
|
|
175
|
+
export declare function renderWorkflowEntryCard(data: WorkflowEntryData | undefined, theme: Theme): Text | undefined;
|