pi-harness-runtime 1.1.235 → 1.1.237

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 (116) hide show
  1. package/index.ts +80 -0
  2. package/package.json +1 -1
  3. package/packages/a2a-adapter/package.json +1 -1
  4. package/packages/agent-policy/package.json +1 -1
  5. package/packages/architecture-generator/package.json +1 -1
  6. package/packages/auth/package.json +1 -1
  7. package/packages/autonomous-refactor/package.json +1 -1
  8. package/packages/autonomous-runtime/package.json +1 -1
  9. package/packages/cache-strategy/package.json +1 -1
  10. package/packages/capability-registry/package.json +1 -1
  11. package/packages/checkpoint/package.json +1 -1
  12. package/packages/cli-plugin-sdk/package.json +1 -1
  13. package/packages/clipboard/package.json +1 -1
  14. package/packages/clipboard-plugin/package.json +1 -1
  15. package/packages/code-generation/package.json +1 -1
  16. package/packages/code-review/package.json +1 -1
  17. package/packages/codex-adapter/package.json +1 -1
  18. package/packages/codex-watcher/package.json +1 -1
  19. package/packages/config-capture/package.json +1 -1
  20. package/packages/context-compiler/package.json +1 -1
  21. package/packages/context-discovery/package.json +1 -1
  22. package/packages/context-manager/package.json +1 -1
  23. package/packages/cookie-sanitizer/package.json +1 -1
  24. package/packages/cost-optimizer/package.json +1 -1
  25. package/packages/dependency-analyzer/package.json +1 -1
  26. package/packages/django-plugin/package.json +1 -1
  27. package/packages/doc-generator/package.json +1 -1
  28. package/packages/e2e-tester/package.json +1 -1
  29. package/packages/evaluation-engine/package.json +1 -1
  30. package/packages/evaluation-runner/package.json +1 -1
  31. package/packages/event-bus/package.json +1 -1
  32. package/packages/event-store/package.json +1 -1
  33. package/packages/experience-replay/package.json +1 -1
  34. package/packages/feedback-collector/package.json +1 -1
  35. package/packages/file-copy-helper/package.json +1 -1
  36. package/packages/framework-detector/package.json +1 -1
  37. package/packages/framework-plugin-sdk/package.json +1 -1
  38. package/packages/frappe-plugin/package.json +1 -1
  39. package/packages/generic-web-plugin/package.json +1 -1
  40. package/packages/health-monitor/package.json +1 -1
  41. package/packages/intent-analyzer/package.json +1 -1
  42. package/packages/jev-judge/dist/continuation-controller.d.ts +4 -0
  43. package/packages/jev-judge/dist/continuation-controller.d.ts.map +1 -1
  44. package/packages/jev-judge/dist/continuation-controller.js +65 -19
  45. package/packages/jev-judge/dist/continuation-controller.js.map +1 -1
  46. package/packages/jev-judge/dist/index.d.ts +5 -3
  47. package/packages/jev-judge/dist/index.d.ts.map +1 -1
  48. package/packages/jev-judge/dist/index.js +3 -1
  49. package/packages/jev-judge/dist/index.js.map +1 -1
  50. package/packages/jev-judge/dist/task-intake.d.ts +71 -0
  51. package/packages/jev-judge/dist/task-intake.d.ts.map +1 -0
  52. package/packages/jev-judge/dist/task-intake.js +217 -0
  53. package/packages/jev-judge/dist/task-intake.js.map +1 -0
  54. package/packages/jev-judge/package.json +1 -1
  55. package/packages/jev-judge/src/continuation-controller.ts +73 -22
  56. package/packages/jev-judge/src/index.ts +7 -4
  57. package/packages/jev-judge/src/task-intake.ts +281 -0
  58. package/packages/knowledge-graph/package.json +1 -1
  59. package/packages/knowledge-retrieval/package.json +1 -1
  60. package/packages/laravel-plugin/package.json +1 -1
  61. package/packages/learning-engine/package.json +1 -1
  62. package/packages/mcp-adapter/package.json +1 -1
  63. package/packages/memory-engine/package.json +1 -1
  64. package/packages/milestone-manager/package.json +1 -1
  65. package/packages/model-registry/package.json +1 -1
  66. package/packages/nextjs-plugin/package.json +1 -1
  67. package/packages/notification/package.json +1 -1
  68. package/packages/observability/package.json +1 -1
  69. package/packages/okf-indexer/package.json +1 -1
  70. package/packages/paperclip-integration/package.json +1 -1
  71. package/packages/performance-optimizer/package.json +1 -1
  72. package/packages/privilege-broker/package.json +1 -1
  73. package/packages/project-analyzer/package.json +1 -1
  74. package/packages/project-bootstrap/package.json +1 -1
  75. package/packages/projection-engine/package.json +1 -1
  76. package/packages/prompt-compiler/package.json +1 -1
  77. package/packages/prompt-versioning/package.json +1 -1
  78. package/packages/provider-adapter-sdk/package.json +1 -1
  79. package/packages/provider-router/package.json +1 -1
  80. package/packages/provider-selector/package.json +1 -1
  81. package/packages/providers/package.json +1 -1
  82. package/packages/qdrant-skills/package.json +1 -1
  83. package/packages/quota-manager/package.json +1 -1
  84. package/packages/rate-limiter/package.json +1 -1
  85. package/packages/react-vite-plugin/package.json +1 -1
  86. package/packages/release-manager/package.json +1 -1
  87. package/packages/requirement-compiler/package.json +1 -1
  88. package/packages/runtime/package.json +1 -1
  89. package/packages/scheduler/package.json +1 -1
  90. package/packages/scheduler-adapter/package.json +1 -1
  91. package/packages/session/package.json +1 -1
  92. package/packages/session-api/package.json +1 -1
  93. package/packages/session-export/package.json +1 -1
  94. package/packages/shared-context/package.json +1 -1
  95. package/packages/skill-mcp-client/package.json +1 -1
  96. package/packages/skill-registry/package.json +1 -1
  97. package/packages/skills/package.json +1 -1
  98. package/packages/sprint-planner/package.json +1 -1
  99. package/packages/subscription-engine/package.json +1 -1
  100. package/packages/task-compiler/package.json +1 -1
  101. package/packages/telegram/package.json +1 -1
  102. package/packages/tencentdb-memory/package.json +1 -1
  103. package/packages/tencentdb-sync/package.json +1 -1
  104. package/packages/test-data-generator/package.json +1 -1
  105. package/packages/test-generator/package.json +1 -1
  106. package/packages/todo-bd-sync/package.json +1 -1
  107. package/packages/token-estimation/package.json +1 -1
  108. package/packages/token-optimizer/package.json +1 -1
  109. package/packages/trajectory/package.json +1 -1
  110. package/packages/tui/package.json +1 -1
  111. package/packages/types/package.json +1 -1
  112. package/packages/webmcp-tester/package.json +1 -1
  113. package/packages/workflow-events/package.json +1 -1
  114. package/packages/workspace-scanner/package.json +1 -1
  115. package/packages/worktree/package.json +1 -1
  116. package/packages/write-review/package.json +1 -1
