pi-workflow-engine 0.13.0 → 1.0.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.
Files changed (92) hide show
  1. package/.pi/extensions/pi-workflow-engine/index.ts +106 -391
  2. package/.pi/extensions/pi-workflow-engine/src/advisory-challenge.ts +1 -1
  3. package/.pi/extensions/pi-workflow-engine/src/advisory-evidence.ts +8 -8
  4. package/.pi/extensions/pi-workflow-engine/src/advisory-schema.ts +7 -1
  5. package/.pi/extensions/pi-workflow-engine/src/agent-attempt.ts +48 -62
  6. package/.pi/extensions/pi-workflow-engine/src/agent-replay.ts +46 -67
  7. package/.pi/extensions/pi-workflow-engine/src/agent-retry.ts +14 -37
  8. package/.pi/extensions/pi-workflow-engine/src/agent-runner-types.ts +5 -11
  9. package/.pi/extensions/pi-workflow-engine/src/agent-runner.ts +15 -21
  10. package/.pi/extensions/pi-workflow-engine/src/agent-session-identity.ts +13 -43
  11. package/.pi/extensions/pi-workflow-engine/src/agent-session-providers.ts +17 -5
  12. package/.pi/extensions/pi-workflow-engine/src/agent-session.ts +93 -100
  13. package/.pi/extensions/pi-workflow-engine/src/agent-skills.ts +11 -43
  14. package/.pi/extensions/pi-workflow-engine/src/agent-workspace.ts +4 -18
  15. package/.pi/extensions/pi-workflow-engine/src/background-workflows.ts +33 -86
  16. package/.pi/extensions/pi-workflow-engine/src/cancellation.ts +1 -5
  17. package/.pi/extensions/pi-workflow-engine/src/concurrency.ts +25 -80
  18. package/.pi/extensions/pi-workflow-engine/src/discovery.ts +16 -23
  19. package/.pi/extensions/pi-workflow-engine/src/dynamax-shortcuts.ts +1 -4
  20. package/.pi/extensions/pi-workflow-engine/src/dynamax.ts +39 -98
  21. package/.pi/extensions/pi-workflow-engine/src/engine.ts +37 -80
  22. package/.pi/extensions/pi-workflow-engine/src/finalizers.ts +2 -10
  23. package/.pi/extensions/pi-workflow-engine/src/git.ts +55 -0
  24. package/.pi/extensions/pi-workflow-engine/src/guards.ts +8 -0
  25. package/.pi/extensions/pi-workflow-engine/src/identity-canonicalization.ts +7 -19
  26. package/.pi/extensions/pi-workflow-engine/src/inline-workflow.ts +171 -106
  27. package/.pi/extensions/pi-workflow-engine/src/journal.ts +0 -12
  28. package/.pi/extensions/pi-workflow-engine/src/model-profile-command.ts +37 -8
  29. package/.pi/extensions/pi-workflow-engine/src/model-profiles.ts +15 -66
  30. package/.pi/extensions/pi-workflow-engine/src/options.ts +97 -16
  31. package/.pi/extensions/pi-workflow-engine/src/perf.ts +43 -72
  32. package/.pi/extensions/pi-workflow-engine/src/process-runner.ts +14 -4
  33. package/.pi/extensions/pi-workflow-engine/src/progress-types.ts +2 -0
  34. package/.pi/extensions/pi-workflow-engine/src/progress.ts +79 -80
  35. package/.pi/extensions/pi-workflow-engine/src/provider-usage-limit.ts +28 -20
  36. package/.pi/extensions/pi-workflow-engine/src/replay-path-identity.ts +2 -7
  37. package/.pi/extensions/pi-workflow-engine/src/research-contract.ts +0 -1
  38. package/.pi/extensions/pi-workflow-engine/src/research-evidence.ts +27 -31
  39. package/.pi/extensions/pi-workflow-engine/src/resume-context.ts +75 -139
  40. package/.pi/extensions/pi-workflow-engine/src/review/github-pr-comments.ts +14 -31
  41. package/.pi/extensions/pi-workflow-engine/src/review/patch-validation.ts +3 -4
  42. package/.pi/extensions/pi-workflow-engine/src/review/review-actions.ts +1 -1
  43. package/.pi/extensions/pi-workflow-engine/src/review/review-diff-lines.ts +54 -0
  44. package/.pi/extensions/pi-workflow-engine/src/review/review-fix-workflow.ts +7 -9
  45. package/.pi/extensions/pi-workflow-engine/src/review/review-format.ts +51 -117
  46. package/.pi/extensions/pi-workflow-engine/src/review/review-handoff.ts +1 -1
  47. package/.pi/extensions/pi-workflow-engine/src/review/review-issues.ts +8 -13
  48. package/.pi/extensions/pi-workflow-engine/src/review/review-report.ts +3 -7
  49. package/.pi/extensions/pi-workflow-engine/src/review/review-results-viewer.ts +158 -241
  50. package/.pi/extensions/pi-workflow-engine/src/review/review-session-coordinator.ts +28 -38
  51. package/.pi/extensions/pi-workflow-engine/src/review/review-snapshot.ts +35 -44
  52. package/.pi/extensions/pi-workflow-engine/src/review-diff-target.ts +13 -14
  53. package/.pi/extensions/pi-workflow-engine/src/text.ts +29 -0
  54. package/.pi/extensions/pi-workflow-engine/src/tool-capabilities.ts +2 -1
  55. package/.pi/extensions/pi-workflow-engine/src/tool-source-identity.ts +16 -28
  56. package/.pi/extensions/pi-workflow-engine/src/tree-fingerprint.ts +34 -14
  57. package/.pi/extensions/pi-workflow-engine/src/types.ts +6 -0
  58. package/.pi/extensions/pi-workflow-engine/src/ui/kit.ts +193 -0
  59. package/.pi/extensions/pi-workflow-engine/src/ui/research-result-renderer.ts +177 -0
  60. package/.pi/extensions/pi-workflow-engine/src/ui/result-layout.ts +209 -0
  61. package/.pi/extensions/pi-workflow-engine/src/ui/workflow-format.ts +17 -44
  62. package/.pi/extensions/pi-workflow-engine/src/ui/workflow-inspector.ts +703 -235
  63. package/.pi/extensions/pi-workflow-engine/src/ui/workflow-picker.ts +48 -0
  64. package/.pi/extensions/pi-workflow-engine/src/ui/workflow-result-renderer.ts +239 -129
  65. package/.pi/extensions/pi-workflow-engine/src/ui/workflow-runs-browser.ts +461 -0
  66. package/.pi/extensions/pi-workflow-engine/src/ui/workflow-tool-renderer.ts +91 -0
  67. package/.pi/extensions/pi-workflow-engine/src/ui/workflow-widget.ts +316 -98
  68. package/.pi/extensions/pi-workflow-engine/src/usage.ts +21 -32
  69. package/.pi/extensions/pi-workflow-engine/src/workflow-advisory-utils.ts +56 -19
  70. package/.pi/extensions/pi-workflow-engine/src/workflow-execution.ts +19 -24
  71. package/.pi/extensions/pi-workflow-engine/src/workflow-module.ts +17 -37
  72. package/.pi/extensions/pi-workflow-engine/src/workflow-result-context.ts +79 -0
  73. package/.pi/extensions/pi-workflow-engine/src/workflow-run-background.ts +4 -14
  74. package/.pi/extensions/pi-workflow-engine/src/workflow-run-controller.ts +77 -63
  75. package/.pi/extensions/pi-workflow-engine/src/workflow-run-history.ts +42 -29
  76. package/.pi/extensions/pi-workflow-engine/src/workflow-run-record.ts +15 -14
  77. package/.pi/extensions/pi-workflow-engine/src/workflow-run-store.ts +27 -31
  78. package/.pi/extensions/pi-workflow-engine/src/workflow-usage-limit-scheduler.ts +1 -5
  79. package/.pi/extensions/pi-workflow-engine/src/workflows.ts +3 -6
  80. package/.pi/extensions/pi-workflow-engine/src/worktree.ts +48 -110
  81. package/.pi/extensions/pi-workflow-engine/workflows/code-review.ts +64 -93
  82. package/.pi/extensions/pi-workflow-engine/workflows/diagnose.ts +25 -67
  83. package/.pi/extensions/pi-workflow-engine/workflows/perf-review.ts +19 -53
  84. package/.pi/extensions/pi-workflow-engine/workflows/refactor-scout.ts +21 -49
  85. package/.pi/extensions/pi-workflow-engine/workflows/research.ts +74 -66
  86. package/USAGE.md +31 -17
  87. package/package.json +1 -2
  88. package/skills/workflow-code-review-actions/SKILL.md +12 -23
  89. package/.pi/extensions/pi-workflow-engine/src/diff-capture.ts +0 -81
  90. package/.pi/extensions/pi-workflow-engine/src/review/code-review-orchestration.ts +0 -24
  91. package/.pi/extensions/pi-workflow-engine/src/review/review-results-flow.ts +0 -52
  92. package/.pi/settings.json +0 -3
