pi-harness-runtime 1.1.350 → 1.1.352

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 (120) hide show
  1. package/README.md +3 -0
  2. package/index.ts +32 -23
  3. package/package.json +1 -1
  4. package/packages/a2a-adapter/package.json +1 -1
  5. package/packages/agent-policy/package.json +1 -1
  6. package/packages/architecture-generator/package.json +1 -1
  7. package/packages/auth/package.json +1 -1
  8. package/packages/autonomous-refactor/package.json +1 -1
  9. package/packages/autonomous-runtime/package.json +1 -1
  10. package/packages/cache-strategy/package.json +1 -1
  11. package/packages/capability-registry/package.json +1 -1
  12. package/packages/checkpoint/package.json +1 -1
  13. package/packages/cli-plugin-sdk/package.json +1 -1
  14. package/packages/clipboard/package.json +1 -1
  15. package/packages/clipboard-plugin/package.json +1 -1
  16. package/packages/code-generation/package.json +1 -1
  17. package/packages/code-review/package.json +1 -1
  18. package/packages/codex-adapter/package.json +1 -1
  19. package/packages/codex-watcher/package.json +1 -1
  20. package/packages/config-capture/package.json +1 -1
  21. package/packages/connection-runtime/package.json +1 -1
  22. package/packages/context-compiler/package.json +1 -1
  23. package/packages/context-discovery/package.json +1 -1
  24. package/packages/context-manager/package.json +1 -1
  25. package/packages/contracts/dist/delegation-store.d.ts +35 -0
  26. package/packages/contracts/dist/delegation-store.js +172 -0
  27. package/packages/contracts/dist/index.d.ts +2 -0
  28. package/packages/contracts/dist/index.js +2 -0
  29. package/packages/contracts/dist/work-partitioner.d.ts +57 -0
  30. package/packages/contracts/dist/work-partitioner.js +165 -0
  31. package/packages/contracts/package.json +1 -1
  32. package/packages/contracts/src/delegation-store.ts +204 -0
  33. package/packages/contracts/src/index.ts +2 -0
  34. package/packages/contracts/src/work-partitioner.ts +251 -0
  35. package/packages/contracts/test/delegation.test.ts +350 -0
  36. package/packages/cookie-sanitizer/package.json +1 -1
  37. package/packages/cost-optimizer/package.json +1 -1
  38. package/packages/dependency-analyzer/package.json +1 -1
  39. package/packages/django-plugin/package.json +1 -1
  40. package/packages/doc-generator/package.json +1 -1
  41. package/packages/durable-review/package.json +1 -1
  42. package/packages/e2e-tester/package.json +1 -1
  43. package/packages/evaluation-engine/package.json +1 -1
  44. package/packages/evaluation-runner/package.json +1 -1
  45. package/packages/event-bus/package.json +1 -1
  46. package/packages/event-sink/package.json +1 -1
  47. package/packages/event-store/package.json +1 -1
  48. package/packages/experience-replay/package.json +1 -1
  49. package/packages/feedback-collector/package.json +1 -1
  50. package/packages/file-copy-helper/package.json +1 -1
  51. package/packages/framework-detector/package.json +1 -1
  52. package/packages/framework-plugin-sdk/package.json +1 -1
  53. package/packages/frappe-plugin/package.json +1 -1
  54. package/packages/generic-web-plugin/package.json +1 -1
  55. package/packages/health-monitor/package.json +1 -1
  56. package/packages/intent-analyzer/package.json +1 -1
  57. package/packages/jev-judge/package.json +1 -1
  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/permission-mode/package.json +1 -1
  73. package/packages/privilege-broker/package.json +1 -1
  74. package/packages/project-analyzer/package.json +1 -1
  75. package/packages/project-bootstrap/package.json +1 -1
  76. package/packages/projection-engine/package.json +1 -1
  77. package/packages/prompt-compiler/package.json +1 -1
  78. package/packages/prompt-versioning/package.json +1 -1
  79. package/packages/provider-adapter-sdk/package.json +1 -1
  80. package/packages/provider-router/package.json +1 -1
  81. package/packages/provider-selector/package.json +1 -1
  82. package/packages/providers/package.json +1 -1
  83. package/packages/qdrant-skills/package.json +1 -1
  84. package/packages/quota-manager/package.json +1 -1
  85. package/packages/rate-limiter/package.json +1 -1
  86. package/packages/react-vite-plugin/package.json +1 -1
  87. package/packages/relay/package.json +1 -1
  88. package/packages/release-manager/package.json +1 -1
  89. package/packages/requirement-compiler/package.json +1 -1
  90. package/packages/runtime/package.json +1 -1
  91. package/packages/scheduler/package.json +1 -1
  92. package/packages/scheduler-adapter/package.json +1 -1
  93. package/packages/session/package.json +1 -1
  94. package/packages/session-api/package.json +1 -1
  95. package/packages/session-export/package.json +1 -1
  96. package/packages/shared-context/package.json +1 -1
  97. package/packages/skill-mcp-client/package.json +1 -1
  98. package/packages/skill-registry/package.json +1 -1
  99. package/packages/skills/package.json +1 -1
  100. package/packages/sprint-planner/package.json +1 -1
  101. package/packages/subscription-engine/package.json +1 -1
  102. package/packages/task-compiler/package.json +1 -1
  103. package/packages/telegram/package.json +1 -1
  104. package/packages/tencentdb-memory/package.json +1 -1
  105. package/packages/tencentdb-sync/package.json +1 -1
  106. package/packages/test-data-generator/package.json +1 -1
  107. package/packages/test-generator/package.json +1 -1
  108. package/packages/todo-bd-sync/package.json +1 -1
  109. package/packages/token-estimation/package.json +1 -1
  110. package/packages/token-optimizer/package.json +1 -1
  111. package/packages/trajectory/package.json +1 -1
  112. package/packages/tui/package.json +1 -1
  113. package/packages/types/package.json +1 -1
  114. package/packages/voice-api/package.json +1 -1
  115. package/packages/webmcp-tester/package.json +1 -1
  116. package/packages/wiki/package.json +1 -1
  117. package/packages/workflow-events/package.json +1 -1
  118. package/packages/workspace-scanner/package.json +1 -1
  119. package/packages/worktree/package.json +1 -1
  120. package/packages/write-review/package.json +1 -1
