pi-workflow-engine 0.13.0 → 1.1.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/.pi/extensions/pi-workflow-engine/index.ts +152 -416
- package/.pi/extensions/pi-workflow-engine/src/advisory-challenge.ts +1 -1
- package/.pi/extensions/pi-workflow-engine/src/advisory-evidence.ts +17 -14
- package/.pi/extensions/pi-workflow-engine/src/advisory-schema.ts +7 -1
- package/.pi/extensions/pi-workflow-engine/src/agent-attempt.ts +48 -62
- package/.pi/extensions/pi-workflow-engine/src/agent-replay.ts +46 -67
- package/.pi/extensions/pi-workflow-engine/src/agent-retry.ts +14 -37
- package/.pi/extensions/pi-workflow-engine/src/agent-runner-types.ts +12 -13
- package/.pi/extensions/pi-workflow-engine/src/agent-runner.ts +15 -21
- package/.pi/extensions/pi-workflow-engine/src/agent-session-identity.ts +13 -43
- package/.pi/extensions/pi-workflow-engine/src/agent-session-providers.ts +17 -5
- package/.pi/extensions/pi-workflow-engine/src/agent-session.ts +131 -117
- package/.pi/extensions/pi-workflow-engine/src/agent-skills.ts +11 -43
- package/.pi/extensions/pi-workflow-engine/src/agent-workspace.ts +4 -18
- package/.pi/extensions/pi-workflow-engine/src/background-workflow-tool.ts +3 -0
- package/.pi/extensions/pi-workflow-engine/src/background-workflows.ts +33 -86
- package/.pi/extensions/pi-workflow-engine/src/cancellation.ts +1 -5
- package/.pi/extensions/pi-workflow-engine/src/classify.ts +107 -0
- package/.pi/extensions/pi-workflow-engine/src/concurrency.ts +25 -80
- package/.pi/extensions/pi-workflow-engine/src/discovery.ts +16 -23
- package/.pi/extensions/pi-workflow-engine/src/dynamax-shortcuts.ts +1 -4
- package/.pi/extensions/pi-workflow-engine/src/dynamax.ts +58 -117
- package/.pi/extensions/pi-workflow-engine/src/engine.ts +41 -80
- package/.pi/extensions/pi-workflow-engine/src/finalizers.ts +2 -10
- package/.pi/extensions/pi-workflow-engine/src/git.ts +55 -0
- package/.pi/extensions/pi-workflow-engine/src/guards.ts +8 -0
- package/.pi/extensions/pi-workflow-engine/src/host-tools.ts +76 -0
- package/.pi/extensions/pi-workflow-engine/src/identity-canonicalization.ts +7 -19
- package/.pi/extensions/pi-workflow-engine/src/inline-workflow.ts +171 -106
- package/.pi/extensions/pi-workflow-engine/src/journal.ts +0 -12
- package/.pi/extensions/pi-workflow-engine/src/model-profile-command.ts +37 -8
- package/.pi/extensions/pi-workflow-engine/src/model-profiles.ts +15 -66
- package/.pi/extensions/pi-workflow-engine/src/model-ref.ts +19 -0
- package/.pi/extensions/pi-workflow-engine/src/options.ts +97 -16
- package/.pi/extensions/pi-workflow-engine/src/perf.ts +43 -72
- package/.pi/extensions/pi-workflow-engine/src/pi-compat.ts +2 -2
- package/.pi/extensions/pi-workflow-engine/src/process-runner.ts +14 -4
- package/.pi/extensions/pi-workflow-engine/src/progress-types.ts +2 -0
- package/.pi/extensions/pi-workflow-engine/src/progress.ts +79 -80
- package/.pi/extensions/pi-workflow-engine/src/provider-usage-limit.ts +28 -20
- package/.pi/extensions/pi-workflow-engine/src/replay-path-identity.ts +2 -7
- package/.pi/extensions/pi-workflow-engine/src/research-contract.ts +0 -1
- package/.pi/extensions/pi-workflow-engine/src/research-evidence.ts +29 -31
- package/.pi/extensions/pi-workflow-engine/src/resume-context.ts +75 -139
- package/.pi/extensions/pi-workflow-engine/src/review/github-pr-comments.ts +14 -31
- package/.pi/extensions/pi-workflow-engine/src/review/patch-validation.ts +3 -4
- package/.pi/extensions/pi-workflow-engine/src/review/review-actions.ts +1 -1
- package/.pi/extensions/pi-workflow-engine/src/review/review-diff-lines.ts +54 -0
- package/.pi/extensions/pi-workflow-engine/src/review/review-fix-workflow.ts +7 -9
- package/.pi/extensions/pi-workflow-engine/src/review/review-format.ts +51 -117
- package/.pi/extensions/pi-workflow-engine/src/review/review-handoff.ts +1 -1
- package/.pi/extensions/pi-workflow-engine/src/review/review-issues.ts +8 -13
- package/.pi/extensions/pi-workflow-engine/src/review/review-report.ts +3 -7
- package/.pi/extensions/pi-workflow-engine/src/review/review-results-viewer.ts +158 -241
- package/.pi/extensions/pi-workflow-engine/src/review/review-session-coordinator.ts +28 -38
- package/.pi/extensions/pi-workflow-engine/src/review/review-snapshot.ts +35 -44
- package/.pi/extensions/pi-workflow-engine/src/review-diff-target.ts +13 -14
- package/.pi/extensions/pi-workflow-engine/src/text.ts +29 -0
- package/.pi/extensions/pi-workflow-engine/src/tool-capabilities.ts +17 -4
- package/.pi/extensions/pi-workflow-engine/src/tool-source-identity.ts +16 -28
- package/.pi/extensions/pi-workflow-engine/src/tree-fingerprint.ts +34 -14
- package/.pi/extensions/pi-workflow-engine/src/types.ts +30 -0
- package/.pi/extensions/pi-workflow-engine/src/ui/kit.ts +193 -0
- package/.pi/extensions/pi-workflow-engine/src/ui/research-result-renderer.ts +177 -0
- package/.pi/extensions/pi-workflow-engine/src/ui/result-layout.ts +209 -0
- package/.pi/extensions/pi-workflow-engine/src/ui/workflow-format.ts +17 -44
- package/.pi/extensions/pi-workflow-engine/src/ui/workflow-inspector.ts +703 -235
- package/.pi/extensions/pi-workflow-engine/src/ui/workflow-picker.ts +48 -0
- package/.pi/extensions/pi-workflow-engine/src/ui/workflow-result-renderer.ts +239 -129
- package/.pi/extensions/pi-workflow-engine/src/ui/workflow-runs-browser.ts +461 -0
- package/.pi/extensions/pi-workflow-engine/src/ui/workflow-tool-renderer.ts +91 -0
- package/.pi/extensions/pi-workflow-engine/src/ui/workflow-widget.ts +316 -98
- package/.pi/extensions/pi-workflow-engine/src/usage.ts +41 -34
- package/.pi/extensions/pi-workflow-engine/src/workflow-advisory-utils.ts +162 -22
- package/.pi/extensions/pi-workflow-engine/src/workflow-execution.ts +19 -24
- package/.pi/extensions/pi-workflow-engine/src/workflow-module.ts +17 -37
- package/.pi/extensions/pi-workflow-engine/src/workflow-result-context.ts +79 -0
- package/.pi/extensions/pi-workflow-engine/src/workflow-run-background.ts +4 -14
- package/.pi/extensions/pi-workflow-engine/src/workflow-run-controller.ts +77 -63
- package/.pi/extensions/pi-workflow-engine/src/workflow-run-history.ts +42 -29
- package/.pi/extensions/pi-workflow-engine/src/workflow-run-record.ts +15 -14
- package/.pi/extensions/pi-workflow-engine/src/workflow-run-store.ts +27 -31
- package/.pi/extensions/pi-workflow-engine/src/workflow-usage-limit-scheduler.ts +1 -5
- package/.pi/extensions/pi-workflow-engine/src/workflows.ts +3 -6
- package/.pi/extensions/pi-workflow-engine/src/worktree.ts +48 -110
- package/.pi/extensions/pi-workflow-engine/workflows/code-review.ts +64 -93
- package/.pi/extensions/pi-workflow-engine/workflows/diagnose.ts +25 -67
- package/.pi/extensions/pi-workflow-engine/workflows/perf-review.ts +19 -53
- package/.pi/extensions/pi-workflow-engine/workflows/refactor-scout.ts +21 -49
- package/.pi/extensions/pi-workflow-engine/workflows/research.ts +74 -66
- package/README.md +1 -1
- package/USAGE.md +79 -20
- package/package.json +1 -2
- package/skills/workflow-code-review-actions/SKILL.md +12 -23
- package/.pi/extensions/pi-workflow-engine/src/diff-capture.ts +0 -81
- package/.pi/extensions/pi-workflow-engine/src/review/code-review-orchestration.ts +0 -24
- package/.pi/extensions/pi-workflow-engine/src/review/review-results-flow.ts +0 -52
- package/.pi/settings.json +0 -3
package/USAGE.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
`pi-workflow-engine` adds zero-dependency Dynamax workflows to pi: opt into live, parallel subagents for the tasks that need a custom investigation instead of one long prompt. Most users only need these surfaces:
|
|
4
4
|
|
|
5
|
-
This release requires **pi 0.
|
|
5
|
+
This release requires **pi 1.0.0 or newer**. pi remains host-provided rather
|
|
6
6
|
than bundled by this package, and the extension rejects older runtimes at load
|
|
7
7
|
time with an update message.
|
|
8
8
|
|
|
@@ -36,7 +36,7 @@ Useful flags:
|
|
|
36
36
|
/workflow code-review --concurrency=4 # cap concurrent subagents
|
|
37
37
|
/workflow code-review --max-agents=20 # cap total live agent calls in the run
|
|
38
38
|
/workflow code-review --agent-timeout-ms=600000 # abort one live agent after 10 minutes
|
|
39
|
-
/workflow code-review --agent-retries=2 #
|
|
39
|
+
/workflow code-review --agent-retries=2 # restart agents whose in-session retries are exhausted
|
|
40
40
|
/workflow code-review --budget=50000 # output-token ceiling for subagents
|
|
41
41
|
/workflow code-review --resume <run-id> # replay matching completed agent calls
|
|
42
42
|
/workflow code-review --resume <run-id> --resume-edited # reuse unchanged calls after a workflow edit
|
|
@@ -109,7 +109,9 @@ command instead of selecting another model.
|
|
|
109
109
|
as external web search, browsing, or HTTP(S) page extraction. Local grep/find
|
|
110
110
|
tools do not satisfy this check. The workflow does not bundle a scraper or a
|
|
111
111
|
paid API; install or enable the web capability you prefer, then restart or
|
|
112
|
-
reload pi so subagent sessions can see it.
|
|
112
|
+
reload pi so subagent sessions can see it. An MCP web search server also
|
|
113
|
+
qualifies when the host agent runs `research` through the `workflow` tool,
|
|
114
|
+
because only those runs can reach the host's MCP tools.
|
|
113
115
|
|
|
114
116
|
The workflow bounds decomposition to four lanes and verification to twelve
|
|
115
117
|
claims, while the engine's concurrency, total-agent, timeout, cancellation, and
|
|
@@ -124,7 +126,7 @@ the journal's deterministic replay surface.
|
|
|
124
126
|
|
|
125
127
|
Use `dynamax` when the built-in workflows are not specific enough and you want the main pi agent to author a temporary workflow for the current question. It is the fastest path from "this needs multiple angles" to a live fan-out, verifier pass, and synthesized result.
|
|
126
128
|
|
|
127
|
-
Interactive shortcut: run `/workflow` with no arguments, choose
|
|
129
|
+
Interactive shortcut: run `/workflow` with no arguments, choose `+ author a one-off workflow` (the last row, below the registered workflows), and type a brief. Escape closes the picker without running anything. pi will send that brief back to the host agent as a `dynamax` request so it can author and run an inline workflow with the `workflow` tool's `script` argument.
|
|
128
130
|
|
|
129
131
|
That inline workflow should investigate, fan out, verify, and summarize. It is **not** where code edits happen. If you want changes made, use the workflow result as evidence and then ask pi to edit separately.
|
|
130
132
|
|
|
@@ -146,7 +148,7 @@ Sticky mode and inspector shortcut:
|
|
|
146
148
|
|
|
147
149
|
The workflow inspector and code-review results viewer are also registered as first-class shortcuts shown by `/hotkeys`. The defaults are `ctrl+shift+m` for the inspector and `ctrl+shift+r` for the latest review results. `ctrl+o` is intentionally not used because pi already uses it for tool-output expansion and tree filtering.
|
|
148
150
|
|
|
149
|
-
When only the literal `dynamax` token is used, the opt-in is one-shot: the next agent run receives the workflow
|
|
151
|
+
When only the literal `dynamax` token is used, the opt-in is one-shot: the next agent run receives a `<dynamax>` system prompt section that permits the workflow tool (pi appends it as a section patch, so the cached prompt head is kept), stays visibly active for that run, then clears after the run ends. When `/workflow:dynamax on` is used, the opt-in is sticky for the current pi session until `/workflow:dynamax off`. The footer status states the mode compactly: `◆ dynamax` while sticky, `◆ dynamax · next prompt` while a one-shot waits for its prompt, and `◆ dynamax · this turn` while that run is active; off mode clears it. A running workflow names itself in its own status next to it.
|
|
150
152
|
|
|
151
153
|
### Prompt editor cue
|
|
152
154
|
|
|
@@ -160,7 +162,7 @@ The default effect is `shine`. Set `PI_DYNAMAX_EFFECT=static` for a motionless
|
|
|
160
162
|
cue or `PI_DYNAMAX_EFFECT=off` to disable it. A non-empty `NO_COLOR` also
|
|
161
163
|
disables the default cue; an explicit `PI_DYNAMAX_EFFECT` value takes precedence.
|
|
162
164
|
|
|
163
|
-
The implementation follows pi
|
|
165
|
+
The implementation follows pi's [official `CustomEditor`
|
|
164
166
|
pattern](https://pi.dev/docs/latest/extensions#custom-editor): it decorates only
|
|
165
167
|
the editor's rendered lines, retaining the wrapped editor's input, cursor,
|
|
166
168
|
deletion, paste, multiline, undo, completion, IME, and app-keybinding behavior.
|
|
@@ -172,7 +174,7 @@ is used so highlighting is never silently disabled. Pi editor registration is
|
|
|
172
174
|
still last-writer-wins; the previous editor is restored on shutdown only while
|
|
173
175
|
the Dynamax decorator still owns the registration.
|
|
174
176
|
|
|
175
|
-
When the host agent calls the `workflow` tool
|
|
177
|
+
When the host agent calls the `workflow` tool, the inspector stays closed so the agent's reply remains in view; the compact workflow widget shows the moving status above the editor. Press the inspector shortcut or run `/workflow:inspector` for the richer view of phases, agents, findings, and logs, live or after the run.
|
|
176
178
|
|
|
177
179
|
Configure either shortcut by creating `~/.pi/agent/extensions/pi-workflow-engine.json`:
|
|
178
180
|
|
|
@@ -241,9 +243,11 @@ Workflow results are rendered in pi with:
|
|
|
241
243
|
|
|
242
244
|
These workflow usage totals are separate from `--perf`, which is internal timing only. They are also separate from pi's built-in footer and `/session` totals, which may still show host-session usage only unless pi core adds a first-class extension usage API. If a model has no pricing configured, token totals can be non-zero while displayed cost remains `$0.000`.
|
|
243
245
|
|
|
244
|
-
|
|
246
|
+
Results, the inspector overview, the runs browser and the live widget header show usage in the compact form `↑34k ↓1.2k · $0.02` (input including cache, output, and cost when known); the footer status line carries no usage. The result text handed to the host agent keeps the full breakdown: providers with a complete breakdown show `fresh`, `cache read`, `cache write`, and `output` separately. Zero cache components are omitted. If a provider reports only some components, the summary labels mixed-run component totals with `≥` and preserves the provider's aggregate `total`; if it reports no components, the summary falls back to aggregate `tokens`. Costs are summed from provider session totals and are never inferred from local pricing.
|
|
245
247
|
|
|
246
|
-
During a run,
|
|
248
|
+
During a run, a widget above the editor shows the workflow's progress bar, finished/total agents, elapsed time and usage; phases in chronological order, with finished phases collapsed to one line and the active phase listing its running, failed and done agents; the declared phases not reached yet; the workflow's counters; and the inspector shortcut. The footer status line reads `◆ review · Find 6/10 · 12s`. Use `--inspect` if you want a larger live view while the workflow is active, then `/workflow:inspector` if you want to bring the last completed inspector back up afterward.
|
|
249
|
+
|
|
250
|
+
The inspector has Overview, Agents, Findings, and Logs sections, plus Result for a retained run opened from `/workflow:runs`. Switch sections with `tab`/`shift+tab`, `←`/`→`, or `1`–`5`; move with `↑`/`↓` or `j`/`k`, jump with `g`/`G`, expand an agent or finding with `enter`, and close with `q` or `esc`. Expanded agents show the full error, last tool, model, and token usage.
|
|
247
251
|
|
|
248
252
|
### Durable run records
|
|
249
253
|
|
|
@@ -257,7 +261,7 @@ Persistence is intentionally bounded and private by default. Raw workflow args,
|
|
|
257
261
|
|
|
258
262
|
The host-facing `workflow` tool accepts `background: true`. It returns as soon as the run ID and origin metadata are durably recorded, while the normal workflow engine continues in-process with the same concurrency, budget, worktree, progress, usage, and resume rules. Synchronous execution remains the default, and the `/workflow` slash command remains synchronous.
|
|
259
263
|
|
|
260
|
-
Background runs are detached from the initiating tool-call signal, so the host agent can finish that turn and continue the conversation. When the run completes or fails, the extension waits for the originating session to become idle and inserts one concise `workflow-result` message containing the run ID, terminal state, and summary. Delivery state is stored with the run record; on reload, the extension checks both that state and the session message history before retrying, which suppresses duplicates even if persistence failed immediately after message insertion.
|
|
264
|
+
Background runs are detached from the initiating tool-call signal, so the host agent can finish that turn and continue the conversation. While one runs, it shows a single line above the editor (`◆ background · code-review 56b57550 · Find 6/10 · 12s`) instead of the full live widget. When the run completes or fails, the extension waits for the originating session to become idle and inserts one concise `workflow-result` message containing the run ID, terminal state, and summary. Delivery state is stored with the run record; on reload, the extension checks both that state and the session message history before retrying, which suppresses duplicates even if persistence failed immediately after message insertion.
|
|
261
265
|
|
|
262
266
|
Provider usage-window continuation is a separate, explicit background option:
|
|
263
267
|
|
|
@@ -281,7 +285,7 @@ A graceful pi session shutdown aborts active background work and records it as `
|
|
|
281
285
|
|
|
282
286
|
### Recent runs and lifecycle actions
|
|
283
287
|
|
|
284
|
-
`/workflow:runs` opens
|
|
288
|
+
`/workflow:runs` opens a runs browser in the TUI: one aligned row per recent project run (state glyph and word, workflow, duration, age, cost when known, short run ID) above a details pane for the selected run with its wall-clock times, phases, agent and token counts, resume lineage, pause details, outcome, and why a relaunch is unavailable when it is. Keys act on the selected run: `enter` or `i` inspect, `r` resume, `s` stop (press twice), `R` restart; only the actions currently valid for that run are listed in the footer, and the others explain why they are unavailable. The browser refreshes while a run is active and reopens on the same run after an action. RPC sessions keep pi's native two-step selection (run, then action). The background activity line is present only while this session owns active background work.
|
|
285
289
|
|
|
286
290
|
The same operations are available without the selection UI:
|
|
287
291
|
|
|
@@ -293,9 +297,9 @@ The same operations are available without the selection UI:
|
|
|
293
297
|
/workflow:inspector <run-id>
|
|
294
298
|
```
|
|
295
299
|
|
|
296
|
-
Inspect is always safe. Stop is available for a background run active in the current session and for a retained paused run with a pending resume timer. Resume is limited to paused registered workflows whose source fingerprint is unchanged and whose invocation had no redacted arguments; it starts a new background run ID with `resumeFromRunId` journal replay. Restart is limited to completed, failed, or stopped registered workflows that had no arguments and also creates a new background run ID. Inline workflows and argument-bearing invocations are intentionally not relaunched because their executable input was not persisted. In `print` and `json` modes, list and inspect return formatted text without opening TUI components, while resume/restart report that background execution requires TUI or RPC mode.
|
|
300
|
+
Inspect is always safe. Stop is available for a background run active in the current session and for a retained paused run with a pending resume timer. Resume is limited to paused registered workflows whose source fingerprint is unchanged and whose invocation had no redacted arguments; it starts a new background run ID with `resumeFromRunId` journal replay. A paused run already resumed by a queued, running, paused, or completed run is listed as `resumed as <run-id>` and offers no second resume; once every resume of it has failed or been stopped, manual resume is offered again, while automatic provider-limit resume never fires twice for the same paused run. Restart is limited to completed, failed, or stopped registered workflows that had no arguments and also creates a new background run ID. Inline workflows and argument-bearing invocations are intentionally not relaunched because their executable input was not persisted. In `print` and `json` modes, list and inspect return formatted text without opening TUI components, while resume/restart report that background execution requires TUI or RPC mode.
|
|
297
301
|
|
|
298
|
-
Code-review findings are rendered as a formatted result message by default. pi no longer asks whether to open the findings viewer. Use `--result-viewer` or `--review-viewer` when you want to inspect findings interactively
|
|
302
|
+
Code-review findings are rendered as a formatted result message by default. pi no longer asks whether to open the findings viewer. Use `--result-viewer` or `--review-viewer` when you want to inspect findings interactively. The viewer lists findings most severe first with the selected finding's full detail beside the list (below it in narrow terminals); `space` or `enter` selects a finding, `a` toggles all, `f` generates patch previews and `c` posts PR comments for the selection, and `pgup`/`pgdn` scroll a long detail. The viewer is sized to its content and shows scroll hints only when something is clipped. `/workflow:results` or `ctrl+shift+r` reopens the most recent validated code-review report in the current pi session without rerunning the workflow; selections reset when it reopens.
|
|
299
303
|
|
|
300
304
|
The Fix action revalidates the exact reviewed PR/ref/index/working-tree snapshot, then runs each selected finding through its own worktree-isolated agent and returns the finding ID, validation summary, patch, and changed status. Failed attempts do not discard successful previews, no patch is applied to your active tree automatically, and a moved or unverifiable review target is rejected rather than patched against the wrong code. The original review and all Fix previews retained in that pi session share one output-token budget. Reopening the viewer does not reset it, finalized preview usage is always deducted, and only one preview can run at a time.
|
|
301
305
|
|
|
@@ -421,6 +425,11 @@ overrides its profile.
|
|
|
421
425
|
|
|
422
426
|
`tools` is a strict allowlist. If you set `tools: ["read", "bash"]`, extension tools such as `ast-grep`, `mgrep`, `fffind`, or `ffgrep` are hidden from that subagent. Add `toolHints: ["search"]` to dynamically expose installed grep/find/search-like tools while keeping the concrete base allowlist portable. Use `toolHints: ["external-search"]` for installed web search, browsing, and URL-extraction tools; `requireToolHints: true` fails before prompting unless each requested capability matched. The built-in advisory workflows use `tools: ["read", "bash", "grep", "find", "ls"]` plus `toolHints: ["search"]`.
|
|
423
427
|
|
|
428
|
+
Subagents are SDK sessions, so pi's built-in codemode and MCP extensions do not load in them. Two opt-ins cover that:
|
|
429
|
+
|
|
430
|
+
- **Codemode.** Add `"codemode"` to an agent's `tools` to let it batch or filter many tool calls in one script, for example `tools: ["read", "grep", "codemode"]`. Scripts can call only that agent's other allowed tools, and never `final_answer`. Classifier calls a script makes count toward the run's usage and budget.
|
|
431
|
+
- **Host MCP tools.** In runs started by the `workflow` tool, subagents reach the host's MCP tools over its existing connections and through its permission handlers. Name a tool in `tools` (for example `"mcp__linear__create_issue"`), or use `toolHints: ["external-search"]` to pick up MCP web research tools; servers that declare a tool not read-only or closed-world are excluded from that hint. Bridged tools act in the host session, so the local `search` hint never bridges them, and an isolated worktree agent that names a local MCP tool sees the main checkout through it, not its worktree. `/workflow` commands and background runs outlive the host tool call that makes this possible: an agent there that names an MCP tool fails before prompting rather than running without it.
|
|
432
|
+
|
|
424
433
|
Subagents receive no skills by default. Opt in per agent with `skills: ["skill-name"]`; if `tools` is also restricted, the engine automatically keeps `read` available so the subagent can load the selected `SKILL.md`. When `skills` is omitted, clear prompt text such as `/skill:name`, `include skill name`, or `use the name skill` is also treated as an opt-in. Pass `skills: []` to suppress that inference.
|
|
425
434
|
|
|
426
435
|
Set `model` only when a subagent should use a specific model. Bare ids keep the Anthropic shorthand; `provider/id` targets built-in, custom, or local providers. Explicit models override a requested profile; calls with neither inherit the host/session default. Malformed or unknown explicit refs fail fast.
|
|
@@ -459,18 +468,37 @@ export default async function run({ workflow }: WorkflowApi) {
|
|
|
459
468
|
|
|
460
469
|
Nesting is one level only: calling `workflow()` from inside a sub-workflow rejects. Resolution throws on an unknown name. Inside `parallel()` or `pipeline()`, recoverable branch errors become `null` results, so filter nulls before synthesis; a genuine run abort still rejects.
|
|
461
470
|
|
|
471
|
+
### Classify between stages
|
|
472
|
+
|
|
473
|
+
`classify(context, opts?)` answers typed `choice`, `score`, or `bool` questions about JSON `state` with one of pi's classifier models (for example TypeSafe Jev or Cloudflare Clef), using the host's credentials and no chat session. It suits cheap gates between stages, such as deduplicating findings or deciding which items need a follow-up agent.
|
|
474
|
+
|
|
475
|
+
```ts
|
|
476
|
+
const answers = await api.classify(
|
|
477
|
+
{
|
|
478
|
+
state: { finding },
|
|
479
|
+
questions: {
|
|
480
|
+
followUp: { type: "bool", instructions: "Does this finding need verification?", criteria: { true: "Plausible but unproven", false: "Clearly settled" } },
|
|
481
|
+
},
|
|
482
|
+
},
|
|
483
|
+
{ label: `triage:${finding.id}` },
|
|
484
|
+
);
|
|
485
|
+
if (answers.followUp?.type === "bool" && answers.followUp.probability > 0.5) { /* verify it */ }
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
Without `opts.model` ("provider/id"), the first classifier with working credentials is used. Calls share the run's concurrency cap, count toward usage and the budget, and are not journaled, so a resumed run classifies again. When no classifier is configured the call rejects with a recoverable error, so guard it or let `parallel()` turn it into `null`.
|
|
489
|
+
|
|
462
490
|
### Where workflows live
|
|
463
491
|
|
|
464
492
|
Guaranteed built-ins are statically registered:
|
|
465
493
|
|
|
466
494
|
1. Add `.pi/extensions/pi-workflow-engine/workflows/<name>.ts`.
|
|
467
495
|
2. Import it in `.pi/extensions/pi-workflow-engine/src/workflows.ts`.
|
|
468
|
-
3. Add
|
|
496
|
+
3. Add a `defineBuiltinWorkflow(mod, "<name>.ts")` entry to `BUILTIN_WORKFLOW_DEFINITIONS`.
|
|
469
497
|
|
|
470
498
|
Drop-in workflows are also discovered best-effort from:
|
|
471
499
|
|
|
472
|
-
-
|
|
473
|
-
-
|
|
500
|
+
- `~/.pi/agent/workflows/*.ts`: the user-level drop-in directory, which survives `pi update`.
|
|
501
|
+
- The extension's own `workflows/*.ts` directory: `.pi/extensions/pi-workflow-engine/workflows/` in a working copy or a project-vendored copy. Files added to an installed package are replaced by `pi update`.
|
|
474
502
|
|
|
475
503
|
Use `/workflow <name> --refresh` after adding a drop-in file.
|
|
476
504
|
|
|
@@ -517,7 +545,7 @@ Only tune these when a workflow is too slow, too expensive, or too noisy:
|
|
|
517
545
|
| `--parallel-limit=N` / `PI_WORKFLOW_PARALLEL_SUBMISSION_LIMIT=N` | Limit eager `parallel()` submission. |
|
|
518
546
|
| `--max-agents=N` / `PI_WORKFLOW_MAX_AGENTS=N` | Cap live model calls across the complete run, including sub-workflows. Default `64`; values are clamped to `1`–`10000`. Replay hits do not consume the cap. The `workflow` tool field is `maxAgents`. |
|
|
519
547
|
| `--agent-timeout-ms=N` / `PI_WORKFLOW_AGENT_TIMEOUT_MS=N` | Abort one live agent after this duration. Default `1800000` (30 minutes); values are clamped to `1000`–`86400000`. The session is aborted and its isolated worktree is cleaned up. The `workflow` tool field is `agentTimeoutMs`. |
|
|
520
|
-
| `--agent-retries=N` / `PI_WORKFLOW_AGENT_RETRIES=N` |
|
|
548
|
+
| `--agent-retries=N` / `PI_WORKFLOW_AGENT_RETRIES=N` | Restart the whole agent after a transient provider or transport failure that pi's in-session turn retry could not recover. Default `0`; values are clamped to `0`–`10`. Backoff starts at one second, doubles, and caps at 30 seconds. The `workflow` tool field is `agentRetries`. |
|
|
521
549
|
| `--budget=N` / `PI_WORKFLOW_BUDGET=N` | Set an output-token ceiling across recorded subagent attempts, including failed provider attempts. `agent()` throws `WorkflowBudgetExceededError` before starting another model request once the ceiling is reached; agents already running may overshoot because the engine does not reserve per-agent estimates. |
|
|
522
550
|
| `--perf` / `PI_WORKFLOW_PERF=1` | Include internal timing aggregates. Usage/cost totals are reported separately from perf. |
|
|
523
551
|
| `PI_WORKFLOW_LANE_ITEM_LIMIT=N` | Cap retained progress lane items. |
|
|
@@ -525,17 +553,29 @@ Only tune these when a workflow is too slow, too expensive, or too noisy:
|
|
|
525
553
|
These controls bound different dimensions: concurrency limits how many agents
|
|
526
554
|
are active together, `max-agents` limits how many live model calls the run may
|
|
527
555
|
start in total, `agent-timeout-ms` bounds one active call (including retry
|
|
528
|
-
backoff), and `budget` limits recorded output tokens. Every
|
|
556
|
+
backoff), and `budget` limits recorded output tokens. Every agent restart consumes
|
|
529
557
|
another live-agent admission and remains inside the original timeout, budget,
|
|
530
558
|
and abort scope. Usage from failed attempts is retained, so it can exhaust the
|
|
531
559
|
budget before the next retry begins. Host cancellation takes precedence over
|
|
532
560
|
limit and timeout failures.
|
|
533
561
|
|
|
534
|
-
|
|
535
|
-
|
|
562
|
+
Transient provider failures are retried in two layers. First, each subagent
|
|
563
|
+
inherits pi's session-level automatic retry from your pi `retry` settings
|
|
564
|
+
(enabled by default: 3 retries with 2s, 4s, 8s backoff). It retries the failed
|
|
565
|
+
turn in place, keeping the agent's earlier tool work; each attempt is logged in
|
|
566
|
+
the workflow progress log, and usage from failed attempts is still recorded.
|
|
567
|
+
Like the agent's other turns, these in-place retries are not budget-checked, and
|
|
568
|
+
a retryable rate-limit or usage-limit error is retried in-session before a
|
|
569
|
+
background run's usage-limit pause takes effect. Only when those retries are
|
|
570
|
+
exhausted does `--agent-retries` restart the agent from scratch. Invalid
|
|
536
571
|
models, schema-contract failures, exhausted budgets, agent limits, worktree
|
|
537
572
|
failures, timeouts, and host aborts are never provider-retried.
|
|
538
573
|
|
|
574
|
+
pi-workflow-engine 0.12.0 and 0.13.0 wrote `"retry": {"enabled": false}` into
|
|
575
|
+
`~/.pi/agent/settings.json` whenever a workflow ran, which disables automatic
|
|
576
|
+
retry for the host session and every subagent. Workflow runs log a warning while
|
|
577
|
+
that setting is in effect; remove it unless you disabled retry on purpose.
|
|
578
|
+
|
|
539
579
|
## Common fixes
|
|
540
580
|
|
|
541
581
|
- **Unknown workflow**: confirm the extension is loaded with `pi list`; use `--refresh` for new drop-ins.
|
|
@@ -561,6 +601,25 @@ fails, the result retains verified records and reports incomplete coverage.
|
|
|
561
601
|
Synthesis selects or merges IDs; the workflow reconstructs evidence-bearing
|
|
562
602
|
fields from those records.
|
|
563
603
|
|
|
604
|
+
### Duplicate candidates
|
|
605
|
+
|
|
606
|
+
Lenses often report the same defect in different words. When a TypeSafe Jev
|
|
607
|
+
classifier is reachable (TypeSafe directly, OpenRouter, Cloudflare Workers AI,
|
|
608
|
+
Vercel AI Gateway, or OpenCode Zen), the four advisory workflows ask it whether
|
|
609
|
+
each pair of candidates in the same file describes one defect. Before
|
|
610
|
+
verification, a candidate joins a group only when the classifier is at least 80%
|
|
611
|
+
sure it matches every member, so each defect gets one verifier. Merged
|
|
612
|
+
candidates keep all of their source IDs, locations, impacts, and evidence, and
|
|
613
|
+
the verifier sees the other wordings as "Also reported as" evidence. If the
|
|
614
|
+
first comparison fails (no Jev credentials, a bad key, a rate limit), the merge
|
|
615
|
+
is skipped.
|
|
616
|
+
|
|
617
|
+
Measured on GPT-6.1 Sol code reviews with planted bugs, the merge cut verifier
|
|
618
|
+
agents and cost by about 40% (e.g. 29 → 18 agents, $0.60 → $0.37 list price on
|
|
619
|
+
a small diff; 22 → 14 agents, $1.74 → $0.89 on a 160 KB diff). In every
|
|
620
|
+
instrumented run, each planted bug that a finder proposed reached the final
|
|
621
|
+
report, with or without merging.
|
|
622
|
+
|
|
564
623
|
### Selective adversarial challenges
|
|
565
624
|
|
|
566
625
|
Add `--challenge` to an advisory workflow to challenge up to three uncertain or
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-workflow-engine",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Zero-dependency Dynamax workflows for pi: live parallel subagents, typed handoffs, synthesized results.",
|
|
6
6
|
"keywords": [
|
|
@@ -22,7 +22,6 @@
|
|
|
22
22
|
},
|
|
23
23
|
"files": [
|
|
24
24
|
".pi/extensions/pi-workflow-engine",
|
|
25
|
-
".pi/settings.json",
|
|
26
25
|
"assets/preview.png",
|
|
27
26
|
"skills",
|
|
28
27
|
"README.md",
|
|
@@ -1,38 +1,27 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: workflow-code-review-actions
|
|
3
|
-
description: "Act on selected code-review findings from pi-workflow-engine:
|
|
3
|
+
description: "Act on selected code-review findings from pi-workflow-engine: post GitHub PR inline comments using gh, GitHub MCP/tools, or project-specific tools."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
Use this skill when the parent agent receives selected code-review finding JSON from `pi-workflow-engine`.
|
|
6
|
+
Use this skill when the parent agent receives selected code-review finding JSON from `pi-workflow-engine`. The engine hands comments to the parent agent only when its own `gh` posting could not resolve the PR or failed for some findings.
|
|
7
|
+
|
|
8
|
+
Fixes are never handed off: the results viewer generates isolated, independently validated patch previews for selected findings. Do not edit files in response to a code-review handoff.
|
|
7
9
|
|
|
8
10
|
## Inputs
|
|
9
11
|
|
|
10
|
-
The prompt will include compact JSON with:
|
|
12
|
+
The prompt will include the verified reviewed PR head SHA, the reason the engine could not post the comments itself, and compact JSON with:
|
|
11
13
|
|
|
12
|
-
- `context`: workflow name, target,
|
|
14
|
+
- `context`: workflow name, target, `diffTarget` (with the PR `number`), display `diffCommand`, changed files, optional summary, and optional snapshot identity.
|
|
13
15
|
- `issues`: selected findings with `id`, `summary`, `category`, `severity`, `confidence`, `location`, `impact`, `evidence`, and `recommendation`.
|
|
14
16
|
|
|
15
|
-
##
|
|
16
|
-
|
|
17
|
-
When mode is `fix selected code-review findings`:
|
|
18
|
-
|
|
19
|
-
1. Inspect the selected issue JSON before editing.
|
|
20
|
-
2. Make minimal edits that address only the selected findings.
|
|
21
|
-
3. Preserve unrelated user changes and avoid broad refactors.
|
|
22
|
-
4. Run focused validation if available for the touched files or behavior.
|
|
23
|
-
5. Summarize changed files and validation results.
|
|
24
|
-
6. Do not post GitHub PR comments in fix mode.
|
|
25
|
-
|
|
26
|
-
## Comment mode
|
|
27
|
-
|
|
28
|
-
When mode is `post inline GitHub PR comments`:
|
|
17
|
+
## Posting comments
|
|
29
18
|
|
|
30
|
-
1.
|
|
31
|
-
2.
|
|
19
|
+
1. Prefer installed GitHub MCP/tools if visible in the active tool list.
|
|
20
|
+
2. Before posting, resolve the current PR head and require it to equal the verified reviewed head from the prompt; stop if it differs.
|
|
32
21
|
3. If no GitHub MCP/tools are available, use `gh`:
|
|
33
|
-
- Resolve the PR with `gh pr view --json
|
|
34
|
-
-
|
|
35
|
-
- Post each inline comment with `gh api repos/{owner}/{repo}/pulls/{number}/comments` and include `commit_id
|
|
22
|
+
- Resolve the PR with `gh pr view <context.diffTarget.number> --json headRefOid,url`.
|
|
23
|
+
- Take owner/repo from the PR `url`, which names the base repository, so fork PRs are commented upstream. Do not use `headRepositoryOwner`/`headRepository`; on a fork PR they name the fork. Fall back to `gh repo view --json nameWithOwner` only if the URL is missing.
|
|
24
|
+
- Post each inline comment with `gh api repos/{owner}/{repo}/pulls/{number}/comments` and include `commit_id` (the verified head), `path`, `line`, and `side=RIGHT`.
|
|
36
25
|
4. Keep each comment concise: summary, severity/confidence/category, impact, evidence, and recommendation.
|
|
37
26
|
5. Report posted, skipped, and failed counts.
|
|
38
27
|
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import type { PerfSink } from "./perf.ts";
|
|
2
|
-
import { runBoundedProcess, type BoundedProcessFailure } from "./process-runner.ts";
|
|
3
|
-
import { parseAllowedDiffCommand, reviewDiffCommand, type ReviewDiffTarget } from "./review-diff-target.ts";
|
|
4
|
-
|
|
5
|
-
export {
|
|
6
|
-
formatReviewDiffTarget,
|
|
7
|
-
GitReviewDiffTargetSchema,
|
|
8
|
-
isReviewDiffTarget,
|
|
9
|
-
parseAllowedDiffCommand,
|
|
10
|
-
PullRequestReviewDiffTargetSchema,
|
|
11
|
-
reviewDiffCommand,
|
|
12
|
-
ReviewDiffTargetSchema,
|
|
13
|
-
reviewGitDiffBaseline,
|
|
14
|
-
type GitDiffBaselineTarget,
|
|
15
|
-
type GitReviewDiffTarget,
|
|
16
|
-
type PullRequestReviewDiffTarget,
|
|
17
|
-
type ReviewDiffTarget,
|
|
18
|
-
} from "./review-diff-target.ts";
|
|
19
|
-
|
|
20
|
-
interface DiffCaptureResultBase {
|
|
21
|
-
readonly stdout: string;
|
|
22
|
-
readonly durationMs: number;
|
|
23
|
-
readonly bytes: number;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export type DiffCaptureResult =
|
|
27
|
-
| (DiffCaptureResultBase & { readonly ok: true; readonly error?: undefined; readonly failure?: undefined })
|
|
28
|
-
| (DiffCaptureResultBase & { readonly ok: false; readonly error: string; readonly failure: DiffCaptureFailure });
|
|
29
|
-
|
|
30
|
-
export type DiffCaptureFailure = BoundedProcessFailure | { readonly kind: "invalid-target"; readonly message: string };
|
|
31
|
-
|
|
32
|
-
export interface DiffCaptureOptions {
|
|
33
|
-
readonly cwd: string;
|
|
34
|
-
readonly signal?: AbortSignal;
|
|
35
|
-
readonly timeoutMs: number;
|
|
36
|
-
readonly maxBufferBytes: number;
|
|
37
|
-
readonly perf?: PerfSink;
|
|
38
|
-
readonly env?: NodeJS.ProcessEnv;
|
|
39
|
-
readonly killGraceMs?: number;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export async function captureDiff(command: string, options: DiffCaptureOptions): Promise<DiffCaptureResult> {
|
|
43
|
-
const parsed = parseAllowedDiffCommand(command);
|
|
44
|
-
if ("error" in parsed) {
|
|
45
|
-
return {
|
|
46
|
-
ok: false,
|
|
47
|
-
stdout: "",
|
|
48
|
-
durationMs: 0,
|
|
49
|
-
bytes: 0,
|
|
50
|
-
error: parsed.error,
|
|
51
|
-
failure: { kind: "invalid-target", message: parsed.error },
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return await captureDiffTarget(parsed, options);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export async function captureDiffTarget(target: ReviewDiffTarget, options: DiffCaptureOptions): Promise<DiffCaptureResult> {
|
|
59
|
-
const command = reviewDiffCommand(target);
|
|
60
|
-
const result = await runBoundedProcess({
|
|
61
|
-
file: command.file,
|
|
62
|
-
args: command.args,
|
|
63
|
-
cwd: options.cwd,
|
|
64
|
-
env: diffCaptureEnv(options.env),
|
|
65
|
-
signal: options.signal,
|
|
66
|
-
timeoutMs: options.timeoutMs,
|
|
67
|
-
maxBufferBytes: options.maxBufferBytes,
|
|
68
|
-
killGraceMs: options.killGraceMs,
|
|
69
|
-
abortError: "diff capture aborted",
|
|
70
|
-
timeoutError: `diff capture timed out after ${options.timeoutMs}ms`,
|
|
71
|
-
maxBufferError: `diff capture exceeded ${options.maxBufferBytes} bytes`,
|
|
72
|
-
exitError: (stderr, code, signal) => stderr.trim() || `diff command exited with code ${code ?? `signal ${signal ?? "unknown"}`}`,
|
|
73
|
-
});
|
|
74
|
-
options.perf?.observe("diff.capture_ms", result.durationMs);
|
|
75
|
-
options.perf?.observe("diff.bytes", result.bytes);
|
|
76
|
-
return result;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function diffCaptureEnv(env: NodeJS.ProcessEnv | undefined): NodeJS.ProcessEnv {
|
|
80
|
-
return { ...(env ?? process.env), GIT_EXTERNAL_DIFF: "", GIT_DIFF_OPTS: "" };
|
|
81
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
const DIFF_EMBED_CAP = 60_000;
|
|
2
|
-
|
|
3
|
-
export function buildCodeReviewScopeBlock(input: {
|
|
4
|
-
readonly diffCommand: string;
|
|
5
|
-
readonly files: readonly string[];
|
|
6
|
-
readonly summary: string;
|
|
7
|
-
readonly conventions?: string;
|
|
8
|
-
readonly diffText: string;
|
|
9
|
-
readonly target: string;
|
|
10
|
-
}): string {
|
|
11
|
-
const diffBlock = input.diffText
|
|
12
|
-
? `\n## Diff (review is bounded to these changed lines)\n\`\`\`diff\n${
|
|
13
|
-
input.diffText.length > DIFF_EMBED_CAP
|
|
14
|
-
? `${input.diffText.slice(0, DIFF_EMBED_CAP)}\n... (truncated — run \`${input.diffCommand}\` for the full diff)`
|
|
15
|
-
: input.diffText
|
|
16
|
-
}\n\`\`\`\n`
|
|
17
|
-
: "";
|
|
18
|
-
return (
|
|
19
|
-
`## Diff command\n${input.diffCommand}\n\n## Changed files\n${input.files.map((file) => `- ${file}`).join("\n")}\n\n` +
|
|
20
|
-
`## Summary\n${input.summary}\n\n## Conventions\n${input.conventions ?? "(none noted)"}\n` +
|
|
21
|
-
diffBlock +
|
|
22
|
-
(input.target ? `\n## User instructions (verbatim)\n${input.target}\n` : "")
|
|
23
|
-
);
|
|
24
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import type { WorkflowRunOptions } from "../types.ts";
|
|
3
|
-
import { toReviewIssues, type ReviewIssue, type ReviewIssueSelection } from "./review-issues.ts";
|
|
4
|
-
import { isReviewReport, type ReviewReport } from "./review-report.ts";
|
|
5
|
-
import { ReviewResultsViewer } from "./review-results-viewer.ts";
|
|
6
|
-
import { WORKFLOW_VIEWER_OVERLAY_OPTIONS } from "../ui/workflow-viewer-layout.ts";
|
|
7
|
-
|
|
8
|
-
export type ReviewResultsPresentationDecision =
|
|
9
|
-
| {
|
|
10
|
-
readonly kind: "send";
|
|
11
|
-
readonly reason: "not-code-review" | "not-advisory" | "no-findings" | "disabled" | "not-tui" | "not-requested";
|
|
12
|
-
}
|
|
13
|
-
| { readonly kind: "open"; readonly issues: readonly ReviewIssue[] };
|
|
14
|
-
|
|
15
|
-
export interface ReviewResultsDecisionInput {
|
|
16
|
-
readonly workflowName: string;
|
|
17
|
-
readonly result: unknown;
|
|
18
|
-
readonly mode?: string;
|
|
19
|
-
readonly hasUI: boolean;
|
|
20
|
-
readonly resultViewer?: WorkflowRunOptions["resultViewer"];
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function codeReviewReport(workflowName: string, result: unknown): ReviewReport | undefined {
|
|
24
|
-
return workflowName === "code-review" && isReviewReport(result) ? result : undefined;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface ReviewResultsViewerContext {
|
|
28
|
-
readonly ui: Pick<ExtensionContext["ui"], "custom">;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function decideReviewResultsPresentation(input: ReviewResultsDecisionInput): ReviewResultsPresentationDecision {
|
|
32
|
-
if (input.workflowName !== "code-review") return { kind: "send", reason: "not-code-review" };
|
|
33
|
-
const report = codeReviewReport(input.workflowName, input.result);
|
|
34
|
-
if (!report) return { kind: "send", reason: "not-advisory" };
|
|
35
|
-
if (report.findings.length === 0) return { kind: "send", reason: "no-findings" };
|
|
36
|
-
if (input.resultViewer === "skip") return { kind: "send", reason: "disabled" };
|
|
37
|
-
if (input.mode !== "tui" || !input.hasUI) return { kind: "send", reason: "not-tui" };
|
|
38
|
-
|
|
39
|
-
if (input.resultViewer !== "open") return { kind: "send", reason: "not-requested" };
|
|
40
|
-
|
|
41
|
-
return { kind: "open", issues: toReviewIssues(input.workflowName, report) };
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export async function showReviewResultsViewer(
|
|
45
|
-
ctx: ReviewResultsViewerContext,
|
|
46
|
-
issues: readonly ReviewIssue[],
|
|
47
|
-
): Promise<ReviewIssueSelection> {
|
|
48
|
-
return await ctx.ui.custom<ReviewIssueSelection>(
|
|
49
|
-
(tui, theme, _keybindings, done) => new ReviewResultsViewer(issues, "code-review", tui, theme, done),
|
|
50
|
-
WORKFLOW_VIEWER_OVERLAY_OPTIONS,
|
|
51
|
-
);
|
|
52
|
-
}
|
package/.pi/settings.json
DELETED