@runfusion/fusion 0.77.0-beta.0 → 0.77.0-beta.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 (138) hide show
  1. package/dist/bin.js +387 -72
  2. package/dist/child-process-worker.js +2479 -2196
  3. package/dist/client/.vite/manifest.json +262 -262
  4. package/dist/client/assets/{AgentDetailView-0G9qFd4j.js → AgentDetailView-Dew3af1O.js} +1 -1
  5. package/dist/client/assets/{AgentPermissionPolicyEditor-BM68g7wo.js → AgentPermissionPolicyEditor-CxPQffiY.js} +1 -1
  6. package/dist/client/assets/{AgentsView-DkOUZWw4.js → AgentsView-Cr4LDGdt.js} +3 -3
  7. package/dist/client/assets/ChatView-cNYtYx05.js +13 -0
  8. package/dist/client/assets/{CommandCenter-DxRSFWNc.js → CommandCenter-DCC90LOP.js} +1 -1
  9. package/dist/client/assets/{DevServerView-DO-bqJFE.js → DevServerView-B5b520w6.js} +1 -1
  10. package/dist/client/assets/{DirectoryPicker-Cp2gddTE.js → DirectoryPicker-1JvRd5mC.js} +1 -1
  11. package/dist/client/assets/{DocumentsView-D0E-3G96.js → DocumentsView-ksK9f7xt.js} +1 -1
  12. package/dist/client/assets/{EvalsView-BoFVq5hw.js → EvalsView-a3LhgRSo.js} +1 -1
  13. package/dist/client/assets/{ExperimentalAgentOnboardingModal-CS1Sdogm.js → ExperimentalAgentOnboardingModal-vdVa8h7F.js} +1 -1
  14. package/dist/client/assets/{GoalsView-sybf7JY4.js → GoalsView-Dz2o91fd.js} +1 -1
  15. package/dist/client/assets/{InsightsView-nHa7aShn.js → InsightsView-De3R_46d.js} +1 -1
  16. package/dist/client/assets/{MemoryView-D0IG44za.js → MemoryView-Cagk2wZG.js} +1 -1
  17. package/dist/client/assets/{PiExtensionsManager-CU76weJe.js → PiExtensionsManager-C9JABO_4.js} +1 -1
  18. package/dist/client/assets/{PluginManager-DyT8XbcG.js → PluginManager-D2csmdQa.js} +1 -1
  19. package/dist/client/assets/{PullRequestView-CnxWUSen.js → PullRequestView-DT8vTeVi.js} +1 -1
  20. package/dist/client/assets/{ReportModal-CMrmMQjD.js → ReportModal-YMP6V4vu.js} +1 -1
  21. package/dist/client/assets/{ResearchView-BTytQSgy.js → ResearchView-cNsjYu8F.js} +1 -1
  22. package/dist/client/assets/{SecretsView-BuSH5J87.js → SecretsView-BAmf7KyS.js} +1 -1
  23. package/dist/client/assets/{SessionTerminal-D04kYRrT.js → SessionTerminal-BjGcxq22.js} +1 -1
  24. package/dist/client/assets/{SettingsModal-Dm-ngbRr.js → SettingsModal-C_9RiEI7.js} +1 -1
  25. package/dist/client/assets/{SettingsModal-xSLhH7Tr.js → SettingsModal-DLfy2e_5.js} +4 -4
  26. package/dist/client/assets/{SettingsTextareaRow-CHPgocEp.js → SettingsTextareaRow-D8RHSj8b.js} +1 -1
  27. package/dist/client/assets/{SetupWizardModal-y88aXNIQ.js → SetupWizardModal-DRJ96pHQ.js} +2 -2
  28. package/dist/client/assets/{SkillsView-CYyQW1Hv.js → SkillsView-DyeCwYit.js} +1 -1
  29. package/dist/client/assets/{WorkflowNodeEditor-hYeoz1X8.js → WorkflowNodeEditor-C5Jc9w_A.js} +3 -3
  30. package/dist/client/assets/{agent-import-generation-CjiYXzCr.js → agent-import-generation-SCPNeF25.js} +1 -1
  31. package/dist/client/assets/{agentsOrgChartLayout-C0UP_X3z.js → agentsOrgChartLayout-CqKtNCjy.js} +1 -1
  32. package/dist/client/assets/{architectureDiagram-3BPJPVTR-Dd6GPcqM.js → architectureDiagram-3BPJPVTR-Cz2HYn0b.js} +1 -1
  33. package/dist/client/assets/{blockDiagram-GPEHLZMM-CC6pLxlz.js → blockDiagram-GPEHLZMM-IimJVscG.js} +1 -1
  34. package/dist/client/assets/{c4Diagram-AAUBKEIU-DxMP_l6y.js → c4Diagram-AAUBKEIU-C-xii7zn.js} +1 -1
  35. package/dist/client/assets/channel-D-UHgx8G.js +1 -0
  36. package/dist/client/assets/{chunk-2J33WTMH-BKYToL43.js → chunk-2J33WTMH-DQ-9Xccu.js} +1 -1
  37. package/dist/client/assets/{chunk-4BX2VUAB-Bg6rjQb3.js → chunk-4BX2VUAB-DmdAX9Bx.js} +1 -1
  38. package/dist/client/assets/{chunk-55IACEB6-CPUwbbGa.js → chunk-55IACEB6-IF2bk5IL.js} +1 -1
  39. package/dist/client/assets/{chunk-727SXJPM-DScQBCvv.js → chunk-727SXJPM-AeYpIzVu.js} +1 -1
  40. package/dist/client/assets/{chunk-AQP2D5EJ-DbX7uaXK.js → chunk-AQP2D5EJ-DV942DD9.js} +1 -1
  41. package/dist/client/assets/{chunk-FMBD7UC4-DvYKea1c.js → chunk-FMBD7UC4-Bt_riVlZ.js} +1 -1
  42. package/dist/client/assets/{chunk-ND2GUHAM-CH-Tvw7w.js → chunk-ND2GUHAM-CbyjNbXR.js} +1 -1
  43. package/dist/client/assets/{chunk-QZHKN3VN-CbyEvOoM.js → chunk-QZHKN3VN-DqiRniYQ.js} +1 -1
  44. package/dist/client/assets/classDiagram-4FO5ZUOK-Do-8MdAc.js +1 -0
  45. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-Do-8MdAc.js +1 -0
  46. package/dist/client/assets/{cose-bilkent-S5V4N54A-BPB5fV3A.js → cose-bilkent-S5V4N54A-UCvthviL.js} +1 -1
  47. package/dist/client/assets/{dagre-BM42HDAG-CilYJ3rR.js → dagre-BM42HDAG-DnMlT1Oi.js} +1 -1
  48. package/dist/client/assets/{dashboard-view-dChSM_So.js → dashboard-view-C9D0aoRW.js} +1 -1
  49. package/dist/client/assets/dashboard-view-Cz0sp2Wl.js +1 -0
  50. package/dist/client/assets/{dashboard-view-DoLU6FxZ.js → dashboard-view-JysoyDRX.js} +1 -1
  51. package/dist/client/assets/{dashboard-view-DnVf3tmI.js → dashboard-view-myjM9tr8.js} +1 -1
  52. package/dist/client/assets/{diagram-2AECGRRQ-m9u1Qhyx.js → diagram-2AECGRRQ-BYFiqXGw.js} +1 -1
  53. package/dist/client/assets/{diagram-5GNKFQAL-DVr7Kf0N.js → diagram-5GNKFQAL-DZU3pSYq.js} +1 -1
  54. package/dist/client/assets/{diagram-KO2AKTUF-D7sgJDFx.js → diagram-KO2AKTUF-0ybdKuMm.js} +1 -1
  55. package/dist/client/assets/{diagram-LMA3HP47-DNKNDS6r.js → diagram-LMA3HP47-Rxbgnbsp.js} +1 -1
  56. package/dist/client/assets/{diagram-OG6HWLK6-1Bff4FWn.js → diagram-OG6HWLK6-BAU_hTeV.js} +1 -1
  57. package/dist/client/assets/{erDiagram-TEJ5UH35-DGua1UHN.js → erDiagram-TEJ5UH35-zr8HrwTt.js} +1 -1
  58. package/dist/client/assets/{flowDiagram-I6XJVG4X-UDfDtwsE.js → flowDiagram-I6XJVG4X-CrTw0iFw.js} +1 -1
  59. package/dist/client/assets/{folder-open-CteOypVk.js → folder-open-DnAlsXXn.js} +1 -1
  60. package/dist/client/assets/{ganttDiagram-6RSMTGT7-COdmD328.js → ganttDiagram-6RSMTGT7-CCORsxxz.js} +1 -1
  61. package/dist/client/assets/{gitGraphDiagram-PVQCEYII-SUSls7Kw.js → gitGraphDiagram-PVQCEYII-C07wWSjj.js} +1 -1
  62. package/dist/client/assets/index-B_z7OKl4.js +2818 -0
  63. package/dist/client/assets/index-DPo-IAb2.css +1 -0
  64. package/dist/client/assets/{infoDiagram-5YYISTIA-e_DloXj7.js → infoDiagram-5YYISTIA-hAeccD_4.js} +1 -1
  65. package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-DVWqihXg.js → ishikawaDiagram-YF4QCWOH-WLCzv-NH.js} +1 -1
  66. package/dist/client/assets/{journeyDiagram-JHISSGLW-BcPY-XP0.js → journeyDiagram-JHISSGLW-ClnasNhy.js} +1 -1
  67. package/dist/client/assets/{kanban-definition-UN3LZRKU-BCFG2Jle.js → kanban-definition-UN3LZRKU-CAuARhUz.js} +1 -1
  68. package/dist/client/assets/{mermaid.core-5yPje9Bi.js → mermaid.core-Bh02RvfX.js} +4 -4
  69. package/dist/client/assets/{mindmap-definition-RKZ34NQL-DDApeT3K.js → mindmap-definition-RKZ34NQL-KNTlbW4V.js} +1 -1
  70. package/dist/client/assets/{pieDiagram-4H26LBE5-N61_jyeP.js → pieDiagram-4H26LBE5-BouAfBEw.js} +1 -1
  71. package/dist/client/assets/{puzzle-BkaCP30D.js → puzzle-CC8Ur3Cy.js} +1 -1
  72. package/dist/client/assets/{quadrantDiagram-W4KKPZXB-C5qHiApF.js → quadrantDiagram-W4KKPZXB-wTdkCUJU.js} +1 -1
  73. package/dist/client/assets/{requirementDiagram-4Y6WPE33-C71okgzt.js → requirementDiagram-4Y6WPE33-BnjY4Tc_.js} +1 -1
  74. package/dist/client/assets/{sankeyDiagram-5OEKKPKP-B2iKyLjB.js → sankeyDiagram-5OEKKPKP-C-QsS08u.js} +1 -1
  75. package/dist/client/assets/{sequenceDiagram-3UESZ5HK-DfdoYKKk.js → sequenceDiagram-3UESZ5HK-DD36MILE.js} +1 -1
  76. package/dist/client/assets/{shield-alert-BNSeDB8l.js → shield-alert-DcXc56Fy.js} +1 -1
  77. package/dist/client/assets/{standing-instructions-template-pZtzo1lK.js → standing-instructions-template-BF5y1BLz.js} +1 -1
  78. package/dist/client/assets/{stateDiagram-AJRCARHV-lS-sUi12.js → stateDiagram-AJRCARHV-WTq1wQr1.js} +1 -1
  79. package/dist/client/assets/{stateDiagram-v2-BHNVJYJU-DXJNDrV9.js → stateDiagram-v2-BHNVJYJU-eILJdjII.js} +1 -1
  80. package/dist/client/assets/{timeline-definition-PNZ67QCA-CCwvX81K.js → timeline-definition-PNZ67QCA-PRNwI0NR.js} +1 -1
  81. package/dist/client/assets/{upload-CDovVbu2.js → upload-qH_64O-B.js} +1 -1
  82. package/dist/client/assets/{useDiscoveredSkillsCache-BYqP-afh.js → useDiscoveredSkillsCache-C-GPCNaO.js} +1 -1
  83. package/dist/client/assets/{users-CTqECGLo.js → users-D2UesRE4.js} +1 -1
  84. package/dist/client/assets/{vennDiagram-CIIHVFJN-DaiR5nv9.js → vennDiagram-CIIHVFJN-CG2Z4T4O.js} +1 -1
  85. package/dist/client/assets/{wardley-L42UT6IY-hA5IHyPW.js → wardley-L42UT6IY-gO_fGvF9.js} +1 -1
  86. package/dist/client/assets/{wardleyDiagram-YWT4CUSO-CILUNESc.js → wardleyDiagram-YWT4CUSO-BkyNpjUb.js} +1 -1
  87. package/dist/client/assets/{xychartDiagram-2RQKCTM6-72eNMmjz.js → xychartDiagram-2RQKCTM6-CMlZsiPq.js} +1 -1
  88. package/dist/client/index.html +2 -2
  89. package/dist/client/version.json +1 -1
  90. package/dist/droid-cli/package.json +1 -1
  91. package/dist/extension.js +345 -61
  92. package/dist/pi-claude-cli/package.json +1 -1
  93. package/dist/plugin-sdk/index.js +29 -2
  94. package/dist/plugins/fusion-plugin-acp-runtime/bundled.js +269 -16
  95. package/dist/plugins/fusion-plugin-acp-runtime/mcp-schema-server.cjs +171 -0
  96. package/dist/plugins/fusion-plugin-acp-runtime/package.json +1 -1
  97. package/dist/plugins/fusion-plugin-claude-runtime/bundled.js +29 -2
  98. package/dist/plugins/fusion-plugin-claude-runtime/package.json +1 -1
  99. package/dist/plugins/fusion-plugin-cli-printing-press/bundled.js +29 -2
  100. package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
  101. package/dist/plugins/fusion-plugin-compound-engineering/bundled.js +29 -2
  102. package/dist/plugins/fusion-plugin-compound-engineering/package.json +1 -1
  103. package/dist/plugins/fusion-plugin-cursor-runtime/bundled.js +29 -2
  104. package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
  105. package/dist/plugins/fusion-plugin-dependency-graph/bundled.js +29 -2
  106. package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
  107. package/dist/plugins/fusion-plugin-droid-runtime/bundled.js +29 -2
  108. package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
  109. package/dist/plugins/fusion-plugin-grok-runtime/bundled.js +29 -2
  110. package/dist/plugins/fusion-plugin-grok-runtime/package.json +1 -1
  111. package/dist/plugins/fusion-plugin-hermes-runtime/bundled.js +29 -2
  112. package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
  113. package/dist/plugins/fusion-plugin-linear-import/bundled.js +29 -2
  114. package/dist/plugins/fusion-plugin-linear-import/package.json +1 -1
  115. package/dist/plugins/fusion-plugin-omp-runtime/bundled.js +29 -2
  116. package/dist/plugins/fusion-plugin-omp-runtime/package.json +1 -1
  117. package/dist/plugins/fusion-plugin-openclaw-runtime/bundled.js +29 -2
  118. package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
  119. package/dist/plugins/fusion-plugin-paperclip-runtime/bundled.js +29 -2
  120. package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
  121. package/dist/plugins/fusion-plugin-quality/bundled.js +29 -2
  122. package/dist/plugins/fusion-plugin-quality/package.json +1 -1
  123. package/dist/plugins/fusion-plugin-reports/bundled.js +29 -2
  124. package/dist/plugins/fusion-plugin-reports/package.json +1 -1
  125. package/dist/plugins/fusion-plugin-roadmap/bundled.js +29 -2
  126. package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
  127. package/dist/plugins/fusion-plugin-todos/bundled.js +29 -2
  128. package/dist/plugins/fusion-plugin-todos/package.json +1 -1
  129. package/dist/plugins/fusion-plugin-whatsapp-chat/bundled.js +29 -2
  130. package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
  131. package/package.json +1 -1
  132. package/dist/client/assets/ChatView-BPSm2JIH.js +0 -13
  133. package/dist/client/assets/channel-DlCEMoEf.js +0 -1
  134. package/dist/client/assets/classDiagram-4FO5ZUOK-Bc92O8Ks.js +0 -1
  135. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-Bc92O8Ks.js +0 -1
  136. package/dist/client/assets/dashboard-view-BnGe8cWo.js +0 -1
  137. package/dist/client/assets/index-0ovTXt3t.css +0 -1
  138. package/dist/client/assets/index-DpCHwyiD.js +0 -2818