package/README.md CHANGED
@@ -30,10 +30,13 @@ pi install npm:pi-harness-runtime
30
30
  This runtime works best with these extensions (auto-installed by pi-harness-runtime):
31
31
 
32
32
  ```bash
33
+ pi install npm:pi-subagents # Sub-agent orchestration for large refactors
33
34
  pi install npm:pi-mcp-adapter # MCP protocol adapter for external tools
34
35
  pi install npm:@juicesharp/rpiv-todo # Task tracking with bd sync
35
36
  ```
36
37
 
38
+ The `pi-subagents` extension enables delegation assessment and parallel task execution for large refactoring work (10+ files, 50+ call sites).
39
+
37
40
  Requires Pi v0.37.3+.
38
41
 
39
42
  ### Headless Server Setup (herdr clipboard bridge)
package/index.ts CHANGED
@@ -276,22 +276,20 @@ async function initAutoContinue(pi: ExtensionAPI): Promise<void> {
276
276
  return content;
277
277
  }
278
278
 
279
- // Detect actual confirmation requests (questions, not progress statements)
280
- // Uses the pending question controller for detection with expanded patterns
281
- function detectConfirmationRequest(text: string): string | null {
282
- const result = pqController.detectQuestion(text);
283
- if (result.detected && result.questionText) {
284
- return result.questionText;
279
+ // Set up pending question callback to dispatch answers to Pi
280
+ pqController.onUserAnswer((question, answer) => {
281
+ logToFile("[PendingQuestion]", `User answered: ${answer} for question ${question.requestId}`);
282
+ // Dispatch answer to Pi if needed
283
+ if (answer === "yes") {
284
+ pi.sendUserMessage("yes", { deliverAs: "steer" }).catch((_e: unknown) =>
285
+ logToFile("[PendingQuestion]", "Failed to send yes to Pi")
286
+ );
287
+ } else if (answer === "no") {
288
+ pi.sendUserMessage("not yet", { deliverAs: "steer" }).catch((_e: unknown) =>
289
+ logToFile("[PendingQuestion]", "Failed to send no to Pi")
290
+ );
285
291
  }
286
- return null;
287
- }
288
-
289
- // Detect routine continuation questions ("Should I continue?")
290
- // These should NOT block immediate continuation - let Jev/todo controller decide
291
- function isRoutineContinuation(question: string): boolean {
292
- const result = pqController.detectQuestion(question);
293
- return result.isRoutine ?? false;
294
- }
292
+ });
295
293
 
296
294
  // Detect when agent asks for continuation
297
295
  pi.on("message_end", async (event) => {
@@ -299,22 +297,33 @@ async function initAutoContinue(pi: ExtensionAPI): Promise<void> {
299
297
  if (!msg || msg.role !== "assistant") return;
300
298
 
301
299
  const content = extractAssistantText(msg);
302
- const detectedQuestion = detectConfirmationRequest(content);
300
+ const result = pqController.detectQuestion(content);
303
301
 
304
302
  // Only trigger if: we found a question AND it's different from last notification
305
303
  // Skip routine continuation questions - let Jev/todo controller decide
306
- if (detectedQuestion && detectedQuestion !== _lastNotifiedQuestion && !waitingForUserSince) {
304
+ if (result.detected && result.questionText && result.questionText !== _lastNotifiedQuestion && !waitingForUserSince) {
307
305
  // Skip routine continuation - don't block automatic continuation
308
- if (isRoutineContinuation(detectedQuestion)) {
309
- logToFile("[auto-continue]", "Routine continuation detected, not blocking");
310
- return;
306
+ if (result.isRoutine) {
307
+ logToFile("[auto-continue]", "Routine continuation detected, not blocking");
308
+ return;
311
309
  }
312
- _lastNotifiedQuestion = detectedQuestion;
310
+
311
+ // Create question in controller
312
+ const question = pqController.createQuestion({
313
+ text: result.questionText,
314
+ sessionId: _sessionId,
315
+ workspacePath: _piSessionCwd || "/",
316
+ kind: result.kind || "approval",
317
+ });
318
+
319
+ logToFile("[PendingQuestion]", `Question created: ${question.requestId} - ${result.questionText?.slice(0, 50)}`);
320
+
321
+ _lastNotifiedQuestion = result.questionText;
313
322
  waitingForUserSince = new Date();
314
323
 
315
324
  // Create stable jobId from question content hash (callback-safe: digits only)
316
325
  const questionHash = Math.abs(
317
- detectedQuestion.split("").reduce((a, c) => {
326
+ result.questionText.split("").reduce((a, c) => {
318
327
  a = ((a << 5) - a) + c.charCodeAt(0);
319
328
  return a & a;
320
329
  }, 0)
@@ -336,7 +345,7 @@ async function initAutoContinue(pi: ExtensionAPI): Promise<void> {
336
345
  // Emit WaitingForUserInput to Telegram with Yes/No buttons
337
346
  _nc?.notifyWithApproval("WaitingForUserInput", {
338
347
  jobId: `waiting-user-${questionHash}`,
339
- requirement: detectedQuestion,
348
+ requirement: result.questionText,
340
349
  }, {
341
350
  approveLabel: "Continue",
342
351
  rejectLabel: "Not yet",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-harness-runtime",
3
- "version": "1.1.350",
3
+ "version": "1.1.352",
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.350",
3
+ "version": "1.1.352",
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.350",
3
+ "version": "1.1.352",
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.350",
3
+ "version": "1.1.352",
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.350",
3
+ "version": "1.1.352",
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.350",
3
+ "version": "1.1.352",
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.350",
3
+ "version": "1.1.352",
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.350",
3
+ "version": "1.1.352",
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.350",
3
+ "version": "1.1.352",
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.350",
3
+ "version": "1.1.352",
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.350",
3
+ "version": "1.1.352",
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.350",
3
+ "version": "1.1.352",
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.350",
3
+ "version": "1.1.352",
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.350",
3
+ "version": "1.1.352",
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.350",
3
+ "version": "1.1.352",
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.350",
3
+ "version": "1.1.352",
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.350",
3
+ "version": "1.1.352",
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.350",
3
+ "version": "1.1.352",
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-harness/connection-runtime",
3
- "version": "1.1.350",
3
+ "version": "1.1.352",
4
4
  "type": "module",
5
5
  "description": "Connection management with jittered exponential backoff for pi-harness",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/context-compiler",
3
- "version": "1.1.350",
3
+ "version": "1.1.352",
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.350",
3
+ "version": "1.1.352",
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.350",
3
+ "version": "1.1.352",
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",
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Delegation Store
3
+ *
4
+ * Durable storage for delegation receipts.
5
+ * Stores in ignored harness state directory.
6
+ */
7
+ import type { DelegationReceipt } from "./delegation.js";
8
+ /**
9
+ * Save delegation receipt
10
+ */
11
+ export declare function saveDelegationReceipt(receipt: DelegationReceipt): void;
12
+ /**
13
+ * Load delegation receipt
14
+ */
15
+ export declare function loadDelegationReceipt(workspacePath: string, taskId: string): DelegationReceipt | null;
16
+ /**
17
+ * Delete delegation receipt
18
+ */
19
+ export declare function deleteDelegationReceipt(workspacePath: string, taskId: string): void;
20
+ /**
21
+ * List all receipts for a workspace
22
+ */
23
+ export declare function listDelegationReceipts(workspacePath: string): DelegationReceipt[];
24
+ /**
25
+ * Update receipt status
26
+ */
27
+ export declare function updateReceiptStatus(workspacePath: string, taskId: string, status: DelegationReceipt["status"], updates?: Partial<DelegationReceipt>): DelegationReceipt | null;
28
+ /**
29
+ * Check if receipt exists for task
30
+ */
31
+ export declare function hasReceipt(workspacePath: string, taskId: string): boolean;
32
+ /**
33
+ * Compact receipt for storage after compaction
34
+ */
35
+ export declare function compactReceipt(receipt: DelegationReceipt): DelegationReceipt;
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Delegation Store
3
+ *
4
+ * Durable storage for delegation receipts.
5
+ * Stores in ignored harness state directory.
6
+ */
7
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
8
+ import { join } from "path";
9
+ /**
10
+ * Store directory path
11
+ */
12
+ const STORE_DIR = join(process.env.HOME || "/home/frappe", ".pi-harness-runtime", "delegation-state");
13
+ /**
14
+ * Ensure store directory exists
15
+ */
16
+ function ensureStoreDir() {
17
+ if (!existsSync(STORE_DIR)) {
18
+ mkdirSync(STORE_DIR, { recursive: true });
19
+ }
20
+ }
21
+ /**
22
+ * Get receipt file path for workspace + task
23
+ */
24
+ function getReceiptPath(workspacePath, taskId) {
25
+ // Sanitize path for use as filename
26
+ const safePath = workspacePath.replace(/[^a-zA-Z0-9_-]/g, "_").slice(-100);
27
+ const safeTask = taskId.replace(/[^a-zA-Z0-9_-]/g, "_");
28
+ return join(STORE_DIR, `${safePath}__${safeTask}.json`);
29
+ }
30
+ /**
31
+ * Save delegation receipt
32
+ */
33
+ export function saveDelegationReceipt(receipt) {
34
+ ensureStoreDir();
35
+ const path = getReceiptPath(receipt.workspacePath, receipt.parentTaskId);
36
+ // Atomic write: write to temp, then rename
37
+ const tempPath = path + ".tmp";
38
+ writeFileSync(tempPath, JSON.stringify(receipt, null, 2), "utf8");
39
+ // Rename is atomic on POSIX
40
+ try {
41
+ const { renameSync } = require("fs");
42
+ renameSync(tempPath, path);
43
+ }
44
+ catch {
45
+ // Fallback: just move the file
46
+ try {
47
+ writeFileSync(path, JSON.stringify(receipt, null, 2), "utf8");
48
+ }
49
+ catch {
50
+ // Ignore write errors
51
+ }
52
+ }
53
+ }
54
+ /**
55
+ * Load delegation receipt
56
+ */
57
+ export function loadDelegationReceipt(workspacePath, taskId) {
58
+ const path = getReceiptPath(workspacePath, taskId);
59
+ if (!existsSync(path)) {
60
+ return null;
61
+ }
62
+ try {
63
+ const content = readFileSync(path, "utf8");
64
+ const receipt = JSON.parse(content);
65
+ // Validate version
66
+ if (receipt.version !== 1) {
67
+ // Future migration logic would go here
68
+ return null;
69
+ }
70
+ return receipt;
71
+ }
72
+ catch {
73
+ return null;
74
+ }
75
+ }
76
+ /**
77
+ * Delete delegation receipt
78
+ */
79
+ export function deleteDelegationReceipt(workspacePath, taskId) {
80
+ const path = getReceiptPath(workspacePath, taskId);
81
+ if (existsSync(path)) {
82
+ try {
83
+ const { unlinkSync } = require("fs");
84
+ unlinkSync(path);
85
+ }
86
+ catch {
87
+ // Ignore delete errors
88
+ }
89
+ }
90
+ }
91
+ /**
92
+ * List all receipts for a workspace
93
+ */
94
+ export function listDelegationReceipts(workspacePath) {
95
+ ensureStoreDir();
96
+ const receipts = [];
97
+ try {
98
+ const { readdirSync } = require("fs");
99
+ const files = readdirSync(STORE_DIR);
100
+ const safePathPrefix = workspacePath.replace(/[^a-zA-Z0-9_-]/g, "_").slice(-100) + "__";
101
+ for (const file of files) {
102
+ if (!file.startsWith(safePathPrefix) || !file.endsWith(".json")) {
103
+ continue;
104
+ }
105
+ try {
106
+ const content = readFileSync(join(STORE_DIR, file), "utf8");
107
+ const receipt = JSON.parse(content);
108
+ if (receipt.workspacePath === workspacePath) {
109
+ receipts.push(receipt);
110
+ }
111
+ }
112
+ catch {
113
+ // Skip invalid files
114
+ }
115
+ }
116
+ }
117
+ catch {
118
+ // Directory doesn't exist or not readable
119
+ }
120
+ return receipts;
121
+ }
122
+ /**
123
+ * Update receipt status
124
+ */
125
+ export function updateReceiptStatus(workspacePath, taskId, status, updates) {
126
+ const receipt = loadDelegationReceipt(workspacePath, taskId);
127
+ if (!receipt) {
128
+ return null;
129
+ }
130
+ const updated = {
131
+ ...receipt,
132
+ ...updates,
133
+ status,
134
+ updatedAt: Date.now(),
135
+ };
136
+ saveDelegationReceipt(updated);
137
+ return updated;
138
+ }
139
+ /**
140
+ * Check if receipt exists for task
141
+ */
142
+ export function hasReceipt(workspacePath, taskId) {
143
+ const path = getReceiptPath(workspacePath, taskId);
144
+ return existsSync(path);
145
+ }
146
+ /**
147
+ * Compact receipt for storage after compaction
148
+ */
149
+ export function compactReceipt(receipt) {
150
+ return {
151
+ version: receipt.version,
152
+ workspacePath: receipt.workspacePath,
153
+ sessionId: receipt.sessionId,
154
+ parentTaskId: receipt.parentTaskId,
155
+ scopeFingerprint: receipt.scopeFingerprint,
156
+ decision: {
157
+ strategy: receipt.decision.strategy,
158
+ reason: receipt.decision.reason,
159
+ workGroups: receipt.decision.workGroups.filter((g) => g.status === "pending" || g.status === "dispatched" || g.status === "running"),
160
+ validationExpectations: receipt.decision.validationExpectations,
161
+ confidence: receipt.decision.confidence,
162
+ jevUsed: receipt.decision.jevUsed,
163
+ reassessmentTriggers: receipt.decision.reassessmentTriggers,
164
+ },
165
+ createdAt: receipt.createdAt,
166
+ updatedAt: Date.now(),
167
+ status: receipt.status,
168
+ childIds: receipt.childIds,
169
+ pendingValidation: receipt.pendingValidation,
170
+ userConstraints: receipt.userConstraints,
171
+ };
172
+ }
@@ -20,4 +20,6 @@ export * from './notifications.js';
20
20
  export * from './approvals.js';
21
21
  export * from './delegation.js';
22
22
  export * from './delegation-assessor.js';
23
+ export * from './delegation-store.js';
23
24
  export * from './scope-discovery.js';
25
+ export * from './work-partitioner.js';
@@ -20,4 +20,6 @@ export * from './notifications.js';
20
20
  export * from './approvals.js';
21
21
  export * from './delegation.js';
22
22
  export * from './delegation-assessor.js';
23
+ export * from './delegation-store.js';
23
24
  export * from './scope-discovery.js';
25
+ export * from './work-partitioner.js';
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Work Partitioner
3
+ *
4
+ * Partitions work into disjoint file ownership groups.
5
+ */
6
+ import type { WorkGroup, ScopeFacts } from "./delegation.js";
7
+ /**
8
+ * File dependency info
9
+ */
10
+ export interface FileDependency {
11
+ path: string;
12
+ imports: string[];
13
+ exports: string[];
14
+ }
15
+ /**
16
+ * Partition configuration
17
+ */
18
+ export interface PartitionConfig {
19
+ /** Maximum files per group */
20
+ maxFilesPerGroup: number;
21
+ /** Whether to group by directory */
22
+ groupByDirectory: boolean;
23
+ /** Shared files that shouldn't be partitioned */
24
+ sharedPaths: string[];
25
+ }
26
+ /**
27
+ * Default partition config
28
+ */
29
+ export declare const DEFAULT_PARTITION_CONFIG: PartitionConfig;
30
+ /**
31
+ * Partition files into ownership groups
32
+ */
33
+ export declare function partitionWork(files: string[], facts: ScopeFacts, config?: Partial<PartitionConfig>): WorkGroup[];
34
+ /**
35
+ * Detect ownership conflicts
36
+ */
37
+ export declare function detectOwnershipConflicts(groups: WorkGroup[], newPaths: string[]): string[];
38
+ /**
39
+ * Assign work to group
40
+ */
41
+ export declare function assignWorkToGroup(groups: WorkGroup[], groupId: string, paths: string[]): WorkGroup | null;
42
+ /**
43
+ * Get unowned files
44
+ */
45
+ export declare function getUnownedFiles(allFiles: string[], groups: WorkGroup[]): string[];
46
+ /**
47
+ * Update group status
48
+ */
49
+ export declare function updateGroupStatus(groups: WorkGroup[], groupId: string, status: WorkGroup["status"], childId?: string): WorkGroup[];
50
+ /**
51
+ * Check if all groups are complete
52
+ */
53
+ export declare function areAllGroupsComplete(groups: WorkGroup[]): boolean;
54
+ /**
55
+ * Get pending groups
56
+ */
57
+ export declare function getPendingGroups(groups: WorkGroup[]): WorkGroup[];