pi-crew 0.9.68 → 0.10.2

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 (253) hide show
  1. package/CHANGELOG.md +222 -0
  2. package/NOTICE.md +21 -0
  3. package/README.md +44 -2
  4. package/agents/analyst.md +1 -1
  5. package/agents/cold-verifier.md +3 -1
  6. package/agents/critic.md +1 -1
  7. package/agents/executor.md +1 -1
  8. package/agents/explorer.md +1 -1
  9. package/agents/planner.md +1 -1
  10. package/agents/reviewer.md +1 -1
  11. package/agents/security-reviewer.md +1 -1
  12. package/agents/test-engineer.md +1 -1
  13. package/agents/verifier.md +1 -1
  14. package/agents/writer.md +1 -1
  15. package/dist/index.mjs +68113 -60774
  16. package/docs/README.md +2 -0
  17. package/docs/actions-reference.md +31 -0
  18. package/docs/commands-reference.md +17 -6
  19. package/docs/resource-formats.md +13 -0
  20. package/package.json +4 -2
  21. package/schema.json +503 -91
  22. package/scripts/resource-sampler.mjs +36 -2
  23. package/skills/requirements-to-task-packet/SKILL.md +26 -0
  24. package/skills/widget-rendering/SKILL.md +7 -7
  25. package/src/agents/agent-config.ts +2 -1
  26. package/src/agents/discover-agents.ts +23 -14
  27. package/src/config/config-merge.ts +183 -0
  28. package/src/config/config-validation.ts +687 -0
  29. package/src/config/config.ts +22 -864
  30. package/src/config/defaults.ts +43 -2
  31. package/src/config/drift-detector.ts +1 -1
  32. package/src/config/env-vars.ts +691 -0
  33. package/src/config/role-tools.ts +11 -9
  34. package/src/config/sanitize-project-config.ts +172 -0
  35. package/src/config/types.ts +49 -1
  36. package/src/extension/async-notifier.ts +25 -2
  37. package/src/extension/crew-cleanup.ts +13 -0
  38. package/src/extension/crew-vibes/config.ts +2 -1
  39. package/src/extension/crew-vibes/footer.ts +19 -0
  40. package/src/extension/crew-vibes/index.ts +11 -1
  41. package/src/extension/plan-orchestrate.ts +132 -0
  42. package/src/extension/register.ts +8 -0
  43. package/src/extension/registration/command-registration.ts +1 -0
  44. package/src/extension/registration/commands/dashboard.ts +158 -0
  45. package/src/extension/registration/commands/index.ts +35 -0
  46. package/src/extension/registration/commands/manage.ts +303 -0
  47. package/src/extension/registration/commands/run.ts +228 -0
  48. package/src/extension/registration/commands/shared.ts +639 -0
  49. package/src/extension/registration/commands/status.ts +60 -0
  50. package/src/extension/registration/commands.ts +13 -1224
  51. package/src/extension/registration/foreground-run-controller.ts +10 -2
  52. package/src/extension/registration/lifecycle-handlers.ts +178 -17
  53. package/src/extension/registration/runtime-cleanup.ts +23 -5
  54. package/src/extension/registration/subagent-tools.ts +218 -9
  55. package/src/extension/registration/team-tool.ts +5 -1
  56. package/src/extension/registration/ui.ts +5 -4
  57. package/src/extension/rpc-hmac.ts +5 -3
  58. package/src/extension/team-tool/api/heartbeat.ts +47 -10
  59. package/src/extension/team-tool/api/plan-approval.ts +9 -0
  60. package/src/extension/team-tool/api/task-claims.ts +109 -40
  61. package/src/extension/team-tool/cancel.ts +84 -50
  62. package/src/extension/team-tool/dispatch/index.ts +1 -0
  63. package/src/extension/team-tool/dispatch/run.ts +4 -1
  64. package/src/extension/team-tool/doctor.ts +103 -1
  65. package/src/extension/team-tool/orchestrate.ts +66 -1
  66. package/src/extension/team-tool/plans.ts +192 -0
  67. package/src/extension/team-tool/respond.ts +197 -65
  68. package/src/extension/team-tool/run-deadline.ts +35 -3
  69. package/src/extension/team-tool/run-intent.ts +63 -0
  70. package/src/extension/team-tool/run.ts +74 -20
  71. package/src/extension/team-tool/status.ts +84 -26
  72. package/src/extension/team-tool.ts +11 -2
  73. package/src/hooks/registry.ts +1 -6
  74. package/src/i18n.ts +9 -0
  75. package/src/prompt/prompt-runtime.ts +521 -2
  76. package/src/prompt/worker-events-channel.ts +173 -0
  77. package/src/runtime/README.md +8 -8
  78. package/src/runtime/async-runner.ts +7 -3
  79. package/src/runtime/background-runner.ts +42 -14
  80. package/src/runtime/broker/broker-issuer.ts +9 -2
  81. package/src/runtime/broker/crew-broker-tokens.ts +43 -6
  82. package/src/runtime/broker/crew-broker.ts +838 -10
  83. package/src/runtime/broker/wait-status-cache.ts +157 -0
  84. package/src/runtime/budget-enforcement.ts +281 -0
  85. package/src/runtime/child-pi/child-pi-constants.ts +8 -0
  86. package/src/runtime/child-pi/child-pi-spawn.ts +60 -14
  87. package/src/runtime/child-pi/child-pi-streams.ts +21 -1
  88. package/src/runtime/child-pi/child-pi-timers.ts +324 -0
  89. package/src/runtime/child-pi/child-pi.ts +97 -201
  90. package/src/runtime/child-pi/mock-fixtures.ts +16 -2
  91. package/src/runtime/crew-agent-records.ts +259 -14
  92. package/src/runtime/delegate-spawn.ts +148 -0
  93. package/src/runtime/detached-run-results.ts +90 -0
  94. package/src/runtime/deterministic-ast.ts +2 -1
  95. package/src/runtime/dispatch-batch.ts +945 -0
  96. package/src/runtime/finalize-run.ts +557 -0
  97. package/src/runtime/goal-workflow/adaptive-plan.ts +116 -15
  98. package/src/runtime/goal-workflow/dynamic-workflow-runner.ts +8 -3
  99. package/src/runtime/goal-workflow/goal-state-store.ts +1 -1
  100. package/src/runtime/group-join.ts +11 -125
  101. package/src/runtime/live-session/live-session-runtime.ts +26 -1
  102. package/src/runtime/merge-gate.ts +32 -10
  103. package/src/runtime/merge-loop.ts +130 -0
  104. package/src/runtime/model/model-budget-summary.ts +53 -0
  105. package/src/runtime/model/model-fallback.ts +36 -2
  106. package/src/runtime/model/pi-args.ts +10 -0
  107. package/src/runtime/model/provider-extensions.ts +10 -0
  108. package/src/runtime/orphan-worker-registry.ts +1 -1
  109. package/src/runtime/output/output-validator.ts +45 -0
  110. package/src/runtime/parent-guard.ts +3 -1
  111. package/src/runtime/peer-dep.ts +2 -1
  112. package/src/runtime/per-write-validator.ts +0 -5
  113. package/src/runtime/pi-spawn.ts +61 -15
  114. package/src/runtime/plan-approval.ts +125 -0
  115. package/src/runtime/plan-replan.ts +151 -0
  116. package/src/runtime/process-status.ts +16 -1
  117. package/src/runtime/recovery/checkpoint.ts +0 -18
  118. package/src/runtime/recovery/crash-recovery.ts +111 -46
  119. package/src/runtime/run-tracker.ts +77 -10
  120. package/src/runtime/scheduler-context.ts +98 -0
  121. package/src/runtime/scheduling/coalesce-tasks.ts +5 -0
  122. package/src/runtime/scheduling/global-worker-cap.ts +2 -1
  123. package/src/runtime/scheduling/nested-slots.ts +70 -0
  124. package/src/runtime/scheduling/run-coalesced-task-group.ts +64 -13
  125. package/src/runtime/scheduling/task-graph-scheduler.ts +0 -10
  126. package/src/runtime/settings-store.ts +219 -0
  127. package/src/runtime/spawn-policy.ts +217 -0
  128. package/src/runtime/stale-reconciler.ts +87 -6
  129. package/src/runtime/subagent-manager.ts +25 -1
  130. package/src/runtime/task-output-context.ts +230 -9
  131. package/src/runtime/task-packet.ts +23 -1
  132. package/src/runtime/task-runner/child-executor.ts +106 -7
  133. package/src/runtime/task-runner/post-execution.ts +125 -1
  134. package/src/runtime/task-runner/pre-execution.ts +39 -1
  135. package/src/runtime/task-runner/prompt-builder.ts +51 -1
  136. package/src/runtime/task-runner/retrieval-orchestrator.ts +72 -18
  137. package/src/runtime/task-runner/spec-evidence.ts +403 -0
  138. package/src/runtime/task-runner/state-helpers.ts +26 -24
  139. package/src/runtime/task-runner.ts +11 -0
  140. package/src/runtime/team-runner.ts +132 -1673
  141. package/src/runtime/verification/spec-sandbox.ts +255 -0
  142. package/src/runtime/verification/verification-gates.ts +3 -2
  143. package/src/runtime/verification/verification-worktree.ts +2 -1
  144. package/src/runtime/workflow-phase-advance.ts +100 -0
  145. package/src/runtime/workspace-tree.ts +9 -0
  146. package/src/schema/config-schema.ts +66 -26
  147. package/src/schema/sensitive-config-paths.ts +64 -0
  148. package/src/schema/team-tool-schema.ts +13 -3
  149. package/src/state/README.md +4 -10
  150. package/src/state/atomic-write.ts +20 -3
  151. package/src/state/contracts.ts +38 -0
  152. package/src/state/coordination/mailbox.ts +12 -2
  153. package/src/state/event-log/cursor.ts +223 -0
  154. package/src/state/event-log/event-log-rotation.ts +12 -4
  155. package/src/state/event-log/event-log.ts +152 -369
  156. package/src/state/event-log/sequence-cache.ts +373 -0
  157. package/src/state/event-log/worker-atomic-writer.ts +2 -1
  158. package/src/state/stores/active-run-registry.ts +3 -2
  159. package/src/state/stores/manifest-io.ts +237 -0
  160. package/src/state/stores/ownership-map.ts +162 -0
  161. package/src/state/stores/plan-store.ts +241 -0
  162. package/src/state/stores/run-cache.ts +0 -90
  163. package/src/state/stores/spec-store.ts +189 -0
  164. package/src/state/stores/state-store.ts +139 -232
  165. package/src/state/types.ts +199 -0
  166. package/src/ui/dashboard-panes/plan-pane.ts +136 -0
  167. package/src/ui/dashboard-panes/progress-pane.ts +6 -0
  168. package/src/ui/dashboard-panes/transcript-pane.ts +31 -0
  169. package/src/ui/dock-footer.ts +49 -0
  170. package/src/ui/heartbeat-aggregator.ts +9 -1
  171. package/src/ui/inline-panel/agent-pane.ts +375 -0
  172. package/src/ui/inline-panel/agent-transcript.ts +338 -0
  173. package/src/ui/inline-panel/agent-view-overlay.ts +225 -0
  174. package/src/ui/inline-panel/crew-editor.ts +192 -0
  175. package/src/ui/inline-panel/index.ts +290 -0
  176. package/src/ui/inline-panel/panel-rows.ts +37 -0
  177. package/src/ui/inline-panel/panel-selection.ts +157 -0
  178. package/src/ui/inline-panel/panel-store.ts +111 -0
  179. package/src/ui/inline-panel/view-session-store.ts +36 -0
  180. package/src/ui/keybinding-map.ts +54 -13
  181. package/src/ui/pi-ui-compat.ts +9 -0
  182. package/src/ui/powerbar-publisher.ts +52 -1
  183. package/src/ui/run-dashboard.ts +31 -5
  184. package/src/ui/run-snapshot-cache.ts +57 -30
  185. package/src/ui/snapshot-types.ts +6 -1
  186. package/src/ui/widget/index.ts +176 -22
  187. package/src/ui/widget/task-list.ts +198 -0
  188. package/src/ui/widget/widget-formatters.ts +240 -4
  189. package/src/ui/widget/widget-renderer.ts +243 -38
  190. package/src/ui/widget/widget-types.ts +11 -0
  191. package/src/utils/child-process-shield.ts +106 -0
  192. package/src/utils/file-coalescer.ts +0 -4
  193. package/src/utils/fs-errno.ts +66 -0
  194. package/src/utils/fs-watch.ts +1 -1
  195. package/src/utils/internal-error.ts +3 -1
  196. package/src/utils/paths.ts +11 -3
  197. package/src/utils/redaction.ts +7 -0
  198. package/src/utils/safe-abort.ts +45 -0
  199. package/src/utils/task-name-generator.ts +1 -8
  200. package/src/workflows/discover-workflows.ts +20 -2
  201. package/src/workflows/validate-workflow.ts +7 -1
  202. package/src/workflows/workflow-config.ts +17 -0
  203. package/src/workflows/workflow-serializer.ts +3 -0
  204. package/src/worktree/worktree-manager.ts +22 -0
  205. package/workflows/default.workflow.md +36 -26
  206. package/workflows/strict-fast-fix.workflow.md +26 -0
  207. package/src/agents/agent-search.ts +0 -98
  208. package/src/benchmark/benchmark-runner.ts +0 -313
  209. package/src/benchmark/feedback-loop.ts +0 -73
  210. package/src/config/resilient-parser.ts +0 -117
  211. package/src/extension/crew-vibes/cat-frames.ts +0 -18
  212. package/src/extension/result-watcher.ts +0 -139
  213. package/src/observability/exporters/prometheus-exporter.ts +0 -54
  214. package/src/observability/metric-retention.ts +0 -64
  215. package/src/runtime/compaction/compaction-summary.ts +0 -278
  216. package/src/runtime/errors/crew-errors.ts +0 -162
  217. package/src/runtime/live-session/intercom-bridge.ts +0 -187
  218. package/src/runtime/loop-gates.ts +0 -128
  219. package/src/runtime/metric-parser.ts +0 -36
  220. package/src/runtime/output/stream-preview.ts +0 -184
  221. package/src/runtime/output/tool-progress.ts +0 -278
  222. package/src/runtime/phase-tracker.ts +0 -385
  223. package/src/runtime/pipeline-runner.ts +0 -523
  224. package/src/runtime/process/process-lifecycle.ts +0 -491
  225. package/src/runtime/recovery/retry-runner.ts +0 -330
  226. package/src/runtime/run-drift.ts +0 -219
  227. package/src/runtime/task-quality.ts +0 -199
  228. package/src/runtime/task-runner/run-projection.ts +0 -128
  229. package/src/runtime/verification/post-checks.ts +0 -142
  230. package/src/state/coordination/schedule.ts +0 -166
  231. package/src/state/event-log/jsonl-writer.ts +0 -115
  232. package/src/state/hook-instinct-bridge.ts +0 -94
  233. package/src/state/hook-integrations.ts +0 -51
  234. package/src/state/session-state-map.ts +0 -51
  235. package/src/state/stores/blob-store.ts +0 -308
  236. package/src/state/stores/instinct-store.ts +0 -275
  237. package/src/state/stores/observation-store.ts +0 -176
  238. package/src/state/tiered-eval.ts +0 -480
  239. package/src/state/types-eval.ts +0 -58
  240. package/src/tools/safe-bash-extension.ts +0 -54
  241. package/src/tools/safe-bash.ts +0 -505
  242. package/src/ui/agent-management-overlay.ts +0 -160
  243. package/src/ui/crew-footer.ts +0 -102
  244. package/src/ui/crew-select-list.ts +0 -114
  245. package/src/ui/dashboard-panes/capability-pane.ts +0 -77
  246. package/src/ui/transcript-entries.ts +0 -256
  247. package/src/utils/conflict-detect.ts +0 -721
  248. package/src/utils/fingerprint.ts +0 -180
  249. package/src/utils/gh-protocol.ts +0 -556
  250. package/src/utils/project-detector.ts +0 -160
  251. package/src/utils/sse-parser.ts +0 -131
  252. package/src/workflows/cost-estimator.ts +0 -34
  253. package/src/workflows/intermediate-store.ts +0 -166