package/dist/extension.js CHANGED
@@ -16765,8 +16765,34 @@ function didFallBackToDefault(ir2) {
16765
16765
  async function resolveWorkflowIrForTaskWithProvenance(store, taskId, irCache, selectionCache) {
16766
16766
  let workflowId;
16767
16767
  try {
16768
- const selection = selectionCache?.has(taskId) ? selectionCache.get(taskId) : store.getTaskWorkflowSelectionAsync ? await store.getTaskWorkflowSelectionAsync(taskId) : store.getTaskWorkflowSelection(taskId);
16769
- if (!selectionCache?.has(taskId)) selectionCache?.set(taskId, selection);
16768
+ const isSelectionCached = selectionCache?.has(taskId) ?? false;
16769
+ let selection = isSelectionCached && selectionCache ? selectionCache.get(taskId) : void 0;
16770
+ if (!isSelectionCached) {
16771
+ let inflight;
16772
+ let coalesced = false;
16773
+ if (selectionCache) {
16774
+ inflight = inflightSelectionReads.get(selectionCache);
16775
+ if (!inflight) {
16776
+ inflight = /* @__PURE__ */ new Map();
16777
+ inflightSelectionReads.set(selectionCache, inflight);
16778
+ }
16779
+ const pending = inflight.get(taskId);
16780
+ if (pending) {
16781
+ selection = await pending;
16782
+ coalesced = true;
16783
+ }
16784
+ }
16785
+ if (!coalesced) {
16786
+ const readPromise = store.getTaskWorkflowSelectionAsync ? store.getTaskWorkflowSelectionAsync(taskId) : Promise.resolve(store.getTaskWorkflowSelection(taskId));
16787
+ if (inflight) inflight.set(taskId, readPromise);
16788
+ try {
16789
+ selection = await readPromise;
16790
+ } finally {
16791
+ inflight?.delete(taskId);
16792
+ }
16793
+ }
16794
+ selectionCache?.set(taskId, selection);
16795
+ }
16770
16796
  workflowId = selection?.workflowId;
16771
16797
  } catch {
16772
16798
  return { ir: defaultCodingWorkflowIr(), source: "default" };
@@ -16790,13 +16816,14 @@ async function isTaskTerminalNodeIdAsync(store, taskId, nodeId) {
16790
16816
  }
16791
16817
  return nodeId === "end";
16792
16818
  }
16793
- var FELL_BACK_TO_DEFAULT;
16819
+ var inflightSelectionReads, FELL_BACK_TO_DEFAULT;
16794
16820
  var init_workflow_ir_resolver = __esm({
16795
16821
  "../core/src/workflows/workflow-ir-resolver.ts"() {
16796
16822
  "use strict";
16797
16823
  init_builtin_workflows();
16798
16824
  init_workflow_ir();
16799
16825
  init_workflow_prompt_overrides();
16826
+ inflightSelectionReads = /* @__PURE__ */ new WeakMap();
16800
16827
  FELL_BACK_TO_DEFAULT = /* @__PURE__ */ Symbol.for("fusion.workflowIr.fellBackToDefault");
16801
16828
  }
16802
16829
  });
@@ -36417,9 +36444,12 @@ async function markApprovalRequestCompleted(layer, requestId, input) {
36417
36444
  });
36418
36445
  }
