@adhdev/daemon-core 0.9.82-rc.114 → 0.9.82-rc.115
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/config/mesh-config.d.ts +2 -0
- package/dist/git/git-commands.d.ts +5 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +956 -262
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +940 -253
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-active-work.d.ts +13 -0
- package/dist/mesh/mesh-refine-status.d.ts +27 -0
- package/dist/mesh/preview-freshness.d.ts +18 -0
- package/dist/mesh/refine-config.d.ts +17 -0
- package/dist/mesh/worktree-bootstrap-config.d.ts +115 -0
- package/dist/repo-mesh-types.d.ts +17 -0
- package/package.json +1 -1
- package/src/commands/router.ts +341 -5
- package/src/config/mesh-config.ts +4 -1
- package/src/git/git-commands.ts +17 -5
- package/src/index.ts +13 -2
- package/src/mesh/mesh-active-work.ts +37 -0
- package/src/mesh/mesh-refine-status.ts +145 -0
- package/src/mesh/preview-freshness.ts +118 -0
- package/src/mesh/refine-config.ts +17 -7
- package/src/mesh/worktree-bootstrap-config.ts +234 -0
- package/src/repo-mesh-types.ts +17 -0
package/dist/index.mjs
CHANGED
|
@@ -1053,6 +1053,7 @@ function addNode(meshId, opts) {
|
|
|
1053
1053
|
isLocalWorktree: opts.isLocalWorktree,
|
|
1054
1054
|
worktreeBranch: opts.worktreeBranch,
|
|
1055
1055
|
clonedFromNodeId: opts.clonedFromNodeId,
|
|
1056
|
+
worktreeBootstrap: opts.worktreeBootstrap,
|
|
1056
1057
|
role: opts.role
|
|
1057
1058
|
};
|
|
1058
1059
|
mesh.nodes.push(node);
|
|
@@ -1079,6 +1080,7 @@ function updateNode(meshId, nodeId, opts) {
|
|
|
1079
1080
|
if (!node) return void 0;
|
|
1080
1081
|
if (opts.userOverrides) node.userOverrides = { ...node.userOverrides, ...opts.userOverrides };
|
|
1081
1082
|
if (opts.policy) node.policy = { ...node.policy, ...opts.policy };
|
|
1083
|
+
if (opts.worktreeBootstrap) node.worktreeBootstrap = opts.worktreeBootstrap;
|
|
1082
1084
|
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1083
1085
|
saveMeshConfig(config);
|
|
1084
1086
|
return node;
|
|
@@ -1291,8 +1293,8 @@ __export(mesh_ledger_exports, {
|
|
|
1291
1293
|
readLedgerEntries: () => readLedgerEntries,
|
|
1292
1294
|
readLedgerSlice: () => readLedgerSlice
|
|
1293
1295
|
});
|
|
1294
|
-
import { appendFileSync, existsSync as
|
|
1295
|
-
import { join as
|
|
1296
|
+
import { appendFileSync, existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync5, statSync as statSync2, renameSync } from "fs";
|
|
1297
|
+
import { join as join7 } from "path";
|
|
1296
1298
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
1297
1299
|
import { EventEmitter } from "events";
|
|
1298
1300
|
function isIntentionalCleanupStopEntry(entry) {
|
|
@@ -1301,19 +1303,19 @@ function isIntentionalCleanupStopEntry(entry) {
|
|
|
1301
1303
|
return payload.intentional === true && (payload.reason === "operator_cleanup" || payload.intentionalStopReason === "operator_cleanup" || payload.source === "mesh_cleanup_sessions" || payload.source === "mesh_remove_node");
|
|
1302
1304
|
}
|
|
1303
1305
|
function getLedgerDir() {
|
|
1304
|
-
const dir =
|
|
1305
|
-
if (!
|
|
1306
|
+
const dir = join7(getConfigDir(), LEDGER_DIR_NAME);
|
|
1307
|
+
if (!existsSync7(dir)) {
|
|
1306
1308
|
mkdirSync3(dir, { recursive: true, mode: 448 });
|
|
1307
1309
|
}
|
|
1308
1310
|
return dir;
|
|
1309
1311
|
}
|
|
1310
1312
|
function getLedgerPath(meshId) {
|
|
1311
1313
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1312
|
-
return
|
|
1314
|
+
return join7(getLedgerDir(), `${safe}.jsonl`);
|
|
1313
1315
|
}
|
|
1314
1316
|
function getRotatedPath(meshId, index) {
|
|
1315
1317
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1316
|
-
return
|
|
1318
|
+
return join7(getLedgerDir(), `${safe}.${index}.jsonl`);
|
|
1317
1319
|
}
|
|
1318
1320
|
function readNonEmptyString(value) {
|
|
1319
1321
|
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
@@ -1435,7 +1437,7 @@ function appendLedgerEntry(meshId, partial) {
|
|
|
1435
1437
|
...partial
|
|
1436
1438
|
};
|
|
1437
1439
|
const filePath = getLedgerPath(meshId);
|
|
1438
|
-
if (
|
|
1440
|
+
if (existsSync7(filePath)) {
|
|
1439
1441
|
try {
|
|
1440
1442
|
const stat2 = statSync2(filePath);
|
|
1441
1443
|
if (stat2.size >= MAX_FILE_SIZE_BYTES) {
|
|
@@ -1502,10 +1504,10 @@ function appendRemoteLedgerEntries(meshId, entries) {
|
|
|
1502
1504
|
}
|
|
1503
1505
|
function readLedgerEntries(meshId, opts) {
|
|
1504
1506
|
const filePath = getLedgerPath(meshId);
|
|
1505
|
-
if (!
|
|
1507
|
+
if (!existsSync7(filePath)) return [];
|
|
1506
1508
|
let content;
|
|
1507
1509
|
try {
|
|
1508
|
-
content =
|
|
1510
|
+
content = readFileSync5(filePath, "utf-8");
|
|
1509
1511
|
} catch {
|
|
1510
1512
|
return [];
|
|
1511
1513
|
}
|
|
@@ -1677,7 +1679,7 @@ function getSessionRecoveryContext(meshId, opts) {
|
|
|
1677
1679
|
}
|
|
1678
1680
|
function rotateLedgerFile(meshId, currentPath) {
|
|
1679
1681
|
let index = 1;
|
|
1680
|
-
while (
|
|
1682
|
+
while (existsSync7(getRotatedPath(meshId, index))) {
|
|
1681
1683
|
index++;
|
|
1682
1684
|
if (index > 10) break;
|
|
1683
1685
|
}
|
|
@@ -1702,8 +1704,8 @@ var init_mesh_ledger = __esm({
|
|
|
1702
1704
|
});
|
|
1703
1705
|
|
|
1704
1706
|
// src/mesh/beads-db.ts
|
|
1705
|
-
import { existsSync as
|
|
1706
|
-
import { dirname as dirname2, join as
|
|
1707
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync4, readFileSync as readFileSync6 } from "fs";
|
|
1708
|
+
import { dirname as dirname2, join as join8 } from "path";
|
|
1707
1709
|
import { createRequire } from "module";
|
|
1708
1710
|
function loadDatabaseCtor() {
|
|
1709
1711
|
if (DatabaseCtor) return DatabaseCtor;
|
|
@@ -1715,7 +1717,7 @@ function safeMeshId(meshId) {
|
|
|
1715
1717
|
return meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1716
1718
|
}
|
|
1717
1719
|
function legacyQueuePath(meshId) {
|
|
1718
|
-
return
|
|
1720
|
+
return join8(getLedgerDir(), `${safeMeshId(meshId)}.queue.json`);
|
|
1719
1721
|
}
|
|
1720
1722
|
var DatabaseCtor, BeadsDB;
|
|
1721
1723
|
var init_beads_db = __esm({
|
|
@@ -1728,7 +1730,7 @@ var init_beads_db = __esm({
|
|
|
1728
1730
|
migratedMeshIds = /* @__PURE__ */ new Set();
|
|
1729
1731
|
constructor(dbPath) {
|
|
1730
1732
|
const dir = dirname2(dbPath);
|
|
1731
|
-
if (!
|
|
1733
|
+
if (!existsSync8(dir)) mkdirSync4(dir, { recursive: true });
|
|
1732
1734
|
this.db = new (loadDatabaseCtor())(dbPath);
|
|
1733
1735
|
this.db.pragma("journal_mode = WAL");
|
|
1734
1736
|
this.db.pragma("synchronous = NORMAL");
|
|
@@ -1738,7 +1740,7 @@ var init_beads_db = __esm({
|
|
|
1738
1740
|
}
|
|
1739
1741
|
static getInstance() {
|
|
1740
1742
|
if (!this.instance) {
|
|
1741
|
-
this.instance = new _BeadsDB(
|
|
1743
|
+
this.instance = new _BeadsDB(join8(getLedgerDir(), "beads.db"));
|
|
1742
1744
|
}
|
|
1743
1745
|
return this.instance;
|
|
1744
1746
|
}
|
|
@@ -1779,9 +1781,9 @@ var init_beads_db = __esm({
|
|
|
1779
1781
|
const count = this.db.prepare("SELECT COUNT(*) AS count FROM mesh_queue WHERE mesh_id = ?").get(meshId);
|
|
1780
1782
|
if (count.count > 0) return;
|
|
1781
1783
|
const path28 = legacyQueuePath(meshId);
|
|
1782
|
-
if (!
|
|
1784
|
+
if (!existsSync8(path28)) return;
|
|
1783
1785
|
try {
|
|
1784
|
-
const entries = JSON.parse(
|
|
1786
|
+
const entries = JSON.parse(readFileSync6(path28, "utf-8"));
|
|
1785
1787
|
if (!Array.isArray(entries)) return;
|
|
1786
1788
|
const insert = this.db.prepare(`
|
|
1787
1789
|
INSERT OR REPLACE INTO mesh_queue (
|
|
@@ -2120,7 +2122,7 @@ var init_mesh_work_queue = __esm({
|
|
|
2120
2122
|
import { exec } from "child_process";
|
|
2121
2123
|
import * as os2 from "os";
|
|
2122
2124
|
import * as path8 from "path";
|
|
2123
|
-
import { existsSync as
|
|
2125
|
+
import { existsSync as existsSync9 } from "fs";
|
|
2124
2126
|
function parseVersion(raw) {
|
|
2125
2127
|
const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
|
|
2126
2128
|
return match ? match[1] : raw.split("\n")[0].slice(0, 100);
|
|
@@ -2144,24 +2146,24 @@ function resolveCommandPath(command) {
|
|
|
2144
2146
|
if (isExplicitCommandPath(trimmed)) {
|
|
2145
2147
|
const expanded = expandHome(trimmed);
|
|
2146
2148
|
const candidate = path8.isAbsolute(expanded) ? expanded : path8.resolve(expanded);
|
|
2147
|
-
return
|
|
2149
|
+
return existsSync9(candidate) ? candidate : null;
|
|
2148
2150
|
}
|
|
2149
2151
|
return null;
|
|
2150
2152
|
}
|
|
2151
2153
|
function execAsync(cmd, timeoutMs = 5e3) {
|
|
2152
|
-
return new Promise((
|
|
2154
|
+
return new Promise((resolve17) => {
|
|
2153
2155
|
const child = exec(cmd, {
|
|
2154
2156
|
encoding: "utf-8",
|
|
2155
2157
|
timeout: timeoutMs,
|
|
2156
2158
|
...process.platform === "win32" ? { windowsHide: true } : {}
|
|
2157
2159
|
}, (err, stdout) => {
|
|
2158
2160
|
if (err || !stdout?.trim()) {
|
|
2159
|
-
|
|
2161
|
+
resolve17(null);
|
|
2160
2162
|
} else {
|
|
2161
|
-
|
|
2163
|
+
resolve17(stdout.trim());
|
|
2162
2164
|
}
|
|
2163
2165
|
});
|
|
2164
|
-
child.on("error", () =>
|
|
2166
|
+
child.on("error", () => resolve17(null));
|
|
2165
2167
|
});
|
|
2166
2168
|
}
|
|
2167
2169
|
async function detectCLIs(providerLoader, options) {
|
|
@@ -2531,10 +2533,10 @@ __export(mesh_events_exports, {
|
|
|
2531
2533
|
triggerMeshQueue: () => triggerMeshQueue,
|
|
2532
2534
|
tryAssignQueueTask: () => tryAssignQueueTask
|
|
2533
2535
|
});
|
|
2534
|
-
import { appendFileSync as appendFileSync2, existsSync as
|
|
2535
|
-
import { join as
|
|
2536
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync11, readFileSync as readFileSync7, unlinkSync as unlinkSync2 } from "fs";
|
|
2537
|
+
import { join as join11 } from "path";
|
|
2536
2538
|
function readWorkerResultMetadata(event) {
|
|
2537
|
-
return
|
|
2539
|
+
return readRecord2(event.workerResult) || readRecord2(event.meshWorkerResult) || readRecord2(event.structuredResult);
|
|
2538
2540
|
}
|
|
2539
2541
|
function sweepExpiredRemoteIdleSessions() {
|
|
2540
2542
|
const now = Date.now();
|
|
@@ -2543,9 +2545,9 @@ function sweepExpiredRemoteIdleSessions() {
|
|
|
2543
2545
|
}
|
|
2544
2546
|
}
|
|
2545
2547
|
function readRefineJobId(event) {
|
|
2546
|
-
const metadata =
|
|
2547
|
-
const result =
|
|
2548
|
-
const refineJob =
|
|
2548
|
+
const metadata = readRecord2(event.metadataEvent) || event;
|
|
2549
|
+
const result = readRecord2(metadata.result);
|
|
2550
|
+
const refineJob = readRecord2(result?.refineJob);
|
|
2549
2551
|
return readNonEmptyString2(metadata.jobId) || readNonEmptyString2(refineJob?.jobId);
|
|
2550
2552
|
}
|
|
2551
2553
|
function buildRefineTerminalEventFingerprint(meshId, eventName, metadataEvent) {
|
|
@@ -2561,10 +2563,10 @@ function hasPendingRefineTerminalEventDuplicate(event) {
|
|
|
2561
2563
|
);
|
|
2562
2564
|
}
|
|
2563
2565
|
function buildPendingEventFingerprint(event) {
|
|
2564
|
-
const metadata =
|
|
2566
|
+
const metadata = readRecord2(event.metadataEvent) || {};
|
|
2565
2567
|
const sessionId = resolveEventSessionId(metadata);
|
|
2566
2568
|
const providerSessionId = readNonEmptyString2(metadata.providerSessionId);
|
|
2567
|
-
const taskId = readNonEmptyString2(metadata.taskId) || readNonEmptyString2(
|
|
2569
|
+
const taskId = readNonEmptyString2(metadata.taskId) || readNonEmptyString2(readRecord2(metadata.payload)?.taskId);
|
|
2568
2570
|
const jobId = readRefineJobId(event);
|
|
2569
2571
|
const timestamp = metadata.timestamp !== void 0 && metadata.timestamp !== null ? String(metadata.timestamp) : "";
|
|
2570
2572
|
return [
|
|
@@ -2585,7 +2587,7 @@ function hasPendingCoordinatorEventDuplicate(event) {
|
|
|
2585
2587
|
}
|
|
2586
2588
|
function getPendingEventsPath(meshId) {
|
|
2587
2589
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
2588
|
-
return
|
|
2590
|
+
return join11(getLedgerDir(), `${safe}.pending-events.jsonl`);
|
|
2589
2591
|
}
|
|
2590
2592
|
function queuePendingMeshCoordinatorEvent(event) {
|
|
2591
2593
|
try {
|
|
@@ -2607,9 +2609,9 @@ function queuePendingMeshCoordinatorEvent(event) {
|
|
|
2607
2609
|
function drainPendingMeshCoordinatorEvents(meshId) {
|
|
2608
2610
|
if (!meshId) return [];
|
|
2609
2611
|
const path28 = getPendingEventsPath(meshId);
|
|
2610
|
-
if (!
|
|
2612
|
+
if (!existsSync11(path28)) return [];
|
|
2611
2613
|
try {
|
|
2612
|
-
const raw =
|
|
2614
|
+
const raw = readFileSync7(path28, "utf-8");
|
|
2613
2615
|
try {
|
|
2614
2616
|
unlinkSync2(path28);
|
|
2615
2617
|
} catch {
|
|
@@ -2628,9 +2630,9 @@ function drainPendingMeshCoordinatorEvents(meshId) {
|
|
|
2628
2630
|
function getPendingMeshCoordinatorEvents(meshId) {
|
|
2629
2631
|
if (!meshId) return [];
|
|
2630
2632
|
const path28 = getPendingEventsPath(meshId);
|
|
2631
|
-
if (!
|
|
2633
|
+
if (!existsSync11(path28)) return [];
|
|
2632
2634
|
try {
|
|
2633
|
-
const raw =
|
|
2635
|
+
const raw = readFileSync7(path28, "utf-8");
|
|
2634
2636
|
return raw.split("\n").filter(Boolean).flatMap((line) => {
|
|
2635
2637
|
try {
|
|
2636
2638
|
return [JSON.parse(line)];
|
|
@@ -2645,7 +2647,7 @@ function getPendingMeshCoordinatorEvents(meshId) {
|
|
|
2645
2647
|
function clearPendingMeshCoordinatorEvents(meshId) {
|
|
2646
2648
|
if (!meshId) return;
|
|
2647
2649
|
const path28 = getPendingEventsPath(meshId);
|
|
2648
|
-
if (
|
|
2650
|
+
if (existsSync11(path28)) try {
|
|
2649
2651
|
unlinkSync2(path28);
|
|
2650
2652
|
} catch {
|
|
2651
2653
|
}
|
|
@@ -2653,7 +2655,7 @@ function clearPendingMeshCoordinatorEvents(meshId) {
|
|
|
2653
2655
|
function readNonEmptyString2(value) {
|
|
2654
2656
|
return typeof value === "string" && value.trim() ? value.trim() : "";
|
|
2655
2657
|
}
|
|
2656
|
-
function
|
|
2658
|
+
function readRecord2(value) {
|
|
2657
2659
|
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
2658
2660
|
}
|
|
2659
2661
|
function resolveEventSessionId(event, fallback) {
|
|
@@ -3093,10 +3095,10 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
|
|
|
3093
3095
|
}
|
|
3094
3096
|
if (args.event === "refine:completed") {
|
|
3095
3097
|
const jobId = readRefineJobId({ metadataEvent: args.metadataEvent });
|
|
3096
|
-
const result =
|
|
3097
|
-
const validationSummary =
|
|
3098
|
-
const patchEquivalence =
|
|
3099
|
-
const finalConvergence =
|
|
3098
|
+
const result = readRecord2(args.metadataEvent.result);
|
|
3099
|
+
const validationSummary = readRecord2(result?.validationSummary);
|
|
3100
|
+
const patchEquivalence = readRecord2(result?.patchEquivalence);
|
|
3101
|
+
const finalConvergence = readRecord2(result?.finalBranchConvergenceState);
|
|
3100
3102
|
const validationStatus = readNonEmptyString2(validationSummary?.status);
|
|
3101
3103
|
const patchStatus = readNonEmptyString2(patchEquivalence?.status) || (patchEquivalence?.equivalent === true ? "passed" : "");
|
|
3102
3104
|
const into = readNonEmptyString2(result?.into);
|
|
@@ -3117,10 +3119,10 @@ Next step: ${nextStep}`;
|
|
|
3117
3119
|
}
|
|
3118
3120
|
if (args.event === "refine:failed") {
|
|
3119
3121
|
const jobId = readRefineJobId({ metadataEvent: args.metadataEvent });
|
|
3120
|
-
const result =
|
|
3121
|
-
const validationSummary =
|
|
3122
|
-
const patchEquivalence =
|
|
3123
|
-
const finalConvergence =
|
|
3122
|
+
const result = readRecord2(args.metadataEvent.result);
|
|
3123
|
+
const validationSummary = readRecord2(result?.validationSummary);
|
|
3124
|
+
const patchEquivalence = readRecord2(result?.patchEquivalence);
|
|
3125
|
+
const finalConvergence = readRecord2(result?.finalBranchConvergenceState);
|
|
3124
3126
|
const code = readNonEmptyString2(result?.code);
|
|
3125
3127
|
const error = readNonEmptyString2(result?.error);
|
|
3126
3128
|
const validationStatus = readNonEmptyString2(validationSummary?.status);
|
|
@@ -5209,7 +5211,7 @@ ${lastSnapshot}`;
|
|
|
5209
5211
|
`[${this.cliType}] Waiting for interactive prompt: status=${status} stableMs=${stableMs} recentOutputMs=${recentlyOutput} screen=${JSON.stringify(summarizeCliTraceText(screenText, 220)).slice(0, 260)}`
|
|
5210
5212
|
);
|
|
5211
5213
|
}
|
|
5212
|
-
await new Promise((
|
|
5214
|
+
await new Promise((resolve17) => setTimeout(resolve17, 50));
|
|
5213
5215
|
}
|
|
5214
5216
|
const finalScreenText = this.terminalScreen.getText() || "";
|
|
5215
5217
|
LOG.warn(
|
|
@@ -6436,7 +6438,7 @@ ${lastSnapshot}`;
|
|
|
6436
6438
|
const deadline = Date.now() + 1e4;
|
|
6437
6439
|
while (this.startupParseGate && Date.now() < deadline) {
|
|
6438
6440
|
this.resolveStartupState("send_wait");
|
|
6439
|
-
await new Promise((
|
|
6441
|
+
await new Promise((resolve17) => setTimeout(resolve17, 50));
|
|
6440
6442
|
}
|
|
6441
6443
|
}
|
|
6442
6444
|
const parsedStatusBeforeSend = !allowInputDuringGeneration ? (() => {
|
|
@@ -6533,13 +6535,13 @@ ${lastSnapshot}`;
|
|
|
6533
6535
|
}
|
|
6534
6536
|
this.responseEpoch += 1;
|
|
6535
6537
|
this.responseSettleIgnoreUntil = Date.now() + submitDelayMs + this.timeouts.outputSettle + 250;
|
|
6536
|
-
await new Promise((
|
|
6538
|
+
await new Promise((resolve17, reject) => {
|
|
6537
6539
|
let resolved = false;
|
|
6538
6540
|
const completion = {
|
|
6539
6541
|
resolveOnce: () => {
|
|
6540
6542
|
if (resolved) return;
|
|
6541
6543
|
resolved = true;
|
|
6542
|
-
|
|
6544
|
+
resolve17();
|
|
6543
6545
|
},
|
|
6544
6546
|
rejectOnce: (error) => {
|
|
6545
6547
|
if (resolved) return;
|
|
@@ -6697,17 +6699,17 @@ ${lastSnapshot}`;
|
|
|
6697
6699
|
}
|
|
6698
6700
|
}
|
|
6699
6701
|
waitForStopped(timeoutMs) {
|
|
6700
|
-
return new Promise((
|
|
6702
|
+
return new Promise((resolve17) => {
|
|
6701
6703
|
const startedAt = Date.now();
|
|
6702
6704
|
const timer = setInterval(() => {
|
|
6703
6705
|
if (!this.ptyProcess || this.currentStatus === "stopped") {
|
|
6704
6706
|
clearInterval(timer);
|
|
6705
|
-
|
|
6707
|
+
resolve17(true);
|
|
6706
6708
|
return;
|
|
6707
6709
|
}
|
|
6708
6710
|
if (Date.now() - startedAt >= timeoutMs) {
|
|
6709
6711
|
clearInterval(timer);
|
|
6710
|
-
|
|
6712
|
+
resolve17(false);
|
|
6711
6713
|
}
|
|
6712
6714
|
}, 100);
|
|
6713
6715
|
});
|
|
@@ -8057,10 +8059,17 @@ async function gitCheckpoint(workspace, message, includeUntracked) {
|
|
|
8057
8059
|
} catch (err) {
|
|
8058
8060
|
const output = (err?.stdout || "") + (err?.stderr || "");
|
|
8059
8061
|
if (/nothing to commit/i.test(output)) {
|
|
8060
|
-
|
|
8061
|
-
|
|
8062
|
-
|
|
8063
|
-
|
|
8062
|
+
return {
|
|
8063
|
+
workspace: repo.workspace,
|
|
8064
|
+
repoRoot,
|
|
8065
|
+
isGitRepo: true,
|
|
8066
|
+
message: fullMsg,
|
|
8067
|
+
status: "skipped",
|
|
8068
|
+
skipped: true,
|
|
8069
|
+
noop: true,
|
|
8070
|
+
reason: "nothing_to_commit",
|
|
8071
|
+
lastCheckedAt: Date.now()
|
|
8072
|
+
};
|
|
8064
8073
|
}
|
|
8065
8074
|
throw err;
|
|
8066
8075
|
}
|
|
@@ -8070,6 +8079,7 @@ async function gitCheckpoint(workspace, message, includeUntracked) {
|
|
|
8070
8079
|
isGitRepo: true,
|
|
8071
8080
|
commit: commitSha,
|
|
8072
8081
|
message: fullMsg,
|
|
8082
|
+
status: "created",
|
|
8073
8083
|
lastCheckedAt: Date.now()
|
|
8074
8084
|
};
|
|
8075
8085
|
}
|
|
@@ -8773,6 +8783,7 @@ var MESH_REFINE_CONFIG_SCHEMA = {
|
|
|
8773
8783
|
category: { enum: [...MESH_REFINE_VALIDATION_CATEGORIES, "custom"] },
|
|
8774
8784
|
cwd: { type: "string" },
|
|
8775
8785
|
timeoutMs: { type: "number", minimum: 1e3, maximum: 6e5 },
|
|
8786
|
+
outputLimitBytes: { type: "number", minimum: 1024, maximum: 1048576 },
|
|
8776
8787
|
env: { type: "object", additionalProperties: { type: "string" } }
|
|
8777
8788
|
}
|
|
8778
8789
|
}
|
|
@@ -8790,6 +8801,7 @@ var MESH_REFINE_CONFIG_SCHEMA = {
|
|
|
8790
8801
|
category: { enum: [...MESH_REFINE_VALIDATION_CATEGORIES, "custom"] },
|
|
8791
8802
|
cwd: { type: "string" },
|
|
8792
8803
|
timeoutMs: { type: "number", minimum: 1e3, maximum: 6e5 },
|
|
8804
|
+
outputLimitBytes: { type: "number", minimum: 1024, maximum: 1048576 },
|
|
8793
8805
|
env: { type: "object", additionalProperties: { type: "string" } }
|
|
8794
8806
|
}
|
|
8795
8807
|
}
|
|
@@ -8798,7 +8810,7 @@ var MESH_REFINE_CONFIG_SCHEMA = {
|
|
|
8798
8810
|
}
|
|
8799
8811
|
}
|
|
8800
8812
|
};
|
|
8801
|
-
function
|
|
8813
|
+
function isMeshConfigRecord(value) {
|
|
8802
8814
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
8803
8815
|
}
|
|
8804
8816
|
function tokenizeCommandString(command) {
|
|
@@ -8813,8 +8825,8 @@ function tokenizeCommandString(command) {
|
|
|
8813
8825
|
function validateCategory(value) {
|
|
8814
8826
|
return typeof value === "string" && [...MESH_REFINE_VALIDATION_CATEGORIES, "custom"].includes(value) ? value : "custom";
|
|
8815
8827
|
}
|
|
8816
|
-
function
|
|
8817
|
-
if (!
|
|
8828
|
+
function normalizeMeshCommandConfig(entry, source) {
|
|
8829
|
+
if (!isMeshConfigRecord(entry) || typeof entry.command !== "string") {
|
|
8818
8830
|
return { rejected: { source, reason: "validation command must be an object with a command string" } };
|
|
8819
8831
|
}
|
|
8820
8832
|
const commandText = entry.command.trim();
|
|
@@ -8841,7 +8853,10 @@ function normalizeCommandConfig(entry, source) {
|
|
|
8841
8853
|
if (entry.timeoutMs !== void 0 && (typeof entry.timeoutMs !== "number" || !Number.isFinite(entry.timeoutMs) || entry.timeoutMs < 1e3 || entry.timeoutMs > 6e5)) {
|
|
8842
8854
|
return { rejected: { source, command: commandText, reason: "timeoutMs must be between 1000 and 600000" } };
|
|
8843
8855
|
}
|
|
8844
|
-
if (entry.
|
|
8856
|
+
if (entry.outputLimitBytes !== void 0 && (typeof entry.outputLimitBytes !== "number" || !Number.isFinite(entry.outputLimitBytes) || entry.outputLimitBytes < 1024 || entry.outputLimitBytes > 1048576)) {
|
|
8857
|
+
return { rejected: { source, command: commandText, reason: "outputLimitBytes must be between 1024 and 1048576" } };
|
|
8858
|
+
}
|
|
8859
|
+
if (entry.env !== void 0 && (!isMeshConfigRecord(entry.env) || !Object.values(entry.env).every((value) => typeof value === "string"))) {
|
|
8845
8860
|
return { rejected: { source, command: commandText, reason: "env must be an object of string values" } };
|
|
8846
8861
|
}
|
|
8847
8862
|
return {
|
|
@@ -8853,10 +8868,12 @@ function normalizeCommandConfig(entry, source) {
|
|
|
8853
8868
|
source,
|
|
8854
8869
|
...typeof entry.cwd === "string" && entry.cwd.trim() ? { cwd: entry.cwd.trim() } : {},
|
|
8855
8870
|
...typeof entry.timeoutMs === "number" ? { timeoutMs: entry.timeoutMs } : {},
|
|
8856
|
-
...
|
|
8871
|
+
...typeof entry.outputLimitBytes === "number" ? { outputLimitBytes: entry.outputLimitBytes } : {},
|
|
8872
|
+
...isMeshConfigRecord(entry.env) ? { env: entry.env } : {}
|
|
8857
8873
|
}
|
|
8858
8874
|
};
|
|
8859
8875
|
}
|
|
8876
|
+
var isRecord = isMeshConfigRecord;
|
|
8860
8877
|
function validateMeshRefineConfig(config, source = "inline") {
|
|
8861
8878
|
const errors = [];
|
|
8862
8879
|
const bootstrapCommands = [];
|
|
@@ -8875,14 +8892,14 @@ function validateMeshRefineConfig(config, source = "inline") {
|
|
|
8875
8892
|
if (rawBootstrapCommands !== void 0 && !Array.isArray(rawBootstrapCommands)) errors.push("validation.bootstrapCommands must be an array");
|
|
8876
8893
|
if (Array.isArray(rawBootstrapCommands)) {
|
|
8877
8894
|
rawBootstrapCommands.forEach((entry, index) => {
|
|
8878
|
-
const normalized =
|
|
8895
|
+
const normalized = normalizeMeshCommandConfig(entry, `${source}:validation.bootstrapCommands[${index}]`);
|
|
8879
8896
|
if (normalized.command) bootstrapCommands.push(normalized.command);
|
|
8880
8897
|
if (normalized.rejected) rejectedCommands.push(normalized.rejected);
|
|
8881
8898
|
});
|
|
8882
8899
|
}
|
|
8883
8900
|
if (Array.isArray(rawCommands)) {
|
|
8884
8901
|
rawCommands.forEach((entry, index) => {
|
|
8885
|
-
const normalized =
|
|
8902
|
+
const normalized = normalizeMeshCommandConfig(entry, `${source}:validation.commands[${index}]`);
|
|
8886
8903
|
if (normalized.command) commands.push(normalized.command);
|
|
8887
8904
|
if (normalized.rejected) rejectedCommands.push(normalized.rejected);
|
|
8888
8905
|
});
|
|
@@ -8994,6 +9011,190 @@ function resolveMeshRefineValidationPlan(mesh, workspace) {
|
|
|
8994
9011
|
};
|
|
8995
9012
|
}
|
|
8996
9013
|
|
|
9014
|
+
// src/mesh/worktree-bootstrap-config.ts
|
|
9015
|
+
import { existsSync as existsSync6, readFileSync as readFileSync4 } from "fs";
|
|
9016
|
+
import { join as join6, resolve as pathResolve } from "path";
|
|
9017
|
+
import { execFile as execFile3 } from "child_process";
|
|
9018
|
+
import { promisify as promisify3 } from "util";
|
|
9019
|
+
import * as yaml2 from "js-yaml";
|
|
9020
|
+
var MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS = [
|
|
9021
|
+
".adhdev/worktree_bootstrap.json",
|
|
9022
|
+
".adhdev/worktree_bootstrap.yaml",
|
|
9023
|
+
".adhdev/worktree_bootstrap.yml",
|
|
9024
|
+
".adhdev/worktree-bootstrap.json",
|
|
9025
|
+
".adhdev/worktree-bootstrap.yaml",
|
|
9026
|
+
".adhdev/worktree-bootstrap.yml"
|
|
9027
|
+
];
|
|
9028
|
+
var MESH_WORKTREE_BOOTSTRAP_CONFIG_SCHEMA = {
|
|
9029
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
9030
|
+
title: "ADHDev Repo Mesh Worktree Bootstrap Config",
|
|
9031
|
+
type: "object",
|
|
9032
|
+
additionalProperties: false,
|
|
9033
|
+
required: ["version"],
|
|
9034
|
+
properties: {
|
|
9035
|
+
version: { const: 1 },
|
|
9036
|
+
enabled: { type: "boolean", default: true },
|
|
9037
|
+
runOnClone: { type: "boolean", default: true },
|
|
9038
|
+
required: { type: "boolean", default: true },
|
|
9039
|
+
staleInputs: { type: "array", maxItems: 16, items: { type: "string", minLength: 1 } },
|
|
9040
|
+
commands: {
|
|
9041
|
+
type: "array",
|
|
9042
|
+
minItems: 1,
|
|
9043
|
+
maxItems: 4,
|
|
9044
|
+
items: {
|
|
9045
|
+
type: "object",
|
|
9046
|
+
additionalProperties: false,
|
|
9047
|
+
required: ["command"],
|
|
9048
|
+
properties: {
|
|
9049
|
+
command: { type: "string", minLength: 1 },
|
|
9050
|
+
args: { type: "array", items: { type: "string" } },
|
|
9051
|
+
category: { enum: ["typecheck", "test", "lint", "build", "custom"] },
|
|
9052
|
+
cwd: { type: "string" },
|
|
9053
|
+
timeoutMs: { type: "number", minimum: 1e3, maximum: 6e5 },
|
|
9054
|
+
outputLimitBytes: { type: "number", minimum: 1024, maximum: 1048576 },
|
|
9055
|
+
env: { type: "object", additionalProperties: { type: "string" } }
|
|
9056
|
+
}
|
|
9057
|
+
}
|
|
9058
|
+
}
|
|
9059
|
+
}
|
|
9060
|
+
};
|
|
9061
|
+
var DEFAULT_TIMEOUT_MS2 = 12e4;
|
|
9062
|
+
var DEFAULT_OUTPUT_LIMIT_BYTES = 128 * 1024;
|
|
9063
|
+
var OUTPUT_SUMMARY_CHARS = 2e3;
|
|
9064
|
+
function parseConfigText2(path28, text) {
|
|
9065
|
+
if (/\.json$/i.test(path28)) return JSON.parse(text);
|
|
9066
|
+
return yaml2.load(text);
|
|
9067
|
+
}
|
|
9068
|
+
function truncateOutput(value) {
|
|
9069
|
+
const text = typeof value === "string" ? value : value == null ? "" : String(value);
|
|
9070
|
+
if (text.length <= OUTPUT_SUMMARY_CHARS) return text;
|
|
9071
|
+
return `${text.slice(0, OUTPUT_SUMMARY_CHARS)}
|
|
9072
|
+
[truncated ${text.length - OUTPUT_SUMMARY_CHARS} chars]`;
|
|
9073
|
+
}
|
|
9074
|
+
function validateMeshWorktreeBootstrapConfig(config, source = "inline") {
|
|
9075
|
+
const errors = [];
|
|
9076
|
+
const commands = [];
|
|
9077
|
+
const rejectedCommands = [];
|
|
9078
|
+
if (!isMeshConfigRecord(config)) return { valid: false, errors: ["config must be an object"], commands, rejectedCommands };
|
|
9079
|
+
if (config.version !== 1) errors.push("version must be 1");
|
|
9080
|
+
if (config.enabled !== void 0 && typeof config.enabled !== "boolean") errors.push("enabled must be a boolean when provided");
|
|
9081
|
+
if (config.runOnClone !== void 0 && typeof config.runOnClone !== "boolean") errors.push("runOnClone must be a boolean when provided");
|
|
9082
|
+
if (config.required !== void 0 && typeof config.required !== "boolean") errors.push("required must be a boolean when provided");
|
|
9083
|
+
if (config.staleInputs !== void 0 && (!Array.isArray(config.staleInputs) || !config.staleInputs.every((input) => typeof input === "string" && input.trim()))) {
|
|
9084
|
+
errors.push("staleInputs must be an array of non-empty strings when provided");
|
|
9085
|
+
}
|
|
9086
|
+
if (config.commands !== void 0 && !Array.isArray(config.commands)) errors.push("commands must be an array");
|
|
9087
|
+
if (Array.isArray(config.commands)) {
|
|
9088
|
+
config.commands.forEach((entry, index) => {
|
|
9089
|
+
const normalized = normalizeMeshCommandConfig(entry, `${source}:commands[${index}]`);
|
|
9090
|
+
if (normalized.command) commands.push(normalized.command);
|
|
9091
|
+
if (normalized.rejected) rejectedCommands.push(normalized.rejected);
|
|
9092
|
+
});
|
|
9093
|
+
}
|
|
9094
|
+
if (config.enabled !== false && config.runOnClone !== false && commands.length === 0) errors.push("commands must contain at least one command when bootstrap is enabled");
|
|
9095
|
+
if (rejectedCommands.length) errors.push("one or more bootstrap commands are invalid");
|
|
9096
|
+
return { valid: errors.length === 0, errors, commands, rejectedCommands };
|
|
9097
|
+
}
|
|
9098
|
+
function loadMeshWorktreeBootstrapConfig(mesh, workspace) {
|
|
9099
|
+
const inline = mesh?.worktreeBootstrapConfig || mesh?.policy?.worktreeBootstrapConfig || mesh?.policy?.worktreeBootstrap;
|
|
9100
|
+
if (inline !== void 0) {
|
|
9101
|
+
const validation = validateMeshWorktreeBootstrapConfig(inline, "mesh.policy.worktreeBootstrapConfig");
|
|
9102
|
+
if (!validation.valid) return { source: "mesh.policy.worktreeBootstrapConfig", sourceType: "invalid", error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
9103
|
+
return { config: inline, source: "mesh.policy.worktreeBootstrapConfig", sourceType: "mesh_policy" };
|
|
9104
|
+
}
|
|
9105
|
+
for (const relative3 of MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS) {
|
|
9106
|
+
const configPath = join6(workspace, relative3);
|
|
9107
|
+
if (!existsSync6(configPath)) continue;
|
|
9108
|
+
try {
|
|
9109
|
+
const parsed = parseConfigText2(configPath, readFileSync4(configPath, "utf-8"));
|
|
9110
|
+
const validation = validateMeshWorktreeBootstrapConfig(parsed, relative3);
|
|
9111
|
+
if (!validation.valid) return { source: relative3, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
9112
|
+
return { config: parsed, source: relative3, sourceType: "repo_file", path: configPath };
|
|
9113
|
+
} catch (error) {
|
|
9114
|
+
return { source: relative3, sourceType: "invalid", path: configPath, error: error?.message || String(error) };
|
|
9115
|
+
}
|
|
9116
|
+
}
|
|
9117
|
+
return { source: "unavailable", sourceType: "unavailable", error: `No worktree bootstrap config found. Checked: ${MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS.join(", ")}` };
|
|
9118
|
+
}
|
|
9119
|
+
async function runMeshWorktreeBootstrap(mesh, workspace) {
|
|
9120
|
+
const loaded = loadMeshWorktreeBootstrapConfig(mesh, workspace);
|
|
9121
|
+
if (!loaded.config) {
|
|
9122
|
+
return { status: "not_configured", required: false, configSource: loaded.source, configSourceType: loaded.sourceType, error: loaded.error };
|
|
9123
|
+
}
|
|
9124
|
+
const required = loaded.config.required !== false;
|
|
9125
|
+
if (loaded.config.enabled === false || loaded.config.runOnClone === false) {
|
|
9126
|
+
return { status: "disabled", required, configSource: loaded.path || loaded.source, configSourceType: loaded.sourceType };
|
|
9127
|
+
}
|
|
9128
|
+
const validation = validateMeshWorktreeBootstrapConfig(loaded.config, loaded.source);
|
|
9129
|
+
if (!validation.valid) {
|
|
9130
|
+
return { status: "failed", required, configSource: loaded.path || loaded.source, configSourceType: "invalid", error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")), commandsRun: [] };
|
|
9131
|
+
}
|
|
9132
|
+
const execFileAsync3 = promisify3(execFile3);
|
|
9133
|
+
const state = {
|
|
9134
|
+
status: "running",
|
|
9135
|
+
required,
|
|
9136
|
+
configSource: loaded.path || loaded.source,
|
|
9137
|
+
configSourceType: loaded.sourceType,
|
|
9138
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9139
|
+
commandsRun: [],
|
|
9140
|
+
staleInputs: loaded.config.staleInputs
|
|
9141
|
+
};
|
|
9142
|
+
for (const command of validation.commands) {
|
|
9143
|
+
const cwd = command.cwd ? pathResolve(workspace, command.cwd) : workspace;
|
|
9144
|
+
const startedAt = Date.now();
|
|
9145
|
+
state.lastCommand = command.displayCommand;
|
|
9146
|
+
try {
|
|
9147
|
+
const result = await execFileAsync3(command.command, command.args, {
|
|
9148
|
+
cwd,
|
|
9149
|
+
encoding: "utf8",
|
|
9150
|
+
timeout: command.timeoutMs || DEFAULT_TIMEOUT_MS2,
|
|
9151
|
+
maxBuffer: command.outputLimitBytes || DEFAULT_OUTPUT_LIMIT_BYTES,
|
|
9152
|
+
env: { ...process.env, CI: process.env.CI || "1", ...command.env || {} },
|
|
9153
|
+
windowsHide: true
|
|
9154
|
+
});
|
|
9155
|
+
state.commandsRun?.push({
|
|
9156
|
+
command: command.command,
|
|
9157
|
+
args: command.args,
|
|
9158
|
+
displayCommand: command.displayCommand,
|
|
9159
|
+
category: command.category,
|
|
9160
|
+
source: command.source,
|
|
9161
|
+
cwd,
|
|
9162
|
+
passed: true,
|
|
9163
|
+
durationMs: Date.now() - startedAt,
|
|
9164
|
+
exitCode: 0,
|
|
9165
|
+
stdout: truncateOutput(result.stdout),
|
|
9166
|
+
stderr: truncateOutput(result.stderr)
|
|
9167
|
+
});
|
|
9168
|
+
} catch (error) {
|
|
9169
|
+
const exitCode = typeof error?.code === "number" ? error.code : null;
|
|
9170
|
+
state.status = "failed";
|
|
9171
|
+
state.exitCode = exitCode;
|
|
9172
|
+
state.error = error?.message || String(error);
|
|
9173
|
+
state.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
9174
|
+
state.commandsRun?.push({
|
|
9175
|
+
command: command.command,
|
|
9176
|
+
args: command.args,
|
|
9177
|
+
displayCommand: command.displayCommand,
|
|
9178
|
+
category: command.category,
|
|
9179
|
+
source: command.source,
|
|
9180
|
+
cwd,
|
|
9181
|
+
passed: false,
|
|
9182
|
+
durationMs: Date.now() - startedAt,
|
|
9183
|
+
exitCode,
|
|
9184
|
+
signal: typeof error?.signal === "string" ? error.signal : null,
|
|
9185
|
+
timedOut: error?.killed === true || /timed out/i.test(String(error?.message || "")),
|
|
9186
|
+
stdout: truncateOutput(error?.stdout),
|
|
9187
|
+
stderr: truncateOutput(error?.stderr || error?.message)
|
|
9188
|
+
});
|
|
9189
|
+
return state;
|
|
9190
|
+
}
|
|
9191
|
+
}
|
|
9192
|
+
state.status = "ready";
|
|
9193
|
+
state.exitCode = 0;
|
|
9194
|
+
state.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
9195
|
+
return state;
|
|
9196
|
+
}
|
|
9197
|
+
|
|
8997
9198
|
// src/mesh/mesh-sync.ts
|
|
8998
9199
|
init_mesh_config();
|
|
8999
9200
|
async function syncMeshes(transport) {
|
|
@@ -9645,6 +9846,134 @@ function buildMeshActiveWork(opts) {
|
|
|
9645
9846
|
}
|
|
9646
9847
|
return { activeWork: records, staleDirectWork, staleDirectWorkNote, terminalDirectWork, summary };
|
|
9647
9848
|
}
|
|
9849
|
+
function buildCompactStaleDirectWorkSummary(staleDirectWork, opts = {}) {
|
|
9850
|
+
const sampleLimit = Math.max(0, Math.min(10, Math.floor(opts.sampleLimit ?? 3)));
|
|
9851
|
+
const reasonCounts = {};
|
|
9852
|
+
for (const entry of staleDirectWork) {
|
|
9853
|
+
const reason = entry.staleReason || "unknown";
|
|
9854
|
+
reasonCounts[reason] = (reasonCounts[reason] || 0) + 1;
|
|
9855
|
+
}
|
|
9856
|
+
return {
|
|
9857
|
+
count: staleDirectWork.length,
|
|
9858
|
+
sampleLimit,
|
|
9859
|
+
sample: staleDirectWork.slice(0, sampleLimit).map((entry) => ({
|
|
9860
|
+
taskId: entry.taskId,
|
|
9861
|
+
status: entry.status,
|
|
9862
|
+
nodeId: entry.nodeId,
|
|
9863
|
+
sessionId: entry.sessionId,
|
|
9864
|
+
taskTitle: entry.taskTitle,
|
|
9865
|
+
createdAt: entry.createdAt,
|
|
9866
|
+
staleReason: entry.staleReason
|
|
9867
|
+
})),
|
|
9868
|
+
reasonCounts,
|
|
9869
|
+
detailHint: opts.detailHint || "Stale direct records are historical recovery evidence only. Use mesh_task_history for full ledger details, or request includeStaleDirectWorkDetails when supported by the caller.",
|
|
9870
|
+
...opts.note ? { note: opts.note } : {}
|
|
9871
|
+
};
|
|
9872
|
+
}
|
|
9873
|
+
|
|
9874
|
+
// src/mesh/mesh-refine-status.ts
|
|
9875
|
+
function readString3(value) {
|
|
9876
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
9877
|
+
}
|
|
9878
|
+
function readRecord(value) {
|
|
9879
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
9880
|
+
}
|
|
9881
|
+
function eventStatus(event, fallback) {
|
|
9882
|
+
if (event === "refine:accepted") return "accepted";
|
|
9883
|
+
if (event === "refine:completed") return "completed";
|
|
9884
|
+
if (event === "refine:failed") return "failed";
|
|
9885
|
+
if (fallback === "completed" || fallback === "failed" || fallback === "accepted") return fallback;
|
|
9886
|
+
return void 0;
|
|
9887
|
+
}
|
|
9888
|
+
function ledgerStatus(kind, fallback) {
|
|
9889
|
+
if (kind === "task_completed") return "completed";
|
|
9890
|
+
if (kind === "task_failed") return "failed";
|
|
9891
|
+
if (fallback === "accepted") return "accepted";
|
|
9892
|
+
return "running";
|
|
9893
|
+
}
|
|
9894
|
+
function instructionForStatus(status) {
|
|
9895
|
+
if (status === "accepted") return "Refine job is accepted; wait for asyncRefineJobs or pendingCoordinatorEvents to report running/completed/failed.";
|
|
9896
|
+
if (status === "running") return "Refine job is running; do not poll the ledger repeatedly. Watch asyncRefineJobs or pendingCoordinatorEvents for the terminal result.";
|
|
9897
|
+
if (status === "completed") return "Refine job completed; inspect branch convergence and cleanup evidence before reporting final merge state.";
|
|
9898
|
+
return "Refine job failed; inspect result/finalBranchConvergenceState in mesh_task_history, fix the blocker, then rerun mesh_refine_node when ready.";
|
|
9899
|
+
}
|
|
9900
|
+
function mergeJob(jobs, patch) {
|
|
9901
|
+
const jobId = readString3(patch.jobId);
|
|
9902
|
+
if (!jobId) return;
|
|
9903
|
+
const previous = jobs.get(jobId);
|
|
9904
|
+
const status = patch.status || previous?.status || "running";
|
|
9905
|
+
const definedPatch = Object.fromEntries(
|
|
9906
|
+
Object.entries(patch).filter(([, value]) => value !== void 0)
|
|
9907
|
+
);
|
|
9908
|
+
jobs.set(jobId, {
|
|
9909
|
+
...previous,
|
|
9910
|
+
...definedPatch,
|
|
9911
|
+
jobId,
|
|
9912
|
+
status,
|
|
9913
|
+
instruction: instructionForStatus(status)
|
|
9914
|
+
});
|
|
9915
|
+
}
|
|
9916
|
+
function buildMeshAsyncRefineJobs(args) {
|
|
9917
|
+
const jobs = /* @__PURE__ */ new Map();
|
|
9918
|
+
for (const entry of args.ledgerEntries || []) {
|
|
9919
|
+
const payload = readRecord(entry.payload);
|
|
9920
|
+
if (payload?.source !== "refine_mesh_node_async_job") continue;
|
|
9921
|
+
const refineJob = readRecord(payload.refineJob);
|
|
9922
|
+
const result = readRecord(payload.result);
|
|
9923
|
+
const finalState = readRecord(payload.finalBranchConvergenceState) || readRecord(result?.finalBranchConvergenceState);
|
|
9924
|
+
const jobId = readString3(refineJob?.jobId);
|
|
9925
|
+
if (!jobId) continue;
|
|
9926
|
+
const status = ledgerStatus(entry.kind, readString3(refineJob?.status));
|
|
9927
|
+
mergeJob(jobs, {
|
|
9928
|
+
jobId,
|
|
9929
|
+
interactionId: readString3(refineJob?.interactionId),
|
|
9930
|
+
status,
|
|
9931
|
+
meshId: readString3(refineJob?.meshId) || args.meshId,
|
|
9932
|
+
nodeId: readString3(refineJob?.nodeId) || entry.nodeId,
|
|
9933
|
+
targetNodeId: readString3(refineJob?.nodeId) || entry.nodeId,
|
|
9934
|
+
targetDaemonId: readString3(refineJob?.targetDaemonId),
|
|
9935
|
+
workspace: readString3(refineJob?.workspace),
|
|
9936
|
+
branch: readString3(result?.branch) || readString3(finalState?.branch),
|
|
9937
|
+
into: readString3(result?.into) || readString3(finalState?.baseBranch),
|
|
9938
|
+
startedAt: readString3(refineJob?.startedAt),
|
|
9939
|
+
completedAt: readString3(refineJob?.completedAt),
|
|
9940
|
+
retryOfJobId: readString3(refineJob?.retryOfJobId) || readString3(payload.retryOfJobId),
|
|
9941
|
+
lastLedgerKind: entry.kind,
|
|
9942
|
+
lastUpdatedAt: entry.timestamp
|
|
9943
|
+
});
|
|
9944
|
+
}
|
|
9945
|
+
for (const event of args.pendingEvents || []) {
|
|
9946
|
+
const metadata = readRecord(event.metadataEvent);
|
|
9947
|
+
if (metadata?.source !== "refine_mesh_node_async_job") continue;
|
|
9948
|
+
const result = readRecord(metadata.result);
|
|
9949
|
+
const finalState = readRecord(result?.finalBranchConvergenceState);
|
|
9950
|
+
const jobId = readString3(metadata.jobId);
|
|
9951
|
+
if (!jobId) continue;
|
|
9952
|
+
const status = eventStatus(event.event, readString3(metadata.status));
|
|
9953
|
+
mergeJob(jobs, {
|
|
9954
|
+
jobId,
|
|
9955
|
+
interactionId: readString3(metadata.interactionId),
|
|
9956
|
+
...status ? { status } : {},
|
|
9957
|
+
meshId: readString3(metadata.meshId) || event.meshId || args.meshId,
|
|
9958
|
+
nodeId: readString3(metadata.nodeId) || event.nodeId,
|
|
9959
|
+
targetNodeId: readString3(metadata.nodeId) || event.nodeId,
|
|
9960
|
+
targetDaemonId: readString3(metadata.targetDaemonId),
|
|
9961
|
+
workspace: readString3(metadata.workspace) || event.workspace,
|
|
9962
|
+
branch: readString3(result?.branch) || readString3(finalState?.branch),
|
|
9963
|
+
into: readString3(result?.into) || readString3(finalState?.baseBranch),
|
|
9964
|
+
startedAt: readString3(metadata.startedAt),
|
|
9965
|
+
completedAt: readString3(metadata.completedAt),
|
|
9966
|
+
retryOfJobId: readString3(metadata.retryOfJobId),
|
|
9967
|
+
lastEvent: event.event,
|
|
9968
|
+
lastUpdatedAt: new Date(event.queuedAt).toISOString()
|
|
9969
|
+
});
|
|
9970
|
+
}
|
|
9971
|
+
return Array.from(jobs.values()).sort((a, b) => {
|
|
9972
|
+
const aTime = new Date(a.lastUpdatedAt || a.startedAt || "").getTime();
|
|
9973
|
+
const bTime = new Date(b.lastUpdatedAt || b.startedAt || "").getTime();
|
|
9974
|
+
return (Number.isFinite(bTime) ? bTime : 0) - (Number.isFinite(aTime) ? aTime : 0);
|
|
9975
|
+
});
|
|
9976
|
+
}
|
|
9648
9977
|
|
|
9649
9978
|
// src/index.ts
|
|
9650
9979
|
init_mesh_host_ownership();
|
|
@@ -9762,8 +10091,8 @@ var P2pRelayFailureError = class extends Error {
|
|
|
9762
10091
|
|
|
9763
10092
|
// src/config/state-store.ts
|
|
9764
10093
|
init_config();
|
|
9765
|
-
import { existsSync as
|
|
9766
|
-
import { join as
|
|
10094
|
+
import { existsSync as existsSync12, readFileSync as readFileSync8, writeFileSync as writeFileSync3 } from "fs";
|
|
10095
|
+
import { join as join12 } from "path";
|
|
9767
10096
|
var DEFAULT_STATE = {
|
|
9768
10097
|
recentActivity: [],
|
|
9769
10098
|
savedProviderSessions: [],
|
|
@@ -9776,7 +10105,7 @@ function isPlainObject2(value) {
|
|
|
9776
10105
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
9777
10106
|
}
|
|
9778
10107
|
function getStatePath() {
|
|
9779
|
-
return
|
|
10108
|
+
return join12(getConfigDir(), "state.json");
|
|
9780
10109
|
}
|
|
9781
10110
|
function normalizeState(raw) {
|
|
9782
10111
|
const parsed = isPlainObject2(raw) ? raw : {};
|
|
@@ -9812,11 +10141,11 @@ function normalizeState(raw) {
|
|
|
9812
10141
|
}
|
|
9813
10142
|
function loadState() {
|
|
9814
10143
|
const statePath = getStatePath();
|
|
9815
|
-
if (!
|
|
10144
|
+
if (!existsSync12(statePath)) {
|
|
9816
10145
|
return { ...DEFAULT_STATE };
|
|
9817
10146
|
}
|
|
9818
10147
|
try {
|
|
9819
|
-
const raw =
|
|
10148
|
+
const raw = readFileSync8(statePath, "utf-8");
|
|
9820
10149
|
return normalizeState(JSON.parse(raw));
|
|
9821
10150
|
} catch {
|
|
9822
10151
|
return { ...DEFAULT_STATE };
|
|
@@ -9833,11 +10162,11 @@ function resetState() {
|
|
|
9833
10162
|
|
|
9834
10163
|
// src/detection/ide-detector.ts
|
|
9835
10164
|
import { exec as exec2 } from "child_process";
|
|
9836
|
-
import { promisify as
|
|
9837
|
-
import { existsSync as
|
|
10165
|
+
import { promisify as promisify4 } from "util";
|
|
10166
|
+
import { existsSync as existsSync13, statSync as statSync4 } from "fs";
|
|
9838
10167
|
import { platform as platform2, homedir as homedir5 } from "os";
|
|
9839
10168
|
import * as path10 from "path";
|
|
9840
|
-
var execAsync2 =
|
|
10169
|
+
var execAsync2 = promisify4(exec2);
|
|
9841
10170
|
var BUILTIN_IDE_DEFINITIONS = [];
|
|
9842
10171
|
var registeredIDEs = /* @__PURE__ */ new Map();
|
|
9843
10172
|
function registerIDEDefinition(def) {
|
|
@@ -9859,7 +10188,7 @@ function findCliCommand(command) {
|
|
|
9859
10188
|
if (path10.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
|
|
9860
10189
|
const candidate = trimmed.startsWith("~") ? path10.join(homedir5(), trimmed.slice(1)) : trimmed;
|
|
9861
10190
|
const resolved = path10.isAbsolute(candidate) ? candidate : path10.resolve(candidate);
|
|
9862
|
-
return
|
|
10191
|
+
return existsSync13(resolved) ? resolved : null;
|
|
9863
10192
|
}
|
|
9864
10193
|
const isWin = platform2() === "win32";
|
|
9865
10194
|
const paths = (process.env.PATH || "").split(isWin ? ";" : ":");
|
|
@@ -9869,7 +10198,7 @@ function findCliCommand(command) {
|
|
|
9869
10198
|
for (const ext of exes) {
|
|
9870
10199
|
const fullPath = path10.join(p, trimmed + ext);
|
|
9871
10200
|
try {
|
|
9872
|
-
if (
|
|
10201
|
+
if (existsSync13(fullPath)) {
|
|
9873
10202
|
const stat2 = statSync4(fullPath);
|
|
9874
10203
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
9875
10204
|
return fullPath;
|
|
@@ -9899,9 +10228,9 @@ function checkPathExists(paths) {
|
|
|
9899
10228
|
if (normalized.includes("*")) {
|
|
9900
10229
|
const username = home.split(/[\\/]/).pop() || "";
|
|
9901
10230
|
const resolved = normalized.replace("*", username);
|
|
9902
|
-
if (
|
|
10231
|
+
if (existsSync13(resolved)) return resolved;
|
|
9903
10232
|
} else {
|
|
9904
|
-
if (
|
|
10233
|
+
if (existsSync13(normalized)) return normalized;
|
|
9905
10234
|
}
|
|
9906
10235
|
}
|
|
9907
10236
|
return null;
|
|
@@ -9915,7 +10244,7 @@ async function detectIDEs(providerLoader) {
|
|
|
9915
10244
|
let resolvedCli = cliPath;
|
|
9916
10245
|
if (!resolvedCli && appPath && os22 === "darwin") {
|
|
9917
10246
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
9918
|
-
if (
|
|
10247
|
+
if (existsSync13(bundledCli)) resolvedCli = bundledCli;
|
|
9919
10248
|
}
|
|
9920
10249
|
if (!resolvedCli && appPath && os22 === "win32") {
|
|
9921
10250
|
const { dirname: dirname9 } = await import("path");
|
|
@@ -9928,7 +10257,7 @@ async function detectIDEs(providerLoader) {
|
|
|
9928
10257
|
`${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
|
|
9929
10258
|
];
|
|
9930
10259
|
for (const c of candidates) {
|
|
9931
|
-
if (
|
|
10260
|
+
if (existsSync13(c)) {
|
|
9932
10261
|
resolvedCli = c;
|
|
9933
10262
|
break;
|
|
9934
10263
|
}
|
|
@@ -9956,8 +10285,8 @@ init_cli_detector();
|
|
|
9956
10285
|
// src/system/host-memory.ts
|
|
9957
10286
|
import * as os4 from "os";
|
|
9958
10287
|
import { exec as exec3 } from "child_process";
|
|
9959
|
-
import { promisify as
|
|
9960
|
-
var execAsync3 =
|
|
10288
|
+
import { promisify as promisify5 } from "util";
|
|
10289
|
+
var execAsync3 = promisify5(exec3);
|
|
9961
10290
|
var cachedDarwinAvail = null;
|
|
9962
10291
|
var darwinMemoryInterval = null;
|
|
9963
10292
|
async function updateDarwinMemoryCache() {
|
|
@@ -10244,7 +10573,7 @@ var DaemonCdpManager = class {
|
|
|
10244
10573
|
* Returns multiple entries if multiple IDE windows are open on same port
|
|
10245
10574
|
*/
|
|
10246
10575
|
static listAllTargets(port) {
|
|
10247
|
-
return new Promise((
|
|
10576
|
+
return new Promise((resolve17) => {
|
|
10248
10577
|
const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
|
|
10249
10578
|
let data = "";
|
|
10250
10579
|
res.on("data", (chunk) => data += chunk.toString());
|
|
@@ -10260,16 +10589,16 @@ var DaemonCdpManager = class {
|
|
|
10260
10589
|
(t) => !isNonMain(t.title || "") && t.url?.includes("workbench.html") && !t.url?.includes("agent")
|
|
10261
10590
|
);
|
|
10262
10591
|
const fallbackPages = pages.filter((t) => !isNonMain(t.title || ""));
|
|
10263
|
-
|
|
10592
|
+
resolve17(mainPages.length > 0 ? mainPages : fallbackPages);
|
|
10264
10593
|
} catch {
|
|
10265
|
-
|
|
10594
|
+
resolve17([]);
|
|
10266
10595
|
}
|
|
10267
10596
|
});
|
|
10268
10597
|
});
|
|
10269
|
-
req.on("error", () =>
|
|
10598
|
+
req.on("error", () => resolve17([]));
|
|
10270
10599
|
req.setTimeout(2e3, () => {
|
|
10271
10600
|
req.destroy();
|
|
10272
|
-
|
|
10601
|
+
resolve17([]);
|
|
10273
10602
|
});
|
|
10274
10603
|
});
|
|
10275
10604
|
}
|
|
@@ -10309,7 +10638,7 @@ var DaemonCdpManager = class {
|
|
|
10309
10638
|
}
|
|
10310
10639
|
}
|
|
10311
10640
|
findTargetOnPort(port) {
|
|
10312
|
-
return new Promise((
|
|
10641
|
+
return new Promise((resolve17) => {
|
|
10313
10642
|
const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
|
|
10314
10643
|
let data = "";
|
|
10315
10644
|
res.on("data", (chunk) => data += chunk.toString());
|
|
@@ -10320,7 +10649,7 @@ var DaemonCdpManager = class {
|
|
|
10320
10649
|
(t) => (t.type === "page" || t.type === "browser" || t.type === "Page") && t.webSocketDebuggerUrl
|
|
10321
10650
|
);
|
|
10322
10651
|
if (pages.length === 0) {
|
|
10323
|
-
|
|
10652
|
+
resolve17(targets.find((t) => t.webSocketDebuggerUrl) || null);
|
|
10324
10653
|
return;
|
|
10325
10654
|
}
|
|
10326
10655
|
const titleFilteredPages = pages.filter((t) => !this.isNonMainTitle(t.title || ""));
|
|
@@ -10339,25 +10668,25 @@ var DaemonCdpManager = class {
|
|
|
10339
10668
|
this._targetId = selected.target.id;
|
|
10340
10669
|
}
|
|
10341
10670
|
this._pageTitle = selected.target.title || "";
|
|
10342
|
-
|
|
10671
|
+
resolve17(selected.target);
|
|
10343
10672
|
return;
|
|
10344
10673
|
}
|
|
10345
10674
|
if (previousTargetId) {
|
|
10346
10675
|
this.log(`[CDP] Target ${previousTargetId} not found in page list`);
|
|
10347
|
-
|
|
10676
|
+
resolve17(null);
|
|
10348
10677
|
return;
|
|
10349
10678
|
}
|
|
10350
10679
|
this._pageTitle = list[0]?.title || "";
|
|
10351
|
-
|
|
10680
|
+
resolve17(list[0]);
|
|
10352
10681
|
} catch {
|
|
10353
|
-
|
|
10682
|
+
resolve17(null);
|
|
10354
10683
|
}
|
|
10355
10684
|
});
|
|
10356
10685
|
});
|
|
10357
|
-
req.on("error", () =>
|
|
10686
|
+
req.on("error", () => resolve17(null));
|
|
10358
10687
|
req.setTimeout(2e3, () => {
|
|
10359
10688
|
req.destroy();
|
|
10360
|
-
|
|
10689
|
+
resolve17(null);
|
|
10361
10690
|
});
|
|
10362
10691
|
});
|
|
10363
10692
|
}
|
|
@@ -10368,7 +10697,7 @@ var DaemonCdpManager = class {
|
|
|
10368
10697
|
this.extensionProviders = providers;
|
|
10369
10698
|
}
|
|
10370
10699
|
connectToTarget(wsUrl) {
|
|
10371
|
-
return new Promise((
|
|
10700
|
+
return new Promise((resolve17) => {
|
|
10372
10701
|
this.ws = new WebSocket(wsUrl);
|
|
10373
10702
|
this.ws.on("open", async () => {
|
|
10374
10703
|
this._connected = true;
|
|
@@ -10378,17 +10707,17 @@ var DaemonCdpManager = class {
|
|
|
10378
10707
|
}
|
|
10379
10708
|
this.connectBrowserWs().catch(() => {
|
|
10380
10709
|
});
|
|
10381
|
-
|
|
10710
|
+
resolve17(true);
|
|
10382
10711
|
});
|
|
10383
10712
|
this.ws.on("message", (data) => {
|
|
10384
10713
|
try {
|
|
10385
10714
|
const msg = JSON.parse(data.toString());
|
|
10386
10715
|
if (msg.id && this.pending.has(msg.id)) {
|
|
10387
|
-
const { resolve:
|
|
10716
|
+
const { resolve: resolve18, reject } = this.pending.get(msg.id);
|
|
10388
10717
|
this.pending.delete(msg.id);
|
|
10389
10718
|
this.failureCount = 0;
|
|
10390
10719
|
if (msg.error) reject(new Error(msg.error.message));
|
|
10391
|
-
else
|
|
10720
|
+
else resolve18(msg.result);
|
|
10392
10721
|
} else if (msg.method === "Runtime.executionContextCreated") {
|
|
10393
10722
|
this.contexts.add(msg.params.context.id);
|
|
10394
10723
|
} else if (msg.method === "Runtime.executionContextDestroyed") {
|
|
@@ -10411,7 +10740,7 @@ var DaemonCdpManager = class {
|
|
|
10411
10740
|
this.ws.on("error", (err) => {
|
|
10412
10741
|
this.log(`[CDP] WebSocket error: ${err.message}`);
|
|
10413
10742
|
this._connected = false;
|
|
10414
|
-
|
|
10743
|
+
resolve17(false);
|
|
10415
10744
|
});
|
|
10416
10745
|
});
|
|
10417
10746
|
}
|
|
@@ -10425,7 +10754,7 @@ var DaemonCdpManager = class {
|
|
|
10425
10754
|
return;
|
|
10426
10755
|
}
|
|
10427
10756
|
this.log(`[CDP] Connecting browser WS for target discovery...`);
|
|
10428
|
-
await new Promise((
|
|
10757
|
+
await new Promise((resolve17, reject) => {
|
|
10429
10758
|
this.browserWs = new WebSocket(browserWsUrl);
|
|
10430
10759
|
this.browserWs.on("open", async () => {
|
|
10431
10760
|
this._browserConnected = true;
|
|
@@ -10435,16 +10764,16 @@ var DaemonCdpManager = class {
|
|
|
10435
10764
|
} catch (e) {
|
|
10436
10765
|
this.log(`[CDP] setDiscoverTargets failed: ${e.message}`);
|
|
10437
10766
|
}
|
|
10438
|
-
|
|
10767
|
+
resolve17();
|
|
10439
10768
|
});
|
|
10440
10769
|
this.browserWs.on("message", (data) => {
|
|
10441
10770
|
try {
|
|
10442
10771
|
const msg = JSON.parse(data.toString());
|
|
10443
10772
|
if (msg.id && this.browserPending.has(msg.id)) {
|
|
10444
|
-
const { resolve:
|
|
10773
|
+
const { resolve: resolve18, reject: reject2 } = this.browserPending.get(msg.id);
|
|
10445
10774
|
this.browserPending.delete(msg.id);
|
|
10446
10775
|
if (msg.error) reject2(new Error(msg.error.message));
|
|
10447
|
-
else
|
|
10776
|
+
else resolve18(msg.result);
|
|
10448
10777
|
}
|
|
10449
10778
|
} catch {
|
|
10450
10779
|
}
|
|
@@ -10464,31 +10793,31 @@ var DaemonCdpManager = class {
|
|
|
10464
10793
|
}
|
|
10465
10794
|
}
|
|
10466
10795
|
getBrowserWsUrl() {
|
|
10467
|
-
return new Promise((
|
|
10796
|
+
return new Promise((resolve17) => {
|
|
10468
10797
|
const req = http.get(`http://127.0.0.1:${this.port}/json/version`, (res) => {
|
|
10469
10798
|
let data = "";
|
|
10470
10799
|
res.on("data", (chunk) => data += chunk.toString());
|
|
10471
10800
|
res.on("end", () => {
|
|
10472
10801
|
try {
|
|
10473
10802
|
const info = JSON.parse(data);
|
|
10474
|
-
|
|
10803
|
+
resolve17(info.webSocketDebuggerUrl || null);
|
|
10475
10804
|
} catch {
|
|
10476
|
-
|
|
10805
|
+
resolve17(null);
|
|
10477
10806
|
}
|
|
10478
10807
|
});
|
|
10479
10808
|
});
|
|
10480
|
-
req.on("error", () =>
|
|
10809
|
+
req.on("error", () => resolve17(null));
|
|
10481
10810
|
req.setTimeout(3e3, () => {
|
|
10482
10811
|
req.destroy();
|
|
10483
|
-
|
|
10812
|
+
resolve17(null);
|
|
10484
10813
|
});
|
|
10485
10814
|
});
|
|
10486
10815
|
}
|
|
10487
10816
|
sendBrowser(method, params = {}, timeoutMs = 15e3) {
|
|
10488
|
-
return new Promise((
|
|
10817
|
+
return new Promise((resolve17, reject) => {
|
|
10489
10818
|
if (!this.browserWs || !this._browserConnected) return reject(new Error("Browser WS not connected"));
|
|
10490
10819
|
const id = this.browserMsgId++;
|
|
10491
|
-
this.browserPending.set(id, { resolve:
|
|
10820
|
+
this.browserPending.set(id, { resolve: resolve17, reject });
|
|
10492
10821
|
this.browserWs.send(JSON.stringify({ id, method, params }));
|
|
10493
10822
|
setTimeout(() => {
|
|
10494
10823
|
if (this.browserPending.has(id)) {
|
|
@@ -10528,11 +10857,11 @@ var DaemonCdpManager = class {
|
|
|
10528
10857
|
}
|
|
10529
10858
|
// ─── CDP Protocol ────────────────────────────────────────
|
|
10530
10859
|
sendInternal(method, params = {}, timeoutMs = 15e3) {
|
|
10531
|
-
return new Promise((
|
|
10860
|
+
return new Promise((resolve17, reject) => {
|
|
10532
10861
|
if (!this.ws || !this._connected) return reject(new Error("CDP not connected"));
|
|
10533
10862
|
if (this.ws.readyState !== WebSocket.OPEN) return reject(new Error("WebSocket not open"));
|
|
10534
10863
|
const id = this.msgId++;
|
|
10535
|
-
this.pending.set(id, { resolve:
|
|
10864
|
+
this.pending.set(id, { resolve: resolve17, reject });
|
|
10536
10865
|
this.ws.send(JSON.stringify({ id, method, params }));
|
|
10537
10866
|
setTimeout(() => {
|
|
10538
10867
|
if (this.pending.has(id)) {
|
|
@@ -10781,7 +11110,7 @@ var DaemonCdpManager = class {
|
|
|
10781
11110
|
const browserWs = this.browserWs;
|
|
10782
11111
|
let msgId = this.browserMsgId;
|
|
10783
11112
|
const sendWs = (method, params = {}, sessionId) => {
|
|
10784
|
-
return new Promise((
|
|
11113
|
+
return new Promise((resolve17, reject) => {
|
|
10785
11114
|
const mid = msgId++;
|
|
10786
11115
|
this.browserMsgId = msgId;
|
|
10787
11116
|
const handler = (raw) => {
|
|
@@ -10790,7 +11119,7 @@ var DaemonCdpManager = class {
|
|
|
10790
11119
|
if (msg.id === mid) {
|
|
10791
11120
|
browserWs.removeListener("message", handler);
|
|
10792
11121
|
if (msg.error) reject(new Error(msg.error.message || JSON.stringify(msg.error)));
|
|
10793
|
-
else
|
|
11122
|
+
else resolve17(msg.result);
|
|
10794
11123
|
}
|
|
10795
11124
|
} catch {
|
|
10796
11125
|
}
|
|
@@ -10991,14 +11320,14 @@ var DaemonCdpManager = class {
|
|
|
10991
11320
|
if (!ws || ws.readyState !== WebSocket.OPEN) {
|
|
10992
11321
|
throw new Error("CDP not connected");
|
|
10993
11322
|
}
|
|
10994
|
-
return new Promise((
|
|
11323
|
+
return new Promise((resolve17, reject) => {
|
|
10995
11324
|
const id = getNextId();
|
|
10996
11325
|
pendingMap.set(id, {
|
|
10997
11326
|
resolve: (result) => {
|
|
10998
11327
|
if (result?.result?.subtype === "error") {
|
|
10999
11328
|
reject(new Error(result.result.description));
|
|
11000
11329
|
} else {
|
|
11001
|
-
|
|
11330
|
+
resolve17(result?.result?.value);
|
|
11002
11331
|
}
|
|
11003
11332
|
},
|
|
11004
11333
|
reject
|
|
@@ -11030,10 +11359,10 @@ var DaemonCdpManager = class {
|
|
|
11030
11359
|
throw new Error("CDP not connected");
|
|
11031
11360
|
}
|
|
11032
11361
|
const sendViaSession = (method, params = {}) => {
|
|
11033
|
-
return new Promise((
|
|
11362
|
+
return new Promise((resolve17, reject) => {
|
|
11034
11363
|
const pendingMap = this._browserConnected ? this.browserPending : this.pending;
|
|
11035
11364
|
const id = this._browserConnected ? this.browserMsgId++ : this.msgId++;
|
|
11036
|
-
pendingMap.set(id, { resolve:
|
|
11365
|
+
pendingMap.set(id, { resolve: resolve17, reject });
|
|
11037
11366
|
ws.send(JSON.stringify({ id, sessionId, method, params }));
|
|
11038
11367
|
setTimeout(() => {
|
|
11039
11368
|
if (pendingMap.has(id)) {
|
|
@@ -16135,7 +16464,7 @@ function getSendChatInputEnvelope(args) {
|
|
|
16135
16464
|
return normalizeInputEnvelope(args?.input ? { input: args.input } : args);
|
|
16136
16465
|
}
|
|
16137
16466
|
function sleep(ms) {
|
|
16138
|
-
return new Promise((
|
|
16467
|
+
return new Promise((resolve17) => setTimeout(resolve17, ms));
|
|
16139
16468
|
}
|
|
16140
16469
|
async function waitOnceForFreshHermesCliStart(adapter, log) {
|
|
16141
16470
|
if (adapter.cliType !== "hermes-cli") return;
|
|
@@ -16922,7 +17251,7 @@ function getCliVisibleTranscriptCount(adapter) {
|
|
|
16922
17251
|
async function getStableExtensionBaseline(h) {
|
|
16923
17252
|
const first = await readExtensionChatState(h);
|
|
16924
17253
|
if (getStateMessageCount(first) > 0 || getStateLastSignature(first)) return first;
|
|
16925
|
-
await new Promise((
|
|
17254
|
+
await new Promise((resolve17) => setTimeout(resolve17, 150));
|
|
16926
17255
|
const second = await readExtensionChatState(h);
|
|
16927
17256
|
return getStateMessageCount(second) >= getStateMessageCount(first) ? second : first;
|
|
16928
17257
|
}
|
|
@@ -16930,7 +17259,7 @@ async function verifyExtensionSendObserved(h, before) {
|
|
|
16930
17259
|
const beforeCount = getStateMessageCount(before);
|
|
16931
17260
|
const beforeSignature = getStateLastSignature(before);
|
|
16932
17261
|
for (let attempt = 0; attempt < 12; attempt += 1) {
|
|
16933
|
-
await new Promise((
|
|
17262
|
+
await new Promise((resolve17) => setTimeout(resolve17, 250));
|
|
16934
17263
|
const state = await readExtensionChatState(h);
|
|
16935
17264
|
if (state?.status === "waiting_approval") return true;
|
|
16936
17265
|
const afterCount = getStateMessageCount(state);
|
|
@@ -18819,7 +19148,7 @@ async function executeProviderScript(h, args, scriptName) {
|
|
|
18819
19148
|
const enterCount = cliCommand.enterCount || 1;
|
|
18820
19149
|
await adapter.writeRaw(cliCommand.text + "\r");
|
|
18821
19150
|
for (let i = 1; i < enterCount; i += 1) {
|
|
18822
|
-
await new Promise((
|
|
19151
|
+
await new Promise((resolve17) => setTimeout(resolve17, 50));
|
|
18823
19152
|
await adapter.writeRaw("\r");
|
|
18824
19153
|
}
|
|
18825
19154
|
}
|
|
@@ -19508,7 +19837,7 @@ var DaemonCommandHandler = class {
|
|
|
19508
19837
|
try {
|
|
19509
19838
|
const http3 = await import("http");
|
|
19510
19839
|
const postData = JSON.stringify(body);
|
|
19511
|
-
const result = await new Promise((
|
|
19840
|
+
const result = await new Promise((resolve17, reject) => {
|
|
19512
19841
|
const req = http3.request({
|
|
19513
19842
|
hostname: "127.0.0.1",
|
|
19514
19843
|
port: 19280,
|
|
@@ -19520,9 +19849,9 @@ var DaemonCommandHandler = class {
|
|
|
19520
19849
|
res.on("data", (chunk) => data += chunk);
|
|
19521
19850
|
res.on("end", () => {
|
|
19522
19851
|
try {
|
|
19523
|
-
|
|
19852
|
+
resolve17(JSON.parse(data));
|
|
19524
19853
|
} catch {
|
|
19525
|
-
|
|
19854
|
+
resolve17({ raw: data });
|
|
19526
19855
|
}
|
|
19527
19856
|
});
|
|
19528
19857
|
});
|
|
@@ -19540,15 +19869,15 @@ var DaemonCommandHandler = class {
|
|
|
19540
19869
|
if (!providerType) return { success: false, error: "providerType required" };
|
|
19541
19870
|
try {
|
|
19542
19871
|
const http3 = await import("http");
|
|
19543
|
-
const result = await new Promise((
|
|
19872
|
+
const result = await new Promise((resolve17, reject) => {
|
|
19544
19873
|
http3.get(`http://127.0.0.1:19280/api/providers/${providerType}/${endpoint}`, (res) => {
|
|
19545
19874
|
let data = "";
|
|
19546
19875
|
res.on("data", (chunk) => data += chunk);
|
|
19547
19876
|
res.on("end", () => {
|
|
19548
19877
|
try {
|
|
19549
|
-
|
|
19878
|
+
resolve17(JSON.parse(data));
|
|
19550
19879
|
} catch {
|
|
19551
|
-
|
|
19880
|
+
resolve17({ raw: data });
|
|
19552
19881
|
}
|
|
19553
19882
|
});
|
|
19554
19883
|
}).on("error", reject);
|
|
@@ -19562,7 +19891,7 @@ var DaemonCommandHandler = class {
|
|
|
19562
19891
|
try {
|
|
19563
19892
|
const http3 = await import("http");
|
|
19564
19893
|
const postData = JSON.stringify(args || {});
|
|
19565
|
-
const result = await new Promise((
|
|
19894
|
+
const result = await new Promise((resolve17, reject) => {
|
|
19566
19895
|
const req = http3.request({
|
|
19567
19896
|
hostname: "127.0.0.1",
|
|
19568
19897
|
port: 19280,
|
|
@@ -19574,9 +19903,9 @@ var DaemonCommandHandler = class {
|
|
|
19574
19903
|
res.on("data", (chunk) => data += chunk);
|
|
19575
19904
|
res.on("end", () => {
|
|
19576
19905
|
try {
|
|
19577
|
-
|
|
19906
|
+
resolve17(JSON.parse(data));
|
|
19578
19907
|
} catch {
|
|
19579
|
-
|
|
19908
|
+
resolve17({ raw: data });
|
|
19580
19909
|
}
|
|
19581
19910
|
});
|
|
19582
19911
|
});
|
|
@@ -19598,7 +19927,7 @@ init_config();
|
|
|
19598
19927
|
import * as os13 from "os";
|
|
19599
19928
|
import * as path18 from "path";
|
|
19600
19929
|
import * as crypto4 from "crypto";
|
|
19601
|
-
import { existsSync as
|
|
19930
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync10, writeFileSync as writeFileSync8 } from "fs";
|
|
19602
19931
|
import { execFileSync } from "child_process";
|
|
19603
19932
|
import chalk from "chalk";
|
|
19604
19933
|
|
|
@@ -19820,7 +20149,7 @@ async function waitForCliAdapterReady(adapter, options) {
|
|
|
19820
20149
|
if (status === "stopped") {
|
|
19821
20150
|
throw new Error("CLI runtime stopped before it became ready");
|
|
19822
20151
|
}
|
|
19823
|
-
await new Promise((
|
|
20152
|
+
await new Promise((resolve17) => setTimeout(resolve17, pollMs));
|
|
19824
20153
|
}
|
|
19825
20154
|
throw new Error(`CLI runtime did not become ready within ${timeoutMs}ms`);
|
|
19826
20155
|
}
|
|
@@ -20197,7 +20526,7 @@ var CliProviderInstance = class {
|
|
|
20197
20526
|
const enterCount = cliCommand.enterCount || 1;
|
|
20198
20527
|
await this.adapter.writeRaw(cliCommand.text + "\r");
|
|
20199
20528
|
for (let i = 1; i < enterCount; i += 1) {
|
|
20200
|
-
await new Promise((
|
|
20529
|
+
await new Promise((resolve17) => setTimeout(resolve17, 50));
|
|
20201
20530
|
await this.adapter.writeRaw("\r");
|
|
20202
20531
|
}
|
|
20203
20532
|
}
|
|
@@ -21598,13 +21927,13 @@ var AcpProviderInstance = class {
|
|
|
21598
21927
|
}
|
|
21599
21928
|
this.currentStatus = "waiting_approval";
|
|
21600
21929
|
this.detectStatusTransition();
|
|
21601
|
-
const approved = await new Promise((
|
|
21602
|
-
this.permissionResolvers.push(
|
|
21930
|
+
const approved = await new Promise((resolve17) => {
|
|
21931
|
+
this.permissionResolvers.push(resolve17);
|
|
21603
21932
|
setTimeout(() => {
|
|
21604
|
-
const idx = this.permissionResolvers.indexOf(
|
|
21933
|
+
const idx = this.permissionResolvers.indexOf(resolve17);
|
|
21605
21934
|
if (idx >= 0) {
|
|
21606
21935
|
this.permissionResolvers.splice(idx, 1);
|
|
21607
|
-
|
|
21936
|
+
resolve17(false);
|
|
21608
21937
|
}
|
|
21609
21938
|
}, 3e5);
|
|
21610
21939
|
});
|
|
@@ -22215,7 +22544,7 @@ function commandExists(command) {
|
|
|
22215
22544
|
const trimmed = command.trim();
|
|
22216
22545
|
if (!trimmed) return false;
|
|
22217
22546
|
if (isExplicitCommand(trimmed)) {
|
|
22218
|
-
return
|
|
22547
|
+
return existsSync17(expandExecutable(trimmed));
|
|
22219
22548
|
}
|
|
22220
22549
|
try {
|
|
22221
22550
|
execFileSync(process.platform === "win32" ? "where" : "which", [trimmed], {
|
|
@@ -22313,7 +22642,7 @@ async function waitForZeroMessageStartingLaunch(adapter) {
|
|
|
22313
22642
|
} catch {
|
|
22314
22643
|
return false;
|
|
22315
22644
|
}
|
|
22316
|
-
await new Promise((
|
|
22645
|
+
await new Promise((resolve17) => setTimeout(resolve17, ZERO_MESSAGE_STARTING_SEND_WAIT_MS));
|
|
22317
22646
|
try {
|
|
22318
22647
|
return hasZeroMessageStartingLaunch(adapter);
|
|
22319
22648
|
} catch {
|
|
@@ -24386,8 +24715,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
24386
24715
|
}
|
|
24387
24716
|
const https = __require("https");
|
|
24388
24717
|
const { exec: exec7 } = __require("child_process");
|
|
24389
|
-
const { promisify:
|
|
24390
|
-
const execAsync5 =
|
|
24718
|
+
const { promisify: promisify7 } = __require("util");
|
|
24719
|
+
const execAsync5 = promisify7(exec7);
|
|
24391
24720
|
const metaPath = path19.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
24392
24721
|
let prevEtag = "";
|
|
24393
24722
|
let prevTimestamp = 0;
|
|
@@ -24405,7 +24734,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
24405
24734
|
return { updated: false };
|
|
24406
24735
|
}
|
|
24407
24736
|
try {
|
|
24408
|
-
const etag = await new Promise((
|
|
24737
|
+
const etag = await new Promise((resolve17, reject) => {
|
|
24409
24738
|
const options = {
|
|
24410
24739
|
method: "HEAD",
|
|
24411
24740
|
hostname: "github.com",
|
|
@@ -24423,7 +24752,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
24423
24752
|
headers: { "User-Agent": "adhdev-launcher" },
|
|
24424
24753
|
timeout: 1e4
|
|
24425
24754
|
}, (res2) => {
|
|
24426
|
-
|
|
24755
|
+
resolve17(res2.headers.etag || res2.headers["last-modified"] || "");
|
|
24427
24756
|
});
|
|
24428
24757
|
req2.on("error", reject);
|
|
24429
24758
|
req2.on("timeout", () => {
|
|
@@ -24432,7 +24761,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
24432
24761
|
});
|
|
24433
24762
|
req2.end();
|
|
24434
24763
|
} else {
|
|
24435
|
-
|
|
24764
|
+
resolve17(res.headers.etag || res.headers["last-modified"] || "");
|
|
24436
24765
|
}
|
|
24437
24766
|
});
|
|
24438
24767
|
req.on("error", reject);
|
|
@@ -24496,7 +24825,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
24496
24825
|
downloadFile(url, destPath) {
|
|
24497
24826
|
const https = __require("https");
|
|
24498
24827
|
const http3 = __require("http");
|
|
24499
|
-
return new Promise((
|
|
24828
|
+
return new Promise((resolve17, reject) => {
|
|
24500
24829
|
const doRequest = (reqUrl, redirectCount = 0) => {
|
|
24501
24830
|
if (redirectCount > 5) {
|
|
24502
24831
|
reject(new Error("Too many redirects"));
|
|
@@ -24516,7 +24845,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
24516
24845
|
res.pipe(ws);
|
|
24517
24846
|
ws.on("finish", () => {
|
|
24518
24847
|
ws.close();
|
|
24519
|
-
|
|
24848
|
+
resolve17();
|
|
24520
24849
|
});
|
|
24521
24850
|
ws.on("error", reject);
|
|
24522
24851
|
});
|
|
@@ -25019,10 +25348,10 @@ function findMacAppProcessPids(psOutput, appPaths) {
|
|
|
25019
25348
|
|
|
25020
25349
|
// src/launch.ts
|
|
25021
25350
|
async function execQuiet(command, options = {}) {
|
|
25022
|
-
return new Promise((
|
|
25351
|
+
return new Promise((resolve17) => {
|
|
25023
25352
|
exec4(command, options, (error, stdout) => {
|
|
25024
|
-
if (error) return
|
|
25025
|
-
|
|
25353
|
+
if (error) return resolve17("");
|
|
25354
|
+
resolve17(stdout.toString());
|
|
25026
25355
|
});
|
|
25027
25356
|
});
|
|
25028
25357
|
}
|
|
@@ -25103,17 +25432,17 @@ async function findFreePort(ports) {
|
|
|
25103
25432
|
throw new Error("No free port found");
|
|
25104
25433
|
}
|
|
25105
25434
|
function checkPortFree(port) {
|
|
25106
|
-
return new Promise((
|
|
25435
|
+
return new Promise((resolve17) => {
|
|
25107
25436
|
const server = net.createServer();
|
|
25108
25437
|
server.unref();
|
|
25109
|
-
server.on("error", () =>
|
|
25438
|
+
server.on("error", () => resolve17(false));
|
|
25110
25439
|
server.listen(port, "127.0.0.1", () => {
|
|
25111
|
-
server.close(() =>
|
|
25440
|
+
server.close(() => resolve17(true));
|
|
25112
25441
|
});
|
|
25113
25442
|
});
|
|
25114
25443
|
}
|
|
25115
25444
|
async function isCdpActive(port) {
|
|
25116
|
-
return new Promise((
|
|
25445
|
+
return new Promise((resolve17) => {
|
|
25117
25446
|
const req = __require("http").get(`http://127.0.0.1:${port}/json/version`, {
|
|
25118
25447
|
timeout: 2e3
|
|
25119
25448
|
}, (res) => {
|
|
@@ -25122,16 +25451,16 @@ async function isCdpActive(port) {
|
|
|
25122
25451
|
res.on("end", () => {
|
|
25123
25452
|
try {
|
|
25124
25453
|
const info = JSON.parse(data);
|
|
25125
|
-
|
|
25454
|
+
resolve17(!!info["WebKit-Version"] || !!info["Browser"]);
|
|
25126
25455
|
} catch {
|
|
25127
|
-
|
|
25456
|
+
resolve17(false);
|
|
25128
25457
|
}
|
|
25129
25458
|
});
|
|
25130
25459
|
});
|
|
25131
|
-
req.on("error", () =>
|
|
25460
|
+
req.on("error", () => resolve17(false));
|
|
25132
25461
|
req.on("timeout", () => {
|
|
25133
25462
|
req.destroy();
|
|
25134
|
-
|
|
25463
|
+
resolve17(false);
|
|
25135
25464
|
});
|
|
25136
25465
|
});
|
|
25137
25466
|
}
|
|
@@ -25606,12 +25935,12 @@ cleanOldFiles();
|
|
|
25606
25935
|
|
|
25607
25936
|
// src/commands/router.ts
|
|
25608
25937
|
init_logger();
|
|
25609
|
-
import * as
|
|
25938
|
+
import * as yaml3 from "js-yaml";
|
|
25610
25939
|
|
|
25611
25940
|
// src/commands/mesh-coordinator.ts
|
|
25612
25941
|
import { createHash as createHash3 } from "crypto";
|
|
25613
25942
|
import * as os17 from "os";
|
|
25614
|
-
import { isAbsolute as isAbsolute11, join as
|
|
25943
|
+
import { isAbsolute as isAbsolute11, join as join23, resolve as resolve13 } from "path";
|
|
25615
25944
|
var DEFAULT_SERVER_NAME = "adhdev-mesh";
|
|
25616
25945
|
var DEFAULT_ADHDEV_MCP_COMMAND = "adhdev";
|
|
25617
25946
|
var HERMES_CLI_TYPE = "hermes-cli";
|
|
@@ -25633,7 +25962,7 @@ function resolveHermesMeshCoordinatorSetup(options) {
|
|
|
25633
25962
|
reason: "Could not resolve the ADHDev MCP server entrypoint and a Node runtime with WebSocket support for daemon IPC mode"
|
|
25634
25963
|
};
|
|
25635
25964
|
}
|
|
25636
|
-
const configPath =
|
|
25965
|
+
const configPath = join23(resolveHermesCoordinatorHome(options.meshId, options.workspace), "config.yaml");
|
|
25637
25966
|
if (!configPath.trim()) {
|
|
25638
25967
|
return createHermesManualMeshCoordinatorSetup(options.meshId, options.workspace);
|
|
25639
25968
|
}
|
|
@@ -25753,14 +26082,14 @@ function resolveHermesCoordinatorHome(meshId, workspace) {
|
|
|
25753
26082
|
const key = `${meshId || "mesh"}
|
|
25754
26083
|
${resolve13(workspace || os17.tmpdir())}`;
|
|
25755
26084
|
const hash = createHash3("sha256").update(key).digest("hex").slice(0, 16);
|
|
25756
|
-
return
|
|
26085
|
+
return join23(os17.tmpdir(), `adhdev-hermes-mesh-coordinator-${hash}`);
|
|
25757
26086
|
}
|
|
25758
26087
|
function resolveMcpConfigPath(configPath, workspace) {
|
|
25759
26088
|
const trimmed = configPath.trim();
|
|
25760
26089
|
if (trimmed === "~") return os17.homedir();
|
|
25761
|
-
if (trimmed.startsWith("~/")) return
|
|
26090
|
+
if (trimmed.startsWith("~/")) return join23(os17.homedir(), trimmed.slice(2));
|
|
25762
26091
|
if (isAbsolute11(trimmed)) return trimmed;
|
|
25763
|
-
return
|
|
26092
|
+
return join23(workspace, trimmed);
|
|
25764
26093
|
}
|
|
25765
26094
|
function resolveAdhdevMcpServerLaunch(options) {
|
|
25766
26095
|
const command = resolveAdhdevCommand(options.adhdevMcpCommand);
|
|
@@ -25793,6 +26122,88 @@ function resolveMcpPort(explicitPort) {
|
|
|
25793
26122
|
init_mesh_events();
|
|
25794
26123
|
init_mesh_host_ownership();
|
|
25795
26124
|
|
|
26125
|
+
// src/mesh/preview-freshness.ts
|
|
26126
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
26127
|
+
import { existsSync as existsSync20, readFileSync as readFileSync13 } from "fs";
|
|
26128
|
+
import { resolve as resolve14 } from "path";
|
|
26129
|
+
var PREVIEW_DEPLOY_RECORD = ".adhdev/preview-deploy.json";
|
|
26130
|
+
function runGit2(repoRoot, args) {
|
|
26131
|
+
try {
|
|
26132
|
+
return execFileSync2("git", args, {
|
|
26133
|
+
cwd: repoRoot,
|
|
26134
|
+
encoding: "utf8",
|
|
26135
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
26136
|
+
timeout: 5e3
|
|
26137
|
+
}).trim();
|
|
26138
|
+
} catch {
|
|
26139
|
+
return "";
|
|
26140
|
+
}
|
|
26141
|
+
}
|
|
26142
|
+
function readRecord3(repoRoot) {
|
|
26143
|
+
const path28 = resolve14(repoRoot, PREVIEW_DEPLOY_RECORD);
|
|
26144
|
+
if (!existsSync20(path28)) return null;
|
|
26145
|
+
try {
|
|
26146
|
+
const parsed = JSON.parse(readFileSync13(path28, "utf8"));
|
|
26147
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
26148
|
+
} catch {
|
|
26149
|
+
return null;
|
|
26150
|
+
}
|
|
26151
|
+
}
|
|
26152
|
+
function normalizeCommit(value) {
|
|
26153
|
+
return typeof value === "string" && /^[0-9a-f]{7,40}$/i.test(value.trim()) ? value.trim() : null;
|
|
26154
|
+
}
|
|
26155
|
+
function readTargetFreshness(record, currentCommit) {
|
|
26156
|
+
const targets = record?.targets && typeof record.targets === "object" && !Array.isArray(record.targets) ? record.targets : {};
|
|
26157
|
+
const result = {};
|
|
26158
|
+
for (const targetName of ["npm", "server", "web"]) {
|
|
26159
|
+
const targetRecord = targets[targetName] && typeof targets[targetName] === "object" && !Array.isArray(targets[targetName]) ? targets[targetName] : {};
|
|
26160
|
+
const commit = normalizeCommit(targetRecord.commit);
|
|
26161
|
+
result[targetName] = {
|
|
26162
|
+
commit,
|
|
26163
|
+
deployedAt: typeof targetRecord.deployedAt === "string" ? targetRecord.deployedAt : void 0,
|
|
26164
|
+
status: commit && currentCommit ? commit === currentCommit ? "fresh" : "stale" : "unknown"
|
|
26165
|
+
};
|
|
26166
|
+
}
|
|
26167
|
+
return result;
|
|
26168
|
+
}
|
|
26169
|
+
function readCurrentMainCommit(repoRoot) {
|
|
26170
|
+
const originMain = runGit2(repoRoot, ["rev-parse", "--verify", "origin/main^{commit}"]);
|
|
26171
|
+
if (originMain) {
|
|
26172
|
+
return { currentMainCommit: originMain, currentMainCommitSource: "origin/main" };
|
|
26173
|
+
}
|
|
26174
|
+
const head = runGit2(repoRoot, ["rev-parse", "--verify", "HEAD"]);
|
|
26175
|
+
if (head) {
|
|
26176
|
+
return { currentMainCommit: head, currentMainCommitSource: "HEAD" };
|
|
26177
|
+
}
|
|
26178
|
+
return { currentMainCommit: null, currentMainCommitSource: "unknown" };
|
|
26179
|
+
}
|
|
26180
|
+
function buildPreviewFreshness(repoRoot) {
|
|
26181
|
+
const current = readCurrentMainCommit(repoRoot);
|
|
26182
|
+
const record = readRecord3(repoRoot);
|
|
26183
|
+
const lastPreviewCommit = normalizeCommit(record?.lastPreviewCommit);
|
|
26184
|
+
const targets = readTargetFreshness(record, current.currentMainCommit);
|
|
26185
|
+
let status = "unknown";
|
|
26186
|
+
let nextAction = "Run npm run deploy:preview from the current main commit, then smoke preview.";
|
|
26187
|
+
if (lastPreviewCommit && current.currentMainCommit) {
|
|
26188
|
+
status = lastPreviewCommit === current.currentMainCommit ? "fresh" : "stale";
|
|
26189
|
+
nextAction = status === "fresh" ? "No preview deploy action needed." : "Run npm run deploy:preview from origin/main, then smoke preview.";
|
|
26190
|
+
} else if (!current.currentMainCommit) {
|
|
26191
|
+
nextAction = "Resolve the current main commit before judging preview freshness.";
|
|
26192
|
+
}
|
|
26193
|
+
return {
|
|
26194
|
+
status,
|
|
26195
|
+
lastPreviewCommit,
|
|
26196
|
+
currentMainCommit: current.currentMainCommit,
|
|
26197
|
+
currentMainCommitSource: current.currentMainCommitSource,
|
|
26198
|
+
recordPath: PREVIEW_DEPLOY_RECORD,
|
|
26199
|
+
lastDeployedAt: typeof record?.updatedAt === "string" ? record.updatedAt : void 0,
|
|
26200
|
+
lastTarget: typeof record?.target === "string" ? record.target : void 0,
|
|
26201
|
+
previewVersion: typeof record?.previewVersion === "string" ? record.previewVersion : void 0,
|
|
26202
|
+
targets,
|
|
26203
|
+
nextAction
|
|
26204
|
+
};
|
|
26205
|
+
}
|
|
26206
|
+
|
|
25796
26207
|
// src/status/snapshot.ts
|
|
25797
26208
|
init_config();
|
|
25798
26209
|
import * as os18 from "os";
|
|
@@ -26107,7 +26518,7 @@ function buildStatusSnapshot(options) {
|
|
|
26107
26518
|
}
|
|
26108
26519
|
|
|
26109
26520
|
// src/commands/upgrade-helper.ts
|
|
26110
|
-
import { execFileSync as
|
|
26521
|
+
import { execFileSync as execFileSync3 } from "child_process";
|
|
26111
26522
|
import { spawn as spawn3 } from "child_process";
|
|
26112
26523
|
import * as fs10 from "fs";
|
|
26113
26524
|
import * as os19 from "os";
|
|
@@ -26227,7 +26638,7 @@ function getNpmExecOptions(platform10 = process.platform) {
|
|
|
26227
26638
|
}
|
|
26228
26639
|
function execNpmCommandSync(args, options = {}, surface) {
|
|
26229
26640
|
const execOptions = surface?.execOptions || getNpmExecOptions();
|
|
26230
|
-
return
|
|
26641
|
+
return execFileSync3(
|
|
26231
26642
|
surface?.npmExecutable || "npm",
|
|
26232
26643
|
[...surface?.npmArgsPrefix || [], ...args],
|
|
26233
26644
|
{
|
|
@@ -26240,7 +26651,7 @@ function execNpmCommandSync(args, options = {}, surface) {
|
|
|
26240
26651
|
function killPid(pid) {
|
|
26241
26652
|
try {
|
|
26242
26653
|
if (process.platform === "win32") {
|
|
26243
|
-
|
|
26654
|
+
execFileSync3("taskkill", ["/PID", String(pid), "/T", "/F"], { stdio: "ignore", windowsHide: true });
|
|
26244
26655
|
} else {
|
|
26245
26656
|
process.kill(pid, "SIGTERM");
|
|
26246
26657
|
}
|
|
@@ -26252,7 +26663,7 @@ function killPid(pid) {
|
|
|
26252
26663
|
function getWindowsProcessCommandLine(pid) {
|
|
26253
26664
|
const pidFilter = `ProcessId=${pid}`;
|
|
26254
26665
|
try {
|
|
26255
|
-
const psOut =
|
|
26666
|
+
const psOut = execFileSync3("powershell.exe", [
|
|
26256
26667
|
"-NoProfile",
|
|
26257
26668
|
"-NonInteractive",
|
|
26258
26669
|
"-ExecutionPolicy",
|
|
@@ -26264,7 +26675,7 @@ function getWindowsProcessCommandLine(pid) {
|
|
|
26264
26675
|
} catch {
|
|
26265
26676
|
}
|
|
26266
26677
|
try {
|
|
26267
|
-
const wmicOut =
|
|
26678
|
+
const wmicOut = execFileSync3("wmic", [
|
|
26268
26679
|
"process",
|
|
26269
26680
|
"where",
|
|
26270
26681
|
pidFilter,
|
|
@@ -26280,7 +26691,7 @@ function getProcessCommandLine(pid) {
|
|
|
26280
26691
|
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
26281
26692
|
if (process.platform === "win32") return getWindowsProcessCommandLine(pid);
|
|
26282
26693
|
try {
|
|
26283
|
-
const text =
|
|
26694
|
+
const text = execFileSync3("ps", ["-o", "command=", "-p", String(pid)], {
|
|
26284
26695
|
encoding: "utf8",
|
|
26285
26696
|
timeout: 3e3,
|
|
26286
26697
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -26299,7 +26710,7 @@ async function waitForPidExit(pid, timeoutMs) {
|
|
|
26299
26710
|
while (Date.now() - start < timeoutMs) {
|
|
26300
26711
|
try {
|
|
26301
26712
|
process.kill(pid, 0);
|
|
26302
|
-
await new Promise((
|
|
26713
|
+
await new Promise((resolve17) => setTimeout(resolve17, 250));
|
|
26303
26714
|
} catch {
|
|
26304
26715
|
return;
|
|
26305
26716
|
}
|
|
@@ -26396,7 +26807,7 @@ async function runDaemonUpgradeHelper(payload) {
|
|
|
26396
26807
|
cleanupStaleGlobalInstallDirs(payload.packageName, installCommand.surface);
|
|
26397
26808
|
const spec = `${payload.packageName}@${payload.targetVersion || "latest"}`;
|
|
26398
26809
|
appendUpgradeLog(`Installing ${spec}`);
|
|
26399
|
-
const installOutput =
|
|
26810
|
+
const installOutput = execFileSync3(
|
|
26400
26811
|
installCommand.command,
|
|
26401
26812
|
installCommand.args,
|
|
26402
26813
|
{
|
|
@@ -26410,7 +26821,7 @@ async function runDaemonUpgradeHelper(payload) {
|
|
|
26410
26821
|
appendUpgradeLog(installOutput.trim());
|
|
26411
26822
|
}
|
|
26412
26823
|
if (process.platform === "win32") {
|
|
26413
|
-
await new Promise((
|
|
26824
|
+
await new Promise((resolve17) => setTimeout(resolve17, 500));
|
|
26414
26825
|
cleanupStaleGlobalInstallDirs(payload.packageName, installCommand.surface);
|
|
26415
26826
|
appendUpgradeLog("Post-install staging cleanup complete");
|
|
26416
26827
|
}
|
|
@@ -26447,8 +26858,9 @@ async function maybeRunDaemonUpgradeHelperFromEnv() {
|
|
|
26447
26858
|
// src/commands/router.ts
|
|
26448
26859
|
init_mesh_work_queue();
|
|
26449
26860
|
import { homedir as homedir19, hostname as osHostname } from "os";
|
|
26450
|
-
import { basename as pathBasename, join as pathJoin, resolve as
|
|
26861
|
+
import { basename as pathBasename, join as pathJoin, resolve as pathResolve2 } from "path";
|
|
26451
26862
|
import * as fs11 from "fs";
|
|
26863
|
+
import { execFileSync as execFileSync4 } from "child_process";
|
|
26452
26864
|
var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
|
|
26453
26865
|
var CHANNEL_SERVER_URL = {
|
|
26454
26866
|
stable: "https://api.adhf.dev",
|
|
@@ -27160,6 +27572,16 @@ function finalizeMeshNodeStatus(args) {
|
|
|
27160
27572
|
if (machineStatus) status.machineStatus = machineStatus;
|
|
27161
27573
|
}
|
|
27162
27574
|
synthesizeMeshNodeFreshnessFromConnection(status);
|
|
27575
|
+
const bootstrap = readObjectRecord(node?.worktreeBootstrap);
|
|
27576
|
+
if (node?.isLocalWorktree && readStringValue(bootstrap.status)) {
|
|
27577
|
+
status.worktreeBootstrap = bootstrap;
|
|
27578
|
+
if (bootstrap.status === "failed" && bootstrap.required !== false) {
|
|
27579
|
+
status.launchReady = false;
|
|
27580
|
+
status.launchBlockedReason = "worktree_bootstrap_failed";
|
|
27581
|
+
status.launchBlockedMessage = readStringValue(bootstrap.error) || "Required worktree bootstrap failed; resolve it before launching an agent into this node.";
|
|
27582
|
+
return;
|
|
27583
|
+
}
|
|
27584
|
+
}
|
|
27163
27585
|
const connectionState = readStringValue(readObjectRecord(status.connection).state);
|
|
27164
27586
|
status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || connectionState === "connected" || isSelfNode);
|
|
27165
27587
|
}
|
|
@@ -27301,6 +27723,40 @@ function collectLiveMeshSessionRecords(args) {
|
|
|
27301
27723
|
}
|
|
27302
27724
|
return matches;
|
|
27303
27725
|
}
|
|
27726
|
+
function buildHistoricalMeshSessions(args) {
|
|
27727
|
+
const liveNodeIds = /* @__PURE__ */ new Set();
|
|
27728
|
+
const liveWorkspaces = /* @__PURE__ */ new Set();
|
|
27729
|
+
for (const node of args.nodes || []) {
|
|
27730
|
+
const nodeId = readStringValue(node?.id, node?.nodeId);
|
|
27731
|
+
const workspace = readStringValue(node?.workspace);
|
|
27732
|
+
if (nodeId) liveNodeIds.add(nodeId);
|
|
27733
|
+
if (workspace) liveWorkspaces.add(workspace);
|
|
27734
|
+
}
|
|
27735
|
+
const sessions = [];
|
|
27736
|
+
for (const record of args.liveSessionRecords || []) {
|
|
27737
|
+
const meta = readObjectRecord(record?.meta);
|
|
27738
|
+
const recordMeshId = readStringValue(meta.meshNodeFor, meta.meshCoordinatorFor);
|
|
27739
|
+
if (recordMeshId !== args.meshId) continue;
|
|
27740
|
+
const recordNodeId = readStringValue(meta.meshNodeId);
|
|
27741
|
+
const workspace = readStringValue(record?.workspace);
|
|
27742
|
+
const removedNode = !!recordNodeId && !liveNodeIds.has(recordNodeId);
|
|
27743
|
+
const orphanedWorkspace = !!workspace && !liveWorkspaces.has(workspace) && meta.meshCoordinatorFor !== args.meshId;
|
|
27744
|
+
if (!removedNode && !orphanedWorkspace) continue;
|
|
27745
|
+
sessions.push({
|
|
27746
|
+
...summarizeMeshSessionRecord(record),
|
|
27747
|
+
classification: removedNode ? "removedNode" : "orphanedSession",
|
|
27748
|
+
historical: true,
|
|
27749
|
+
meshNodeId: recordNodeId || null,
|
|
27750
|
+
reason: removedNode ? "Session is tagged to a mesh node that is no longer in live membership." : "Session workspace is no longer attached to a live mesh node."
|
|
27751
|
+
});
|
|
27752
|
+
}
|
|
27753
|
+
if (sessions.length === 0) return void 0;
|
|
27754
|
+
return {
|
|
27755
|
+
count: sessions.length,
|
|
27756
|
+
sessions: sessions.slice(0, 5),
|
|
27757
|
+
instruction: "These sessions are separated from normal node activeSessions because their mesh node/workspace is no longer live. Use mesh_cleanup_sessions only if cleanup is intended."
|
|
27758
|
+
};
|
|
27759
|
+
}
|
|
27304
27760
|
function applyCachedInlineMeshNodeStatus(status, node, options) {
|
|
27305
27761
|
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
27306
27762
|
const liveGit = buildInlineMeshTransitGitStatus(node);
|
|
@@ -27386,14 +27842,14 @@ function resolveRefineryAutoPublishSubmoduleMainCommits(mesh, workspace) {
|
|
|
27386
27842
|
return { enabled: false };
|
|
27387
27843
|
}
|
|
27388
27844
|
async function computeGitPatchId(cwd, fromRef, toRef) {
|
|
27389
|
-
const { execFileSync:
|
|
27390
|
-
const diff =
|
|
27845
|
+
const { execFileSync: execFileSync5 } = await import("child_process");
|
|
27846
|
+
const diff = execFileSync5("git", ["diff", "--patch", "--full-index", fromRef, toRef], {
|
|
27391
27847
|
cwd,
|
|
27392
27848
|
encoding: "utf8",
|
|
27393
27849
|
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
|
|
27394
27850
|
});
|
|
27395
27851
|
if (!diff.trim()) return "";
|
|
27396
|
-
const patchId =
|
|
27852
|
+
const patchId = execFileSync5("git", ["patch-id", "--stable"], {
|
|
27397
27853
|
cwd,
|
|
27398
27854
|
input: diff,
|
|
27399
27855
|
encoding: "utf8",
|
|
@@ -27404,8 +27860,8 @@ async function computeGitPatchId(cwd, fromRef, toRef) {
|
|
|
27404
27860
|
async function runMeshRefinePatchEquivalenceGate(repoRoot, baseHead, branchHead) {
|
|
27405
27861
|
const startedAt = Date.now();
|
|
27406
27862
|
try {
|
|
27407
|
-
const { execFileSync:
|
|
27408
|
-
const git = (args) =>
|
|
27863
|
+
const { execFileSync: execFileSync5 } = await import("child_process");
|
|
27864
|
+
const git = (args) => execFileSync5("git", args, {
|
|
27409
27865
|
cwd: repoRoot,
|
|
27410
27866
|
encoding: "utf8",
|
|
27411
27867
|
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
|
|
@@ -27449,6 +27905,135 @@ async function runMeshRefinePatchEquivalenceGate(repoRoot, baseHead, branchHead)
|
|
|
27449
27905
|
durationMs: Date.now() - startedAt,
|
|
27450
27906
|
error: e?.message || String(e),
|
|
27451
27907
|
stdout: truncateValidationOutput(e?.stdout),
|
|
27908
|
+
stderr: truncateValidationOutput(e?.stderr),
|
|
27909
|
+
actionableHint: buildPatchEquivalenceSubmoduleConflictHint(
|
|
27910
|
+
repoRoot,
|
|
27911
|
+
baseHead,
|
|
27912
|
+
branchHead,
|
|
27913
|
+
`${e?.message || ""}
|
|
27914
|
+
${e?.stdout || ""}
|
|
27915
|
+
${e?.stderr || ""}`
|
|
27916
|
+
)
|
|
27917
|
+
};
|
|
27918
|
+
}
|
|
27919
|
+
}
|
|
27920
|
+
function buildPatchEquivalenceSubmoduleConflictHint(repoRoot, baseHead, branchHead, output) {
|
|
27921
|
+
if (!/(submodule|160000)/i.test(output) || !/(conflict|failed to merge)/i.test(output)) return void 0;
|
|
27922
|
+
const conflicts = readChangedGitlinkPaths(repoRoot, baseHead, branchHead).map((path28) => ({
|
|
27923
|
+
path: path28,
|
|
27924
|
+
baseCommit: readTreeObject(repoRoot, baseHead, path28),
|
|
27925
|
+
branchCommit: readTreeObject(repoRoot, branchHead, path28)
|
|
27926
|
+
}));
|
|
27927
|
+
if (conflicts.length === 0) return void 0;
|
|
27928
|
+
return {
|
|
27929
|
+
kind: "submodule_conflict",
|
|
27930
|
+
message: "Refinery could not synthesize a safe merge tree because the branch and base point the same submodule path at different commits.",
|
|
27931
|
+
conflicts,
|
|
27932
|
+
nextSteps: [
|
|
27933
|
+
"Inspect the listed submodule path in both base and branch: baseCommit is the commit currently recorded by the base workspace, branchCommit is the commit recorded by the worktree branch.",
|
|
27934
|
+
"Resolve the submodule first by checking out or creating the intended submodule commit, then commit the chosen gitlink in the root branch.",
|
|
27935
|
+
"Ensure the chosen submodule commit is reachable from the configured submodule remote main branch, then rerun mesh_refine_node."
|
|
27936
|
+
]
|
|
27937
|
+
};
|
|
27938
|
+
}
|
|
27939
|
+
function readChangedGitlinkPaths(repoRoot, fromRef, toRef) {
|
|
27940
|
+
try {
|
|
27941
|
+
const output = execFileSync4("git", ["diff", "--raw", "--no-abbrev", fromRef, toRef], {
|
|
27942
|
+
cwd: repoRoot,
|
|
27943
|
+
encoding: "utf8",
|
|
27944
|
+
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
|
|
27945
|
+
});
|
|
27946
|
+
const paths = /* @__PURE__ */ new Set();
|
|
27947
|
+
for (const line of output.split("\n")) {
|
|
27948
|
+
if (!line.trim()) continue;
|
|
27949
|
+
const metaAndPath = line.split(" ");
|
|
27950
|
+
const meta = metaAndPath[0] || "";
|
|
27951
|
+
const path28 = metaAndPath[metaAndPath.length - 1]?.trim();
|
|
27952
|
+
if (!path28) continue;
|
|
27953
|
+
const parts = meta.split(/\s+/);
|
|
27954
|
+
if (parts[0]?.includes("160000") || parts[1]?.includes("160000")) {
|
|
27955
|
+
paths.add(path28);
|
|
27956
|
+
}
|
|
27957
|
+
}
|
|
27958
|
+
return [...paths].sort();
|
|
27959
|
+
} catch {
|
|
27960
|
+
return [];
|
|
27961
|
+
}
|
|
27962
|
+
}
|
|
27963
|
+
function readTreeObject(repoRoot, ref, path28) {
|
|
27964
|
+
try {
|
|
27965
|
+
const output = execFileSync4("git", ["ls-tree", ref, "--", path28], {
|
|
27966
|
+
cwd: repoRoot,
|
|
27967
|
+
encoding: "utf8",
|
|
27968
|
+
maxBuffer: 1024 * 1024
|
|
27969
|
+
}).trim();
|
|
27970
|
+
const match = output.match(/\bcommit\s+([0-9a-f]{40})\b/i);
|
|
27971
|
+
return match?.[1];
|
|
27972
|
+
} catch {
|
|
27973
|
+
return void 0;
|
|
27974
|
+
}
|
|
27975
|
+
}
|
|
27976
|
+
async function alignRefinerySubmodulesAfterMerge(repoRoot, previousBaseHead, currentHead, options = {}) {
|
|
27977
|
+
const startedAt = Date.now();
|
|
27978
|
+
const changedGitlinkPaths = readChangedGitlinkPaths(repoRoot, previousBaseHead, currentHead).filter((path28) => !(options.submoduleIgnorePaths || []).includes(path28));
|
|
27979
|
+
const preStatus = await getGitRepoStatus(repoRoot, {
|
|
27980
|
+
includeSubmodules: true,
|
|
27981
|
+
submoduleIgnorePaths: options.submoduleIgnorePaths,
|
|
27982
|
+
timeoutMs: 15e3
|
|
27983
|
+
});
|
|
27984
|
+
const outOfSyncPaths = (preStatus.submodules || []).filter((submodule) => submodule.dirty || submodule.outOfSync || !!submodule.error).map((submodule) => submodule.path);
|
|
27985
|
+
const updatePaths = [.../* @__PURE__ */ new Set([...changedGitlinkPaths, ...outOfSyncPaths])].sort();
|
|
27986
|
+
if (updatePaths.length === 0) {
|
|
27987
|
+
return {
|
|
27988
|
+
status: "skipped",
|
|
27989
|
+
changedGitlinkPaths,
|
|
27990
|
+
outOfSyncPaths,
|
|
27991
|
+
updatedPaths: [],
|
|
27992
|
+
verifiedPaths: [],
|
|
27993
|
+
durationMs: Date.now() - startedAt,
|
|
27994
|
+
reason: "no_changed_or_out_of_sync_submodules"
|
|
27995
|
+
};
|
|
27996
|
+
}
|
|
27997
|
+
const commandArgs = ["submodule", "update", "--init", "--recursive", "--", ...updatePaths];
|
|
27998
|
+
try {
|
|
27999
|
+
const { execFile: execFile4 } = await import("child_process");
|
|
28000
|
+
const { promisify: promisify7 } = await import("util");
|
|
28001
|
+
const execFileAsync3 = promisify7(execFile4);
|
|
28002
|
+
const result = await execFileAsync3("git", commandArgs, {
|
|
28003
|
+
cwd: repoRoot,
|
|
28004
|
+
encoding: "utf8",
|
|
28005
|
+
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES,
|
|
28006
|
+
timeout: 6e4
|
|
28007
|
+
});
|
|
28008
|
+
const postStatus = await getGitRepoStatus(repoRoot, {
|
|
28009
|
+
includeSubmodules: true,
|
|
28010
|
+
submoduleIgnorePaths: options.submoduleIgnorePaths,
|
|
28011
|
+
timeoutMs: 15e3
|
|
28012
|
+
});
|
|
28013
|
+
const remaining = (postStatus.submodules || []).filter((submodule) => updatePaths.includes(submodule.path) && (submodule.dirty || submodule.outOfSync || !!submodule.error));
|
|
28014
|
+
return {
|
|
28015
|
+
status: remaining.length === 0 ? "passed" : "failed",
|
|
28016
|
+
changedGitlinkPaths,
|
|
28017
|
+
outOfSyncPaths,
|
|
28018
|
+
updatedPaths: updatePaths,
|
|
28019
|
+
verifiedPaths: updatePaths.filter((path28) => !remaining.some((submodule) => submodule.path === path28)),
|
|
28020
|
+
durationMs: Date.now() - startedAt,
|
|
28021
|
+
command: `git ${commandArgs.join(" ")}`,
|
|
28022
|
+
stdout: truncateValidationOutput(result.stdout),
|
|
28023
|
+
stderr: truncateValidationOutput(result.stderr),
|
|
28024
|
+
...remaining.length > 0 ? { error: `Submodule checkout remained out of sync after update: ${remaining.map((entry) => entry.path).join(", ")}` } : {}
|
|
28025
|
+
};
|
|
28026
|
+
} catch (e) {
|
|
28027
|
+
return {
|
|
28028
|
+
status: "failed",
|
|
28029
|
+
changedGitlinkPaths,
|
|
28030
|
+
outOfSyncPaths,
|
|
28031
|
+
updatedPaths: updatePaths,
|
|
28032
|
+
verifiedPaths: [],
|
|
28033
|
+
durationMs: Date.now() - startedAt,
|
|
28034
|
+
command: `git ${commandArgs.join(" ")}`,
|
|
28035
|
+
error: e?.message || String(e),
|
|
28036
|
+
stdout: truncateValidationOutput(e?.stdout),
|
|
27452
28037
|
stderr: truncateValidationOutput(e?.stderr)
|
|
27453
28038
|
};
|
|
27454
28039
|
}
|
|
@@ -27457,10 +28042,10 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
27457
28042
|
const startedAt = Date.now();
|
|
27458
28043
|
const entries = [];
|
|
27459
28044
|
try {
|
|
27460
|
-
const { execFile:
|
|
27461
|
-
const { promisify:
|
|
27462
|
-
const execFileAsync3 =
|
|
27463
|
-
const
|
|
28045
|
+
const { execFile: execFile4 } = await import("child_process");
|
|
28046
|
+
const { promisify: promisify7 } = await import("util");
|
|
28047
|
+
const execFileAsync3 = promisify7(execFile4);
|
|
28048
|
+
const runGit3 = async (cwd, args) => {
|
|
27464
28049
|
const { stdout } = await execFileAsync3("git", args, {
|
|
27465
28050
|
cwd,
|
|
27466
28051
|
encoding: "utf8",
|
|
@@ -27471,8 +28056,8 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
27471
28056
|
return String(stdout || "");
|
|
27472
28057
|
};
|
|
27473
28058
|
const verifyRemoteMainContainsCommit = async (submodulePath, commit, branch = "main") => {
|
|
27474
|
-
await
|
|
27475
|
-
await
|
|
28059
|
+
await runGit3(submodulePath, ["-c", "protocol.file.allow=always", "fetch", "origin", `refs/heads/${branch}:refs/remotes/origin/${branch}`]);
|
|
28060
|
+
await runGit3(submodulePath, ["merge-base", "--is-ancestor", commit, `refs/remotes/origin/${branch}`]);
|
|
27476
28061
|
};
|
|
27477
28062
|
const publishCommitToRemoteMain = async (submodulePath, commit, branch = "main") => {
|
|
27478
28063
|
const refspec = `${commit}:refs/heads/${branch}`;
|
|
@@ -27488,21 +28073,21 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
27488
28073
|
const importCommitFromWorktreeSubmodule = async (submodulePath, worktreeSubmodulePath, commit) => {
|
|
27489
28074
|
if (!fs11.existsSync(worktreeSubmodulePath)) return false;
|
|
27490
28075
|
try {
|
|
27491
|
-
await
|
|
28076
|
+
await runGit3(worktreeSubmodulePath, ["cat-file", "-e", `${commit}^{commit}`]);
|
|
27492
28077
|
} catch {
|
|
27493
28078
|
return false;
|
|
27494
28079
|
}
|
|
27495
|
-
await
|
|
27496
|
-
await
|
|
28080
|
+
await runGit3(submodulePath, ["-c", "protocol.file.allow=always", "fetch", worktreeSubmodulePath, commit]);
|
|
28081
|
+
await runGit3(submodulePath, ["cat-file", "-e", `${commit}^{commit}`]);
|
|
27497
28082
|
return true;
|
|
27498
28083
|
};
|
|
27499
|
-
const treeOutput = await
|
|
28084
|
+
const treeOutput = await runGit3(repoRoot, ["ls-tree", "-r", "-z", mergedTree]);
|
|
27500
28085
|
const gitlinks = treeOutput.split("\0").filter(Boolean).map((record) => {
|
|
27501
28086
|
const match = /^160000\s+commit\s+([0-9a-f]{40})\t(.+)$/.exec(record);
|
|
27502
28087
|
return match ? { commit: match[1], path: match[2] } : null;
|
|
27503
28088
|
}).filter((entry) => !!entry);
|
|
27504
28089
|
for (const gitlink of gitlinks) {
|
|
27505
|
-
const submodulePath =
|
|
28090
|
+
const submodulePath = pathResolve2(repoRoot, gitlink.path);
|
|
27506
28091
|
const entry = {
|
|
27507
28092
|
path: gitlink.path,
|
|
27508
28093
|
commit: gitlink.commit,
|
|
@@ -27522,7 +28107,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
27522
28107
|
}
|
|
27523
28108
|
entry.checkedLocal = true;
|
|
27524
28109
|
try {
|
|
27525
|
-
await
|
|
28110
|
+
await runGit3(submodulePath, ["cat-file", "-e", `${gitlink.commit}^{commit}`]);
|
|
27526
28111
|
entry.localReachable = true;
|
|
27527
28112
|
} catch {
|
|
27528
28113
|
entry.localReachable = false;
|
|
@@ -27530,7 +28115,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
27530
28115
|
try {
|
|
27531
28116
|
const imported = await importCommitFromWorktreeSubmodule(
|
|
27532
28117
|
submodulePath,
|
|
27533
|
-
|
|
28118
|
+
pathResolve2(options.worktreeRoot, gitlink.path),
|
|
27534
28119
|
gitlink.commit
|
|
27535
28120
|
);
|
|
27536
28121
|
if (imported) {
|
|
@@ -27546,7 +28131,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
27546
28131
|
entry.remote = "origin";
|
|
27547
28132
|
let remoteUrl = "";
|
|
27548
28133
|
try {
|
|
27549
|
-
remoteUrl = (await
|
|
28134
|
+
remoteUrl = (await runGit3(submodulePath, ["remote", "get-url", "origin"])).trim();
|
|
27550
28135
|
if (!remoteUrl) throw new Error("origin remote has no URL");
|
|
27551
28136
|
entry.remoteUrl = remoteUrl;
|
|
27552
28137
|
} catch {
|
|
@@ -27661,9 +28246,9 @@ function buildMeshRefineValidationPlan(mesh, workspace) {
|
|
|
27661
28246
|
};
|
|
27662
28247
|
}
|
|
27663
28248
|
async function runMeshRefineValidationGate(mesh, workspace) {
|
|
27664
|
-
const { execFile:
|
|
27665
|
-
const { promisify:
|
|
27666
|
-
const execFileAsync3 =
|
|
28249
|
+
const { execFile: execFile4 } = await import("child_process");
|
|
28250
|
+
const { promisify: promisify7 } = await import("util");
|
|
28251
|
+
const execFileAsync3 = promisify7(execFile4);
|
|
27667
28252
|
const selection = resolveMeshRefineValidationPlan(mesh, workspace);
|
|
27668
28253
|
const summary = {
|
|
27669
28254
|
status: "skipped",
|
|
@@ -27707,14 +28292,14 @@ async function runMeshRefineValidationGate(mesh, workspace) {
|
|
|
27707
28292
|
};
|
|
27708
28293
|
for (const candidate of selection.bootstrapCommands) {
|
|
27709
28294
|
const startedAt = Date.now();
|
|
27710
|
-
const cwd = candidate.cwd ?
|
|
28295
|
+
const cwd = candidate.cwd ? pathResolve2(workspace, candidate.cwd) : workspace;
|
|
27711
28296
|
const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
|
|
27712
28297
|
try {
|
|
27713
28298
|
const result = await execFileAsync3(candidate.command, candidate.args, {
|
|
27714
28299
|
cwd,
|
|
27715
28300
|
encoding: "utf8",
|
|
27716
28301
|
timeout,
|
|
27717
|
-
maxBuffer: REFINE_VALIDATION_OUTPUT_LIMIT_BYTES,
|
|
28302
|
+
maxBuffer: candidate.outputLimitBytes || REFINE_VALIDATION_OUTPUT_LIMIT_BYTES,
|
|
27718
28303
|
env: { ...process.env, CI: process.env.CI || "1", ...candidate.env || {} }
|
|
27719
28304
|
});
|
|
27720
28305
|
summary.bootstrapCommandsRun.push(commandRecord(candidate, cwd, startedAt, result, true, { exitCode: 0 }));
|
|
@@ -27733,7 +28318,7 @@ async function runMeshRefineValidationGate(mesh, workspace) {
|
|
|
27733
28318
|
}
|
|
27734
28319
|
for (const candidate of selection.commands) {
|
|
27735
28320
|
const startedAt = Date.now();
|
|
27736
|
-
const cwd = candidate.cwd ?
|
|
28321
|
+
const cwd = candidate.cwd ? pathResolve2(workspace, candidate.cwd) : workspace;
|
|
27737
28322
|
const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
|
|
27738
28323
|
if (selection.bootstrapCommands.length === 0 && isPackageManagerValidation(candidate) && dependenciesLikelyMissing(cwd)) {
|
|
27739
28324
|
summary.commandsRun.push(commandRecord(candidate, cwd, startedAt, {
|
|
@@ -27753,7 +28338,7 @@ async function runMeshRefineValidationGate(mesh, workspace) {
|
|
|
27753
28338
|
cwd,
|
|
27754
28339
|
encoding: "utf8",
|
|
27755
28340
|
timeout,
|
|
27756
|
-
maxBuffer: REFINE_VALIDATION_OUTPUT_LIMIT_BYTES,
|
|
28341
|
+
maxBuffer: candidate.outputLimitBytes || REFINE_VALIDATION_OUTPUT_LIMIT_BYTES,
|
|
27757
28342
|
env: { ...process.env, CI: process.env.CI || "1", ...candidate.env || {} }
|
|
27758
28343
|
});
|
|
27759
28344
|
summary.commandsRun.push(commandRecord(candidate, cwd, startedAt, result, true, { exitCode: 0 }));
|
|
@@ -27778,7 +28363,7 @@ async function runMeshRefineValidationGate(mesh, workspace) {
|
|
|
27778
28363
|
return summary;
|
|
27779
28364
|
}
|
|
27780
28365
|
function loadYamlModule() {
|
|
27781
|
-
return
|
|
28366
|
+
return yaml3;
|
|
27782
28367
|
}
|
|
27783
28368
|
function getMcpServersKey(format) {
|
|
27784
28369
|
return format === "hermes_config_yaml" ? "mcp_servers" : "mcpServers";
|
|
@@ -27801,7 +28386,7 @@ function loadHermesCoordinatorBaseConfig(targetConfigPath) {
|
|
|
27801
28386
|
const sourceHome = resolveHermesUserHome();
|
|
27802
28387
|
const sourceConfigPath = pathJoin(sourceHome, "config.yaml");
|
|
27803
28388
|
if (!fs11.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
27804
|
-
if (
|
|
28389
|
+
if (pathResolve2(sourceConfigPath) === pathResolve2(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
27805
28390
|
const parsed = parseMeshCoordinatorMcpConfig(fs11.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
|
|
27806
28391
|
const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
|
|
27807
28392
|
return { config: baseConfig, sourceHome, sourceConfigPath };
|
|
@@ -27835,7 +28420,7 @@ function stripHermesCoordinatorTempModelProviderOverrides(config) {
|
|
|
27835
28420
|
return sanitized;
|
|
27836
28421
|
}
|
|
27837
28422
|
function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
|
|
27838
|
-
if (
|
|
28423
|
+
if (pathResolve2(sourceHome) === pathResolve2(targetHome)) return;
|
|
27839
28424
|
for (const fileName of [".env", "auth.json"]) {
|
|
27840
28425
|
const sourcePath = pathJoin(sourceHome, fileName);
|
|
27841
28426
|
const targetPath = pathJoin(targetHome, fileName);
|
|
@@ -28220,7 +28805,7 @@ var DaemonCommandRouter = class {
|
|
|
28220
28805
|
}
|
|
28221
28806
|
const { resolveWorktreePath: resolveWorktreePath2, listWorktrees: listWorktrees2, removeWorktree: removeWorktree2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
|
|
28222
28807
|
const normalizePath = (value) => {
|
|
28223
|
-
const resolved =
|
|
28808
|
+
const resolved = pathResolve2(value);
|
|
28224
28809
|
try {
|
|
28225
28810
|
return fs11.realpathSync(resolved);
|
|
28226
28811
|
} catch {
|
|
@@ -28294,10 +28879,10 @@ var DaemonCommandRouter = class {
|
|
|
28294
28879
|
if (metadataStatus === "merged_to_main" || metadataStatus === "cleanup_candidate") {
|
|
28295
28880
|
return { allow: true, status: metadataStatus, source: "node_branch_convergence" };
|
|
28296
28881
|
}
|
|
28297
|
-
const { execFile:
|
|
28298
|
-
const { promisify:
|
|
28299
|
-
const execFileAsync3 =
|
|
28300
|
-
const
|
|
28882
|
+
const { execFile: execFile4 } = await import("child_process");
|
|
28883
|
+
const { promisify: promisify7 } = await import("util");
|
|
28884
|
+
const execFileAsync3 = promisify7(execFile4);
|
|
28885
|
+
const runGit3 = async (gitArgs, cwd) => {
|
|
28301
28886
|
const { stdout } = await execFileAsync3("git", gitArgs, {
|
|
28302
28887
|
cwd,
|
|
28303
28888
|
encoding: "utf8",
|
|
@@ -28309,14 +28894,14 @@ var DaemonCommandRouter = class {
|
|
|
28309
28894
|
};
|
|
28310
28895
|
let head = "";
|
|
28311
28896
|
try {
|
|
28312
|
-
head = await
|
|
28897
|
+
head = await runGit3(["rev-parse", "HEAD"], args.workspace);
|
|
28313
28898
|
} catch (e) {
|
|
28314
28899
|
return { allow: false, error: `could not resolve worktree HEAD: ${e?.message || e}` };
|
|
28315
28900
|
}
|
|
28316
28901
|
if (!head) return { allow: false, error: "worktree HEAD is empty" };
|
|
28317
28902
|
const candidateRefs = [];
|
|
28318
28903
|
try {
|
|
28319
|
-
const defaultBranch = await
|
|
28904
|
+
const defaultBranch = await runGit3(["branch", "--show-current"], args.repoRoot);
|
|
28320
28905
|
if (defaultBranch) {
|
|
28321
28906
|
candidateRefs.push(defaultBranch, `origin/${defaultBranch}`);
|
|
28322
28907
|
}
|
|
@@ -28330,13 +28915,13 @@ var DaemonCommandRouter = class {
|
|
|
28330
28915
|
seen.add(ref);
|
|
28331
28916
|
let commit = "";
|
|
28332
28917
|
try {
|
|
28333
|
-
commit = await
|
|
28918
|
+
commit = await runGit3(["rev-parse", "--verify", `${ref}^{commit}`], args.repoRoot);
|
|
28334
28919
|
} catch {
|
|
28335
28920
|
continue;
|
|
28336
28921
|
}
|
|
28337
28922
|
checkedRefs.push(ref);
|
|
28338
28923
|
try {
|
|
28339
|
-
await
|
|
28924
|
+
await runGit3(["merge-base", "--is-ancestor", head, commit], args.repoRoot);
|
|
28340
28925
|
return { allow: true, status: "merged_to_default_ref", source: "git_merge_base", ref };
|
|
28341
28926
|
} catch {
|
|
28342
28927
|
}
|
|
@@ -28728,9 +29313,9 @@ var DaemonCommandRouter = class {
|
|
|
28728
29313
|
const sourceNode = node.clonedFromNodeId ? mesh?.nodes.find((n) => n.id === node.clonedFromNodeId || n.nodeId === node.clonedFromNodeId) : mesh?.nodes.find((n) => !n.isLocalWorktree);
|
|
28729
29314
|
const repoRoot = sourceNode?.repoRoot || sourceNode?.workspace;
|
|
28730
29315
|
if (!repoRoot) return { success: false, error: "Source node repoRoot not found", refineStages };
|
|
28731
|
-
const { execFile:
|
|
28732
|
-
const { promisify:
|
|
28733
|
-
const execFileAsync3 =
|
|
29316
|
+
const { execFile: execFile4 } = await import("child_process");
|
|
29317
|
+
const { promisify: promisify7 } = await import("util");
|
|
29318
|
+
const execFileAsync3 = promisify7(execFile4);
|
|
28734
29319
|
const resolveStarted = Date.now();
|
|
28735
29320
|
const { stdout: branchStdout } = await execFileAsync3("git", ["branch", "--show-current"], { cwd: node.workspace, encoding: "utf8" });
|
|
28736
29321
|
const branch = branchStdout.trim();
|
|
@@ -28797,7 +29382,8 @@ var DaemonCommandRouter = class {
|
|
|
28797
29382
|
equivalent: patchEquivalence.equivalent,
|
|
28798
29383
|
expectedPatchId: patchEquivalence.expectedPatchId,
|
|
28799
29384
|
actualPatchId: patchEquivalence.actualPatchId,
|
|
28800
|
-
error: patchEquivalence.error
|
|
29385
|
+
error: patchEquivalence.error,
|
|
29386
|
+
actionableHint: patchEquivalence.actionableHint
|
|
28801
29387
|
});
|
|
28802
29388
|
if (!patchEquivalence.equivalent) {
|
|
28803
29389
|
return {
|
|
@@ -28956,6 +29542,49 @@ var DaemonCommandRouter = class {
|
|
|
28956
29542
|
}
|
|
28957
29543
|
};
|
|
28958
29544
|
}
|
|
29545
|
+
const submoduleAlignmentStarted = Date.now();
|
|
29546
|
+
const submoduleAlignment = await alignRefinerySubmodulesAfterMerge(repoRoot, baseHead, "HEAD", {
|
|
29547
|
+
submoduleIgnorePaths: Array.isArray(sourceNode?.policy?.submoduleIgnorePaths) ? sourceNode.policy.submoduleIgnorePaths.filter((value) => typeof value === "string") : void 0
|
|
29548
|
+
});
|
|
29549
|
+
if (submoduleAlignment.status !== "skipped") {
|
|
29550
|
+
recordMeshRefineStage(refineStages, "submodule_alignment", submoduleAlignment.status, submoduleAlignmentStarted, {
|
|
29551
|
+
changedGitlinkPaths: submoduleAlignment.changedGitlinkPaths,
|
|
29552
|
+
outOfSyncPaths: submoduleAlignment.outOfSyncPaths,
|
|
29553
|
+
updatedPaths: submoduleAlignment.updatedPaths,
|
|
29554
|
+
verifiedPaths: submoduleAlignment.verifiedPaths,
|
|
29555
|
+
command: submoduleAlignment.command,
|
|
29556
|
+
error: submoduleAlignment.error
|
|
29557
|
+
});
|
|
29558
|
+
}
|
|
29559
|
+
if (submoduleAlignment.status === "failed") {
|
|
29560
|
+
return {
|
|
29561
|
+
success: false,
|
|
29562
|
+
code: "post_merge_submodule_alignment_failed",
|
|
29563
|
+
error: "Refinery merge completed but post-merge submodule checkout alignment failed; run the reported git submodule update command and re-check base workspace status.",
|
|
29564
|
+
merged: true,
|
|
29565
|
+
branch,
|
|
29566
|
+
into: baseBranch,
|
|
29567
|
+
validationSummary,
|
|
29568
|
+
patchEquivalence,
|
|
29569
|
+
submoduleReachability,
|
|
29570
|
+
submoduleAlignment,
|
|
29571
|
+
mergeResult,
|
|
29572
|
+
refineStages,
|
|
29573
|
+
finalBranchConvergenceState: {
|
|
29574
|
+
branch: baseBranch,
|
|
29575
|
+
mergedBranch: branch,
|
|
29576
|
+
baseBranch,
|
|
29577
|
+
merged: true,
|
|
29578
|
+
removed: false,
|
|
29579
|
+
validation: "passed",
|
|
29580
|
+
patchEquivalence: "passed",
|
|
29581
|
+
submoduleReachability: "passed",
|
|
29582
|
+
submoduleAlignment: "failed",
|
|
29583
|
+
status: "post_merge_alignment_failed",
|
|
29584
|
+
nextStep: submoduleAlignment.command || "Run git submodule update --init --recursive for the reported path(s), then re-check base workspace status."
|
|
29585
|
+
}
|
|
29586
|
+
};
|
|
29587
|
+
}
|
|
28959
29588
|
const cleanupStarted = Date.now();
|
|
28960
29589
|
const removeResult = await this.execute("remove_mesh_node", {
|
|
28961
29590
|
meshId,
|
|
@@ -28975,7 +29604,7 @@ var DaemonCommandRouter = class {
|
|
|
28975
29604
|
appendLedgerEntry2(meshId, {
|
|
28976
29605
|
kind: "node_removed",
|
|
28977
29606
|
nodeId,
|
|
28978
|
-
payload: { refined: true, mergedBranch: branch, into: baseBranch, validationSummary, patchEquivalence, submoduleReachability }
|
|
29607
|
+
payload: { refined: true, mergedBranch: branch, into: baseBranch, validationSummary, patchEquivalence, submoduleReachability, submoduleAlignment }
|
|
28979
29608
|
});
|
|
28980
29609
|
recordMeshRefineStage(refineStages, "ledger", "passed", ledgerStarted);
|
|
28981
29610
|
} catch (e) {
|
|
@@ -28990,6 +29619,7 @@ var DaemonCommandRouter = class {
|
|
|
28990
29619
|
removed: removeResult?.success !== false,
|
|
28991
29620
|
validation: "passed",
|
|
28992
29621
|
patchEquivalence: "passed",
|
|
29622
|
+
submoduleAlignment: submoduleAlignment.status,
|
|
28993
29623
|
status: removeResult?.success === false ? "merged_cleanup_failed" : "merged"
|
|
28994
29624
|
};
|
|
28995
29625
|
if (removeResult?.success === false) {
|
|
@@ -29004,6 +29634,7 @@ var DaemonCommandRouter = class {
|
|
|
29004
29634
|
validationSummary,
|
|
29005
29635
|
patchEquivalence,
|
|
29006
29636
|
submoduleReachability,
|
|
29637
|
+
submoduleAlignment,
|
|
29007
29638
|
mergeResult,
|
|
29008
29639
|
refineStages,
|
|
29009
29640
|
...ledgerError ? { ledgerError } : {},
|
|
@@ -29019,6 +29650,7 @@ var DaemonCommandRouter = class {
|
|
|
29019
29650
|
validationSummary,
|
|
29020
29651
|
patchEquivalence,
|
|
29021
29652
|
submoduleReachability,
|
|
29653
|
+
submoduleAlignment,
|
|
29022
29654
|
mergeResult,
|
|
29023
29655
|
refineStages,
|
|
29024
29656
|
...ledgerError ? { ledgerError } : {},
|
|
@@ -30101,6 +30733,12 @@ var DaemonCommandRouter = class {
|
|
|
30101
30733
|
success: true,
|
|
30102
30734
|
schema: MESH_REFINE_CONFIG_SCHEMA,
|
|
30103
30735
|
locations: MESH_REFINE_CONFIG_LOCATIONS,
|
|
30736
|
+
worktreeBootstrap: {
|
|
30737
|
+
schema: MESH_WORKTREE_BOOTSTRAP_CONFIG_SCHEMA,
|
|
30738
|
+
locations: MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS,
|
|
30739
|
+
sourceOfTruth: "repo worktree bootstrap config",
|
|
30740
|
+
runBehavior: "When present and enabled, clone_mesh_node runs commands after submodule initialization and records status on the worktree node."
|
|
30741
|
+
},
|
|
30104
30742
|
sourceOfTruth: "repo mesh/refine config",
|
|
30105
30743
|
heuristicRole: "suggestions_only_not_execution_path"
|
|
30106
30744
|
};
|
|
@@ -30295,8 +30933,8 @@ var DaemonCommandRouter = class {
|
|
|
30295
30933
|
const initSubmodules = sourceNode.policy?.initSubmodulesOnClone !== false;
|
|
30296
30934
|
if (initSubmodules) {
|
|
30297
30935
|
try {
|
|
30298
|
-
const { runGit:
|
|
30299
|
-
await
|
|
30936
|
+
const { runGit: runGit3 } = await Promise.resolve().then(() => (init_git_executor(), git_executor_exports));
|
|
30937
|
+
await runGit3(
|
|
30300
30938
|
{ workspace: result.worktreePath, repoRoot: result.worktreePath, isGitRepo: true },
|
|
30301
30939
|
["submodule", "update", "--init", "--recursive"],
|
|
30302
30940
|
{ timeoutMs: 12e4 }
|
|
@@ -30305,12 +30943,35 @@ var DaemonCommandRouter = class {
|
|
|
30305
30943
|
console.warn("[mesh] Submodule init failed for worktree:", subErr.message);
|
|
30306
30944
|
}
|
|
30307
30945
|
}
|
|
30946
|
+
const bootstrapState = await runMeshWorktreeBootstrap(mesh, result.worktreePath);
|
|
30947
|
+
node.worktreeBootstrap = bootstrapState;
|
|
30948
|
+
if (!meshRecord.inline) {
|
|
30949
|
+
try {
|
|
30950
|
+
const { updateNode: updateNode2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
30951
|
+
updateNode2(meshId, node.id, { worktreeBootstrap: bootstrapState });
|
|
30952
|
+
this.invalidateAggregateMeshStatus(meshId);
|
|
30953
|
+
} catch {
|
|
30954
|
+
}
|
|
30955
|
+
}
|
|
30308
30956
|
try {
|
|
30309
30957
|
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
30310
30958
|
appendLedgerEntry2(meshId, {
|
|
30311
30959
|
kind: "node_cloned",
|
|
30312
30960
|
nodeId: node.id,
|
|
30313
|
-
payload: {
|
|
30961
|
+
payload: {
|
|
30962
|
+
sourceNodeId,
|
|
30963
|
+
branch: result.branch,
|
|
30964
|
+
worktreePath: result.worktreePath,
|
|
30965
|
+
submodulesInitialized: initSubmodules,
|
|
30966
|
+
worktreeBootstrap: {
|
|
30967
|
+
status: bootstrapState.status,
|
|
30968
|
+
required: bootstrapState.required,
|
|
30969
|
+
configSource: bootstrapState.configSource,
|
|
30970
|
+
configSourceType: bootstrapState.configSourceType,
|
|
30971
|
+
lastCommand: bootstrapState.lastCommand,
|
|
30972
|
+
exitCode: bootstrapState.exitCode
|
|
30973
|
+
}
|
|
30974
|
+
}
|
|
30314
30975
|
});
|
|
30315
30976
|
} catch {
|
|
30316
30977
|
}
|
|
@@ -30318,7 +30979,8 @@ var DaemonCommandRouter = class {
|
|
|
30318
30979
|
success: true,
|
|
30319
30980
|
node,
|
|
30320
30981
|
worktreePath: result.worktreePath,
|
|
30321
|
-
branch: result.branch
|
|
30982
|
+
branch: result.branch,
|
|
30983
|
+
worktreeBootstrap: bootstrapState
|
|
30322
30984
|
};
|
|
30323
30985
|
} catch (e) {
|
|
30324
30986
|
return { success: false, error: e.message };
|
|
@@ -30546,7 +31208,7 @@ ${block2}`);
|
|
|
30546
31208
|
workspace
|
|
30547
31209
|
};
|
|
30548
31210
|
}
|
|
30549
|
-
const { existsSync:
|
|
31211
|
+
const { existsSync: existsSync28, readFileSync: readFileSync21, writeFileSync: writeFileSync14, copyFileSync: copyFileSync4, mkdirSync: mkdirSync18 } = await import("fs");
|
|
30550
31212
|
const { dirname: dirname9 } = await import("path");
|
|
30551
31213
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
30552
31214
|
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
@@ -30589,14 +31251,14 @@ ${block2}`);
|
|
|
30589
31251
|
if (hermesManualFallback) return returnManualFallback(message);
|
|
30590
31252
|
return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
|
|
30591
31253
|
}
|
|
30592
|
-
const hadExistingMcpConfig =
|
|
31254
|
+
const hadExistingMcpConfig = existsSync28(mcpConfigPath);
|
|
30593
31255
|
let existingMcpConfig = hermesBaseConfig?.config || {};
|
|
30594
31256
|
if (hermesBaseConfig) {
|
|
30595
31257
|
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname9(mcpConfigPath));
|
|
30596
31258
|
}
|
|
30597
31259
|
if (hadExistingMcpConfig) {
|
|
30598
31260
|
try {
|
|
30599
|
-
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(
|
|
31261
|
+
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync21(mcpConfigPath, "utf-8"), configFormat);
|
|
30600
31262
|
const existingCoordinatorConfig = hermesManualFallback ? stripHermesCoordinatorTempModelProviderOverrides(parsedExistingMcpConfig) : parsedExistingMcpConfig;
|
|
30601
31263
|
existingMcpConfig = { ...existingMcpConfig, ...existingCoordinatorConfig };
|
|
30602
31264
|
copyFileSync4(mcpConfigPath, mcpConfigPath + ".backup");
|
|
@@ -30708,6 +31370,7 @@ ${block2}`);
|
|
|
30708
31370
|
const queueSummary = getMeshQueueStats2(meshId);
|
|
30709
31371
|
const { readLedgerEntries: readLedgerEntries2, getLedgerSummary: getLedgerSummary2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
30710
31372
|
const ledgerEntries = readLedgerEntries2(meshId, { tail: 20 });
|
|
31373
|
+
const asyncRefineLedgerEntries = readLedgerEntries2(meshId, { tail: 100 });
|
|
30711
31374
|
const ledgerSummary = getLedgerSummary2(meshId);
|
|
30712
31375
|
const sessionHostRecords = this.deps.sessionHostControl?.listSessions ? await this.deps.sessionHostControl.listSessions().catch(() => []) : [];
|
|
30713
31376
|
const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
|
|
@@ -30970,6 +31633,20 @@ ${block2}`);
|
|
|
30970
31633
|
nodeStatuses.push(status);
|
|
30971
31634
|
}
|
|
30972
31635
|
const pendingCoordinatorEvents = drainPendingMeshCoordinatorEvents(meshId);
|
|
31636
|
+
const previewFreshness = (() => {
|
|
31637
|
+
const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate && fs11.existsSync(candidate));
|
|
31638
|
+
return localRepoRoot ? buildPreviewFreshness(localRepoRoot) : void 0;
|
|
31639
|
+
})();
|
|
31640
|
+
const asyncRefineJobs = buildMeshAsyncRefineJobs({
|
|
31641
|
+
meshId,
|
|
31642
|
+
ledgerEntries: asyncRefineLedgerEntries,
|
|
31643
|
+
pendingEvents: pendingCoordinatorEvents
|
|
31644
|
+
});
|
|
31645
|
+
const historicalSessions = buildHistoricalMeshSessions({
|
|
31646
|
+
meshId,
|
|
31647
|
+
nodes: mesh.nodes || [],
|
|
31648
|
+
liveSessionRecords: liveMeshSessions
|
|
31649
|
+
});
|
|
30973
31650
|
const statusResult = {
|
|
30974
31651
|
success: true,
|
|
30975
31652
|
meshId: mesh.id,
|
|
@@ -31001,12 +31678,15 @@ ${block2}`);
|
|
|
31001
31678
|
partialNodeFailures: effectiveDirectTruth.unavailableNodeIds
|
|
31002
31679
|
}
|
|
31003
31680
|
} : {},
|
|
31004
|
-
historicalEvidenceOnly: ["recoveryHints", "ledger.summary", "queue.summary"]
|
|
31681
|
+
historicalEvidenceOnly: ["recoveryHints", "ledger.summary", "queue.summary", "historicalSessions"]
|
|
31005
31682
|
},
|
|
31006
31683
|
branchConvergenceSummary: summarizeInlineMeshBranchConvergence(nodeStatuses),
|
|
31684
|
+
...previewFreshness ? { previewFreshness, deployFreshness: previewFreshness } : {},
|
|
31007
31685
|
nodes: nodeStatuses,
|
|
31008
31686
|
queue: { tasks: queue, summary: queueSummary },
|
|
31009
31687
|
ledger: { entries: ledgerEntries, summary: ledgerSummary },
|
|
31688
|
+
...asyncRefineJobs.length > 0 ? { asyncRefineJobs } : {},
|
|
31689
|
+
...historicalSessions ? { historicalSessions } : {},
|
|
31010
31690
|
...pendingCoordinatorEvents.length > 0 ? { pendingCoordinatorEvents } : {}
|
|
31011
31691
|
};
|
|
31012
31692
|
const { pendingCoordinatorEvents: _pendingCoordinatorEvents, ...cacheableStatusResult } = statusResult;
|
|
@@ -31657,7 +32337,7 @@ var ProviderStreamAdapter = class {
|
|
|
31657
32337
|
const beforeCount = this.messageCount(before);
|
|
31658
32338
|
const beforeSignature = this.lastMessageSignature(before);
|
|
31659
32339
|
for (let attempt = 0; attempt < 12; attempt += 1) {
|
|
31660
|
-
await new Promise((
|
|
32340
|
+
await new Promise((resolve17) => setTimeout(resolve17, 250));
|
|
31661
32341
|
let state;
|
|
31662
32342
|
try {
|
|
31663
32343
|
state = await this.readChat(evaluate);
|
|
@@ -31679,7 +32359,7 @@ var ProviderStreamAdapter = class {
|
|
|
31679
32359
|
if (this.messageCount(first) > 0 || this.lastMessageSignature(first)) {
|
|
31680
32360
|
return first;
|
|
31681
32361
|
}
|
|
31682
|
-
await new Promise((
|
|
32362
|
+
await new Promise((resolve17) => setTimeout(resolve17, 150));
|
|
31683
32363
|
const second = await this.readChat(evaluate);
|
|
31684
32364
|
return this.messageCount(second) >= this.messageCount(first) ? second : first;
|
|
31685
32365
|
}
|
|
@@ -31830,7 +32510,7 @@ var ProviderStreamAdapter = class {
|
|
|
31830
32510
|
if (typeof data.error === "string" && data.error.trim()) return false;
|
|
31831
32511
|
}
|
|
31832
32512
|
for (let attempt = 0; attempt < 6; attempt += 1) {
|
|
31833
|
-
await new Promise((
|
|
32513
|
+
await new Promise((resolve17) => setTimeout(resolve17, 250));
|
|
31834
32514
|
const state = await this.readChat(evaluate);
|
|
31835
32515
|
const title = this.getStateTitle(state);
|
|
31836
32516
|
if (this.titlesMatch(title, sessionId)) return true;
|
|
@@ -32758,13 +33438,13 @@ var VersionArchive = class {
|
|
|
32758
33438
|
}
|
|
32759
33439
|
};
|
|
32760
33440
|
async function runCommand(cmd, timeout = 1e4) {
|
|
32761
|
-
return new Promise((
|
|
33441
|
+
return new Promise((resolve17) => {
|
|
32762
33442
|
exec5(cmd, {
|
|
32763
33443
|
encoding: "utf-8",
|
|
32764
33444
|
timeout
|
|
32765
33445
|
}, (error, stdout) => {
|
|
32766
|
-
if (error) return
|
|
32767
|
-
|
|
33446
|
+
if (error) return resolve17(null);
|
|
33447
|
+
resolve17(stdout.trim());
|
|
32768
33448
|
});
|
|
32769
33449
|
});
|
|
32770
33450
|
}
|
|
@@ -34453,7 +35133,7 @@ function getCliTargetBundle(ctx, type, instanceId) {
|
|
|
34453
35133
|
return { target, instance, adapter };
|
|
34454
35134
|
}
|
|
34455
35135
|
function sleep2(ms) {
|
|
34456
|
-
return new Promise((
|
|
35136
|
+
return new Promise((resolve17) => setTimeout(resolve17, ms));
|
|
34457
35137
|
}
|
|
34458
35138
|
async function waitForCliReady(ctx, type, instanceId, timeoutMs) {
|
|
34459
35139
|
const startedAt = Date.now();
|
|
@@ -36708,15 +37388,15 @@ var DevServer = class _DevServer {
|
|
|
36708
37388
|
this.json(res, 500, { error: e.message });
|
|
36709
37389
|
}
|
|
36710
37390
|
});
|
|
36711
|
-
return new Promise((
|
|
37391
|
+
return new Promise((resolve17, reject) => {
|
|
36712
37392
|
this.server.listen(port, "127.0.0.1", () => {
|
|
36713
37393
|
this.log(`Dev server listening on http://127.0.0.1:${port}`);
|
|
36714
|
-
|
|
37394
|
+
resolve17();
|
|
36715
37395
|
});
|
|
36716
37396
|
this.server.on("error", (e) => {
|
|
36717
37397
|
if (e.code === "EADDRINUSE") {
|
|
36718
37398
|
this.log(`Port ${port} in use, skipping dev server`);
|
|
36719
|
-
|
|
37399
|
+
resolve17();
|
|
36720
37400
|
} else {
|
|
36721
37401
|
reject(e);
|
|
36722
37402
|
}
|
|
@@ -36798,20 +37478,20 @@ var DevServer = class _DevServer {
|
|
|
36798
37478
|
child.stderr?.on("data", (d) => {
|
|
36799
37479
|
stderr += d.toString().slice(0, 2e3);
|
|
36800
37480
|
});
|
|
36801
|
-
await new Promise((
|
|
37481
|
+
await new Promise((resolve17) => {
|
|
36802
37482
|
const timer = setTimeout(() => {
|
|
36803
37483
|
child.kill();
|
|
36804
|
-
|
|
37484
|
+
resolve17();
|
|
36805
37485
|
}, 3e3);
|
|
36806
37486
|
child.on("exit", () => {
|
|
36807
37487
|
clearTimeout(timer);
|
|
36808
|
-
|
|
37488
|
+
resolve17();
|
|
36809
37489
|
});
|
|
36810
37490
|
child.stdout?.once("data", () => {
|
|
36811
37491
|
setTimeout(() => {
|
|
36812
37492
|
child.kill();
|
|
36813
37493
|
clearTimeout(timer);
|
|
36814
|
-
|
|
37494
|
+
resolve17();
|
|
36815
37495
|
}, 500);
|
|
36816
37496
|
});
|
|
36817
37497
|
});
|
|
@@ -37314,14 +37994,14 @@ var DevServer = class _DevServer {
|
|
|
37314
37994
|
child.stderr?.on("data", (d) => {
|
|
37315
37995
|
stderr += d.toString();
|
|
37316
37996
|
});
|
|
37317
|
-
await new Promise((
|
|
37997
|
+
await new Promise((resolve17) => {
|
|
37318
37998
|
const timer = setTimeout(() => {
|
|
37319
37999
|
child.kill();
|
|
37320
|
-
|
|
38000
|
+
resolve17();
|
|
37321
38001
|
}, timeout);
|
|
37322
38002
|
child.on("exit", () => {
|
|
37323
38003
|
clearTimeout(timer);
|
|
37324
|
-
|
|
38004
|
+
resolve17();
|
|
37325
38005
|
});
|
|
37326
38006
|
});
|
|
37327
38007
|
const elapsed = Date.now() - start;
|
|
@@ -37991,14 +38671,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
37991
38671
|
res.end(JSON.stringify(data, null, 2));
|
|
37992
38672
|
}
|
|
37993
38673
|
async readBody(req) {
|
|
37994
|
-
return new Promise((
|
|
38674
|
+
return new Promise((resolve17) => {
|
|
37995
38675
|
let body = "";
|
|
37996
38676
|
req.on("data", (chunk) => body += chunk);
|
|
37997
38677
|
req.on("end", () => {
|
|
37998
38678
|
try {
|
|
37999
|
-
|
|
38679
|
+
resolve17(JSON.parse(body));
|
|
38000
38680
|
} catch {
|
|
38001
|
-
|
|
38681
|
+
resolve17({});
|
|
38002
38682
|
}
|
|
38003
38683
|
});
|
|
38004
38684
|
});
|
|
@@ -38541,7 +39221,7 @@ async function waitForReady(endpoint, timeoutMs = STARTUP_TIMEOUT_MS, requiredRe
|
|
|
38541
39221
|
const deadline = Date.now() + timeoutMs;
|
|
38542
39222
|
while (Date.now() < deadline) {
|
|
38543
39223
|
if (await canConnect(endpoint, requiredRequestTypes)) return;
|
|
38544
|
-
await new Promise((
|
|
39224
|
+
await new Promise((resolve17) => setTimeout(resolve17, STARTUP_POLL_MS));
|
|
38545
39225
|
}
|
|
38546
39226
|
throw new Error(`Session host did not become ready within ${timeoutMs}ms`);
|
|
38547
39227
|
}
|
|
@@ -38592,7 +39272,7 @@ function shouldAutoRestoreHostedSessionsOnStartup(env = process.env) {
|
|
|
38592
39272
|
|
|
38593
39273
|
// src/installer.ts
|
|
38594
39274
|
import { exec as exec6 } from "child_process";
|
|
38595
|
-
import { promisify as
|
|
39275
|
+
import { promisify as promisify6 } from "util";
|
|
38596
39276
|
var EXTENSION_CATALOG = [
|
|
38597
39277
|
// AI Agent extensions
|
|
38598
39278
|
{
|
|
@@ -38679,7 +39359,7 @@ var EXTENSION_CATALOG = [
|
|
|
38679
39359
|
apiKeyName: "OpenAI/Anthropic API key"
|
|
38680
39360
|
}
|
|
38681
39361
|
];
|
|
38682
|
-
var execAsync4 =
|
|
39362
|
+
var execAsync4 = promisify6(exec6);
|
|
38683
39363
|
async function isExtensionInstalled(ide, marketplaceId) {
|
|
38684
39364
|
if (!ide.cliCommand) return false;
|
|
38685
39365
|
try {
|
|
@@ -38721,10 +39401,10 @@ async function installExtension(ide, extension) {
|
|
|
38721
39401
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
38722
39402
|
const fs17 = await import("fs");
|
|
38723
39403
|
fs17.writeFileSync(vsixPath, buffer);
|
|
38724
|
-
return new Promise((
|
|
39404
|
+
return new Promise((resolve17) => {
|
|
38725
39405
|
const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
|
|
38726
39406
|
exec6(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
|
|
38727
|
-
|
|
39407
|
+
resolve17({
|
|
38728
39408
|
extensionId: extension.id,
|
|
38729
39409
|
marketplaceId: extension.marketplaceId,
|
|
38730
39410
|
success: !error,
|
|
@@ -38737,11 +39417,11 @@ async function installExtension(ide, extension) {
|
|
|
38737
39417
|
} catch (e) {
|
|
38738
39418
|
}
|
|
38739
39419
|
}
|
|
38740
|
-
return new Promise((
|
|
39420
|
+
return new Promise((resolve17) => {
|
|
38741
39421
|
const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
|
|
38742
39422
|
exec6(cmd, { timeout: 6e4 }, (error, stdout, stderr) => {
|
|
38743
39423
|
if (error) {
|
|
38744
|
-
|
|
39424
|
+
resolve17({
|
|
38745
39425
|
extensionId: extension.id,
|
|
38746
39426
|
marketplaceId: extension.marketplaceId,
|
|
38747
39427
|
success: false,
|
|
@@ -38749,7 +39429,7 @@ async function installExtension(ide, extension) {
|
|
|
38749
39429
|
error: stderr || error.message
|
|
38750
39430
|
});
|
|
38751
39431
|
} else {
|
|
38752
|
-
|
|
39432
|
+
resolve17({
|
|
38753
39433
|
extensionId: extension.id,
|
|
38754
39434
|
marketplaceId: extension.marketplaceId,
|
|
38755
39435
|
success: true,
|
|
@@ -39123,6 +39803,8 @@ export {
|
|
|
39123
39803
|
MAX_LEDGER_SLICE_LIMIT,
|
|
39124
39804
|
MESH_REFINE_CONFIG_LOCATIONS,
|
|
39125
39805
|
MESH_REFINE_CONFIG_SCHEMA,
|
|
39806
|
+
MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS,
|
|
39807
|
+
MESH_WORKTREE_BOOTSTRAP_CONFIG_SCHEMA,
|
|
39126
39808
|
MIN_GIT_WORKSPACE_POLL_INTERVAL_MS,
|
|
39127
39809
|
MIN_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS,
|
|
39128
39810
|
MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS,
|
|
@@ -39143,10 +39825,12 @@ export {
|
|
|
39143
39825
|
buildChatMessage,
|
|
39144
39826
|
buildChatMessageSignature,
|
|
39145
39827
|
buildChatTailDeliverySignature,
|
|
39828
|
+
buildCompactStaleDirectWorkSummary,
|
|
39146
39829
|
buildCoordinatorSystemPrompt,
|
|
39147
39830
|
buildMachineInfo,
|
|
39148
39831
|
buildMeshActiveWork,
|
|
39149
39832
|
buildMeshActiveWorkSummary,
|
|
39833
|
+
buildMeshAsyncRefineJobs,
|
|
39150
39834
|
buildMeshHostRequiredFailure,
|
|
39151
39835
|
buildMeshLedgerReconciliationEvidence,
|
|
39152
39836
|
buildMeshLedgerReplicaEvidence,
|
|
@@ -39255,6 +39939,7 @@ export {
|
|
|
39255
39939
|
listWorktrees,
|
|
39256
39940
|
loadConfig,
|
|
39257
39941
|
loadMeshRefineConfig,
|
|
39942
|
+
loadMeshWorktreeBootstrapConfig,
|
|
39258
39943
|
loadState,
|
|
39259
39944
|
logCommand,
|
|
39260
39945
|
markSetupComplete,
|
|
@@ -39306,6 +39991,7 @@ export {
|
|
|
39306
39991
|
resolveWorktreePath,
|
|
39307
39992
|
runAsyncBatch,
|
|
39308
39993
|
runGit,
|
|
39994
|
+
runMeshWorktreeBootstrap,
|
|
39309
39995
|
saveConfig,
|
|
39310
39996
|
saveState,
|
|
39311
39997
|
setDebugRuntimeConfig,
|
|
@@ -39327,6 +40013,7 @@ export {
|
|
|
39327
40013
|
updateTaskStatus,
|
|
39328
40014
|
upsertSavedProviderSession,
|
|
39329
40015
|
validateMeshRefineConfig,
|
|
39330
|
-
validateMeshTaskModeRequest
|
|
40016
|
+
validateMeshTaskModeRequest,
|
|
40017
|
+
validateMeshWorktreeBootstrapConfig
|
|
39331
40018
|
};
|
|
39332
40019
|
//# sourceMappingURL=index.mjs.map
|