@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.
- package/dist/bin.js +387 -72
- package/dist/child-process-worker.js +2479 -2196
- package/dist/client/.vite/manifest.json +262 -262
- package/dist/client/assets/{AgentDetailView-0G9qFd4j.js → AgentDetailView-Dew3af1O.js} +1 -1
- package/dist/client/assets/{AgentPermissionPolicyEditor-BM68g7wo.js → AgentPermissionPolicyEditor-CxPQffiY.js} +1 -1
- package/dist/client/assets/{AgentsView-DkOUZWw4.js → AgentsView-Cr4LDGdt.js} +3 -3
- package/dist/client/assets/ChatView-cNYtYx05.js +13 -0
- package/dist/client/assets/{CommandCenter-DxRSFWNc.js → CommandCenter-DCC90LOP.js} +1 -1
- package/dist/client/assets/{DevServerView-DO-bqJFE.js → DevServerView-B5b520w6.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-Cp2gddTE.js → DirectoryPicker-1JvRd5mC.js} +1 -1
- package/dist/client/assets/{DocumentsView-D0E-3G96.js → DocumentsView-ksK9f7xt.js} +1 -1
- package/dist/client/assets/{EvalsView-BoFVq5hw.js → EvalsView-a3LhgRSo.js} +1 -1
- package/dist/client/assets/{ExperimentalAgentOnboardingModal-CS1Sdogm.js → ExperimentalAgentOnboardingModal-vdVa8h7F.js} +1 -1
- package/dist/client/assets/{GoalsView-sybf7JY4.js → GoalsView-Dz2o91fd.js} +1 -1
- package/dist/client/assets/{InsightsView-nHa7aShn.js → InsightsView-De3R_46d.js} +1 -1
- package/dist/client/assets/{MemoryView-D0IG44za.js → MemoryView-Cagk2wZG.js} +1 -1
- package/dist/client/assets/{PiExtensionsManager-CU76weJe.js → PiExtensionsManager-C9JABO_4.js} +1 -1
- package/dist/client/assets/{PluginManager-DyT8XbcG.js → PluginManager-D2csmdQa.js} +1 -1
- package/dist/client/assets/{PullRequestView-CnxWUSen.js → PullRequestView-DT8vTeVi.js} +1 -1
- package/dist/client/assets/{ReportModal-CMrmMQjD.js → ReportModal-YMP6V4vu.js} +1 -1
- package/dist/client/assets/{ResearchView-BTytQSgy.js → ResearchView-cNsjYu8F.js} +1 -1
- package/dist/client/assets/{SecretsView-BuSH5J87.js → SecretsView-BAmf7KyS.js} +1 -1
- package/dist/client/assets/{SessionTerminal-D04kYRrT.js → SessionTerminal-BjGcxq22.js} +1 -1
- package/dist/client/assets/{SettingsModal-Dm-ngbRr.js → SettingsModal-C_9RiEI7.js} +1 -1
- package/dist/client/assets/{SettingsModal-xSLhH7Tr.js → SettingsModal-DLfy2e_5.js} +4 -4
- package/dist/client/assets/{SettingsTextareaRow-CHPgocEp.js → SettingsTextareaRow-D8RHSj8b.js} +1 -1
- package/dist/client/assets/{SetupWizardModal-y88aXNIQ.js → SetupWizardModal-DRJ96pHQ.js} +2 -2
- package/dist/client/assets/{SkillsView-CYyQW1Hv.js → SkillsView-DyeCwYit.js} +1 -1
- package/dist/client/assets/{WorkflowNodeEditor-hYeoz1X8.js → WorkflowNodeEditor-C5Jc9w_A.js} +3 -3
- package/dist/client/assets/{agent-import-generation-CjiYXzCr.js → agent-import-generation-SCPNeF25.js} +1 -1
- package/dist/client/assets/{agentsOrgChartLayout-C0UP_X3z.js → agentsOrgChartLayout-CqKtNCjy.js} +1 -1
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-Dd6GPcqM.js → architectureDiagram-3BPJPVTR-Cz2HYn0b.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-CC6pLxlz.js → blockDiagram-GPEHLZMM-IimJVscG.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-DxMP_l6y.js → c4Diagram-AAUBKEIU-C-xii7zn.js} +1 -1
- package/dist/client/assets/channel-D-UHgx8G.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-BKYToL43.js → chunk-2J33WTMH-DQ-9Xccu.js} +1 -1
- package/dist/client/assets/{chunk-4BX2VUAB-Bg6rjQb3.js → chunk-4BX2VUAB-DmdAX9Bx.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-CPUwbbGa.js → chunk-55IACEB6-IF2bk5IL.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-DScQBCvv.js → chunk-727SXJPM-AeYpIzVu.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-DbX7uaXK.js → chunk-AQP2D5EJ-DV942DD9.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-DvYKea1c.js → chunk-FMBD7UC4-Bt_riVlZ.js} +1 -1
- package/dist/client/assets/{chunk-ND2GUHAM-CH-Tvw7w.js → chunk-ND2GUHAM-CbyjNbXR.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-CbyEvOoM.js → chunk-QZHKN3VN-DqiRniYQ.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-Do-8MdAc.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-Do-8MdAc.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-BPB5fV3A.js → cose-bilkent-S5V4N54A-UCvthviL.js} +1 -1
- package/dist/client/assets/{dagre-BM42HDAG-CilYJ3rR.js → dagre-BM42HDAG-DnMlT1Oi.js} +1 -1
- package/dist/client/assets/{dashboard-view-dChSM_So.js → dashboard-view-C9D0aoRW.js} +1 -1
- package/dist/client/assets/dashboard-view-Cz0sp2Wl.js +1 -0
- package/dist/client/assets/{dashboard-view-DoLU6FxZ.js → dashboard-view-JysoyDRX.js} +1 -1
- package/dist/client/assets/{dashboard-view-DnVf3tmI.js → dashboard-view-myjM9tr8.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-m9u1Qhyx.js → diagram-2AECGRRQ-BYFiqXGw.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-DVr7Kf0N.js → diagram-5GNKFQAL-DZU3pSYq.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-D7sgJDFx.js → diagram-KO2AKTUF-0ybdKuMm.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-DNKNDS6r.js → diagram-LMA3HP47-Rxbgnbsp.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-1Bff4FWn.js → diagram-OG6HWLK6-BAU_hTeV.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-DGua1UHN.js → erDiagram-TEJ5UH35-zr8HrwTt.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-UDfDtwsE.js → flowDiagram-I6XJVG4X-CrTw0iFw.js} +1 -1
- package/dist/client/assets/{folder-open-CteOypVk.js → folder-open-DnAlsXXn.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-COdmD328.js → ganttDiagram-6RSMTGT7-CCORsxxz.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-SUSls7Kw.js → gitGraphDiagram-PVQCEYII-C07wWSjj.js} +1 -1
- package/dist/client/assets/index-B_z7OKl4.js +2818 -0
- package/dist/client/assets/index-DPo-IAb2.css +1 -0
- package/dist/client/assets/{infoDiagram-5YYISTIA-e_DloXj7.js → infoDiagram-5YYISTIA-hAeccD_4.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-DVWqihXg.js → ishikawaDiagram-YF4QCWOH-WLCzv-NH.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-BcPY-XP0.js → journeyDiagram-JHISSGLW-ClnasNhy.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-BCFG2Jle.js → kanban-definition-UN3LZRKU-CAuARhUz.js} +1 -1
- package/dist/client/assets/{mermaid.core-5yPje9Bi.js → mermaid.core-Bh02RvfX.js} +4 -4
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-DDApeT3K.js → mindmap-definition-RKZ34NQL-KNTlbW4V.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-N61_jyeP.js → pieDiagram-4H26LBE5-BouAfBEw.js} +1 -1
- package/dist/client/assets/{puzzle-BkaCP30D.js → puzzle-CC8Ur3Cy.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-C5qHiApF.js → quadrantDiagram-W4KKPZXB-wTdkCUJU.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-C71okgzt.js → requirementDiagram-4Y6WPE33-BnjY4Tc_.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-B2iKyLjB.js → sankeyDiagram-5OEKKPKP-C-QsS08u.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-DfdoYKKk.js → sequenceDiagram-3UESZ5HK-DD36MILE.js} +1 -1
- package/dist/client/assets/{shield-alert-BNSeDB8l.js → shield-alert-DcXc56Fy.js} +1 -1
- package/dist/client/assets/{standing-instructions-template-pZtzo1lK.js → standing-instructions-template-BF5y1BLz.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-lS-sUi12.js → stateDiagram-AJRCARHV-WTq1wQr1.js} +1 -1
- package/dist/client/assets/{stateDiagram-v2-BHNVJYJU-DXJNDrV9.js → stateDiagram-v2-BHNVJYJU-eILJdjII.js} +1 -1
- package/dist/client/assets/{timeline-definition-PNZ67QCA-CCwvX81K.js → timeline-definition-PNZ67QCA-PRNwI0NR.js} +1 -1
- package/dist/client/assets/{upload-CDovVbu2.js → upload-qH_64O-B.js} +1 -1
- package/dist/client/assets/{useDiscoveredSkillsCache-BYqP-afh.js → useDiscoveredSkillsCache-C-GPCNaO.js} +1 -1
- package/dist/client/assets/{users-CTqECGLo.js → users-D2UesRE4.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-DaiR5nv9.js → vennDiagram-CIIHVFJN-CG2Z4T4O.js} +1 -1
- package/dist/client/assets/{wardley-L42UT6IY-hA5IHyPW.js → wardley-L42UT6IY-gO_fGvF9.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-CILUNESc.js → wardleyDiagram-YWT4CUSO-BkyNpjUb.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-72eNMmjz.js → xychartDiagram-2RQKCTM6-CMlZsiPq.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/version.json +1 -1
- package/dist/droid-cli/package.json +1 -1
- package/dist/extension.js +345 -61
- package/dist/pi-claude-cli/package.json +1 -1
- package/dist/plugin-sdk/index.js +29 -2
- package/dist/plugins/fusion-plugin-acp-runtime/bundled.js +269 -16
- package/dist/plugins/fusion-plugin-acp-runtime/mcp-schema-server.cjs +171 -0
- package/dist/plugins/fusion-plugin-acp-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-claude-runtime/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-claude-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-cli-printing-press/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
- package/dist/plugins/fusion-plugin-compound-engineering/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-compound-engineering/package.json +1 -1
- package/dist/plugins/fusion-plugin-cursor-runtime/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-dependency-graph/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
- package/dist/plugins/fusion-plugin-droid-runtime/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-grok-runtime/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-grok-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-hermes-runtime/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-linear-import/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-linear-import/package.json +1 -1
- package/dist/plugins/fusion-plugin-omp-runtime/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-omp-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-openclaw-runtime/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-paperclip-runtime/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-quality/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-quality/package.json +1 -1
- package/dist/plugins/fusion-plugin-reports/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-reports/package.json +1 -1
- package/dist/plugins/fusion-plugin-roadmap/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
- package/dist/plugins/fusion-plugin-todos/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-todos/package.json +1 -1
- package/dist/plugins/fusion-plugin-whatsapp-chat/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
- package/package.json +1 -1
- package/dist/client/assets/ChatView-BPSm2JIH.js +0 -13
- package/dist/client/assets/channel-DlCEMoEf.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-Bc92O8Ks.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-Bc92O8Ks.js +0 -1
- package/dist/client/assets/dashboard-view-BnGe8cWo.js +0 -1
- package/dist/client/assets/index-0ovTXt3t.css +0 -1
- 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
|
|
16769
|
-
|
|
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
|
|
36421
|
-
|
|
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,
|
|
139948
|
-
if (!target
|
|
139949
|
-
const
|
|
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:
|
|
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 = {
|
|
139968
|
-
|
|
139969
|
-
|
|
139970
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
179407
|
-
|
|
179408
|
-
|
|
179409
|
-
|
|
179410
|
-
|
|
179411
|
-
|
|
179412
|
-
|
|
179413
|
-
|
|
179414
|
-
|
|
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 {
|
|
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
|
-
{
|
|
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
|
-
{
|
|
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
|
-
|
|
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
|
|
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
|
}
|