pi-loop 0.1.1 → 0.1.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 (121) hide show
  1. package/dist/agents/adapter.d.ts +7 -1
  2. package/dist/agents/adapter.d.ts.map +1 -1
  3. package/dist/agents/adapter.js +28 -3
  4. package/dist/agents/adapter.js.map +1 -1
  5. package/dist/agents/factory.d.ts +1 -1
  6. package/dist/agents/factory.d.ts.map +1 -1
  7. package/dist/agents/factory.js +10 -2
  8. package/dist/agents/factory.js.map +1 -1
  9. package/dist/agents/registry.d.ts.map +1 -1
  10. package/dist/agents/registry.js +1 -1
  11. package/dist/agents/registry.js.map +1 -1
  12. package/dist/agents/types.d.ts.map +1 -1
  13. package/dist/agents/types.js +1 -9
  14. package/dist/agents/types.js.map +1 -1
  15. package/dist/cli/args.d.ts +15 -1
  16. package/dist/cli/args.d.ts.map +1 -1
  17. package/dist/cli/args.js +47 -0
  18. package/dist/cli/args.js.map +1 -1
  19. package/dist/cli/commands.d.ts +4 -0
  20. package/dist/cli/commands.d.ts.map +1 -1
  21. package/dist/cli/commands.js +294 -16
  22. package/dist/cli/commands.js.map +1 -1
  23. package/dist/cli/live-interface.d.ts +31 -0
  24. package/dist/cli/live-interface.d.ts.map +1 -0
  25. package/dist/cli/live-interface.js +190 -0
  26. package/dist/cli/live-interface.js.map +1 -0
  27. package/dist/cli/output.d.ts.map +1 -1
  28. package/dist/cli/output.js.map +1 -1
  29. package/dist/config/defaults.d.ts.map +1 -1
  30. package/dist/config/defaults.js +2 -0
  31. package/dist/config/defaults.js.map +1 -1
  32. package/dist/config/global-store.d.ts +15 -0
  33. package/dist/config/global-store.d.ts.map +1 -0
  34. package/dist/config/global-store.js +136 -0
  35. package/dist/config/global-store.js.map +1 -0
  36. package/dist/config/loader.d.ts.map +1 -1
  37. package/dist/config/loader.js +79 -24
  38. package/dist/config/loader.js.map +1 -1
  39. package/dist/config/provider-api-keys.d.ts +11 -0
  40. package/dist/config/provider-api-keys.d.ts.map +1 -0
  41. package/dist/config/provider-api-keys.js +15 -0
  42. package/dist/config/provider-api-keys.js.map +1 -0
  43. package/dist/config/types.d.ts +3 -0
  44. package/dist/config/types.d.ts.map +1 -1
  45. package/dist/core/checkpoint.d.ts +1 -0
  46. package/dist/core/checkpoint.d.ts.map +1 -1
  47. package/dist/core/checkpoint.js.map +1 -1
  48. package/dist/core/concurrency-controller.d.ts +34 -0
  49. package/dist/core/concurrency-controller.d.ts.map +1 -0
  50. package/dist/core/concurrency-controller.js +63 -0
  51. package/dist/core/concurrency-controller.js.map +1 -0
  52. package/dist/core/judge.d.ts.map +1 -1
  53. package/dist/core/judge.js +4 -1
  54. package/dist/core/judge.js.map +1 -1
  55. package/dist/core/learnings.js +1 -1
  56. package/dist/core/learnings.js.map +1 -1
  57. package/dist/core/orchestrator.d.ts +7 -0
  58. package/dist/core/orchestrator.d.ts.map +1 -1
  59. package/dist/core/orchestrator.js +108 -22
  60. package/dist/core/orchestrator.js.map +1 -1
  61. package/dist/core/plan.js +1 -1
  62. package/dist/core/plan.js.map +1 -1
  63. package/dist/core/runtime-events.d.ts +60 -0
  64. package/dist/core/runtime-events.d.ts.map +1 -0
  65. package/dist/core/runtime-events.js +45 -0
  66. package/dist/core/runtime-events.js.map +1 -0
  67. package/dist/core/runtime-hooks.d.ts +8 -0
  68. package/dist/core/runtime-hooks.d.ts.map +1 -0
  69. package/dist/core/runtime-hooks.js +2 -0
  70. package/dist/core/runtime-hooks.js.map +1 -0
  71. package/dist/core/task-backend.d.ts +5 -0
  72. package/dist/core/task-backend.d.ts.map +1 -1
  73. package/dist/core/task-backend.js.map +1 -1
  74. package/dist/core/task-state.d.ts.map +1 -1
  75. package/dist/core/task-state.js +14 -6
  76. package/dist/core/task-state.js.map +1 -1
  77. package/dist/core/wiring.d.ts +2 -1
  78. package/dist/core/wiring.d.ts.map +1 -1
  79. package/dist/core/wiring.js +22 -9
  80. package/dist/core/wiring.js.map +1 -1
  81. package/dist/index.js +4 -1
  82. package/dist/index.js.map +1 -1
  83. package/dist/integrations/linear/backend.d.ts +8 -0
  84. package/dist/integrations/linear/backend.d.ts.map +1 -1
  85. package/dist/integrations/linear/backend.js +139 -8
  86. package/dist/integrations/linear/backend.js.map +1 -1
  87. package/dist/integrations/linear/client.js +1 -1
  88. package/dist/integrations/linear/client.js.map +1 -1
  89. package/dist/integrations/linear/seed-description.d.ts +3 -0
  90. package/dist/integrations/linear/seed-description.d.ts.map +1 -0
  91. package/dist/integrations/linear/seed-description.js +23 -0
  92. package/dist/integrations/linear/seed-description.js.map +1 -0
  93. package/dist/swarm/pool.d.ts +20 -0
  94. package/dist/swarm/pool.d.ts.map +1 -1
  95. package/dist/swarm/pool.js +124 -23
  96. package/dist/swarm/pool.js.map +1 -1
  97. package/dist/swarm/scheduler.d.ts.map +1 -1
  98. package/dist/swarm/scheduler.js +50 -6
  99. package/dist/swarm/scheduler.js.map +1 -1
  100. package/dist/swarm/worker.d.ts +4 -0
  101. package/dist/swarm/worker.d.ts.map +1 -1
  102. package/dist/swarm/worker.js +120 -86
  103. package/dist/swarm/worker.js.map +1 -1
  104. package/dist/tools/bash-tool.d.ts.map +1 -1
  105. package/dist/tools/bash-tool.js.map +1 -1
  106. package/dist/tools/file-tools.d.ts.map +1 -1
  107. package/dist/tools/file-tools.js +1 -1
  108. package/dist/tools/file-tools.js.map +1 -1
  109. package/dist/tools/git-tools.d.ts.map +1 -1
  110. package/dist/tools/git-tools.js.map +1 -1
  111. package/dist/tools/learnings-tool.d.ts.map +1 -1
  112. package/dist/tools/learnings-tool.js +3 -3
  113. package/dist/tools/learnings-tool.js.map +1 -1
  114. package/dist/tools/plan-tool.d.ts.map +1 -1
  115. package/dist/tools/plan-tool.js.map +1 -1
  116. package/dist/tools/task-tools.d.ts.map +1 -1
  117. package/dist/tools/task-tools.js +1 -1
  118. package/dist/tools/task-tools.js.map +1 -1
  119. package/dist/tools/test-tool.d.ts.map +1 -1
  120. package/dist/tools/test-tool.js.map +1 -1
  121. package/package.json +46 -45