package/index.ts CHANGED
@@ -282,6 +282,17 @@ async function initAutoContinue(pi: ExtensionAPI): Promise<void> {
282
282
  return null;
283
283
  }
284
284
 
285
+ // Detect routine continuation questions ("Should I continue?")
286
+ // These should NOT block immediate continuation - let Jev/todo controller decide
287
+ // Detect routine continuation questions ("Should I continue?")
288
+ // These should NOT block immediate continuation - let Jev/todo controller decide
289
+ function isRoutineContinuation(question: string): boolean {
290
+ const lower = question.toLowerCase();
291
+ // Match patterns like "should i continue?", "should we continue?", etc.
292
+ return (/\b(should i|should we|should the|can i continue|can we continue)\b/.test(lower)
293
+ && /\b(continue|proceed|with the next|to the next|move on)\b/.test(lower));
294
+ }
295
+
285
296
  // Detect when agent asks for continuation
286
297
  pi.on("message_end", async (event) => {
287
298
  const msg = event.message as { role?: string; content?: string | Array<{ type?: string; text?: string }> } | undefined;
@@ -291,7 +302,13 @@ async function initAutoContinue(pi: ExtensionAPI): Promise<void> {
291
302
  const detectedQuestion = detectConfirmationRequest(content);
292
303
 
293
304
  // Only trigger if: we found a question AND it's different from last notification
305
+ // Skip routine continuation questions - let Jev/todo controller decide
294
306
  if (detectedQuestion && detectedQuestion !== _lastNotifiedQuestion && !waitingForUserSince) {
307
+ // Skip routine continuation - don't block automatic continuation
308
+ if (isRoutineContinuation(detectedQuestion)) {
309
+ logToFile("[auto-continue]", "Routine continuation detected, not blocking");
310
+ return;
311
+ }
295
312
  _lastNotifiedQuestion = detectedQuestion;
296
313
  waitingForUserSince = new Date();
297
314
 
@@ -467,6 +484,69 @@ async function initAutoContinue(pi: ExtensionAPI): Promise<void> {
467
484
  todoContinuationController = null;
468
485
  });
469
486
 
487
+ // --- task-intake: Automatic todo capture from user requests -----------
488
+ let taskIntakeController: import("./packages/jev-judge/dist/task-intake.js").TaskIntakeController | null = null;
489
+
490
+ // Create task intake controller if Jev API key is available
491
+ if (resolvedApiKey) {
492
+ try {
493
+ const { TaskIntakeController } = await import("./packages/jev-judge/dist/task-intake.js");
494
+ taskIntakeController = new TaskIntakeController({
495
+ apiKey: resolvedApiKey,
496
+ dispatch: async (content: string) => {
497
+ await pi.sendUserMessage(content, { deliverAs: "steer" });
498
+ },
499
+ });
500
+ logToFile("[auto-continue]", "Task intake controller initialized");
501
+ } catch (err) {
502
+ logToFile("[auto-continue]", "Failed to create task intake controller:", String(err));
503
+ }
504
+ }
505
+
506
+ // Clean up task intake on session shutdown
507
+ pi.on("session_shutdown", () => {
508
+ taskIntakeController = null;
509
+ });
510
+
511
+ // Wire user messages to task intake
512
+ pi.on("message_start", (event) => {
513
+ const msg = (event as { message?: { role?: string; content?: string } }).message;
514
+ if (msg?.role === "user" && taskIntakeController) {
515
+ // Pause continuation when user sends message
516
+ if (todoContinuationController) {
517
+ todoContinuationController.pause();
518
+ logToFile("[auto-continue]", "User input received, pausing continuation");
519
+ }
520
+
521
+ // Extract user message content
522
+ const content = msg.content;
523
+ let userMessage = "";
524
+ if (typeof content === "string") {
525
+ userMessage = content;
526
+ } else if (Array.isArray(content)) {
527
+ const textBlocks = (content as Array<{ type?: string; text?: string }>)
528
+ .filter((c): c is { type: "text"; text: string } =>
529
+ c.type === "text" && typeof c.text === "string"
530
+ );
531
+ userMessage = textBlocks.map((c) => c.text).join("\n");
532
+ }
533
+
534
+ // Evaluate with task intake controller (non-blocking)
535
+ if (userMessage.trim().length > 10 && taskIntakeController) {
536
+ const intake = taskIntakeController;
537
+ intake.evaluate(userMessage).then(async (result) => {
538
+ if (result.actionable && result.action !== "skip") {
539
+ logToFile("[auto-continue]", "Task intake result:", JSON.stringify(result));
540
+ // Request capture if actionable
541
+ await intake.requestCapture(userMessage);
542
+ }
543
+ }).catch((err) => {
544
+ logToFile("[auto-continue]", "Task intake error:", String(err));
545
+ });
546
+ }
547
+ }
548
+ });
549
+
470
550
  // --- agent_settled: Check todos and continue work ---------------
471
551
  pi.on("agent_settled", async (_event, ctx) => {
472
552
  // Don't continue if user is waiting for response
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-harness-runtime",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "description": "[BETA] Codex-style /usage status + autonomous coding harness for pi. Not production ready — expect breaking changes.",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/a2a-adapter",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "type": "module",
5
5
  "description": "Google Agent-to-Agent (A2A) protocol adapter for pi-harness",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/agent-policy",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "description": "Agent policy runtime for pi-harness - enforces mandatory rule delivery and mutation gating",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/architecture-generator",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "description": "Generate ADR and Mermaid diagrams from project analysis",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/auth",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "description": "pi-harness-runtime — auth",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/autonomous-refactor",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "type": "module",
5
5
  "description": "Autonomous refactoring engine",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/autonomous-runtime",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "description": "Autonomous Operations Runtime — task inbox, lease management, and worker lifecycle (RFC-0101)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/cache-strategy",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "type": "module",
5
5
  "description": "Smart caching with TTL and invalidation strategies (RFC-0022)",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/capability-registry",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "description": "Capability Registry for pi-harness-runtime — tracks model capabilities and enables capability-based routing",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/checkpoint",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "description": "Enhanced checkpoint system with incremental snapshots, diff-based storage, and recovery strategies",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/cli-plugin-sdk",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "type": "module",
5
5
  "description": "CLI Plugin SDK for pi-harness — install, list, remove, update, invoke plugins",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/clipboard",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/clipboard-plugin",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/code-generation",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "description": "Code generation pipeline for pi-harness-runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/code-review",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "description": "Automated code review engine for pi-harness-runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/codex-adapter",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "type": "module",
5
5
  "description": "OpenAI Codex provider adapter for pi-harness",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/codex-watcher",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "description": "Watches Codex CLI sessions and emits visible messages for PING-PONG monitoring",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moocoding/config-capture",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "description": "Auto-capture API-fetched configuration values to AGENTS.md",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/context-compiler",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "description": "Bounded context selection engine for pi-harness-runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/context-discovery",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/context-manager",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "description": "Context Window Manager — prevents model context overflow via compaction and resume prompts (RFC-0010)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/cookie-sanitizer",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "description": "pi-harness-runtime — cookie sanitizer (provider-quota cookie file normaliser)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/cost-optimizer",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "description": "Cost Optimizer for pi-harness-runtime — budget tracking, forecasting, and model selection optimization",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/dependency-analyzer",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/django-plugin",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "description": "Django framework analysis — models, management commands, settings",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/doc-generator",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "description": "Auto-Doc Generator — generate documentation from source code (RFC-0014)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/e2e-tester",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "description": "WebMCP-powered E2E testing for pi-harness - natural language test scenarios",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/evaluation-engine",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "description": "Evaluation engine for pi-harness runtime (RFC-0057)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/evaluation-runner",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "type": "module",
5
5
  "description": "Framework-agnostic evaluation framework for AI outputs (RFC-0020)",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/event-bus",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/event-store",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/experience-replay",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "description": "Experience replay for debugging and reproducibility (RFC-0059)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/feedback-collector",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "type": "module",
5
5
  "description": "Collect and aggregate human/automated feedback (RFC-0021)",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moocoding/file-copy-helper",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "description": "Injects cp/sudo cp rule when user asks to mimic/copy files",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/framework-detector",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "description": "Framework detection system for pi-harness-runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/framework-plugin-sdk",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "description": "Framework plugin SDK for pi-harness-runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/frappe-plugin",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "description": "Frappe/ERPNext framework analysis — DocTypes, hooks, bench sites, site config",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/generic-web-plugin",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "description": "Generic web framework analysis — REST/GraphQL endpoints, OpenAPI, auth",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/health-monitor",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "type": "module",
5
5
  "description": "Health monitoring and auto-healing",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/intent-analyzer",
3
- "version": "1.1.235",
3
+ "version": "1.1.237",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -65,6 +65,10 @@ export declare class TodoContinuationController {
65
65
  * Continue a specific todo item
66
66
  */
67
67
  continueItem(item: TodoItem): Promise<void>;
68
+ /**
69
+ * Guarded dispatch - checks all conditions before sending
70
+ */
71
+ private guardedDispatch;
68
72
  /**
69
73
  * Steer to continue a todo item
70
74
  */
@@ -1 +1 @@
1
- {"version":3,"file":"continuation-controller.d.ts","sourceRoot":"","sources":["../src/continuation-controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAmBhE;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,iEAAiE;IACjE,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,4CAA4C;IAC5C,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,yCAAyC;IACzC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qCAAqC;IACrC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qCAAqC;IACrC,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,2BAA2B,EAAE,MAAM,CAAC;IACpC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,KAAK,CAAC;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,qBAAa,0BAA0B;IACtC,OAAO,CAAC,GAAG,CAAc;IACzB,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,YAAY,CAAwC;IAE5D,OAAO,CAAC,KAAK,CAaX;IAEF,YAAY,GAAG,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,kBAAkB,EAUxD;IAED;;OAEG;IACH,OAAO,CAAC,WAAW;IAgBnB;;;;OAIG;IACG,MAAM,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAuE1C;IAED;;OAEG;IACG,YAAY,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BhD;IAED;;OAEG;IACG,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiCnD;IAED;;OAEG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIjD;IAED;;OAEG;IACH,KAAK,IAAI,IAAI,CAIZ;IAED;;OAEG;IACH,MAAM,IAAI,IAAI,CAeb;IAED;;OAEG;IACH,QAAQ,IAAI,IAAI,CAIf;IAED;;OAEG;IACH,QAAQ,IAAI;QAAE,OAAO,EAAE,QAAQ,GAAG,IAAI,CAAC;QAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAM7E;CACD;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACrC,GAAG,EAAE,WAAW,EAChB,MAAM,CAAC,EAAE,kBAAkB,GACzB,0BAA0B,CAE5B"}
1
+ {"version":3,"file":"continuation-controller.d.ts","sourceRoot":"","sources":["../src/continuation-controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAmBhE;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,iEAAiE;IACjE,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,4CAA4C;IAC5C,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,yCAAyC;IACzC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qCAAqC;IACrC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qCAAqC;IACrC,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,2BAA2B,EAAE,MAAM,CAAC;IACpC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,KAAK,CAAC;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,qBAAa,0BAA0B;IACtC,OAAO,CAAC,GAAG,CAAc;IACzB,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,YAAY,CAAwC;IAE5D,OAAO,CAAC,KAAK,CAaX;IAEF,YAAY,GAAG,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,kBAAkB,EAUxD;IAED;;OAEG;IACH,OAAO,CAAC,WAAW;IAgBnB;;;;OAIG;IACG,MAAM,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAmF1C;IAED;;OAEG;IACG,YAAY,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BhD;IAED;;OAEG;YACW,eAAe;IA+C7B;;OAEG;IACG,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBnD;IAED;;OAEG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIjD;IAED;;OAEG;IACH,KAAK,IAAI,IAAI,CAIZ;IAED;;OAEG;IACH,MAAM,IAAI,IAAI,CAeb;IAED;;OAEG;IACH,QAAQ,IAAI,IAAI,CAIf;IAED;;OAEG;IACH,QAAQ,IAAI;QAAE,OAAO,EAAE,QAAQ,GAAG,IAAI,CAAC;QAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAM7E;CACD;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACrC,GAAG,EAAE,WAAW,EAChB,MAAM,CAAC,EAAE,kBAAkB,GACzB,0BAA0B,CAE5B"}
@@ -87,19 +87,29 @@ export class TodoContinuationController {
87
87
  let inProgress;
88
88
  let ready;
89
89
  let blocked;
90
+ let allItems;
90
91
  try {
91
92
  inProgress = await this.todoProvider.getInProgress();
92
93
  ready = await this.todoProvider.getReady();
93
94
  blocked = await this.todoProvider.getBlocked();
95
+ const snapshot = await this.todoProvider.getSnapshot();
96
+ allItems = snapshot.items;
94
97
  }
95
98
  catch (err) {
96
99
  const msg = err instanceof Error ? err.message : String(err);
97
100
  debugLog("TodoContinuation", "Failed to read todos:", msg);
98
101
  return { action: "stop", reason: `todo read failed: ${msg}` };
99
102
  }
100
- // 4. Continue in-progress work first
101
- if (inProgress.length > 0) {
102
- const item = inProgress[0];
103
+ // 4. Filter in-progress for items without unfinished blockers
104
+ const unblockedInProgress = inProgress.filter((item) => {
105
+ if (!item.blockedBy?.length)
106
+ return true;
107
+ const blockerIds = new Set(item.blockedBy);
108
+ return !allItems.some((i) => blockerIds.has(i.id) && i.status !== "completed" && i.id !== item.id);
109
+ });
110
+ // 5. Continue unblocked in-progress work first
111
+ if (unblockedInProgress.length > 0) {
112
+ const item = unblockedInProgress[0];
103
113
  // Reset counter if switching to a different task
104
114
  if (this.state.lastItemContinued !== item.id) {
105
115
  this.state.steerAttemptsForCurrentItem = 0;
@@ -163,6 +173,52 @@ export class TodoContinuationController {
163
173
  this.state.continuationQueued = false;
164
174
  }
165
175
  }
176
+ /**
177
+ * Guarded dispatch - checks all conditions before sending
178
+ */
179
+ async guardedDispatch(itemId, message) {
180
+ // 1. Check if paused by user
181
+ if (this.state.userPaused) {
182
+ debugLog("TodoContinuation", "Guarded dispatch: user paused, skipping");
183
+ return false;
184
+ }
185
+ // 2. Check if session is still idle
186
+ if (this.ctx.isIdle?.() === false) {
187
+ debugLog("TodoContinuation", "Guarded dispatch: session not idle, skipping");
188
+ return false;
189
+ }
190
+ // 3. Check if continuation already queued (prevent duplicates)
191
+ if (this.state.continuationQueued) {
192
+ debugLog("TodoContinuation", "Guarded dispatch: already queued, skipping");
193
+ return false;
194
+ }
195
+ // 4. Verify item still needs work (not completed)
196
+ try {
197
+ const snapshot = await this.todoProvider.getSnapshot();
198
+ const item = snapshot.items.find((i) => i.id === itemId);
199
+ if (item?.status === "completed") {
200
+ debugLog("TodoContinuation", "Guarded dispatch: item completed, skipping");
201
+ return false;
202
+ }
203
+ }
204
+ catch {
205
+ // If we can't read todos, skip dispatch
206
+ debugLog("TodoContinuation", "Guarded dispatch: failed to read todos, skipping");
207
+ return false;
208
+ }
209
+ // All checks passed - dispatch
210
+ this.state.continuationQueued = true;
211
+ this.state.lastSteerMessage = message;
212
+ try {
213
+ await this.config.dispatch(message);
214
+ return true;
215
+ }
216
+ catch (err) {
217
+ debugLog("TodoContinuation", "Guarded dispatch failed:", String(err));
218
+ this.state.continuationQueued = false;
219
+ return false;
220
+ }
221
+ }
166
222
  /**
167
223
  * Steer to continue a todo item
168
224
  */
@@ -177,22 +233,12 @@ export class TodoContinuationController {
177
233
  return;
178
234
  }
179
235
  this.state.steerAttemptsForCurrentItem++;
180
- this.state.continuationQueued = true;
181
- const snapshot = await this.todoProvider.getSnapshot();
182
- const item = snapshot.items.find((i) => i.id === itemId);
183
- const message = item
184
- ? `Continue todo item: "${item.subject}". ${item.description ?? ""}`
185
- : `Continue work on the next ready task.`;
186
- this.state.lastSteerMessage = message;
187
- this.state.todoRevision = snapshot.revision;
188
- debugLog("TodoContinuation", "Steering to continue item", itemId);
189
- // Send continuation message via dispatch callback
190
- try {
191
- await this.config.dispatch(message);
192
- }
193
- catch (err) {
194
- debugLog("TodoContinuation", "Failed to send steer:", String(err));
195
- this.state.continuationQueued = false;
236
+ const message = `Continue todo item ID ${itemId}.`;
237
+ debugLog("TodoContinuation", "Attempting steer to continue item", itemId);
238
+ // Use guarded dispatch to verify all conditions
239
+ const sent = await this.guardedDispatch(itemId, message);
240
+ if (!sent) {
241
+ debugLog("TodoContinuation", "Steer blocked by guard conditions");
196
242
  }
197
243
  }
198
244
  /**