@@ -1,7 +1,8 @@
1
1
  import type { Theme } from "@earendil-works/pi-coding-agent";
2
2
  import { truncateToWidth } from "@earendil-works/pi-tui";
3
- import type { AgentRowSnapshot, WorkflowLaneItemStatus, WorkflowProgressSnapshot } from "../progress-types.ts";
3
+ import type { AgentRowSnapshot, PhaseSnapshot, WorkflowLaneItemStatus, WorkflowProgressSnapshot } from "../progress-types.ts";
4
4
  import { formatWorkflowUsageLine } from "../usage.ts";
5
+ import { dot, GLYPH } from "./kit.ts";
5
6
 
6
7
  export type WorkflowDisplayStatus = WorkflowLaneItemStatus | "queued" | "done" | "failed";
7
8
  export type WorkflowThemeColor = Parameters<Theme["fg"]>[0];
@@ -22,13 +23,9 @@ export function formatDuration(ms: number): string {
22
23
  return remainingMinutes === 0 ? `${hours}h` : `${hours}h ${remainingMinutes}m`;
23
24
  }
24
25
 
25
- export function formatCount(n: number): string {
26
- if (!Number.isFinite(n)) return "0";
27
- const sign = n < 0 ? "-" : "";
28
- const value = Math.abs(n);
29
- if (value < 1_000) return `${Math.trunc(n)}`;
30
- if (value < 1_000_000) return `${sign}${formatCompact(value / 1_000)}k`;
31
- return `${sign}${formatCompact(value / 1_000_000)}m`;
26
+ /** Whole seconds, for clocks that tick once a second (`0s`, `12s`, `1m 4s`). */
27
+ export function formatElapsed(ms: number): string {
28
+ return formatDuration(Math.floor(Math.max(0, ms) / 1_000) * 1_000);
32
29
  }
33
30
 
34
31
  export function statusIcon(status: WorkflowDisplayStatus, theme: Theme): string {
@@ -59,10 +56,7 @@ export interface AgentDetailOptions {
59
56
  includeQueuedStatus?: boolean;
60
57
  }
61
58
 
62
- export function agentDetailParts(agent: AgentRowSnapshot, now?: number): string[];
63
- export function agentDetailParts(agent: AgentRowSnapshot, options?: AgentDetailOptions): string[];
64
- export function agentDetailParts(agent: AgentRowSnapshot, optionsOrNow: AgentDetailOptions | number = {}): string[] {
65
- const options = typeof optionsOrNow === "number" ? { now: optionsOrNow } : optionsOrNow;
59
+ export function agentDetailParts(agent: AgentRowSnapshot, options: AgentDetailOptions = {}): string[] {
66
60
  const now = options.now ?? Date.now();
67
61
  const includeQueuedStatus = options.includeQueuedStatus ?? true;
68
62
  const parts: string[] = [];
@@ -86,13 +80,6 @@ export interface WorkflowStatusCounts {
86
80
  readonly total: number;
87
81
  }
88
82
 
89
- export interface WorkflowStatusSource {
90
- readonly title: string;
91
- readonly doneAt?: number;
92
- readonly currentPhase: string;
93
- readonly counters: readonly { readonly key: string; readonly label: string; readonly value: number }[];
94
- }
95
-
96
83
  interface WorkflowInspectionSource {
97
84
  readonly name: string;
98
85
  readonly snapshot: WorkflowProgressSnapshot | (() => WorkflowProgressSnapshot);
@@ -104,7 +91,7 @@ export function workflowInspectionSnapshot(inspection: WorkflowInspectionSource)
104
91
 
105
92
  export function formatWorkflowInspection(inspection: WorkflowInspectionSource): string {
106
93
  const snapshot = workflowInspectionSnapshot(inspection);
107
- const counts = countSnapshotAgents(snapshot);
94
+ const counts = countAgents(snapshot.phases);
108
95
  const lines = [
109
96
  `Workflow inspector: ${inspection.name}`,
110
97
  `Run: ${snapshot.runId}`,
@@ -117,30 +104,22 @@ export function formatWorkflowInspection(inspection: WorkflowInspectionSource):
117
104
  return lines.join("\n");
118
105
  }
119
106
 
120
- export function statusText(snapshot: WorkflowProgressSnapshot, theme: Theme): string | undefined {
121
- const counts = countSnapshotAgents(snapshot);
122
- return statusTextFromCounts(snapshot, counts, theme);
123
- }
124
-
125
- export function statusTextFromCounts(snapshot: WorkflowStatusSource, counts: WorkflowStatusCounts, theme: Theme): string | undefined {
107
+ /** Footer status: `◆ review · Find 6/10 · 12s`. Usage and counters live in the widget, not here. */
108
+ export function statusTextFromCounts(snapshot: WorkflowProgressSnapshot, counts: WorkflowStatusCounts, theme: Theme): string | undefined {
126
109
  if (snapshot.doneAt !== undefined) return undefined;
127
110
 
128
- const complete = counts.done + counts.failed;
129
- const active = counts.running + counts.queued;
130
- const kept = snapshot.counters.find((counter) => counter.key === "kept" || counter.label.toLowerCase() === "kept");
131
111
  const displayName = snapshot.title === "code-review" ? "review" : snapshot.title;
132
-
133
- const parts = [theme.fg("accent", displayName), theme.fg("muted", snapshot.currentPhase)];
134
- if (counts.total > 0) parts.push(theme.fg("muted", `${complete}/${counts.total}`));
135
- if (kept) parts.push(theme.fg("success", `${formatCount(kept.value)} kept`));
136
- else if (active > 0) parts.push(theme.fg("muted", `${active} active`));
137
-
138
- return parts.join(theme.fg("dim", " · "));
112
+ const progress = counts.total > 0 ? ` ${counts.done + counts.failed}/${counts.total}` : "";
113
+ return [
114
+ `${theme.fg("accent", GLYPH.workflow)} ${theme.fg("accent", displayName)}`,
115
+ theme.fg("muted", `${snapshot.currentPhase}${progress}`),
116
+ theme.fg("dim", formatElapsed(Date.now() - snapshot.startedAt)),
117
+ ].join(dot(theme));
139
118
  }
140
119
 
141
- function countSnapshotAgents(snapshot: WorkflowProgressSnapshot): WorkflowStatusCounts {
120
+ export function countAgents(phases: readonly PhaseSnapshot[]): WorkflowStatusCounts {
142
121
  const counts = { queued: 0, running: 0, done: 0, failed: 0, total: 0 };
143
- for (const phase of snapshot.phases) {
122
+ for (const phase of phases) {
144
123
  for (const agent of phase.agents) {
145
124
  counts[agent.status]++;
146
125
  counts.total++;
@@ -148,9 +127,3 @@ function countSnapshotAgents(snapshot: WorkflowProgressSnapshot): WorkflowStatus
148
127
  }
149
128
  return counts;
150
129
  }
151
-
152
- function formatCompact(value: number): string {
153
- if (value >= 100) return `${Math.round(value)}`;
154
- const rounded = Math.round(value * 10) / 10;
155
- return Number.isInteger(rounded) ? `${rounded}` : rounded.toFixed(1);
156
- }