@@ -4,6 +4,7 @@
4
4
  export interface ModelConfig {
5
5
  provider: string;
6
6
  modelId: string;
7
+ baseUrl?: string;
7
8
  }
8
9
  export interface GitConfig {
9
10
  commitPrefix: string;
@@ -14,6 +15,7 @@ export interface LinearConfig {
14
15
  enabled: boolean;
15
16
  apiUrl: string;
16
17
  teamId?: string;
18
+ projectName?: string;
17
19
  cycleName?: string;
18
20
  readyStateName: string;
19
21
  inProgressStateName: string;
@@ -31,6 +33,7 @@ export interface PiLoopConfig {
31
33
  agentsDir: string;
32
34
  maxConcurrency: number;
33
35
  maxCycles: number;
36
+ maxWorkerAttempts: number;
34
37
  thinkingLevel: ThinkingLevel;
35
38
  git: GitConfig;
36
39
  taskBackend: TaskBackendMode;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,WAAW;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,QAAQ,CAAC;AAEpD,MAAM,WAAW,YAAY;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC5B,YAAY,EAAE,WAAW,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,aAAa,CAAC;IAC7B,GAAG,EAAE,SAAS,CAAC;IACf,WAAW,EAAE,eAAe,CAAC;IAC7B,MAAM,EAAE,YAAY,CAAC;CACrB;AAED,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,WAAW;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,QAAQ,CAAC;AAEpD,MAAM,WAAW,YAAY;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC5B,YAAY,EAAE,WAAW,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,aAAa,CAAC;IAC7B,GAAG,EAAE,SAAS,CAAC;IACf,WAAW,EAAE,eAAe,CAAC;IAC7B,MAAM,EAAE,YAAY,CAAC;CACrB;AAED,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC"}
@@ -5,6 +5,7 @@ export interface CheckpointState {
5
5
  planHash: string;
6
6
  planPath: string;
7
7
  tasksSnapshot: string;
8
+ linearNeedsSeeding?: boolean;
8
9
  backendContext?: {
9
10
  currentTaskId?: string;
10
11
  lastSyncedAt?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"checkpoint.d.ts","sourceRoot":"","sources":["../../src/core/checkpoint.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,iBAAiB,GAC1B,MAAM,GACN,aAAa,GACb,iBAAiB,GACjB,iBAAiB,GACjB,WAAW,GACX,SAAS,GACT,aAAa,GACb,WAAW,CAAC;AAEf,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,iBAAiB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE;QAChB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,qBAAqB,CAAC,EAAE,MAAM,CAAC;KAC/B,CAAC;IACF,SAAS,EAAE,MAAM,CAAC;CAClB;AAUD,wBAAsB,cAAc,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAS5F;AAED,wBAAsB,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAStF;AAED,wBAAsB,eAAe,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMrE"}
1
+ {"version":3,"file":"checkpoint.d.ts","sourceRoot":"","sources":["../../src/core/checkpoint.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,iBAAiB,GAC1B,MAAM,GACN,aAAa,GACb,iBAAiB,GACjB,iBAAiB,GACjB,WAAW,GACX,SAAS,GACT,aAAa,GACb,WAAW,CAAC;AAEf,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,iBAAiB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,cAAc,CAAC,EAAE;QAChB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,qBAAqB,CAAC,EAAE,MAAM,CAAC;KAC/B,CAAC;IACF,SAAS,EAAE,MAAM,CAAC;CAClB;AAUD,wBAAsB,cAAc,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAS5F;AAED,wBAAsB,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAStF;AAED,wBAAsB,eAAe,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMrE"}
@@ -1 +1 @@
1
- {"version":3,"file":"checkpoint.js","sourceRoot":"","sources":["../../src/core/checkpoint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AA0BjC,MAAM,cAAc,GAAG,UAAU,CAAC;AAClC,MAAM,eAAe,GAAG,iBAAiB,CAAC;AAE1C,SAAS,cAAc,CAAC,OAAgB;IACvC,MAAM,IAAI,GAAG,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACtC,OAAO,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,eAAe,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAsB,EAAE,OAAgB;IAC5E,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC;IAE3D,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;AACtE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAgB;IACpD,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IAEzC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC;IACb,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC7C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAoB,CAAC;AAC3C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAgB;IACrD,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IAEzC,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC;IACpB,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"checkpoint.js","sourceRoot":"","sources":["../../src/core/checkpoint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AA2BjC,MAAM,cAAc,GAAG,UAAU,CAAC;AAClC,MAAM,eAAe,GAAG,iBAAiB,CAAC;AAE1C,SAAS,cAAc,CAAC,OAAgB;IACvC,MAAM,IAAI,GAAG,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACtC,OAAO,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,eAAe,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAsB,EAAE,OAAgB;IAC5E,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC;IAE3D,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;AACtE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAgB;IACpD,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IAEzC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC;IACb,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC7C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAoB,CAAC;AAC3C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAgB;IACrD,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IAEzC,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC;IACpB,CAAC;AACF,CAAC"}
@@ -0,0 +1,34 @@
1
+ export interface ConcurrencyChange {
2
+ previous: number;
3
+ current: number;
4
+ source: string;
5
+ timestamp: string;
6
+ }
7
+ export type ConcurrencyChangeListener = (change: ConcurrencyChange) => void;
8
+ export interface ConcurrencyController {
9
+ get(): number;
10
+ getMin(): number;
11
+ getMax(): number;
12
+ set(next: number, source?: string): number;
13
+ increment(source?: string): number;
14
+ decrement(source?: string): number;
15
+ subscribe(listener: ConcurrencyChangeListener): () => void;
16
+ }
17
+ export declare class MutableConcurrencyController implements ConcurrencyController {
18
+ private current;
19
+ private readonly min;
20
+ private readonly max;
21
+ private readonly listeners;
22
+ constructor(initial: number, options?: {
23
+ min?: number;
24
+ max?: number;
25
+ });
26
+ get(): number;
27
+ getMin(): number;
28
+ getMax(): number;
29
+ set(next: number, source?: string): number;
30
+ increment(source?: string): number;
31
+ decrement(source?: string): number;
32
+ subscribe(listener: ConcurrencyChangeListener): () => void;
33
+ }
34
+ //# sourceMappingURL=concurrency-controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concurrency-controller.d.ts","sourceRoot":"","sources":["../../src/core/concurrency-controller.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,yBAAyB,GAAG,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;AAE5E,MAAM,WAAW,qBAAqB;IACrC,GAAG,IAAI,MAAM,CAAC;IACd,MAAM,IAAI,MAAM,CAAC;IACjB,MAAM,IAAI,MAAM,CAAC;IACjB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3C,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACnC,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACnC,SAAS,CAAC,QAAQ,EAAE,yBAAyB,GAAG,MAAM,IAAI,CAAC;CAC3D;AAUD,qBAAa,4BAA6B,YAAW,qBAAqB;IACzE,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwC;gBAEtD,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE;IAQrE,GAAG,IAAI,MAAM;IAIb,MAAM,IAAI,MAAM;IAIhB,MAAM,IAAI,MAAM;IAIhB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,SAAa,GAAG,MAAM;IAmB9C,SAAS,CAAC,MAAM,SAAa,GAAG,MAAM;IAItC,SAAS,CAAC,MAAM,SAAa,GAAG,MAAM;IAItC,SAAS,CAAC,QAAQ,EAAE,yBAAyB,GAAG,MAAM,IAAI;CAM1D"}
@@ -0,0 +1,63 @@
1
+ function normalize(value, min, max) {
2
+ if (!Number.isFinite(value))
3
+ return min;
4
+ const rounded = Math.floor(value);
5
+ if (rounded < min)
6
+ return min;
7
+ if (rounded > max)
8
+ return max;
9
+ return rounded;
10
+ }
11
+ export class MutableConcurrencyController {
12
+ current;
13
+ min;
14
+ max;
15
+ listeners = new Set();
16
+ constructor(initial, options) {
17
+ const min = options?.min ?? 1;
18
+ const max = options?.max ?? Number.MAX_SAFE_INTEGER;
19
+ this.min = Math.max(1, Math.floor(min));
20
+ this.max = Math.max(this.min, Math.floor(max));
21
+ this.current = normalize(initial, this.min, this.max);
22
+ }
23
+ get() {
24
+ return this.current;
25
+ }
26
+ getMin() {
27
+ return this.min;
28
+ }
29
+ getMax() {
30
+ return this.max;
31
+ }
32
+ set(next, source = "external") {
33
+ const normalized = normalize(next, this.min, this.max);
34
+ const previous = this.current;
35
+ if (normalized === previous) {
36
+ return this.current;
37
+ }
38
+ this.current = normalized;
39
+ const change = {
40
+ previous,
41
+ current: normalized,
42
+ source,
43
+ timestamp: new Date().toISOString(),
44
+ };
45
+ for (const listener of this.listeners) {
46
+ listener(change);
47
+ }
48
+ return this.current;
49
+ }
50
+ increment(source = "external") {
51
+ return this.set(this.current + 1, source);
52
+ }
53
+ decrement(source = "external") {
54
+ return this.set(this.current - 1, source);
55
+ }
56
+ subscribe(listener) {
57
+ this.listeners.add(listener);
58
+ return () => {
59
+ this.listeners.delete(listener);
60
+ };
61
+ }
62
+ }
63
+ //# sourceMappingURL=concurrency-controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concurrency-controller.js","sourceRoot":"","sources":["../../src/core/concurrency-controller.ts"],"names":[],"mappings":"AAmBA,SAAS,SAAS,CAAC,KAAa,EAAE,GAAW,EAAE,GAAW;IACzD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IACxC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAClC,IAAI,OAAO,GAAG,GAAG;QAAE,OAAO,GAAG,CAAC;IAC9B,IAAI,OAAO,GAAG,GAAG;QAAE,OAAO,GAAG,CAAC;IAC9B,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,MAAM,OAAO,4BAA4B;IAChC,OAAO,CAAS;IACP,GAAG,CAAS;IACZ,GAAG,CAAS;IACZ,SAAS,GAAG,IAAI,GAAG,EAA6B,CAAC;IAElE,YAAY,OAAe,EAAE,OAAwC;QACpE,MAAM,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;QAC9B,MAAM,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,MAAM,CAAC,gBAAgB,CAAC;QACpD,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QACxC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/C,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;IACvD,CAAC;IAED,GAAG;QACF,OAAO,IAAI,CAAC,OAAO,CAAC;IACrB,CAAC;IAED,MAAM;QACL,OAAO,IAAI,CAAC,GAAG,CAAC;IACjB,CAAC;IAED,MAAM;QACL,OAAO,IAAI,CAAC,GAAG,CAAC;IACjB,CAAC;IAED,GAAG,CAAC,IAAY,EAAE,MAAM,GAAG,UAAU;QACpC,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC;QAC9B,IAAI,UAAU,KAAK,QAAQ,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC,OAAO,CAAC;QACrB,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC;QAC1B,MAAM,MAAM,GAAsB;YACjC,QAAQ;YACR,OAAO,EAAE,UAAU;YACnB,MAAM;YACN,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACnC,CAAC;QACF,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACvC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAClB,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC;IACrB,CAAC;IAED,SAAS,CAAC,MAAM,GAAG,UAAU;QAC5B,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IAED,SAAS,CAAC,MAAM,GAAG,UAAU;QAC5B,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IAED,SAAS,CAAC,QAAmC;QAC5C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7B,OAAO,GAAG,EAAE;YACX,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC,CAAC;IACH,CAAC;CACD"}
@@ -1 +1 @@
1
- {"version":3,"file":"judge.d.ts","sourceRoot":"","sources":["../../src/core/judge.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC5B,MAAM,EAAE,MAAM,GAAG,UAAU,CAAC;IAC5B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,gBAAgB,CAC/B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GACjB,MAAM,CAqCR;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CAoDhE"}
1
+ {"version":3,"file":"judge.d.ts","sourceRoot":"","sources":["../../src/core/judge.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC5B,MAAM,EAAE,MAAM,GAAG,UAAU,CAAC;IAC5B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,gBAAgB,CAC/B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GACjB,MAAM,CAqCR;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CAyDhE"}
@@ -78,7 +78,10 @@ export function parseJudgeVerdict(response) {
78
78
  // Strategy 3: Keyword heuristic — if we can't parse JSON, infer from text
79
79
  const upper = response.toUpperCase();
80
80
  const hasDone = upper.includes("ALL GOALS") && (upper.includes("MET") || upper.includes("ACHIEVED") || upper.includes("COMPLETE"));
81
- const hasNotDone = upper.includes("REMAINING") || upper.includes("NOT DONE") || upper.includes("NOT_DONE") || upper.includes("INCOMPLETE");
81
+ const hasNotDone = upper.includes("REMAINING") ||
82
+ upper.includes("NOT DONE") ||
83
+ upper.includes("NOT_DONE") ||
84
+ upper.includes("INCOMPLETE");
82
85
  return {
83
86
  status: hasDone && !hasNotDone ? "done" : "not_done",
84
87
  completedGoals: [],
@@ -1 +1 @@
1
- {"version":3,"file":"judge.js","sourceRoot":"","sources":["../../src/core/judge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"judge.js","sourceRoot":"","sources":["../../src/core/judge.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { readFile, appendFile } from "node:fs/promises";
2
1
  import { existsSync } from "node:fs";
2
+ import { appendFile, readFile } from "node:fs/promises";
3
3
  export async function readLearnings(path) {
4
4
  if (!existsSync(path)) {
5
5
  return "";
@@ -1 +1 @@
1
- {"version":3,"file":"learnings.js","sourceRoot":"","sources":["../../src/core/learnings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAY;IAC/C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC;IACX,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAY,EAAE,KAAa;IAC/D,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3C,MAAM,SAAS,GAAG,QAAQ,SAAS,OAAO,KAAK,IAAI,CAAC;IACpD,MAAM,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAe,EAAE,SAAiB;IACpE,IAAI,OAAO,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC;QACjC,OAAO,OAAO,CAAC;IAChB,CAAC;IAED,+CAA+C;IAC/C,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAEjD,2CAA2C;IAC3C,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACzB,IAAI,WAAW,GAAG,KAAK,CAAC,MAAM,GAAG,SAAS,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/D,MAAM;QACP,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACpB,WAAW,IAAI,KAAK,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC"}
1
+ {"version":3,"file":"learnings.js","sourceRoot":"","sources":["../../src/core/learnings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAY;IAC/C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC;IACX,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAY,EAAE,KAAa;IAC/D,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3C,MAAM,SAAS,GAAG,QAAQ,SAAS,OAAO,KAAK,IAAI,CAAC;IACpD,MAAM,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAe,EAAE,SAAiB;IACpE,IAAI,OAAO,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC;QACjC,OAAO,OAAO,CAAC;IAChB,CAAC;IAED,+CAA+C;IAC/C,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAEjD,2CAA2C;IAC3C,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACzB,IAAI,WAAW,GAAG,KAAK,CAAC,MAAM,GAAG,SAAS,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/D,MAAM;QACP,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACpB,WAAW,IAAI,KAAK,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC"}
@@ -2,6 +2,7 @@ import type { AgentDefinition, AgentRole } from "../agents/types.js";
2
2
  import type { PiLoopConfig } from "../config/types.js";
3
3
  import { type CheckpointState, type OrchestratorPhase } from "./checkpoint.js";
4
4
  import { type JudgeVerdict } from "./judge.js";
5
+ import type { RuntimeHooks } from "./runtime-hooks.js";
5
6
  import type { TaskBackend } from "./task-backend.js";
6
7
  import { type Task } from "./task-state.js";
7
8
  /**
@@ -32,6 +33,7 @@ export interface OrchestratorOptions {
32
33
  config: PiLoopConfig;
33
34
  deps: OrchestratorDeps;
34
35
  workDir?: string;
36
+ runtimeHooks?: RuntimeHooks;
35
37
  }
36
38
  export type { OrchestratorPhase };
37
39
  export declare class Orchestrator {
@@ -44,19 +46,24 @@ export declare class Orchestrator {
44
46
  private readonly config;
45
47
  private readonly deps;
46
48
  private readonly workDir;
49
+ private readonly runtimeHooks?;
50
+ private linearNeedsSeeding;
47
51
  constructor(options: OrchestratorOptions);
48
52
  run(): Promise<JudgeVerdict>;
49
53
  resume(checkpoint: CheckpointState): Promise<JudgeVerdict>;
50
54
  private log;
55
+ private emit;
51
56
  private executeFromPhase;
52
57
  private phaseInit;
53
58
  private phaseDecompose;
54
59
  private phaseReviewTasks;
55
60
  private phaseSubDecompose;
61
+ private seedLinearFromTasks;
56
62
  private phaseExecute;
57
63
  private phaseJudge;
58
64
  private phaseRePlan;
59
65
  private saveCurrentCheckpoint;
66
+ private emitTaskSummary;
60
67
  private withBackendRetry;
61
68
  private safeMarkNeedsDecision;
62
69
  private countRejectedTasks;
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/core/orchestrator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EACN,KAAK,eAAe,EACpB,KAAK,iBAAiB,EAItB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,KAAK,YAAY,EAAuC,MAAM,YAAY,CAAC;AAKpF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,KAAK,IAAI,EAA8C,MAAM,iBAAiB,CAAC;AAExF;;;GAGG;AACH,MAAM,WAAW,KAAK;IACrB,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,EAAE,eAAe,CAAC;IAC5B,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,YAAY;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAChC,aAAa,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC;IACtE,eAAe,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,YAAY,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAClF,WAAW,EAAE,WAAW,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,EAAE,gBAAgB,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAElC,qBAAa,YAAY;IACxB,OAAO,CAAC,KAAK,CAA6B;IAC1C,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAmB;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,OAAO,EAAE,mBAAmB;IASlC,GAAG,IAAI,OAAO,CAAC,YAAY,CAAC;IAU5B,MAAM,CAAC,UAAU,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC;IAShE,OAAO,CAAC,GAAG;YAKG,gBAAgB;YAgFhB,SAAS;YAOT,cAAc;YA8Dd,gBAAgB;YAmDhB,iBAAiB;YA8DjB,YAAY;YAqIZ,UAAU;YAuCV,WAAW;YASX,qBAAqB;YAqBrB,gBAAgB;YAqBhB,qBAAqB;IAYnC,OAAO,CAAC,kBAAkB;CAS1B"}
1
+ {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/core/orchestrator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,OAAO,EACN,KAAK,eAAe,EACpB,KAAK,iBAAiB,EAItB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,KAAK,YAAY,EAAuC,MAAM,YAAY,CAAC;AAKpF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,KAAK,IAAI,EAA8C,MAAM,iBAAiB,CAAC;AAExF;;;GAGG;AACH,MAAM,WAAW,KAAK;IACrB,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,EAAE,eAAe,CAAC;IAC5B,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,YAAY;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAChC,aAAa,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC;IACtE,eAAe,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,YAAY,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAClF,WAAW,EAAE,WAAW,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,EAAE,gBAAgB,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,YAAY,CAAC;CAC5B;AAED,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAElC,qBAAa,YAAY;IACxB,OAAO,CAAC,KAAK,CAA6B;IAC1C,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAmB;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAe;IAC7C,OAAO,CAAC,kBAAkB,CAAS;gBAEvB,OAAO,EAAE,mBAAmB;IAUlC,GAAG,IAAI,OAAO,CAAC,YAAY,CAAC;IAU5B,MAAM,CAAC,UAAU,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC;IAUhE,OAAO,CAAC,GAAG;IAcX,OAAO,CAAC,IAAI;YAIE,gBAAgB;YAwGhB,SAAS;YAOT,cAAc;YAmEd,gBAAgB;YAmDhB,iBAAiB;YAoEjB,mBAAmB;YAmBnB,YAAY;YAyIZ,UAAU;YAuCV,WAAW;YASX,qBAAqB;YAsBrB,eAAe;YAef,gBAAgB;YAqBhB,qBAAqB;IAYnC,OAAO,CAAC,kBAAkB;CAS1B"}
@@ -1,10 +1,12 @@
1
1
  import { readFile, writeFile } from "node:fs/promises";
2
2
  import { formatBuilderWorklog, formatVerifierWorklog } from "../integrations/linear/comment-templates.js";
3
+ import { buildSeedDescription } from "../integrations/linear/seed-description.js";
3
4
  import { clearCheckpoint, loadCheckpoint, saveCheckpoint, } from "./checkpoint.js";
4
5
  import { buildJudgePrompt, parseJudgeVerdict } from "./judge.js";
5
6
  import { appendLearning, readLearnings } from "./learnings.js";
6
7
  import { readPlan, verifyPlanUnchanged } from "./plan.js";
7
8
  import { evaluateTaskReadiness } from "./readiness-policy.js";
9
+ import { summarizeTasksSnapshot } from "./runtime-events.js";
8
10
  import { selectExecutionOrder } from "./scheduling-policy.js";
9
11
  import { createSubtasks, parseTasks, serializeTasks } from "./task-state.js";
10
12
  export class Orchestrator {
@@ -17,6 +19,8 @@ export class Orchestrator {
17
19
  config;
18
20
  deps;
19
21
  workDir;
22
+ runtimeHooks;
23
+ linearNeedsSeeding = false;
20
24
  constructor(options) {
21
25
  this.planPath = options.planPath;
22
26
  this.tasksPath = options.tasksPath;
@@ -24,6 +28,7 @@ export class Orchestrator {
24
28
  this.config = options.config;
25
29
  this.deps = options.deps;
26
30
  this.workDir = options.workDir ?? process.cwd();
31
+ this.runtimeHooks = options.runtimeHooks;
27
32
  }
28
33
  async run() {
29
34
  // Check for existing checkpoint
@@ -37,14 +42,27 @@ export class Orchestrator {
37
42
  this.phase = checkpoint.phase;
38
43
  this.cycle = checkpoint.cycle;
39
44
  this.planHash = checkpoint.planHash;
45
+ this.linearNeedsSeeding = checkpoint.linearNeedsSeeding ?? false;
40
46
  await this.deps.taskBackend.initializeCycle(this.cycle);
41
47
  await this.deps.taskBackend.applyCheckpointContext(checkpoint.backendContext);
42
48
  return this.executeFromPhase(checkpoint.phase);
43
49
  }
44
50
  log(message) {
51
+ this.emit({
52
+ type: "log",
53
+ scope: "orchestrator",
54
+ message,
55
+ timestamp: new Date().toISOString(),
56
+ });
57
+ if (this.runtimeHooks?.suppressConsoleLogs) {
58
+ return;
59
+ }
45
60
  const ts = new Date().toISOString().slice(11, 19);
46
61
  console.error(`[pi-loop ${ts}] ${message}`);
47
62
  }
63
+ emit(event) {
64
+ this.runtimeHooks?.onEvent?.(event);
65
+ }
48
66
  async executeFromPhase(startPhase) {
49
67
  // Phase execution order
50
68
  const phaseOrder = [
@@ -62,6 +80,12 @@ export class Orchestrator {
62
80
  for (let i = startIndex; i < phaseOrder.length; i++) {
63
81
  this.phase = phaseOrder[i];
64
82
  this.log(`cycle ${this.cycle} → phase: ${this.phase}`);
83
+ this.emit({
84
+ type: "phase",
85
+ phase: this.phase,
86
+ cycle: this.cycle,
87
+ timestamp: new Date().toISOString(),
88
+ });
65
89
  await this.saveCurrentCheckpoint();
66
90
  switch (this.phase) {
67
91
  case "init":
@@ -83,12 +107,24 @@ export class Orchestrator {
83
107
  const verdict = await this.phaseJudge();
84
108
  if (verdict.status === "done") {
85
109
  this.phase = "completed";
110
+ this.emit({
111
+ type: "phase",
112
+ phase: this.phase,
113
+ cycle: this.cycle,
114
+ timestamp: new Date().toISOString(),
115
+ });
86
116
  await this.saveCurrentCheckpoint();
87
117
  await clearCheckpoint(this.workDir);
88
118
  return verdict;
89
119
  }
90
120
  if (verdict.feedback.includes("DRIFT_STOP:")) {
91
121
  this.phase = "completed";
122
+ this.emit({
123
+ type: "phase",
124
+ phase: this.phase,
125
+ cycle: this.cycle,
126
+ timestamp: new Date().toISOString(),
127
+ });
92
128
  await this.saveCurrentCheckpoint();
93
129
  await clearCheckpoint(this.workDir);
94
130
  return verdict;
@@ -109,6 +145,12 @@ export class Orchestrator {
109
145
  testsPass: false,
110
146
  };
111
147
  this.phase = "completed";
148
+ this.emit({
149
+ type: "phase",
150
+ phase: this.phase,
151
+ cycle: this.cycle,
152
+ timestamp: new Date().toISOString(),
153
+ });
112
154
  await this.saveCurrentCheckpoint();
113
155
  await clearCheckpoint(this.workDir);
114
156
  return finalVerdict;
@@ -129,8 +171,13 @@ export class Orchestrator {
129
171
  }
130
172
  async phaseDecompose() {
131
173
  if (this.config.taskBackend === "linear") {
132
- this.log("decompose: skipped in linear backend mode");
133
- return;
174
+ const needs = (await this.deps.taskBackend.needsSeeding?.()) ?? false;
175
+ if (!needs) {
176
+ this.log("decompose: issues exist in linear, skipping");
177
+ return;
178
+ }
179
+ this.linearNeedsSeeding = true;
180
+ this.log("decompose: no active issues in linear, running decomposer to seed");
134
181
  }
135
182
  const plan = await readFile(this.planPath, "utf8");
136
183
  const learnings = await readLearnings(this.learningsPath);
@@ -185,7 +232,7 @@ Plan hash: ${this.planHash}`;
185
232
  this.log(`decomposer → ${verifyDoc.tasks.length} parseable tasks`);
186
233
  }
187
234
  async phaseReviewTasks() {
188
- if (this.config.taskBackend === "linear") {
235
+ if (this.config.taskBackend === "linear" && !this.linearNeedsSeeding) {
189
236
  this.log("review-tasks: skipped in linear backend mode");
190
237
  return;
191
238
  }
@@ -231,7 +278,7 @@ ${tasksContent}`;
231
278
  await writeFile(this.tasksPath, reviewedTasks, "utf8");
232
279
  }
233
280
  async phaseSubDecompose() {
234
- if (this.config.taskBackend === "linear") {
281
+ if (this.config.taskBackend === "linear" && !this.linearNeedsSeeding) {
235
282
  this.log("sub-decompose: skipped in linear backend mode");
236
283
  return;
237
284
  }
@@ -246,13 +293,12 @@ ${tasksContent}`;
246
293
  return !hasExistingSubtasks;
247
294
  });
248
295
  this.log(`sub-decompose: ${needsDecomp.length} tasks need decomposition (of ${doc.tasks.length} total)`);
249
- if (needsDecomp.length === 0)
250
- return;
251
- const learnings = await readLearnings(this.learningsPath);
252
- const agent = await this.deps.createAgentFn("decomposer", learnings);
253
- for (const task of needsDecomp) {
254
- this.log(`sub-decompose: breaking down ${task.id} "${task.title}"`);
255
- const prompt = `Break down task ${task.id}: "${task.title}" into smaller subtasks.
296
+ if (needsDecomp.length > 0) {
297
+ const learnings = await readLearnings(this.learningsPath);
298
+ const agent = await this.deps.createAgentFn("decomposer", learnings);
299
+ for (const task of needsDecomp) {
300
+ this.log(`sub-decompose: breaking down ${task.id} "${task.title}"`);
301
+ const prompt = `Break down task ${task.id}: "${task.title}" into smaller subtasks.
256
302
 
257
303
  CRITICAL: Your entire response must be ONLY the subtask definitions. No preamble or explanation.
258
304
 
@@ -275,15 +321,35 @@ Rules:
275
321
  - Each subtask must be completable in under 5 minutes
276
322
  - Include ALL fields: Estimate, Dependencies, Attempts, Cycle
277
323
  - Dependencies can reference other subtask IDs or parent task dependencies`;
278
- const subtasksMarkdown = await agent.run(prompt);
279
- const subtaskDoc = parseTasks(subtasksMarkdown);
280
- this.log(`sub-decompose: ${task.id} → ${subtaskDoc.tasks.length} parseable subtasks`);
281
- if (subtaskDoc.tasks.length > 0) {
282
- createSubtasks(doc, task.id, subtaskDoc.tasks);
324
+ const subtasksMarkdown = await agent.run(prompt);
325
+ const subtaskDoc = parseTasks(subtasksMarkdown);
326
+ this.log(`sub-decompose: ${task.id} → ${subtaskDoc.tasks.length} parseable subtasks`);
327
+ if (subtaskDoc.tasks.length > 0) {
328
+ createSubtasks(doc, task.id, subtaskDoc.tasks);
329
+ }
283
330
  }
331
+ this.log(`sub-decompose: final task count: ${doc.tasks.length}`);
332
+ await writeFile(this.tasksPath, serializeTasks(doc), "utf8");
333
+ }
334
+ if (this.linearNeedsSeeding) {
335
+ await this.seedLinearFromTasks();
336
+ this.linearNeedsSeeding = false;
284
337
  }
285
- this.log(`sub-decompose: final task count: ${doc.tasks.length}`);
286
- await writeFile(this.tasksPath, serializeTasks(doc), "utf8");
338
+ }
339
+ async seedLinearFromTasks() {
340
+ const tasksContent = await readFile(this.tasksPath, "utf8");
341
+ const doc = parseTasks(tasksContent);
342
+ const pending = doc.tasks.filter((t) => t.status === "pending");
343
+ if (pending.length === 0) {
344
+ this.log("seed-linear: no pending tasks to seed");
345
+ return;
346
+ }
347
+ const payload = pending.map((task) => ({
348
+ title: task.title,
349
+ description: buildSeedDescription(task),
350
+ }));
351
+ const count = (await this.deps.taskBackend.seedTasks?.(payload)) ?? 0;
352
+ this.log(`seed-linear: created ${count} issues in linear`);
287
353
  }
288
354
  async phaseExecute() {
289
355
  try {
@@ -294,6 +360,7 @@ Rules:
294
360
  const message = error instanceof Error ? error.message : String(error);
295
361
  this.log(`execute: reconcile failed: ${message}`);
296
362
  }
363
+ await this.emitTaskSummary("execute:start");
297
364
  const ready = await this.deps.taskBackend.getReadyTasks("coder");
298
365
  const scheduled = selectExecutionOrder(ready, {
299
366
  role: "coder",
@@ -313,6 +380,7 @@ Rules:
313
380
  else {
314
381
  this.log("execute: no ready issues in linear queue");
315
382
  }
383
+ await this.emitTaskSummary("execute:no-scheduled");
316
384
  return;
317
385
  }
318
386
  const eligible = [];
@@ -329,9 +397,12 @@ Rules:
329
397
  continue;
330
398
  }
331
399
  eligible.push(task);
400
+ if (eligible.length >= this.config.maxConcurrency)
401
+ break;
332
402
  }
333
403
  if (eligible.length === 0) {
334
404
  this.log("execute: no eligible tasks after DoR validation");
405
+ await this.emitTaskSummary("execute:no-eligible");
335
406
  return;
336
407
  }
337
408
  this.log(`execute: dispatching ${eligible.map((t) => t.id).join(", ")}`);
@@ -350,6 +421,7 @@ Rules:
350
421
  }
351
422
  if (dispatchable.length === 0) {
352
423
  this.log("execute: no dispatchable tasks after in-progress transitions");
424
+ await this.emitTaskSummary("execute:no-dispatchable");
353
425
  return;
354
426
  }
355
427
  // Dispatch to worker pool
@@ -381,10 +453,7 @@ Rules:
381
453
  }
382
454
  else {
383
455
  this.log(`execute: ${result.taskId} FAILED: ${result.output}`);
384
- if (result.output.startsWith("FILE_BUDGET_EXCEEDED:")) {
385
- await this.safeMarkNeedsDecision(result.taskId, result.output);
386
- }
387
- else {
456
+ {
388
457
  const verifierLog = formatVerifierWorklog({
389
458
  passed: false,
390
459
  checks: ["Worker review verdict FAIL"],
@@ -401,6 +470,7 @@ Rules:
401
470
  }
402
471
  }
403
472
  }
473
+ await this.emitTaskSummary("execute:after-results");
404
474
  }
405
475
  async phaseJudge() {
406
476
  const plan = await readFile(this.planPath, "utf8");
@@ -448,6 +518,7 @@ Rules:
448
518
  const state = {
449
519
  phase: this.phase,
450
520
  cycle: this.cycle,
521
+ linearNeedsSeeding: this.linearNeedsSeeding,
451
522
  planHash: this.planHash,
452
523
  planPath: this.planPath,
453
524
  tasksSnapshot,
@@ -456,6 +527,21 @@ Rules:
456
527
  };
457
528
  await saveCheckpoint(state, this.workDir);
458
529
  }
530
+ async emitTaskSummary(source) {
531
+ try {
532
+ const snapshot = await this.deps.taskBackend.snapshotForJudge();
533
+ this.emit({
534
+ type: "task-summary",
535
+ summary: summarizeTasksSnapshot(snapshot),
536
+ source,
537
+ timestamp: new Date().toISOString(),
538
+ });
539
+ }
540
+ catch (error) {
541
+ const message = error instanceof Error ? error.message : String(error);
542
+ this.log(`task-summary failed (${source}): ${message}`);
543
+ }
544
+ }
459
545
  async withBackendRetry(operation, label) {
460
546
  const maxAttempts = this.config.taskBackend === "linear" ? 3 : 1;
461
547
  let lastError;