36419
36446
  async function getApprovalAuditHistory(handle2, requestId, projectId2) {
36420
- const rows = await handle2.select().from(project_exports.approvalRequestAuditEvents).where(and(eq(project_exports.approvalRequestAuditEvents.requestId, requestId), projectScopeFor(project_exports.approvalRequestAuditEvents.projectId, projectId2))).orderBy(
36421
- sql`${project_exports.approvalRequestAuditEvents.createdAt} ASC, ${project_exports.approvalRequestAuditEvents.id} ASC`
36422
- );
36447
+ const eventType = project_exports.approvalRequestAuditEvents.eventType;
36448
+ const lifecycleRank = sql`CASE ${eventType} ${sql.join(
36449
+ APPROVAL_REQUEST_AUDIT_EVENT_TYPES.map((type, rank) => sql`WHEN ${type} THEN ${rank}`),
36450
+ sql` `
36451
+ )} ELSE ${APPROVAL_REQUEST_AUDIT_EVENT_TYPES.length} END`;
36452
+ const rows = await handle2.select().from(project_exports.approvalRequestAuditEvents).where(and(eq(project_exports.approvalRequestAuditEvents.requestId, requestId), projectScopeFor(project_exports.approvalRequestAuditEvents.projectId, projectId2))).orderBy(sql`${project_exports.approvalRequestAuditEvents.createdAt} ASC, ${lifecycleRank} ASC, ${project_exports.approvalRequestAuditEvents.id} ASC`);
36423
36453
  return rows.map((row) => rowToAuditEvent(row));
36424
36454
  }