@@ -1,480 +0,0 @@
1
- /**
2
- * Tiered Evaluation System
3
- *
4
- * Inspired by agent-eval's judge tiers, this module provides a hierarchical
5
- * evaluation system where checks are grouped by computational cost and reliability:
6
- *
7
- * - Tier 1 (deterministic): Fast checks (~1s timeout) - file exists, parse errors, etc.
8
- * - Tier 2 (pattern): Medium checks (~5s timeout) - grep, regex, structural checks
9
- * - Tier 3 (llm): Expensive checks (~60s timeout) - LLM-based evaluation
10
- */
11
-
12
- import type { EvalResult, EvalTier, TierConfig } from "./types-eval.ts";
13
-
14
- /**
15
- * Default tier configurations with increasing timeouts for more expensive evaluations.
16
- */
17
- export const TIER_CONFIGS: Record<EvalTier, TierConfig> = {
18
- 1: {
19
- tier: 1,
20
- name: "deterministic",
21
- description: "File exists, parse errors, fast checks",
22
- timeoutMs: 1000,
23
- },
24
- 2: {
25
- tier: 2,
26
- name: "pattern",
27
- description: "grep, regex, structural checks",
28
- timeoutMs: 5000,
29
- },
30
- 3: {
31
- tier: 3,
32
- name: "llm",
33
- description: "LLM-based evaluation",
34
- timeoutMs: 60000,
35
- },
36
- };
37
-
38
- /**
39
- * Default tier configurations (re-exported for convenience).
40
- */
41
- export const DEFAULT_TIER_CONFIGS = TIER_CONFIGS;
42
-
43
- export type { EvalResult, EvalTier, TierConfig };
44
-
45
- /**
46
- * Individual evaluation check with its assigned tier.
47
- */
48
- export interface EvalCheck<T = unknown> {
49
- /** The evaluation tier for this check */
50
- tier: EvalTier;
51
- /** The check function - returns true if passed */
52
- check: () => Promise<boolean> | boolean;
53
- /** Optional metadata about this check */
54
- metadata?: T;
55
- }
56
-
57
- /**
58
- * Configuration for the TieredEvalRunner.
59
- */
60
- export interface TieredEvalRunnerConfig {
61
- /** Override default tier configurations */
62
- tierConfigs?: Partial<Record<EvalTier, TierConfig>>;
63
- /** Default timeout multiplier for all tiers (default: 1.0) */
64
- timeoutMultiplier?: number;
65
- /** Whether to sort checks by tier before execution (default: true) */
66
- sortByTier?: boolean;
67
- /** Custom error message for timeouts */
68
- timeoutMessage?: string;
69
- }
70
-
71
- /**
72
- * Result of a single evaluation check.
73
- */
74
- export interface CheckResult extends EvalResult {
75
- /** The check function returned true */
76
- passed: boolean;
77
- /** Error message if check failed or timed out */
78
- error?: string;
79
- /** Check index in the original array */
80
- index: number;
81
- }
82
-
83
- /**
84
- * Extended result type for multi-check evaluations.
85
- */
86
- export interface TieredEvalResult {
87
- /** Overall success status - all checks passed */
88
- passed: boolean;
89
- /** Results for each individual check */
90
- results: CheckResult[];
91
- /** Total duration of all checks in milliseconds */
92
- totalDurationMs: number;
93
- /** Tier at which evaluation failed (if any) */
94
- failedAtTier?: EvalTier;
95
- /** Index of first failing check (if any) */
96
- failedAtIndex?: number;
97
- }
98
-
99
- /**
100
- * TieredEvalRunner executes evaluation checks in tiered order,
101
- * with appropriate timeouts for each tier level.
102
- *
103
- * Supports two execution modes:
104
- * - runTieredEval: Runs all checks regardless of failures
105
- * - runTieredEvalFailFast: Stops at first failure (like ECC promotion gates)
106
- *
107
- * @example
108
- * ```typescript
109
- * const runner = new TieredEvalRunner();
110
- *
111
- * // Run all checks
112
- * const allResults = await runner.runTieredEval('task-1', [
113
- * { tier: 1, check: () => fs.existsSync('output.json') },
114
- * { tier: 2, check: async () => (await run('grep', ['pattern', 'output.json'])).exitCode === 0 }
115
- * ]);
116
- *
117
- * // Fail-fast mode
118
- * const failFastResult = await runner.runTieredEvalFailFast('task-2', [
119
- * { tier: 1, check: () => fs.existsSync('output.json') },
120
- * { tier: 2, check: async () => (await run('grep', ['pattern', 'output.json'])).exitCode === 0 }
121
- * ]);
122
- * ```
123
- */
124
- export class TieredEvalRunner {
125
- private readonly tierConfigs: Record<EvalTier, TierConfig>;
126
- private readonly timeoutMultiplier: number;
127
- private readonly sortByTier: boolean;
128
- private readonly timeoutMessage: string;
129
-
130
- /**
131
- * Creates a new TieredEvalRunner instance.
132
- *
133
- * @param config - Optional configuration to override defaults
134
- */
135
- constructor(config?: TieredEvalRunnerConfig) {
136
- this.tierConfigs = { ...TIER_CONFIGS };
137
- this.timeoutMultiplier = config?.timeoutMultiplier ?? 1.0;
138
- this.sortByTier = config?.sortByTier ?? true;
139
- this.timeoutMessage = config?.timeoutMessage ?? "Evaluation timed out";
140
-
141
- // Apply tier config overrides
142
- if (config?.tierConfigs) {
143
- for (const [tierStr, tierConfig] of Object.entries(config.tierConfigs)) {
144
- const tier = Number(tierStr) as EvalTier;
145
- if (tierConfig && !Number.isNaN(tier)) {
146
- this.tierConfigs[tier] = {
147
- ...this.tierConfigs[tier],
148
- ...tierConfig,
149
- };
150
- }
151
- }
152
- }
153
- }
154
-
155
- /**
156
- * Gets the effective timeout for a given tier.
157
- *
158
- * @param tier - The evaluation tier
159
- * @returns The timeout in milliseconds (after multiplier is applied)
160
- */
161
- getTimeout(tier: EvalTier): number {
162
- return this.tierConfigs[tier].timeoutMs * this.timeoutMultiplier;
163
- }
164
-
165
- /**
166
- * Gets the configuration for a specific tier.
167
- *
168
- * @param tier - The evaluation tier
169
- * @returns The tier configuration
170
- */
171
- getTierConfig(tier: EvalTier): TierConfig {
172
- return this.tierConfigs[tier];
173
- }
174
-
175
- /**
176
- * Runs a check with the specified timeout.
177
- *
178
- * @param check - The check function to run
179
- * @param tier - The tier this check belongs to
180
- * @returns The result of the check
181
- */
182
- private async runCheckWithTimeout(check: () => Promise<boolean> | boolean, tier: EvalTier): Promise<CheckResult> {
183
- const timeout = this.getTimeout(tier);
184
- const startTime = Date.now();
185
-
186
- return new Promise<CheckResult>((resolve) => {
187
- const timeoutHandle = setTimeout(() => {
188
- resolve({
189
- tier,
190
- passed: false,
191
- durationMs: timeout,
192
- message: this.timeoutMessage,
193
- error: `Check timed out after ${timeout}ms`,
194
- index: -1,
195
- });
196
- }, timeout);
197
-
198
- // Execute the check
199
- Promise.resolve(check())
200
- .then((result) => {
201
- clearTimeout(timeoutHandle);
202
- const durationMs = Date.now() - startTime;
203
- resolve({
204
- tier,
205
- passed: result === true,
206
- durationMs,
207
- index: -1,
208
- error: result !== true ? "Check returned false" : undefined,
209
- });
210
- })
211
- .catch((error) => {
212
- clearTimeout(timeoutHandle);
213
- const durationMs = Date.now() - startTime;
214
- resolve({
215
- tier,
216
- passed: false,
217
- durationMs,
218
- message: error instanceof Error ? error.message : String(error),
219
- error: error instanceof Error ? error.message : String(error),
220
- index: -1,
221
- });
222
- });
223
- });
224
- }
225
-
226
- /**
227
- * Runs all evaluation checks and returns results for each.
228
- *
229
- * @param taskId - Identifier for the task being evaluated
230
- * @param checks - Array of checks to run, each with a tier assignment
231
- * @returns Array of evaluation results for each check
232
- *
233
- * @example
234
- * ```typescript
235
- * const results = await runner.runTieredEval('task-123', [
236
- * { tier: 1, check: () => fs.existsSync('output.json') },
237
- * { tier: 2, check: async () => (await grep('output.json', 'pattern')).found },
238
- * { tier: 3, check: async () => llmJudge.evaluate(output) }
239
- * ]);
240
- *
241
- * // Check if all passed
242
- * const allPassed = results.every(r => r.passed);
243
- * ```
244
- */
245
- async runTieredEval(
246
- taskId: string,
247
- checks: Array<{
248
- tier: EvalTier;
249
- check: () => Promise<boolean> | boolean;
250
- }>,
251
- ): Promise<EvalResult[]> {
252
- // Sort checks by tier if configured (lower tiers first)
253
- const sortedChecks = this.sortByTier ? [...checks].sort((a, b) => a.tier - b.tier) : checks;
254
-
255
- const results: EvalResult[] = [];
256
-
257
- for (let i = 0; i < sortedChecks.length; i++) {
258
- const { tier, check } = sortedChecks[i];
259
- const result = await this.runCheckWithTimeout(check, tier);
260
- results.push(result);
261
- }
262
-
263
- return results;
264
- }
265
-
266
- /**
267
- * Runs evaluation checks in fail-fast mode, stopping at the first failure.
268
- *
269
- * This is useful for promotion gates where cheaper checks should run first
270
- * and any failure should stop the evaluation immediately.
271
- *
272
- * @param taskId - Identifier for the task being evaluated
273
- * @param checks - Array of checks to run, each with a tier assignment
274
- * @returns Array of evaluation results (may be shorter than input if fail-fast triggered)
275
- *
276
- * @example
277
- * ```typescript
278
- * const results = await runner.runTieredEvalFailFast('task-123', [
279
- * { tier: 1, check: () => fs.existsSync('output.json') },
280
- * { tier: 2, check: async () => (await grep('output.json', 'pattern')).found },
281
- * { tier: 3, check: async () => llmJudge.evaluate(output) }
282
- * ]);
283
- *
284
- * if (results.length < checks.length) {
285
- * console.log(`Failed at tier ${results[results.length - 1].tier}`);
286
- * }
287
- * ```
288
- */
289
- async runTieredEvalFailFast(
290
- taskId: string,
291
- checks: Array<{
292
- tier: EvalTier;
293
- check: () => Promise<boolean> | boolean;
294
- }>,
295
- ): Promise<EvalResult[]> {
296
- // Sort checks by tier if configured (lower tiers first)
297
- const sortedChecks = this.sortByTier ? [...checks].sort((a, b) => a.tier - b.tier) : checks;
298
-
299
- const results: EvalResult[] = [];
300
-
301
- for (let i = 0; i < sortedChecks.length; i++) {
302
- const { tier, check } = sortedChecks[i];
303
- const result = await this.runCheckWithTimeout(check, tier);
304
- results.push(result);
305
-
306
- // Fail-fast: stop at first failure
307
- if (!result.passed) {
308
- break;
309
- }
310
- }
311
-
312
- return results;
313
- }
314
-
315
- /**
316
- * Runs evaluation checks and returns a structured result object.
317
- *
318
- * @param taskId - Identifier for the task being evaluated
319
- * @param checks - Array of checks to run, each with a tier assignment
320
- * @param failFast - Whether to stop at first failure (default: false)
321
- * @returns Structured evaluation result with metadata
322
- */
323
- async runEval(
324
- taskId: string,
325
- checks: Array<{
326
- tier: EvalTier;
327
- check: () => Promise<boolean> | boolean;
328
- }>,
329
- failFast = false,
330
- ): Promise<TieredEvalResult> {
331
- const sortedChecks = this.sortByTier ? [...checks].sort((a, b) => a.tier - b.tier) : checks;
332
-
333
- const results: CheckResult[] = [];
334
- let totalDurationMs = 0;
335
-
336
- for (let i = 0; i < sortedChecks.length; i++) {
337
- const { tier, check } = sortedChecks[i];
338
- const result = await this.runCheckWithTimeout(check, tier);
339
- result.index = i;
340
- results.push(result);
341
- totalDurationMs += result.durationMs;
342
-
343
- // Fail-fast: stop at first failure
344
- if (failFast && !result.passed) {
345
- return {
346
- passed: false,
347
- results,
348
- totalDurationMs,
349
- failedAtTier: tier,
350
- failedAtIndex: i,
351
- };
352
- }
353
- }
354
-
355
- return {
356
- passed: results.every((r) => r.passed),
357
- results,
358
- totalDurationMs,
359
- };
360
- }
361
-
362
- /**
363
- * Runs checks in parallel within each tier, but sequentially across tiers.
364
- *
365
- * This optimizes execution time when multiple checks exist at the same tier level.
366
- *
367
- * @param taskId - Identifier for the task being evaluated
368
- * @param checks - Array of checks to run
369
- * @param failFast - Whether to stop at first failure (default: false)
370
- * @returns Structured evaluation result
371
- */
372
- async runTieredEvalParallel(
373
- taskId: string,
374
- checks: Array<{
375
- tier: EvalTier;
376
- check: () => Promise<boolean> | boolean;
377
- }>,
378
- failFast = false,
379
- ): Promise<TieredEvalResult> {
380
- // Group checks by tier
381
- const checksByTier = new Map<
382
- EvalTier,
383
- Array<{
384
- check: () => Promise<boolean> | boolean;
385
- originalIndex: number;
386
- }>
387
- >();
388
-
389
- checks.forEach((c, originalIndex) => {
390
- const existing = checksByTier.get(c.tier) || [];
391
- existing.push({ check: c.check, originalIndex });
392
- checksByTier.set(c.tier, existing);
393
- });
394
-
395
- // Execute tiers in order
396
- const results: CheckResult[] = [];
397
- let totalDurationMs = 0;
398
-
399
- for (const tier of [1, 2, 3] as EvalTier[]) {
400
- const tierChecks = checksByTier.get(tier);
401
- if (!tierChecks || tierChecks.length === 0) continue;
402
-
403
- // Run all checks for this tier in parallel
404
- const tierResults = await Promise.all(
405
- tierChecks.map(async ({ check, originalIndex }) => {
406
- const result = await this.runCheckWithTimeout(check, tier);
407
- result.index = originalIndex;
408
- return result;
409
- }),
410
- );
411
-
412
- tierResults.forEach((result) => {
413
- results.push(result);
414
- totalDurationMs += result.durationMs;
415
- });
416
-
417
- // Check for any failures in this tier
418
- const tierFailed = tierResults.some((r) => !r.passed);
419
- if (failFast && tierFailed) {
420
- const failedIndex = tierResults.findIndex((r) => !r.passed);
421
- return {
422
- passed: false,
423
- results,
424
- totalDurationMs,
425
- failedAtTier: tier,
426
- failedAtIndex: tierResults[failedIndex].index,
427
- };
428
- }
429
- }
430
-
431
- // Sort results by original index
432
- results.sort((a, b) => a.index - b.index);
433
-
434
- return {
435
- passed: results.every((r) => r.passed),
436
- results,
437
- totalDurationMs,
438
- };
439
- }
440
-
441
- /**
442
- * Creates a new runner with overridden tier configurations.
443
- *
444
- * @param overrides - Tier configurations to override
445
- * @returns A new TieredEvalRunner instance
446
- */
447
- withConfig(overrides: Partial<Record<EvalTier, TierConfig>>): TieredEvalRunner {
448
- return new TieredEvalRunner({
449
- tierConfigs: overrides,
450
- timeoutMultiplier: this.timeoutMultiplier,
451
- sortByTier: this.sortByTier,
452
- timeoutMessage: this.timeoutMessage,
453
- });
454
- }
455
- }
456
-
457
- /**
458
- * Convenience function to create a TieredEvalRunner with default configuration.
459
- *
460
- * @param config - Optional configuration overrides
461
- * @returns A new TieredEvalRunner instance
462
- *
463
- * @example
464
- * ```typescript
465
- * const runner = createRunner({
466
- * timeoutMultiplier: 2.0, // Double all timeouts
467
- * tierConfigs: {
468
- * 3: { timeoutMs: 120000 } // 2 minutes for LLM tier
469
- * }
470
- * });
471
- * ```
472
- */
473
- export function createRunner(config?: TieredEvalRunnerConfig): TieredEvalRunner {
474
- return new TieredEvalRunner(config);
475
- }
476
-
477
- /**
478
- * Default runner instance with standard configuration.
479
- */
480
- export const defaultRunner = new TieredEvalRunner();
@@ -1,58 +0,0 @@
1
- /**
2
- * Types for the Tiered Evaluation System
3
- *
4
- * Inspired by agent-eval's judge tiers for hierarchical evaluation.
5
- */
6
-
7
- /**
8
- * Evaluation tiers with increasing computational cost.
9
- *
10
- * - Tier 1: Deterministic, fast checks (file existence, parse errors)
11
- * - Tier 2: Pattern matching, structural checks (grep, regex)
12
- * - Tier 3: LLM-based evaluation for natural language checks
13
- */
14
- export type EvalTier = 1 | 2 | 3;
15
-
16
- /**
17
- * Configuration for a specific evaluation tier.
18
- */
19
- export interface TierConfig {
20
- /** The tier level */
21
- tier: EvalTier;
22
- /** Human-readable name for the tier */
23
- name: string;
24
- /** Description of what this tier evaluates */
25
- description: string;
26
- /** Maximum time allowed for checks in this tier (milliseconds) */
27
- timeoutMs: number;
28
- }
29
-
30
- /**
31
- * Result of a single evaluation check.
32
- */
33
- export interface EvalResult {
34
- /** The tier this result came from */
35
- tier: EvalTier;
36
- /** Whether the check passed */
37
- passed: boolean;
38
- /** Optional message with additional context */
39
- message?: string;
40
- /** How long the check took in milliseconds */
41
- durationMs: number;
42
- }
43
-
44
- /**
45
- * Summary of a tiered evaluation run.
46
- */
47
- export interface TieredEvalSummary {
48
- /** Number of checks that passed */
49
- passed: number;
50
- /** Number of checks that failed */
51
- failed: number;
52
- /** Number of checks that timed out */
53
- timedOut: number;
54
- /** Total duration of all checks */
55
- totalDurationMs: number;
56
- /** Whether all checks passed */
57
- allPassed: boolean;
58
- }
@@ -1,54 +0,0 @@
1
- /**
2
- * Safe Bash Extension for pi-crew
3
- * Wraps the built-in bash tool with dangerous command blocking.
4
- *
5
- * Delegates pattern matching to the core `safe-bash.ts` module which uses
6
- * linear-time string scanning (no ReDoS-vulnerable regex).
7
- *
8
- * Usage:
9
- * 1. Enable in config: { "tools": { "bash": { "safeMode": true } } }
10
- * 2. Or use via agent config: { "extensions": ["path/to/safe-bash-extension.ts"] }
11
- * 3. Or set env var: PI_CREW_SAFE_BASH=true
12
- */
13
-
14
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
15
- import { createBashTool } from "@earendil-works/pi-coding-agent";
16
- import { Type } from "@sinclair/typebox";
17
- import { checkCommand } from "./safe-bash.ts";
18
-
19
- export default function safeBashExtension(pi: ExtensionAPI): void {
20
- const cwd = process.cwd();
21
- const bashTool = createBashTool(cwd);
22
-
23
- pi.registerTool({
24
- name: "safe_bash",
25
- label: "Safe Bash",
26
- description: "Execute a bash command safely. Blocks dangerous commands like `rm -rf /`, `sudo`, `curl | sh`, etc.",
27
- parameters: Type.Object({
28
- command: Type.String({ description: "Bash command to execute" }),
29
- /** Timeout in seconds (optional). Default: no timeout. If exceeded, the command is killed. */
30
- timeout: Type.Optional(Type.Number({ description: "Timeout in seconds (optional)" })),
31
- description: Type.Optional(
32
- Type.String({
33
- description: "Description of what this command does (optional)",
34
- }),
35
- ),
36
- }),
37
- async execute(toolCallId, params, signal, onUpdate, ctx) {
38
- const danger = checkCommand(params.command);
39
- if (danger) {
40
- return {
41
- details: {},
42
- content: [
43
- {
44
- type: "text" as const,
45
- text: `🚫 ${danger}\n\nCommand blocked by safety policy. If this is a false positive, ask the user for confirmation or use force: true with explicit user approval.`,
46
- },
47
- ],
48
- };
49
- }
50
- // Safe - delegate to real bash tool
51
- return bashTool.execute(toolCallId, params, signal, onUpdate);
52
- },
53
- });
54
- }