36425
36455
  var init_async_approval_request_store = __esm({
@@ -139941,17 +139971,40 @@ var init_auth_storage = __esm({
139941
139971
  async getApiKey(provider, instance) {
139942
139972
  return resolveStoredCredentialApiKey(provider, instance ? this.getInstance(instance) : this.get(provider));
139943
139973
  }
139974
+ /*
139975
+ FNXC:ProviderAuth 2026-08-18-04:40:
139976
+ MODIFY MUST BE ABLE TO CREATE. This is the seam pi persists a COMPLETED LOGIN through
139977
+ (`Models.login` -> `credentials.modify(provider.id, ...)` in pi-ai's models.js), not just the seam
139978
+ it refreshes an existing token through.
139979
+
139980
+ It used to resolve its write target with `creating: false` and then bail —
139981
+ `if (!target || !this.credential(target, current)) return { changed: false }` — whenever the
139982
+ provider had no credential row yet. The callback was never invoked, nothing was written, and pi's
139983
+ login resolved as a SUCCESS. So a first-ever login for a provider could not be saved: the browser
139984
+ flow completed, the token exchange succeeded, the lock file was taken and released, `auth.json`
139985
+ stayed `{}`, and the dashboard's poll saw `authenticated: false` and reported the useless "Login
139986
+ did not complete. Please try again."
139987
+
139988
+ It looked provider-specific and environment-specific for the worst possible reason: it only
139989
+ reproduces on a store with NO existing row, so every developer and every long-lived install — where
139990
+ a row already exists and this path is a plain refresh — works flawlessly, while every fresh install
139991
+ (a new container, a new machine, a wiped `~/.fusion`) can never complete its first login.
139992
+
139993
+ Create when absent, update when present. A callback returning undefined still writes nothing, so
139994
+ pi's refresh-bails-out behaviour is unchanged.
139995
+ */
139944
139996
  async modify(provider, fn2) {
139945
139997
  this.assertRefFromKey(provider);
139946
139998
  return this.withLock(async (current) => {
139947
- const target = this.resolveWriteTarget(provider, current, false);
139948
- if (!target || !this.credential(target, current)) return { result: void 0, changed: false };
139949
- const next = await fn2(this.credential(target, current));
139999
+ const target = this.resolveWriteTarget(provider, current, true);
140000
+ if (!target) return { result: void 0, changed: false };
140001
+ const existing = this.credential(target, current);
140002
+ const next = await fn2(existing);
139950
140003
  if (next !== void 0) {
139951
140004
  current[formatProviderInstanceKey(target)] = next;
139952
140005
  return { result: next, changed: true };
139953
140006
  }
139954
- return { result: this.credential(target, current), changed: false };
140007
+ return { result: existing, changed: false };
139955
140008
  });
139956
140009
  }
139957
140010
  getOAuthProviders() {
@@ -139964,11 +140017,24 @@ var init_auth_storage = __esm({
139964
140017
  if (!this.modelRuntime) throw new Error("OAuth login requires a ModelRuntime-backed Fusion auth storage");
139965
140018
  const executionProvider = toExecutionModelProviderId(provider);
139966
140019
  const legacy = callbacks;
139967
- const interaction = { signal: legacy.signal, prompt: async (prompt) => legacy.onPrompt?.({ message: prompt.message, placeholder: "placeholder" in prompt ? prompt.placeholder : void 0 }) ?? "", notify: (event) => {
139968
- if (event.type === "auth_url") legacy.onAuth?.({ url: event.url, instructions: event.instructions });
139969
- else if (event.type === "device_code") legacy.onDeviceCode?.(event);
139970
- else if (event.type === "progress") legacy.onProgress?.(event.message);
139971
- } };
140020
+ const interaction = {
140021
+ signal: legacy.signal,
140022
+ prompt: async (prompt) => {
140023
+ if (prompt.type === "select") {
140024
+ const chosen = await legacy.onSelect?.({ message: prompt.message, options: prompt.options });
140025
+ return chosen ?? prompt.options[0]?.id ?? "";
140026
+ }
140027
+ if (prompt.type === "manual_code" && legacy.onManualCodeInput) {
140028
+ return await legacy.onManualCodeInput();
140029
+ }
140030
+ return await legacy.onPrompt?.({ message: prompt.message, placeholder: "placeholder" in prompt ? prompt.placeholder : void 0 }) ?? "";
140031
+ },
140032
+ notify: (event) => {
140033
+ if (event.type === "auth_url") legacy.onAuth?.({ url: event.url, instructions: event.instructions });
140034
+ else if (event.type === "device_code") legacy.onDeviceCode?.(event);
140035
+ else if (event.type === "progress") legacy.onProgress?.(event.message);
140036
+ }
140037
+ };
139972
140038
  await this.modelRuntime.login(executionProvider, "oauth", interaction);
139973
140039
  this.reload();
139974
140040
  }
@@ -143643,7 +143709,8 @@ var init_runtime_resolution = __esm({
143643
143709
  const result2 = await createFnAgent2({
143644
143710
  ...agentOptions,
143645
143711
  toolOutputMaxChars,
143646
- mcpServers: normalizeAgentRuntimeMcpServers(mcpServers)
143712
+ mcpServers: normalizeAgentRuntimeMcpServers(mcpServers),
143713
+ __rawPiSession: true
143647
143714
  });
143648
143715
  return {
143649
143716
  ...result2,
@@ -144833,6 +144900,7 @@ var init_agent_session_helpers = __esm({
144833
144900
  init_runtime_resolution();
144834
144901
  init_logger3();
144835
144902
  init_pi();
144903
+ init_pi();
144836
144904
  init_auth_storage();
144837
144905
  init_mock_provider();
144838
144906
  init_cli_provider_routing();
@@ -144840,6 +144908,12 @@ var init_agent_session_helpers = __esm({
144840
144908
  sessionLog = createLogger2("agent-session");
144841
144909
  mockRuntimeSingleton = new MockAgentRuntime();
144842
144910
  RUNTIMES_WITH_INTERNAL_TOOL_GATING = /* @__PURE__ */ new Set(["pi"]);
144911
+ try {
144912
+ registerRoutedAgentSessionFactory?.(
144913
+ createResolvedAgentSession
144914
+ );
144915
+ } catch {
144916
+ }
144843
144917
  }
144844
144918
  });
144845
144919
 
@@ -166386,7 +166460,49 @@ function withMcpPromptOptions(promptOptions, mcpServers) {
166386
166460
  }
166387
166461
  return { mcpServers };
166388
166462
  }
166463
+ function agentPluginRunnerRegistry() {
166464
+ return defaultAgentPluginRunners ??= /* @__PURE__ */ new Map();
166465
+ }
166466
+ function registerRoutedAgentSessionFactory(factory) {
166467
+ routedAgentSessionFactory = factory;
166468
+ }
166469
+ function registerDefaultAgentPluginRunner(rootDir, pluginRunner) {
166470
+ agentPluginRunnerRegistry().set(rootDir, pluginRunner);
166471
+ }
166472
+ function unregisterDefaultAgentPluginRunner(rootDir) {
166473
+ agentPluginRunnerRegistry().delete(rootDir);
166474
+ }
166475
+ function resolveDefaultAgentPluginRunner(cwd) {
166476
+ const registry3 = agentPluginRunnerRegistry();
166477
+ if (registry3.size === 0) return void 0;
166478
+ if (cwd) {
166479
+ let best;
166480
+ for (const [rootDir, runner] of registry3) {
166481
+ if ((cwd === rootDir || cwd.startsWith(`${rootDir}/`)) && (!best || rootDir.length > best.rootDir.length)) {
166482
+ best = { rootDir, runner };
166483
+ }
166484
+ }
166485
+ if (best) return best.runner;
166486
+ }
166487
+ if (registry3.size === 1) {
166488
+ return registry3.values().next().value;
166489
+ }
166490
+ return void 0;
166491
+ }
166389
166492
  async function createFnAgent2(options) {
166493
+ const { __rawPiSession, ...routableOptions } = options;
166494
+ if (!__rawPiSession && routedAgentSessionFactory) {
166495
+ const optionsWithRouting = routableOptions;
166496
+ const pluginRunner = optionsWithRouting.pluginRunner ?? resolveDefaultAgentPluginRunner(routableOptions.cwd);
166497
+ return routedAgentSessionFactory({
166498
+ ...routableOptions,
166499
+ sessionPurpose: routableOptions.sessionPurpose ?? "executor",
166500
+ ...pluginRunner ? { pluginRunner } : {}
166501
+ });
166502
+ }
166503
+ return createPiAgentSessionRaw(routableOptions);
166504
+ }
166505
+ async function createPiAgentSessionRaw(options) {
166390
166506
  piLog.debug(`createFnAgent called (tools=${options.tools}, provider=${options.defaultProvider}, model=${options.defaultModelId})`);
166391
166507
  const requestedMcpServers = options.mcpServers ?? [];
166392
166508
  const forwardedMcpServers = runtimeSupportsMcp("pi", options.defaultProvider) ? requestedMcpServers : [];
@@ -166943,7 +167059,7 @@ async function createFnAgent2(options) {
166943
167059
  settleFallbackDispatch: async () => void 0
166944
167060
  };
166945
167061
  }
166946
- var execAsync, RTK_ACCEPTED_REWRITE_EXIT_CODES, RTK_EXPECTED_PASSTHROUGH_EXIT_CODES, RTK_EXPECTED_FAIL_OPEN_ERROR_CODES, RTK_REWRITE_MAX_BUFFER_BYTES, hostExtensionPaths, FN_MEMORY_APPEND_TOOL_NAME, FUSION_SHUTDOWN_WRAP_FLAG, promptWithFallbackInFlight, COMPACTION_FALLBACK_INSTRUCTIONS, MAX_COMPACTED_PROMPT_MEMORY_CHARS, MAX_COMPACTED_SUBTASK_GUIDANCE_CHARS, MAX_COMPACTED_ATTACHMENTS_CHARS, MAX_COMPACTED_EXISTING_SPEC_CHARS, MAX_COMPACTED_TASK_PROMPT_CHARS, MAX_COMPACTED_USER_COMMENTS_CHARS, ModelFallbackExhaustedError, GATE_BYPASS_TOOL_NAMES, TOOL_OUTPUT_BUDGET_OVERRIDES;
167062
+ var execAsync, RTK_ACCEPTED_REWRITE_EXIT_CODES, RTK_EXPECTED_PASSTHROUGH_EXIT_CODES, RTK_EXPECTED_FAIL_OPEN_ERROR_CODES, RTK_REWRITE_MAX_BUFFER_BYTES, hostExtensionPaths, FN_MEMORY_APPEND_TOOL_NAME, FUSION_SHUTDOWN_WRAP_FLAG, promptWithFallbackInFlight, COMPACTION_FALLBACK_INSTRUCTIONS, MAX_COMPACTED_PROMPT_MEMORY_CHARS, MAX_COMPACTED_SUBTASK_GUIDANCE_CHARS, MAX_COMPACTED_ATTACHMENTS_CHARS, MAX_COMPACTED_EXISTING_SPEC_CHARS, MAX_COMPACTED_TASK_PROMPT_CHARS, MAX_COMPACTED_USER_COMMENTS_CHARS, ModelFallbackExhaustedError, GATE_BYPASS_TOOL_NAMES, TOOL_OUTPUT_BUDGET_OVERRIDES, routedAgentSessionFactory, defaultAgentPluginRunners;
166947
167063
  var init_pi = __esm({
166948
167064
  "../engine/src/pi.ts"() {
166949
167065
  "use strict";
@@ -177621,9 +177737,9 @@ function mergeParkedColumns(base, lanes) {
177621
177737
  terminal: /* @__PURE__ */ new Set([...base.terminal, ...lanes.terminal ?? [], complete, archived])
177622
177738
  };
177623
177739
  }
177624
- async function resolveTaskParkedColumns(store, taskId) {
177740
+ async function resolveTaskParkedColumns(store, taskId, selectionCache) {
177625
177741
  try {
177626
- const ir2 = await resolveWorkflowIrForTask(store, taskId);
177742
+ const ir2 = await resolveWorkflowIrForTask(store, taskId, void 0, selectionCache);
177627
177743
  const l = resolveLifecycleColumns(ir2);
177628
177744
  const complete = l?.complete ?? LEGACY_PARKED_COLUMNS2.complete;
177629
177745
  const archived = l?.archived ?? LEGACY_PARKED_COLUMNS2.archived;
@@ -177868,6 +177984,7 @@ var init_scheduler = __esm({
177868
177984
  }
177869
177985
  });
177870
177986
  this.store.on("task:moved", async ({ task, from, to: to2, source, lanes }) => {
177987
+ const movedSelectionCache = /* @__PURE__ */ new Map();
177871
177988
  this.lastAutoClaimFingerprint.set(task.id, computeAutoClaimFingerprint(task));
177872
177989
  const parked = mergeParkedColumns(LEGACY_PARKED_COLUMNS2, lanes);
177873
177990
  if (from === parked.hold || to2 === parked.hold) {
@@ -177923,7 +178040,7 @@ var init_scheduler = __esm({
177923
178040
  });
177924
178041
  }
177925
178042
  }
177926
- const resolvedParked = mergeParkedColumns(await resolveTaskParkedColumns(this.store, task.id), lanes);
178043
+ const resolvedParked = mergeParkedColumns(await resolveTaskParkedColumns(this.store, task.id, movedSelectionCache), lanes);
177927
178044
  if (resolvedParked.terminal.has(to2)) {
177928
178045
  try {
177929
178046
  const settings = await this.store.getSettings();
@@ -177989,6 +178106,7 @@ var init_scheduler = __esm({
177989
178106
  }
177990
178107
  });
177991
178108
  this.store.on("task:updated", (task, meta2) => {
178109
+ const updatedSelectionCache = /* @__PURE__ */ new Map();
177992
178110
  const nextFingerprint = computeAutoClaimFingerprint(task);
177993
178111
  const previousFingerprint = this.lastAutoClaimFingerprint.get(task.id);
177994
178112
  if (!previousFingerprint || previousFingerprint !== nextFingerprint) {
@@ -178019,7 +178137,7 @@ var init_scheduler = __esm({
178019
178137
  });
178020
178138
  }
178021
178139
  void (async () => {
178022
- const unpausedParked = await resolveTaskParkedColumns(this.store, task.id);
178140
+ const unpausedParked = await resolveTaskParkedColumns(this.store, task.id, updatedSelectionCache);
178023
178141
  if (this.running && unpausedParked.wake.has(task.column)) {
178024
178142
  schedulerLog.log(`Task ${task.id} unpaused \u2014 triggering scheduling`);
178025
178143
  void this.schedule();
@@ -178031,7 +178149,7 @@ var init_scheduler = __esm({
178031
178149
  } else if (this.planningTaskIds.has(task.id)) {
178032
178150
  this.planningTaskIds.delete(task.id);
178033
178151
  void (async () => {
178034
- const planningParked = await resolveTaskParkedColumns(this.store, task.id);
178152
+ const planningParked = await resolveTaskParkedColumns(this.store, task.id, updatedSelectionCache);
178035
178153
  if (this.running && !task.status && !task.paused && !task.userPaused && planningParked.wake.has(task.column)) {
178036
178154
  schedulerLog.log(`Task ${task.id} finished planning \u2014 triggering scheduling`);
178037
178155
  void this.schedule();
@@ -178044,7 +178162,7 @@ var init_scheduler = __esm({
178044
178162
  } else if (!task.status && !task.paused && !task.userPaused && (this.approvalHeldTaskIds.delete(task.id) || (Boolean(task.approvedPlanFingerprint) || task.workflowStepResults?.some(isPlanReviewSatisfied) === true) && !this.approvalReleasedTaskIds.has(task.id))) {
178045
178163
  this.approvalReleasedTaskIds.add(task.id);
178046
178164
  void (async () => {
178047
- const approvalParked = await resolveTaskParkedColumns(this.store, task.id);
178165
+ const approvalParked = await resolveTaskParkedColumns(this.store, task.id, updatedSelectionCache);
178048
178166
  if (this.running && !task.status && !task.paused && !task.userPaused && approvalParked.wake.has(task.column)) {
178049
178167
  schedulerLog.log(`Task ${task.id} plan approval cleared \u2014 triggering scheduling`);
178050
178168
  void this.schedule();
@@ -178083,7 +178201,8 @@ var init_scheduler = __esm({
178083
178201
  if (settings.globalPause || settings.enginePaused) {
178084
178202
  return;
178085
178203
  }
178086
- const deletedParked = await resolveTaskParkedColumns(this.store, task.id);
178204
+ const deletedSelectionCache = /* @__PURE__ */ new Map();
178205
+ const deletedParked = await resolveTaskParkedColumns(this.store, task.id, deletedSelectionCache);
178087
178206
  const deletedWipColumns = await resolveProjectColumnsForRoles(this.store, ["countsTowardWip"]);
178088
178207
  const todoTasks = await this.store.listTasks({ column: deletedParked.hold, slim: true });
178089
178208
  const inProgressById = /* @__PURE__ */ new Map();
@@ -178292,7 +178411,16 @@ var init_scheduler = __esm({
178292
178411
  }
178293
178412
  }
178294
178413
  async transitionQueuedEpisode(task, input) {
178295
- return (await this.store.transitionQueuedEpisode(task.id, input)).appended;
178414
+ if (typeof this.store.transitionQueuedEpisode === "function") {
178415
+ return (await this.store.transitionQueuedEpisode(task.id, input)).appended;
178416
+ }
178417
+ await this.store.updateTask(task.id, {
178418
+ status: "queued",
178419
+ blockedBy: input.blockedBy ?? null,
178420
+ overlapBlockedBy: input.overlapBlockedBy ?? null
178421
+ });
178422
+ await this.logDispatchQueuedReason(task.id, input.action);
178423
+ return true;
178296
178424
  }
178297
178425
  async logDispatchQueuedReason(taskId, reason, memoKey) {
178298
178426
  const key = `${taskId}:${memoKey ?? reason}`;
@@ -178344,13 +178472,14 @@ var init_scheduler = __esm({
178344
178472
  }
178345
178473
  async emitHighOverlapFanoutWarnings(tasks2) {
178346
178474
  const escalationIrCache = /* @__PURE__ */ new Map();
178475
+ const escalationSelectionCache = /* @__PURE__ */ new Map();
178347
178476
  const escalationByTaskId = /* @__PURE__ */ new Map();
178348
178477
  const escalationColumns = /* @__PURE__ */ new Set();
178349
178478
  const holdByTaskId = /* @__PURE__ */ new Map();
178350
178479
  const terminalByTaskId = /* @__PURE__ */ new Map();
178351
178480
  const blockerReviewColumns = /* @__PURE__ */ new Set();
178352
178481
  for (const task of tasks2) {
178353
- const ir2 = await resolveWorkflowIrForTask(this.store, task.id, escalationIrCache).catch(() => void 0);
178482
+ const ir2 = await resolveWorkflowIrForTask(this.store, task.id, escalationIrCache, escalationSelectionCache).catch(() => void 0);
178354
178483
  if (!ir2) continue;
178355
178484
  for (const id of columnsWithFlag(ir2, "countsTowardWip")) escalationColumns.add(id);
178356
178485
  for (const id of columnsWithFlag(ir2, "mergeOrchestration")) escalationColumns.add(id);
@@ -178420,9 +178549,10 @@ var init_scheduler = __esm({
178420
178549
  if (!agentStore) return;
178421
178550
  const runningAgents = await agentStore.listAgents({ state: "running", includeEphemeral: false });
178422
178551
  const linkedAgents = runningAgents.filter((agent) => agent.taskId === taskId);
178552
+ const rollbackSelectionCache = /* @__PURE__ */ new Map();
178423
178553
  for (const agent of linkedAgents) {
178424
178554
  const activeRun = await agentStore.getActiveHeartbeatRun?.(agent.id);
178425
- const rollbackParked = await resolveTaskParkedColumns(this.store, taskId);
178555
+ const rollbackParked = await resolveTaskParkedColumns(this.store, taskId, rollbackSelectionCache);
178426
178556
  const proof = evaluateParkedAgentTaskLink({
178427
178557
  agent,
178428
178558
  linkedTask: { column: rollbackParked.hold },
@@ -178470,11 +178600,12 @@ var init_scheduler = __esm({
178470
178600
  const repo = getCurrentRepo(this.store.getRootDir());
178471
178601
  if (!repo) return;
178472
178602
  const hydrationIrCache = /* @__PURE__ */ new Map();
178603
+ const hydrationSelectionCache = /* @__PURE__ */ new Map();
178473
178604
  for (const task of tasks2) {
178474
178605
  if (!task.prInfo) continue;
178475
178606
  let flags;
178476
178607
  try {
178477
- const ir2 = await resolveWorkflowIrForTask(this.store, task.id, hydrationIrCache);
178608
+ const ir2 = await resolveWorkflowIrForTask(this.store, task.id, hydrationIrCache, hydrationSelectionCache);
178478
178609
  const column = ir2.columns?.find((candidate) => candidate.id === task.column);
178479
178610
  if (column) flags = resolveColumnFlags(column);
178480
178611
  } catch {
@@ -179403,19 +179534,20 @@ var init_scheduler = __esm({
179403
179534
  return;
179404
179535
  }
179405
179536
  const sliceIdBeforeUpdate = feature.sliceId;
179406
- const featureSlice = await missionStore.getSlice(feature.sliceId);
179407
- const milestone = featureSlice ? await missionStore.getMilestone(featureSlice.milestoneId) : void 0;
179408
- const missionId = task.missionId ?? milestone?.missionId;
179409
- if (!missionId) {
179410
- schedulerLog.warn(`Task ${taskId} feature ${feature.id} has no resolvable mission; skipping reconciliation`);
179411
- return;
179412
- }
179413
- if (missionId !== task.missionId) {
179414
- try {
179537
+ let missionId = task.missionId;
179538
+ try {
179539
+ if (!missionId && typeof missionStore.getSlice === "function") {
179540
+ const featureSlice = await missionStore.getSlice(feature.sliceId);
179541
+ const milestone = featureSlice && typeof missionStore.getMilestone === "function" ? await missionStore.getMilestone(featureSlice.milestoneId) : void 0;
179542
+ missionId = milestone?.missionId;
179543
+ }
179544
+ if (!missionId) {
179545
+ schedulerLog.warn(`Task ${taskId} feature ${feature.id} has no resolvable mission; skipping reconciliation`);
179546
+ } else if (missionId !== task.missionId) {
179415
179547
  await reconcileMissionState({ taskStore: this.store, missionStore }, { missionId, source: "task-move" });
179416
- } catch (error3) {
179417
- schedulerLog.warn(`Mission reconciliation failed after resolving task ${taskId}; continuing mission completion handling:`, error3);
179418
179548
  }
179549
+ } catch (error3) {
179550
+ schedulerLog.warn(`Task ${taskId} feature ${feature.id} mission reconcile skipped (${String(error3)}); continuing to completion check`);
179419
179551
  }
179420
179552
  let completionFlags;
179421
179553
  try {
@@ -187084,7 +187216,6 @@ var init_notifier = __esm({
187084
187216
  }
187085
187217
  notifyGridlock(event) {
187086
187218
  if (event === null) {
187087
- this.lastGridlockNotificationAt = null;
187088
187219
  return;
187089
187220
  }
187090
187221
  if (!this.config.enabled || !this.config.topic || !this.isEventEnabled("gridlock")) return;
@@ -197900,6 +198031,63 @@ var init_agent_user_comments = __esm({
197900
198031
  }
197901
198032
  });
197902
198033
 
198034
+ // ../engine/src/git-identity.ts
198035
+ function slugifyAgentEmailLocalPart(value) {
198036
+ return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64);
198037
+ }
198038
+ function resolveCommitIdentity(input = {}) {
198039
+ const { agent, settings } = input;
198040
+ if (settings?.commitAuthorEnabled === false) {
198041
+ return void 0;
198042
+ }
198043
+ const configuredName = settings?.commitAuthorName?.trim();
198044
+ const configuredEmail = settings?.commitAuthorEmail?.trim();
198045
+ if (configuredName && configuredEmail) {
198046
+ return { name: configuredName, email: configuredEmail };
198047
+ }
198048
+ const agentName = agent?.name?.trim() || agent?.id?.trim() || "";
198049
+ if (agentName) {
198050
+ const localPart = slugifyAgentEmailLocalPart(agentName);
198051
+ if (localPart) {
198052
+ return {
198053
+ name: configuredName || `${agentName} (Fusion)`,
198054
+ email: configuredEmail || `${localPart}@agents.fusion.local`
198055
+ };
198056
+ }
198057
+ }
198058
+ return {
198059
+ name: configuredName || FUSION_FALLBACK_IDENTITY.name,
198060
+ email: configuredEmail || FUSION_FALLBACK_IDENTITY.email
198061
+ };
198062
+ }
198063
+ function commitIdentityEnv(identity) {
198064
+ if (!identity) {
198065
+ return {};
198066
+ }
198067
+ return {
198068
+ GIT_AUTHOR_NAME: identity.name,
198069
+ GIT_AUTHOR_EMAIL: identity.email,
198070
+ GIT_COMMITTER_NAME: identity.name,
198071
+ GIT_COMMITTER_EMAIL: identity.email
198072
+ };
198073
+ }
198074
+ function commitIdentityArgs(identity) {
198075
+ if (!identity) {
198076
+ return [];
198077
+ }
198078
+ return ["-c", `user.name=${identity.name}`, "-c", `user.email=${identity.email}`];
198079
+ }
198080
+ var FUSION_FALLBACK_IDENTITY;
198081
+ var init_git_identity = __esm({
198082
+ "../engine/src/git-identity.ts"() {
198083
+ "use strict";
198084
+ FUSION_FALLBACK_IDENTITY = {
198085
+ name: "Fusion",
198086
+ email: "noreply@runfusion.ai"
198087
+ };
198088
+ }
198089
+ });
198090
+
197903
198091
  // ../engine/src/sandbox/bubblewrap-detect.ts
197904
198092
  import { exec as exec20 } from "node:child_process";
197905
198093
  import { promisify as promisify30 } from "node:util";
@@ -203137,8 +203325,12 @@ import { createHash as createHash29 } from "node:crypto";
203137
203325
  import { join as join73, resolve as resolve44 } from "node:path";
203138
203326
  import { hostname as hostname3 } from "node:os";
203139
203327
  import { Type as Type4 } from "typebox";
203140
- function mergerCommitEnv() {
203141
- return { ...process.env, [IDENTITY_GUARD_BYPASS_ENV]: "1" };
203328
+ function mergerCommitEnv(identity) {
203329
+ return {
203330
+ ...process.env,
203331
+ [IDENTITY_GUARD_BYPASS_ENV]: "1",
203332
+ ...commitIdentityEnv(identity ?? resolveCommitIdentity())
203333
+ };
203142
203334
  }
203143
203335
  async function resolveMergerLifecycleColumn(store, taskId, which) {
203144
203336
  const fallback = which === "complete" ? "done" : which === "merge" ? "in-review" : "todo";
@@ -211114,6 +211306,7 @@ var init_merger = __esm({
211114
211306
  init_worktree_hooks();
211115
211307
  init_effective_settings();
211116
211308
  init_agent_user_comments();
211309
+ init_git_identity();
211117
211310
  init_verification_utils();
211118
211311
  init_sandbox();
211119
211312
  init_verification_utils();
@@ -211309,7 +211502,7 @@ function hasTerminalInvalidDoneTransition(task) {
211309
211502
  function isPrincipalHeldPlanningStatusOwned(status) {
211310
211503
  return status === null || status === void 0;
211311
211504
  }
211312
- var log34, worktreeMetadataReconcileLog, yieldEventLoop2, DONE_TASK_INTEGRITY_SWEEP_LIMIT, BOARD_STALL_NOTIFICATION_COOLDOWN_MS, DB_CORRUPTION_NOTIFICATION_COOLDOWN_MS, PHANTOM_EXECUTOR_BINDING_AGE_MULTIPLIER, MAX_NO_PROGRESS_RESUME_ATTEMPTS, PRE_EXECUTION_WORKTREE_MAX_IDLE_MS, APPROVED_TRIAGE_RECOVERY_GRACE_MS, STARVED_REFINEMENT_RECOVERY_GRACE_MS, STARVED_PEER_PROGRESS_THRESHOLD, STARVED_REFINEMENT_ESCALATION_COOLDOWN_MS, ORPHANED_EXECUTION_RECOVERY_GRACE_MS, STALLED_CARD_WATCHDOG_MS, LEAKED_WORKTREE_SLOT_GRACE_MS, NON_TERMINAL_STEP_STATUSES2, STRANDED_COMPLETED_TODO_ACTIVE_STATUSES, GHOST_REVIEW_PRESERVED_STATUSES, ORPHANED_WITH_WORKTREE_GRACE_MS, MAX_TASK_DONE_RETRIES, RECONCILE_SCOPE_OVERRIDE_MERGE_ACTIVE_STATUS_SET, MAX_STARVATION_DROPS, TERMINAL_WORKSPACE_WORKTREE_TEARDOWN_MIN_IDLE_MS, DEADLOCK_RECOVERY_COOLDOWN_MS, DEFAULT_STALE_MERGING_FANOUT_MIN_AGE_MS, DEFAULT_UNBACKED_MERGING_FANOUT_GRACE_MS, DURABLE_ERROR_RECOVERY_BASE_COOLDOWN_MS, DURABLE_ERROR_RECOVERY_MAX_COOLDOWN_MS, RUNNING_ON_INACTIVE_TASK_STALE_RUN_MS, UNREADABLE_WORKFLOW_SELECTION, SelfHealingManager;
211505
+ var log34, worktreeMetadataReconcileLog, yieldEventLoop2, DONE_METADATA_REPAIR_CAP, DONE_TASK_INTEGRITY_SWEEP_LIMIT, GIT_WORKTREE_CHURN_INTERVAL_MS, BOARD_STALL_NOTIFICATION_COOLDOWN_MS, DB_CORRUPTION_NOTIFICATION_COOLDOWN_MS, PHANTOM_EXECUTOR_BINDING_AGE_MULTIPLIER, MAX_NO_PROGRESS_RESUME_ATTEMPTS, PRE_EXECUTION_WORKTREE_MAX_IDLE_MS, APPROVED_TRIAGE_RECOVERY_GRACE_MS, STARVED_REFINEMENT_RECOVERY_GRACE_MS, STARVED_PEER_PROGRESS_THRESHOLD, STARVED_REFINEMENT_ESCALATION_COOLDOWN_MS, ORPHANED_EXECUTION_RECOVERY_GRACE_MS, STALLED_CARD_WATCHDOG_MS, LEAKED_WORKTREE_SLOT_GRACE_MS, NON_TERMINAL_STEP_STATUSES2, STRANDED_COMPLETED_TODO_ACTIVE_STATUSES, GHOST_REVIEW_PRESERVED_STATUSES, ORPHANED_WITH_WORKTREE_GRACE_MS, MAX_TASK_DONE_RETRIES, RECONCILE_SCOPE_OVERRIDE_MERGE_ACTIVE_STATUS_SET, MAX_STARVATION_DROPS, TERMINAL_WORKSPACE_WORKTREE_TEARDOWN_MIN_IDLE_MS, DEADLOCK_RECOVERY_COOLDOWN_MS, DEFAULT_STALE_MERGING_FANOUT_MIN_AGE_MS, DEFAULT_UNBACKED_MERGING_FANOUT_GRACE_MS, DURABLE_ERROR_RECOVERY_BASE_COOLDOWN_MS, DURABLE_ERROR_RECOVERY_MAX_COOLDOWN_MS, RUNNING_ON_INACTIVE_TASK_STALE_RUN_MS, UNREADABLE_WORKFLOW_SELECTION, SelfHealingManager;
211313
211506
  var init_self_healing = __esm({
211314
211507
  "../engine/src/self-healing.ts"() {
211315
211508
  "use strict";
@@ -211372,7 +211565,9 @@ var init_self_healing = __esm({
211372
211565
  log34 = createLogger2("self-healing");
211373
211566
  worktreeMetadataReconcileLog = createLogger2("worktree-metadata-reconcile");
211374
211567
  yieldEventLoop2 = () => new Promise((resolve61) => setImmediateCb2(resolve61));
211568
+ DONE_METADATA_REPAIR_CAP = 25;
211375
211569
  DONE_TASK_INTEGRITY_SWEEP_LIMIT = 50;
211570
+ GIT_WORKTREE_CHURN_INTERVAL_MS = 60 * 60 * 1e3;
211376
211571
  BOARD_STALL_NOTIFICATION_COOLDOWN_MS = 60 * 6e4;
211377
211572
  DB_CORRUPTION_NOTIFICATION_COOLDOWN_MS = 60 * 60 * 1e3;
211378
211573
  PHANTOM_EXECUTOR_BINDING_AGE_MULTIPLIER = 3;
@@ -211428,7 +211623,10 @@ var init_self_healing = __esm({
211428
211623
  lastUnpauseAt = 0;
211429
211624
  // ── Maintenance timer ───────────────────────────────────────────────
211430
211625
  maintenanceInterval = null;
211626
+ maintenanceStarting = false;
211431
211627
  maintenanceRunning = false;
211628
+ /** Last wall-clock a batch-1 git-churn pass ran on this manager (coarse-cadence gate). */
211629
+ lastGitWorktreeChurnAt = 0;
211432
211630
  /** In-process belt only; the durable apply token remains the cross-process fence. */
211433
211631
  autoRecoverTerminalFailuresInFlight = false;
211434
211632
  // ── Event listener cleanup ──────────────────────────────────────────
@@ -212326,6 +212524,7 @@ var init_self_healing = __esm({
212326
212524
  }
212327
212525
  // ── Auto-unpause ───────────────────────────────────────────────────
212328
212526
  onSettingsUpdated(settings, previous) {
212527
+ this.syncMaintenanceOnRefresh(settings);
212329
212528
  if (!previous.globalPause && settings.globalPause) {
212330
212529
  if (!settings.autoUnpauseEnabled) {
212331
212530
  log34.log("Global pause activated \u2014 auto-unpause disabled, requires manual intervention");
@@ -212509,6 +212708,7 @@ var init_self_healing = __esm({
212509
212708
  try {
212510
212709
  await this.store.moveTask(taskId, await resolveReboundTargetForTask(this.store, taskId), {
212511
212710
  preserveProgress: true,
212711
+ preserveWorktree: true,
212512
212712
  preserveStatus: true,
212513
212713
  // #1411: backward recovery — skip order-derived adjacency.
212514
212714
  moveSource: "engine",
@@ -212589,7 +212789,23 @@ var init_self_healing = __esm({
212589
212789
  }
212590
212790
  // ── Periodic maintenance ──────────────────────────────────────────
212591
212791
  async startMaintenance() {
212792
+ if (this.maintenanceInterval) return;
212793
+ if (this.maintenanceStarting) return;
212794
+ this.maintenanceStarting = true;
212795
+ try {
212796
+ await this.armMaintenanceInternal();
212797
+ } finally {
212798
+ this.maintenanceStarting = false;
212799
+ }
212800
+ }
212801
+ async armMaintenanceInternal() {
212802
+ if (this.maintenanceInterval) return;
212592
212803
  const settings = await this.store.getSettings();
212804
+ if (this.maintenanceInterval) return;
212805
+ if (settings.globalPause || settings.enginePaused) {
212806
+ log34.debug("Periodic maintenance not armed \u2014 engine/global pause is active");
212807
+ return;
212808
+ }
212593
212809
  const intervalMs = settings.maintenanceIntervalMs ?? 9e5;
212594
212810
  if (intervalMs <= 0) {
212595
212811
  log34.debug("Periodic maintenance disabled (maintenanceIntervalMs <= 0)");
@@ -212600,6 +212816,38 @@ var init_self_healing = __esm({
212600
212816
  void this.runMaintenance();
212601
212817
  }, intervalMs);
212602
212818
  }
212819
+ /*
212820
+ * FNXC:PauseGatedMaintenance 2026-08-13-03:08 (RUFU-076):
212821
+ * Keep the periodic maintenance timer in sync with the engine/global pause state. `onSettingsUpdated`
212822
+ * calls this on every settings:updated event; pausing clears the armed timer (stopping the git churn),
212823
+ * unpausing (re)arms it idempotently via `startMaintenance`'s guard. This is the only writer of the
212824
+ * pause->stop-maintenance transition besides `stop()` teardown.
212825
+ */
212826
+ /*
212827
+ * FNXC:GitWorktreeChurnCadenceCoarsen 2026-08-13-04:05 (RUFU-076):
212828
+ * Coarse-cadence gate for batch-1 git-churn steps. Returns true only when a full coarse window
212829
+ * (hourly) has elapsed since the last batch-1 git-worktree pass, so an idle/healthy active project
212830
+ * does not re-run `git worktree prune` / `git worktree list` / `git branch` on every maintenance
212831
+ * interval. Note the shared timestamp also bounds cleanup-orphaned-branches and enforce-worktree-cap
212832
+ * even though they live further down batch-1.
212833
+ */
212834
+ isGitWorktreeChurnDue() {
212835
+ return Date.now() - this.lastGitWorktreeChurnAt >= GIT_WORKTREE_CHURN_INTERVAL_MS;
212836
+ }
212837
+ syncMaintenanceOnRefresh(settings) {
212838
+ const paused = settings.globalPause || settings.enginePaused;
212839
+ if (paused) {
212840
+ if (this.maintenanceInterval) {
212841
+ clearInterval(this.maintenanceInterval);
212842
+ this.maintenanceInterval = null;
212843
+ log34.debug("Periodic maintenance paused \u2014 cleared maintenance timer");
212844
+ }
212845
+ return;
212846
+ }
212847
+ if (!this.maintenanceInterval) {
212848
+ void this.startMaintenance();
212849
+ }
212850
+ }
212603
212851
  /*
212604
212852
  FNXC:CrossProcessDeleteObservation 2026-08-01-11:39:
212605
212853
  Periodic self-healing owns outbox retention. Each already-open PostgreSQL project is gated to
@@ -212936,17 +213184,26 @@ var init_self_healing = __esm({
212936
213184
  log34.debug("Maintenance cycle starting");
212937
213185
  try {
212938
213186
  const settings = await this.store.getSettings();
213187
+ const maintenancePaused = settings.globalPause || settings.enginePaused;
213188
+ const gitWorktreeChurnDue = this.isGitWorktreeChurnDue();
213189
+ if (!maintenancePaused && gitWorktreeChurnDue) {
213190
+ this.lastGitWorktreeChurnAt = Date.now();
213191
+ }
212939
213192
  const batch1Fns = [
212940
- { name: "prune-worktrees", fn: () => this.pruneWorktrees() },
213193
+ {
213194
+ name: "prune-worktrees",
213195
+ fn: () => maintenancePaused || !gitWorktreeChurnDue ? Promise.resolve(0) : this.pruneWorktrees()
213196
+ },
212941
213197
  {
212942
213198
  name: "prune-task-lifecycle-events",
212943
213199
  fn: async () => this.pruneTaskLifecycleEventsForMaintenance()
212944
213200
  },
212945
213201
  { name: "prune-github-check-states", fn: async () => this.pruneGitHubCheckStatesForMaintenance() },
212946
- { name: "cleanup-orphans", fn: () => this.cleanupOrphans() },
213202
+ { name: "cleanup-orphans", fn: () => maintenancePaused || !gitWorktreeChurnDue ? Promise.resolve(0) : this.cleanupOrphans() },
212947
213203
  {
212948
213204
  name: "cleanup-stale-temp-merge-worktrees",
212949
213205
  fn: async () => {
213206
+ if (maintenancePaused || !gitWorktreeChurnDue) return 0;
212950
213207
  const cleaned = await this.cleanupStaleTempMergeWorktrees();
212951
213208
  if (cleaned > 0) {
212952
213209
  log34.debug(`Cleaned ${cleaned} stale AI merge temp worktree(s)`);
@@ -212954,7 +213211,10 @@ var init_self_healing = __esm({
212954
213211
  return cleaned;
212955
213212
  }
212956
213213
  },
212957
- { name: "cleanup-orphaned-branches", fn: () => this.cleanupOrphanedBranches() },
213214
+ {
213215
+ name: "cleanup-orphaned-branches",
213216
+ fn: () => maintenancePaused || !gitWorktreeChurnDue ? Promise.resolve(0) : this.cleanupOrphanedBranches()
213217
+ },
212958
213218
  {
212959
213219
  name: "reconcile-orphaned-task-dirs",
212960
213220
  fn: async () => {
@@ -213062,7 +213322,7 @@ var init_self_healing = __esm({
213062
213322
  },
213063
213323
  { name: "fts-maintenance", fn: () => this.maintainTaskFts() },
213064
213324
  { name: "checkpoint-wal", fn: () => Promise.resolve(this.checkpointWal()) },
213065
- { name: "enforce-worktree-cap", fn: () => this.enforceWorktreeCap() }
213325
+ { name: "enforce-worktree-cap", fn: () => maintenancePaused || !gitWorktreeChurnDue ? Promise.resolve(0) : this.enforceWorktreeCap() }
213066
213326
  ];
213067
213327
  for (const fn2 of batch1Fns) {
213068
213328
  try {
@@ -214344,6 +214604,7 @@ var init_self_healing = __esm({
214344
214604
  moveSource: "engine",
214345
214605
  // #1411: backward recovery — skip order-derived adjacency.
214346
214606
  recoveryRehome: true,
214607
+ // worktree-discard-intended: reclaim proved the branch already merged / has zero unique commits; the checkout holds nothing worth keeping and worktree was explicitly nulled above.
214347
214608
  preserveProgress: true,
214348
214609
  preserveResumeState: true
214349
214610
  });
@@ -214434,6 +214695,7 @@ var init_self_healing = __esm({
214434
214695
  moveSource: "engine",
214435
214696
  // #1411: backward recovery — skip order-derived adjacency.
214436
214697
  recoveryRehome: true,
214698
+ // worktree-discard-intended: reclaim proved the branch already merged / has zero unique commits; the checkout holds nothing worth keeping and worktree was explicitly nulled above.
214437
214699
  preserveProgress: true,
214438
214700
  preserveResumeState: true
214439
214701
  });
@@ -215230,7 +215492,18 @@ var init_self_healing = __esm({
215230
215492
  const withUniqueWork = existingCandidates.filter((candidate) => candidate.aheadCount > 0);
215231
215493
  if (withUniqueWork.length === 1) {
215232
215494
  const selected = withUniqueWork[0];
215233
- const patch = { branch: selected.branch, worktree: null };
215495
+ let preservedWorktree = false;
215496
+ if (task.worktree && existsSync59(task.worktree)) {
215497
+ try {
215498
+ const { stdout } = await execAsync18("git rev-parse --abbrev-ref HEAD", {
215499
+ cwd: task.worktree,
215500
+ timeout: 3e4
215501
+ });
215502
+ preservedWorktree = stdout.trim() === selected.branch;
215503
+ } catch {
215504
+ }
215505
+ }
215506
+ const patch = preservedWorktree ? { branch: selected.branch } : { branch: selected.branch, worktree: null };
215234
215507
  if (!task.baseCommitSha) {
215235
215508
  const derivedBaseCommit = (await execAsync18(
215236
215509
  `git merge-base ${shellQuote2(integrationBase)} ${shellQuote2(selected.branch)}`,
@@ -215269,7 +215542,8 @@ var init_self_healing = __esm({
215269
215542
  aheadCount: selected.aheadCount,
215270
215543
  integrationBase,
215271
215544
  source: "auto-rebind-in-review",
215272
- previousBranch: task.branch ?? null
215545
+ previousBranch: task.branch ?? null,
215546
+ preservedWorktree
215273
215547
  }
215274
215548
  });
215275
215549
  result2.repaired++;
@@ -215279,7 +215553,8 @@ var init_self_healing = __esm({
215279
215553
  branch: selected.branch,
215280
215554
  aheadCount: selected.aheadCount,
215281
215555
  integrationBase,
215282
- previousBranch: task.branch ?? null
215556
+ previousBranch: task.branch ?? null,
215557
+ preservedWorktree
215283
215558
  });
215284
215559
  continue;
215285
215560
  }
@@ -216811,7 +217086,8 @@ var init_self_healing = __esm({
216811
217086
  */
216812
217087
  recoveryRehome: true,
216813
217088
  bypassGuards: true,
216814
- preserveProgress: true
217089
+ preserveProgress: true,
217090
+ preserveWorktree: true
216815
217091
  });
216816
217092
  rehomed += 1;
216817
217093
  await createRunAuditor(this.store, {
@@ -217449,7 +217725,7 @@ var init_self_healing = __esm({
217449
217725
  await this.emitBackwardMoveNoAction(task, "finalize-no-op-review", "task:finalize-no-op-review-no-action", proof);
217450
217726
  continue;
217451
217727
  }
217452
- await this.store.moveTask(task.id, await resolveReboundTargetForTask(this.store, task.id), { preserveProgress: true, moveSource: "engine", recoveryRehome: true });
217728
+ await this.store.moveTask(task.id, await resolveReboundTargetForTask(this.store, task.id), { preserveProgress: true, preserveWorktree: true, moveSource: "engine", recoveryRehome: true });
217453
217729
  continue;
217454
217730
  }
217455
217731
  const mergedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -217499,7 +217775,7 @@ var init_self_healing = __esm({
217499
217775
  baseRef: classification.baseRef,
217500
217776
  lane: "self-healing-finalize-no-op-review"
217501
217777
  });
217502
- await this.store.moveTask(task.id, await resolveReboundTargetForTask(this.store, task.id), { preserveProgress: true, moveSource: "engine", recoveryRehome: true });
217778
+ await this.store.moveTask(task.id, await resolveReboundTargetForTask(this.store, task.id), { preserveProgress: true, preserveWorktree: true, moveSource: "engine", recoveryRehome: true });
217503
217779
  recovered++;
217504
217780
  continue;
217505
217781
  }
@@ -217518,7 +217794,7 @@ var init_self_healing = __esm({
217518
217794
  classification: "proven-no-op",
217519
217795
  baseRef: classification.baseRef
217520
217796
  });
217521
- await this.store.moveTask(task.id, await resolveReboundTargetForTask(this.store, task.id), { preserveProgress: true, moveSource: "engine", recoveryRehome: true });
217797
+ await this.store.moveTask(task.id, await resolveReboundTargetForTask(this.store, task.id), { preserveProgress: true, preserveWorktree: true, moveSource: "engine", recoveryRehome: true });
217522
217798
  recovered++;
217523
217799
  continue;
217524
217800
  }
@@ -218061,7 +218337,7 @@ var init_self_healing = __esm({
218061
218337
  task.id,
218062
218338
  "Auto-recovered: in-review task still had incomplete steps \u2014 moved back to todo for retry"
218063
218339
  );
218064
- await this.store.moveTask(task.id, await resolveReboundTargetForTask(this.store, task.id), { preserveProgress: true, moveSource: "engine", recoveryRehome: true });
218340
+ await this.store.moveTask(task.id, await resolveReboundTargetForTask(this.store, task.id), { preserveProgress: true, preserveWorktree: true, moveSource: "engine", recoveryRehome: true });
218065
218341
  log34.log(`Recovered stale incomplete review task ${task.id}: moved back to todo`);
218066
218342
  recovered++;
218067
218343
  } catch (err) {
@@ -218455,7 +218731,7 @@ var init_self_healing = __esm({
218455
218731
  task.id,
218456
218732
  "Auto-recovered: in-review task idle past stuck-task timeout \u2014 kicked back to todo"
218457
218733
  );
218458
- await this.store.moveTask(task.id, await resolveReboundTargetForTask(this.store, task.id), { preserveProgress: true, moveSource: "engine", recoveryRehome: true });
218734
+ await this.store.moveTask(task.id, await resolveReboundTargetForTask(this.store, task.id), { preserveProgress: true, preserveWorktree: true, moveSource: "engine", recoveryRehome: true });
218459
218735
  log34.log(`Kicked ghost review task ${task.id} back to todo`);
218460
218736
  recovered++;
218461
218737
  } catch (err) {
@@ -219379,8 +219655,9 @@ var init_self_healing = __esm({
219379
219655
  return Boolean(task.baseCommitSha);
219380
219656
  });
219381
219657
  if (candidates.length === 0) return 0;
219658
+ const batch = candidates.slice(0, DONE_METADATA_REPAIR_CAP);
219382
219659
  let repaired = 0;
219383
- for (const task of candidates) {
219660
+ for (const task of batch) {
219384
219661
  if (isWorkspaceTask(task)) continue;
219385
219662
  if (task.mergeDetails?.landedFilesAttributionRestricted || task.mergeDetails?.noOpVerifiedShortCircuit) {
219386
219663
  log34.debug(`recoverDoneTaskMergeMetadata: skipped ${task.id} \u2014 attribution-restricted`);
@@ -221037,7 +221314,7 @@ var init_self_healing = __esm({
221037
221314
  nextRecoveryAt: new Date(Date.now() + delayMs).toISOString()
221038
221315
  },
221039
221316
  targetColumn: await resolveReboundTargetForTask(this.store, task.id),
221040
- moveOptions: { preserveProgress: true, moveSource: "engine" }
221317
+ moveOptions: { preserveProgress: true, preserveWorktree: true, moveSource: "engine" }
221041
221318
  });
221042
221319
  if (applied.outcome === "applied") {
221043
221320
  await this.store.logEntry(task.id, `Auto-recovered generic terminal failure (attempt ${claim.attempt}/${MAX_TERMINAL_FAILURE_AUTO_RETRIES})`);
@@ -221179,6 +221456,7 @@ var init_self_healing = __esm({
221179
221456
  if (route.kind === "node-requeue" && fresh.column !== requeueTarget) {
221180
221457
  await this.store.moveTask(task.id, requeueTarget, {
221181
221458
  preserveProgress: true,
221459
+ preserveWorktree: true,
221182
221460
  moveSource: "engine",
221183
221461
  recoveryRehome: true
221184
221462
  });
@@ -221412,6 +221690,7 @@ var init_self_healing = __esm({
221412
221690
  const leaseRecovered = await this.options.leaseManager.recoverAbandonedLease(
221413
221691
  task.id,
221414
221692
  `in-progress limbo: ${describeWorktreeState(task)} + null branch`,
221693
+ // worktree-discard-intended: limbo recovery — the worktree is already missing or its metadata cleared; there is no live checkout to hold.
221415
221694
  { preserveProgress: true }
221416
221695
  );
221417
221696
  if (!leaseRecovered) {
@@ -222597,7 +222876,7 @@ var init_self_healing = __esm({
222597
222876
  task.id,
222598
222877
  `Auto-retry ${nextCount}/${MAX_TASK_DONE_RETRIES}: agent finished without fn_task_done \u2014 requeuing to todo to resume partial work`
222599
222878
  );
222600
- await this.store.moveTask(task.id, await resolveReboundTargetForTask(this.store, task.id), { preserveProgress: true, moveSource: "engine", recoveryRehome: true });
222879
+ await this.store.moveTask(task.id, await resolveReboundTargetForTask(this.store, task.id), { preserveProgress: true, preserveWorktree: true, moveSource: "engine", recoveryRehome: true });
222601
222880
  recovered++;
222602
222881
  } catch (err) {
222603
222882
  const errorMessage2 = err instanceof Error ? err.message : String(err);
@@ -260434,7 +260713,7 @@ async function ensureCommitTaskMetadata(mergeRoot, taskId, includeTaskId, traile
260434
260713
  const needsPrefix = includeTaskId && !subject.toLowerCase().startsWith(taskId.toLowerCase());
260435
260714
  const missingTrailers = trailers.filter((t) => !fullMessage.includes(t));
260436
260715
  if (!needsPrefix && missingTrailers.length === 0) return;
260437
- const args = ["-c", "trailer.ifExists=addIfDifferent", "commit", "--amend"];
260716
+ const args = [...commitIdentityArgs(resolveCommitIdentity()), "-c", "trailer.ifExists=addIfDifferent", "commit", "--amend"];
260438
260717
  if (needsPrefix) {
260439
260718
  args.push("-m", `${taskId}: ${subject}`);
260440
260719
  if (body.trim()) args.push("-m", body);
@@ -262069,6 +262348,7 @@ var execFileAsync25, aiMergeLog, MAX_CONCURRENT_ADVANCE_RETRIES, AiMergeBlockedE
262069
262348
  var init_merger_ai = __esm({
262070
262349
  "../engine/src/merge/merger-ai.ts"() {
262071
262350
  "use strict";
262351
+ init_git_identity();
262072
262352
  init_src2();
262073
262353
  init_agent_user_comments();
262074
262354
  init_worktree_names();
@@ -264847,7 +265127,7 @@ function defaultGitOps(cwd) {
264847
265127
  await runGit8(cwd, ["add", ...paths3]);
264848
265128
  },
264849
265129
  async commit(message) {
264850
- await runGit8(cwd, ["commit", "-m", JSON.stringify(message)]);
265130
+ await runGit8(cwd, [...commitIdentityArgs(resolveCommitIdentity()), "commit", "-m", JSON.stringify(message)]);
264851
265131
  return await runGit8(cwd, ["rev-parse", "HEAD"]);
264852
265132
  },
264853
265133
  async resetHard(ref) {
@@ -264925,6 +265205,7 @@ var execAsync55, GIT_TIMEOUT_MS10, GIT_MAX_BUFFER8;
264925
265205
  var init_git_ops = __esm({
264926
265206
  "../engine/src/experiment/git-ops.ts"() {
264927
265207
  "use strict";
265208
+ init_git_identity();
264928
265209
  init_finalize_types();
264929
265210
  execAsync55 = promisify81(exec59);
264930
265211
  GIT_TIMEOUT_MS10 = 3e4;
@@ -273417,6 +273698,7 @@ var init_in_process_runtime = __esm({
273417
273698
  "use strict";
273418
273699
  init_src2();
273419
273700
  init_scheduler();
273701
+ init_pi();
273420
273702
  init_executor();
273421
273703
  init_pr_nodes();
273422
273704
  init_src2();
@@ -273673,6 +273955,7 @@ var init_in_process_runtime = __esm({
273673
273955
  rootDir: this.config.workingDirectory
273674
273956
  });
273675
273957
  await this.pluginRunner.init();
273958
+ registerDefaultAgentPluginRunner(this.config.workingDirectory, this.pluginRunner);
273676
273959
  const projectScopedPluginMcpProvider = createProjectScopedPluginMcpProvider2(
273677
273960
  createRuntimePluginMcpProviderOptions({
273678
273961
  hostRootDir: this.config.workingDirectory,
@@ -274558,6 +274841,7 @@ var init_in_process_runtime = __esm({
274558
274841
  );
274559
274842
  }
274560
274843
  if (this.pluginRunner) {
274844
+ unregisterDefaultAgentPluginRunner(this.config.workingDirectory);
274561
274845
  await this.pluginRunner.shutdown();
274562
274846
  runtimeLog.log("PluginRunner shutdown complete");
274563
274847
  }