@adhdev/daemon-core 0.9.82-rc.113 → 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 +976 -269
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +960 -260
- 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/chat-commands.ts +28 -10
- 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;
|
|
@@ -16231,7 +16560,16 @@ function readHistorySessionIdFromMessages(messages) {
|
|
|
16231
16560
|
}
|
|
16232
16561
|
return void 0;
|
|
16233
16562
|
}
|
|
16234
|
-
function
|
|
16563
|
+
function shouldPreserveNativeIdentity(providerType, sessionId, message) {
|
|
16564
|
+
const providerUnitKey = typeof message.providerUnitKey === "string" ? message.providerUnitKey.trim() : "";
|
|
16565
|
+
const turnKey = typeof message._turnKey === "string" ? message._turnKey.trim() : "";
|
|
16566
|
+
if (!providerUnitKey || !turnKey) return false;
|
|
16567
|
+
if (providerType === "hermes-cli" && sessionId) {
|
|
16568
|
+
return providerUnitKey.startsWith(`${providerType}:native:${sessionId}:`) && turnKey.startsWith(`${providerType}:native-turn:${sessionId}:`);
|
|
16569
|
+
}
|
|
16570
|
+
return true;
|
|
16571
|
+
}
|
|
16572
|
+
function normalizeNativeHistoryMessages(providerType, messages, nativeSessionId) {
|
|
16235
16573
|
let turnIndex = 0;
|
|
16236
16574
|
return normalizeChatMessages(messages).map((message, index) => {
|
|
16237
16575
|
const role = typeof message.role === "string" ? message.role.trim().toLowerCase() : "";
|
|
@@ -16246,7 +16584,11 @@ function normalizeNativeHistoryMessages(providerType, messages) {
|
|
|
16246
16584
|
kind,
|
|
16247
16585
|
flattenContent(message.content)
|
|
16248
16586
|
]).slice(0, 12);
|
|
16249
|
-
const
|
|
16587
|
+
const nativeIdentitySessionId = historySessionId || (typeof nativeSessionId === "string" ? nativeSessionId.trim() : "");
|
|
16588
|
+
const preserveNativeIdentity = shouldPreserveNativeIdentity(providerType, nativeIdentitySessionId, message);
|
|
16589
|
+
const existingProviderUnitKey = typeof message.providerUnitKey === "string" ? message.providerUnitKey.trim() : "";
|
|
16590
|
+
const existingTurnKey = typeof message._turnKey === "string" ? message._turnKey.trim() : "";
|
|
16591
|
+
const providerUnitKey = preserveNativeIdentity ? existingProviderUnitKey : `${providerType}:native:${nativeIdentitySessionId || "workspace"}:${index}:${role || "message"}:${kind}:${contentHash}`;
|
|
16250
16592
|
const meta = message.meta && typeof message.meta === "object" ? message.meta : void 0;
|
|
16251
16593
|
const isSystemSessionStart = role === "system" || kind === "system" || kind === "session_start";
|
|
16252
16594
|
const isActivity = role === "assistant" && (kind === "tool" || kind === "terminal" || kind === "thought");
|
|
@@ -16255,8 +16597,8 @@ function normalizeNativeHistoryMessages(providerType, messages) {
|
|
|
16255
16597
|
role: role === "human" ? "user" : role || "assistant",
|
|
16256
16598
|
kind: isSystemSessionStart ? "system" : kind,
|
|
16257
16599
|
providerUnitKey,
|
|
16258
|
-
bubbleId: typeof message.bubbleId === "string" && message.bubbleId.trim() ? message.bubbleId.trim() : `bubble:${providerUnitKey}`,
|
|
16259
|
-
_turnKey:
|
|
16600
|
+
bubbleId: typeof message.bubbleId === "string" && message.bubbleId.trim() && preserveNativeIdentity ? message.bubbleId.trim() : `bubble:${providerUnitKey}`,
|
|
16601
|
+
_turnKey: preserveNativeIdentity ? existingTurnKey : `${providerType}:native-turn:${nativeIdentitySessionId || "workspace"}:${turnIndex}`,
|
|
16260
16602
|
bubbleState: message.bubbleState || "final",
|
|
16261
16603
|
...isSystemSessionStart ? {
|
|
16262
16604
|
visibility: message.visibility || "hidden",
|
|
@@ -16909,7 +17251,7 @@ function getCliVisibleTranscriptCount(adapter) {
|
|
|
16909
17251
|
async function getStableExtensionBaseline(h) {
|
|
16910
17252
|
const first = await readExtensionChatState(h);
|
|
16911
17253
|
if (getStateMessageCount(first) > 0 || getStateLastSignature(first)) return first;
|
|
16912
|
-
await new Promise((
|
|
17254
|
+
await new Promise((resolve17) => setTimeout(resolve17, 150));
|
|
16913
17255
|
const second = await readExtensionChatState(h);
|
|
16914
17256
|
return getStateMessageCount(second) >= getStateMessageCount(first) ? second : first;
|
|
16915
17257
|
}
|
|
@@ -16917,7 +17259,7 @@ async function verifyExtensionSendObserved(h, before) {
|
|
|
16917
17259
|
const beforeCount = getStateMessageCount(before);
|
|
16918
17260
|
const beforeSignature = getStateLastSignature(before);
|
|
16919
17261
|
for (let attempt = 0; attempt < 12; attempt += 1) {
|
|
16920
|
-
await new Promise((
|
|
17262
|
+
await new Promise((resolve17) => setTimeout(resolve17, 250));
|
|
16921
17263
|
const state = await readExtensionChatState(h);
|
|
16922
17264
|
if (state?.status === "waiting_approval") return true;
|
|
16923
17265
|
const afterCount = getStateMessageCount(state);
|
|
@@ -16967,7 +17309,7 @@ async function handleChatHistory(h, args) {
|
|
|
16967
17309
|
});
|
|
16968
17310
|
if (supportsCliNativeTranscript(agentStr, provider) && isNativeSourceCanonicalHistory(provider?.canonicalHistory)) {
|
|
16969
17311
|
const lookup = result.lookup === "workspace" ? "workspace" : "session";
|
|
16970
|
-
const messages = Array.isArray(result.messages) ? normalizeNativeHistoryMessages(agentStr, result.messages) : [];
|
|
17312
|
+
const messages = Array.isArray(result.messages) ? normalizeNativeHistoryMessages(agentStr, result.messages, result?.providerSessionId) : [];
|
|
16971
17313
|
const historyProviderSessionId = typeof result?.providerSessionId === "string" ? result.providerSessionId : readHistorySessionIdFromMessages(messages) || historySessionId;
|
|
16972
17314
|
const safeMapping = hasSafeNativeHistoryMapping({
|
|
16973
17315
|
historySessionId: lookup === "workspace" ? void 0 : historySessionId,
|
|
@@ -17075,7 +17417,7 @@ async function handleReadChat(h, args) {
|
|
|
17075
17417
|
nativeHistory = null;
|
|
17076
17418
|
}
|
|
17077
17419
|
if (nativeHistory) {
|
|
17078
|
-
const nativeMessages = Array.isArray(nativeHistory.messages) ? normalizeNativeHistoryMessages(agentStr, nativeHistory.messages) : [];
|
|
17420
|
+
const nativeMessages = Array.isArray(nativeHistory.messages) ? normalizeNativeHistoryMessages(agentStr, nativeHistory.messages, nativeHistory?.providerSessionId) : [];
|
|
17079
17421
|
const historyProviderSessionId = typeof nativeHistory?.providerSessionId === "string" ? nativeHistory.providerSessionId : readHistorySessionIdFromMessages(nativeMessages) || nativeHistorySessionId || historySessionId;
|
|
17080
17422
|
const nativeHistoryCoverage = typeof nativeHistory?.nativeHistoryCoverage === "string" ? nativeHistory.nativeHistoryCoverage : void 0;
|
|
17081
17423
|
const partialReason = typeof nativeHistory?.partialReason === "string" ? nativeHistory.partialReason : void 0;
|
|
@@ -17203,7 +17545,7 @@ async function handleReadChat(h, args) {
|
|
|
17203
17545
|
scripts: provider?.scripts
|
|
17204
17546
|
});
|
|
17205
17547
|
const lookup = history.lookup === "workspace" ? "workspace" : "session";
|
|
17206
|
-
const historyMessages = Array.isArray(history?.messages) ? normalizeNativeHistoryMessages(agentStr, history.messages) : [];
|
|
17548
|
+
const historyMessages = Array.isArray(history?.messages) ? normalizeNativeHistoryMessages(agentStr, history.messages, history?.providerSessionId) : [];
|
|
17207
17549
|
const historyProviderSessionId = typeof history?.providerSessionId === "string" ? history.providerSessionId : readHistorySessionIdFromMessages(historyMessages) || historySessionId;
|
|
17208
17550
|
const nativeHistoryCoverage = typeof history?.nativeHistoryCoverage === "string" ? history.nativeHistoryCoverage : void 0;
|
|
17209
17551
|
const partialReason = typeof history?.partialReason === "string" ? history.partialReason : void 0;
|
|
@@ -18806,7 +19148,7 @@ async function executeProviderScript(h, args, scriptName) {
|
|
|
18806
19148
|
const enterCount = cliCommand.enterCount || 1;
|
|
18807
19149
|
await adapter.writeRaw(cliCommand.text + "\r");
|
|
18808
19150
|
for (let i = 1; i < enterCount; i += 1) {
|
|
18809
|
-
await new Promise((
|
|
19151
|
+
await new Promise((resolve17) => setTimeout(resolve17, 50));
|
|
18810
19152
|
await adapter.writeRaw("\r");
|
|
18811
19153
|
}
|
|
18812
19154
|
}
|
|
@@ -19495,7 +19837,7 @@ var DaemonCommandHandler = class {
|
|
|
19495
19837
|
try {
|
|
19496
19838
|
const http3 = await import("http");
|
|
19497
19839
|
const postData = JSON.stringify(body);
|
|
19498
|
-
const result = await new Promise((
|
|
19840
|
+
const result = await new Promise((resolve17, reject) => {
|
|
19499
19841
|
const req = http3.request({
|
|
19500
19842
|
hostname: "127.0.0.1",
|
|
19501
19843
|
port: 19280,
|
|
@@ -19507,9 +19849,9 @@ var DaemonCommandHandler = class {
|
|
|
19507
19849
|
res.on("data", (chunk) => data += chunk);
|
|
19508
19850
|
res.on("end", () => {
|
|
19509
19851
|
try {
|
|
19510
|
-
|
|
19852
|
+
resolve17(JSON.parse(data));
|
|
19511
19853
|
} catch {
|
|
19512
|
-
|
|
19854
|
+
resolve17({ raw: data });
|
|
19513
19855
|
}
|
|
19514
19856
|
});
|
|
19515
19857
|
});
|
|
@@ -19527,15 +19869,15 @@ var DaemonCommandHandler = class {
|
|
|
19527
19869
|
if (!providerType) return { success: false, error: "providerType required" };
|
|
19528
19870
|
try {
|
|
19529
19871
|
const http3 = await import("http");
|
|
19530
|
-
const result = await new Promise((
|
|
19872
|
+
const result = await new Promise((resolve17, reject) => {
|
|
19531
19873
|
http3.get(`http://127.0.0.1:19280/api/providers/${providerType}/${endpoint}`, (res) => {
|
|
19532
19874
|
let data = "";
|
|
19533
19875
|
res.on("data", (chunk) => data += chunk);
|
|
19534
19876
|
res.on("end", () => {
|
|
19535
19877
|
try {
|
|
19536
|
-
|
|
19878
|
+
resolve17(JSON.parse(data));
|
|
19537
19879
|
} catch {
|
|
19538
|
-
|
|
19880
|
+
resolve17({ raw: data });
|
|
19539
19881
|
}
|
|
19540
19882
|
});
|
|
19541
19883
|
}).on("error", reject);
|
|
@@ -19549,7 +19891,7 @@ var DaemonCommandHandler = class {
|
|
|
19549
19891
|
try {
|
|
19550
19892
|
const http3 = await import("http");
|
|
19551
19893
|
const postData = JSON.stringify(args || {});
|
|
19552
|
-
const result = await new Promise((
|
|
19894
|
+
const result = await new Promise((resolve17, reject) => {
|
|
19553
19895
|
const req = http3.request({
|
|
19554
19896
|
hostname: "127.0.0.1",
|
|
19555
19897
|
port: 19280,
|
|
@@ -19561,9 +19903,9 @@ var DaemonCommandHandler = class {
|
|
|
19561
19903
|
res.on("data", (chunk) => data += chunk);
|
|
19562
19904
|
res.on("end", () => {
|
|
19563
19905
|
try {
|
|
19564
|
-
|
|
19906
|
+
resolve17(JSON.parse(data));
|
|
19565
19907
|
} catch {
|
|
19566
|
-
|
|
19908
|
+
resolve17({ raw: data });
|
|
19567
19909
|
}
|
|
19568
19910
|
});
|
|
19569
19911
|
});
|
|
@@ -19585,7 +19927,7 @@ init_config();
|
|
|
19585
19927
|
import * as os13 from "os";
|
|
19586
19928
|
import * as path18 from "path";
|
|
19587
19929
|
import * as crypto4 from "crypto";
|
|
19588
|
-
import { existsSync as
|
|
19930
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync10, writeFileSync as writeFileSync8 } from "fs";
|
|
19589
19931
|
import { execFileSync } from "child_process";
|
|
19590
19932
|
import chalk from "chalk";
|
|
19591
19933
|
|
|
@@ -19807,7 +20149,7 @@ async function waitForCliAdapterReady(adapter, options) {
|
|
|
19807
20149
|
if (status === "stopped") {
|
|
19808
20150
|
throw new Error("CLI runtime stopped before it became ready");
|
|
19809
20151
|
}
|
|
19810
|
-
await new Promise((
|
|
20152
|
+
await new Promise((resolve17) => setTimeout(resolve17, pollMs));
|
|
19811
20153
|
}
|
|
19812
20154
|
throw new Error(`CLI runtime did not become ready within ${timeoutMs}ms`);
|
|
19813
20155
|
}
|
|
@@ -20184,7 +20526,7 @@ var CliProviderInstance = class {
|
|
|
20184
20526
|
const enterCount = cliCommand.enterCount || 1;
|
|
20185
20527
|
await this.adapter.writeRaw(cliCommand.text + "\r");
|
|
20186
20528
|
for (let i = 1; i < enterCount; i += 1) {
|
|
20187
|
-
await new Promise((
|
|
20529
|
+
await new Promise((resolve17) => setTimeout(resolve17, 50));
|
|
20188
20530
|
await this.adapter.writeRaw("\r");
|
|
20189
20531
|
}
|
|
20190
20532
|
}
|
|
@@ -21585,13 +21927,13 @@ var AcpProviderInstance = class {
|
|
|
21585
21927
|
}
|
|
21586
21928
|
this.currentStatus = "waiting_approval";
|
|
21587
21929
|
this.detectStatusTransition();
|
|
21588
|
-
const approved = await new Promise((
|
|
21589
|
-
this.permissionResolvers.push(
|
|
21930
|
+
const approved = await new Promise((resolve17) => {
|
|
21931
|
+
this.permissionResolvers.push(resolve17);
|
|
21590
21932
|
setTimeout(() => {
|
|
21591
|
-
const idx = this.permissionResolvers.indexOf(
|
|
21933
|
+
const idx = this.permissionResolvers.indexOf(resolve17);
|
|
21592
21934
|
if (idx >= 0) {
|
|
21593
21935
|
this.permissionResolvers.splice(idx, 1);
|
|
21594
|
-
|
|
21936
|
+
resolve17(false);
|
|
21595
21937
|
}
|
|
21596
21938
|
}, 3e5);
|
|
21597
21939
|
});
|
|
@@ -22202,7 +22544,7 @@ function commandExists(command) {
|
|
|
22202
22544
|
const trimmed = command.trim();
|
|
22203
22545
|
if (!trimmed) return false;
|
|
22204
22546
|
if (isExplicitCommand(trimmed)) {
|
|
22205
|
-
return
|
|
22547
|
+
return existsSync17(expandExecutable(trimmed));
|
|
22206
22548
|
}
|
|
22207
22549
|
try {
|
|
22208
22550
|
execFileSync(process.platform === "win32" ? "where" : "which", [trimmed], {
|
|
@@ -22300,7 +22642,7 @@ async function waitForZeroMessageStartingLaunch(adapter) {
|
|
|
22300
22642
|
} catch {
|
|
22301
22643
|
return false;
|
|
22302
22644
|
}
|
|
22303
|
-
await new Promise((
|
|
22645
|
+
await new Promise((resolve17) => setTimeout(resolve17, ZERO_MESSAGE_STARTING_SEND_WAIT_MS));
|
|
22304
22646
|
try {
|
|
22305
22647
|
return hasZeroMessageStartingLaunch(adapter);
|
|
22306
22648
|
} catch {
|
|
@@ -24373,8 +24715,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
24373
24715
|
}
|
|
24374
24716
|
const https = __require("https");
|
|
24375
24717
|
const { exec: exec7 } = __require("child_process");
|
|
24376
|
-
const { promisify:
|
|
24377
|
-
const execAsync5 =
|
|
24718
|
+
const { promisify: promisify7 } = __require("util");
|
|
24719
|
+
const execAsync5 = promisify7(exec7);
|
|
24378
24720
|
const metaPath = path19.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
24379
24721
|
let prevEtag = "";
|
|
24380
24722
|
let prevTimestamp = 0;
|
|
@@ -24392,7 +24734,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
24392
24734
|
return { updated: false };
|
|
24393
24735
|
}
|
|
24394
24736
|
try {
|
|
24395
|
-
const etag = await new Promise((
|
|
24737
|
+
const etag = await new Promise((resolve17, reject) => {
|
|
24396
24738
|
const options = {
|
|
24397
24739
|
method: "HEAD",
|
|
24398
24740
|
hostname: "github.com",
|
|
@@ -24410,7 +24752,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
24410
24752
|
headers: { "User-Agent": "adhdev-launcher" },
|
|
24411
24753
|
timeout: 1e4
|
|
24412
24754
|
}, (res2) => {
|
|
24413
|
-
|
|
24755
|
+
resolve17(res2.headers.etag || res2.headers["last-modified"] || "");
|
|
24414
24756
|
});
|
|
24415
24757
|
req2.on("error", reject);
|
|
24416
24758
|
req2.on("timeout", () => {
|
|
@@ -24419,7 +24761,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
24419
24761
|
});
|
|
24420
24762
|
req2.end();
|
|
24421
24763
|
} else {
|
|
24422
|
-
|
|
24764
|
+
resolve17(res.headers.etag || res.headers["last-modified"] || "");
|
|
24423
24765
|
}
|
|
24424
24766
|
});
|
|
24425
24767
|
req.on("error", reject);
|
|
@@ -24483,7 +24825,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
24483
24825
|
downloadFile(url, destPath) {
|
|
24484
24826
|
const https = __require("https");
|
|
24485
24827
|
const http3 = __require("http");
|
|
24486
|
-
return new Promise((
|
|
24828
|
+
return new Promise((resolve17, reject) => {
|
|
24487
24829
|
const doRequest = (reqUrl, redirectCount = 0) => {
|
|
24488
24830
|
if (redirectCount > 5) {
|
|
24489
24831
|
reject(new Error("Too many redirects"));
|
|
@@ -24503,7 +24845,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
24503
24845
|
res.pipe(ws);
|
|
24504
24846
|
ws.on("finish", () => {
|
|
24505
24847
|
ws.close();
|
|
24506
|
-
|
|
24848
|
+
resolve17();
|
|
24507
24849
|
});
|
|
24508
24850
|
ws.on("error", reject);
|
|
24509
24851
|
});
|
|
@@ -25006,10 +25348,10 @@ function findMacAppProcessPids(psOutput, appPaths) {
|
|
|
25006
25348
|
|
|
25007
25349
|
// src/launch.ts
|
|
25008
25350
|
async function execQuiet(command, options = {}) {
|
|
25009
|
-
return new Promise((
|
|
25351
|
+
return new Promise((resolve17) => {
|
|
25010
25352
|
exec4(command, options, (error, stdout) => {
|
|
25011
|
-
if (error) return
|
|
25012
|
-
|
|
25353
|
+
if (error) return resolve17("");
|
|
25354
|
+
resolve17(stdout.toString());
|
|
25013
25355
|
});
|
|
25014
25356
|
});
|
|
25015
25357
|
}
|
|
@@ -25090,17 +25432,17 @@ async function findFreePort(ports) {
|
|
|
25090
25432
|
throw new Error("No free port found");
|
|
25091
25433
|
}
|
|
25092
25434
|
function checkPortFree(port) {
|
|
25093
|
-
return new Promise((
|
|
25435
|
+
return new Promise((resolve17) => {
|
|
25094
25436
|
const server = net.createServer();
|
|
25095
25437
|
server.unref();
|
|
25096
|
-
server.on("error", () =>
|
|
25438
|
+
server.on("error", () => resolve17(false));
|
|
25097
25439
|
server.listen(port, "127.0.0.1", () => {
|
|
25098
|
-
server.close(() =>
|
|
25440
|
+
server.close(() => resolve17(true));
|
|
25099
25441
|
});
|
|
25100
25442
|
});
|
|
25101
25443
|
}
|
|
25102
25444
|
async function isCdpActive(port) {
|
|
25103
|
-
return new Promise((
|
|
25445
|
+
return new Promise((resolve17) => {
|
|
25104
25446
|
const req = __require("http").get(`http://127.0.0.1:${port}/json/version`, {
|
|
25105
25447
|
timeout: 2e3
|
|
25106
25448
|
}, (res) => {
|
|
@@ -25109,16 +25451,16 @@ async function isCdpActive(port) {
|
|
|
25109
25451
|
res.on("end", () => {
|
|
25110
25452
|
try {
|
|
25111
25453
|
const info = JSON.parse(data);
|
|
25112
|
-
|
|
25454
|
+
resolve17(!!info["WebKit-Version"] || !!info["Browser"]);
|
|
25113
25455
|
} catch {
|
|
25114
|
-
|
|
25456
|
+
resolve17(false);
|
|
25115
25457
|
}
|
|
25116
25458
|
});
|
|
25117
25459
|
});
|
|
25118
|
-
req.on("error", () =>
|
|
25460
|
+
req.on("error", () => resolve17(false));
|
|
25119
25461
|
req.on("timeout", () => {
|
|
25120
25462
|
req.destroy();
|
|
25121
|
-
|
|
25463
|
+
resolve17(false);
|
|
25122
25464
|
});
|
|
25123
25465
|
});
|
|
25124
25466
|
}
|
|
@@ -25593,12 +25935,12 @@ cleanOldFiles();
|
|
|
25593
25935
|
|
|
25594
25936
|
// src/commands/router.ts
|
|
25595
25937
|
init_logger();
|
|
25596
|
-
import * as
|
|
25938
|
+
import * as yaml3 from "js-yaml";
|
|
25597
25939
|
|
|
25598
25940
|
// src/commands/mesh-coordinator.ts
|
|
25599
25941
|
import { createHash as createHash3 } from "crypto";
|
|
25600
25942
|
import * as os17 from "os";
|
|
25601
|
-
import { isAbsolute as isAbsolute11, join as
|
|
25943
|
+
import { isAbsolute as isAbsolute11, join as join23, resolve as resolve13 } from "path";
|
|
25602
25944
|
var DEFAULT_SERVER_NAME = "adhdev-mesh";
|
|
25603
25945
|
var DEFAULT_ADHDEV_MCP_COMMAND = "adhdev";
|
|
25604
25946
|
var HERMES_CLI_TYPE = "hermes-cli";
|
|
@@ -25620,7 +25962,7 @@ function resolveHermesMeshCoordinatorSetup(options) {
|
|
|
25620
25962
|
reason: "Could not resolve the ADHDev MCP server entrypoint and a Node runtime with WebSocket support for daemon IPC mode"
|
|
25621
25963
|
};
|
|
25622
25964
|
}
|
|
25623
|
-
const configPath =
|
|
25965
|
+
const configPath = join23(resolveHermesCoordinatorHome(options.meshId, options.workspace), "config.yaml");
|
|
25624
25966
|
if (!configPath.trim()) {
|
|
25625
25967
|
return createHermesManualMeshCoordinatorSetup(options.meshId, options.workspace);
|
|
25626
25968
|
}
|
|
@@ -25740,14 +26082,14 @@ function resolveHermesCoordinatorHome(meshId, workspace) {
|
|
|
25740
26082
|
const key = `${meshId || "mesh"}
|
|
25741
26083
|
${resolve13(workspace || os17.tmpdir())}`;
|
|
25742
26084
|
const hash = createHash3("sha256").update(key).digest("hex").slice(0, 16);
|
|
25743
|
-
return
|
|
26085
|
+
return join23(os17.tmpdir(), `adhdev-hermes-mesh-coordinator-${hash}`);
|
|
25744
26086
|
}
|
|
25745
26087
|
function resolveMcpConfigPath(configPath, workspace) {
|
|
25746
26088
|
const trimmed = configPath.trim();
|
|
25747
26089
|
if (trimmed === "~") return os17.homedir();
|
|
25748
|
-
if (trimmed.startsWith("~/")) return
|
|
26090
|
+
if (trimmed.startsWith("~/")) return join23(os17.homedir(), trimmed.slice(2));
|
|
25749
26091
|
if (isAbsolute11(trimmed)) return trimmed;
|
|
25750
|
-
return
|
|
26092
|
+
return join23(workspace, trimmed);
|
|
25751
26093
|
}
|
|
25752
26094
|
function resolveAdhdevMcpServerLaunch(options) {
|
|
25753
26095
|
const command = resolveAdhdevCommand(options.adhdevMcpCommand);
|
|
@@ -25780,6 +26122,88 @@ function resolveMcpPort(explicitPort) {
|
|
|
25780
26122
|
init_mesh_events();
|
|
25781
26123
|
init_mesh_host_ownership();
|
|
25782
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
|
+
|
|
25783
26207
|
// src/status/snapshot.ts
|
|
25784
26208
|
init_config();
|
|
25785
26209
|
import * as os18 from "os";
|
|
@@ -26094,7 +26518,7 @@ function buildStatusSnapshot(options) {
|
|
|
26094
26518
|
}
|
|
26095
26519
|
|
|
26096
26520
|
// src/commands/upgrade-helper.ts
|
|
26097
|
-
import { execFileSync as
|
|
26521
|
+
import { execFileSync as execFileSync3 } from "child_process";
|
|
26098
26522
|
import { spawn as spawn3 } from "child_process";
|
|
26099
26523
|
import * as fs10 from "fs";
|
|
26100
26524
|
import * as os19 from "os";
|
|
@@ -26214,7 +26638,7 @@ function getNpmExecOptions(platform10 = process.platform) {
|
|
|
26214
26638
|
}
|
|
26215
26639
|
function execNpmCommandSync(args, options = {}, surface) {
|
|
26216
26640
|
const execOptions = surface?.execOptions || getNpmExecOptions();
|
|
26217
|
-
return
|
|
26641
|
+
return execFileSync3(
|
|
26218
26642
|
surface?.npmExecutable || "npm",
|
|
26219
26643
|
[...surface?.npmArgsPrefix || [], ...args],
|
|
26220
26644
|
{
|
|
@@ -26227,7 +26651,7 @@ function execNpmCommandSync(args, options = {}, surface) {
|
|
|
26227
26651
|
function killPid(pid) {
|
|
26228
26652
|
try {
|
|
26229
26653
|
if (process.platform === "win32") {
|
|
26230
|
-
|
|
26654
|
+
execFileSync3("taskkill", ["/PID", String(pid), "/T", "/F"], { stdio: "ignore", windowsHide: true });
|
|
26231
26655
|
} else {
|
|
26232
26656
|
process.kill(pid, "SIGTERM");
|
|
26233
26657
|
}
|
|
@@ -26239,7 +26663,7 @@ function killPid(pid) {
|
|
|
26239
26663
|
function getWindowsProcessCommandLine(pid) {
|
|
26240
26664
|
const pidFilter = `ProcessId=${pid}`;
|
|
26241
26665
|
try {
|
|
26242
|
-
const psOut =
|
|
26666
|
+
const psOut = execFileSync3("powershell.exe", [
|
|
26243
26667
|
"-NoProfile",
|
|
26244
26668
|
"-NonInteractive",
|
|
26245
26669
|
"-ExecutionPolicy",
|
|
@@ -26251,7 +26675,7 @@ function getWindowsProcessCommandLine(pid) {
|
|
|
26251
26675
|
} catch {
|
|
26252
26676
|
}
|
|
26253
26677
|
try {
|
|
26254
|
-
const wmicOut =
|
|
26678
|
+
const wmicOut = execFileSync3("wmic", [
|
|
26255
26679
|
"process",
|
|
26256
26680
|
"where",
|
|
26257
26681
|
pidFilter,
|
|
@@ -26267,7 +26691,7 @@ function getProcessCommandLine(pid) {
|
|
|
26267
26691
|
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
26268
26692
|
if (process.platform === "win32") return getWindowsProcessCommandLine(pid);
|
|
26269
26693
|
try {
|
|
26270
|
-
const text =
|
|
26694
|
+
const text = execFileSync3("ps", ["-o", "command=", "-p", String(pid)], {
|
|
26271
26695
|
encoding: "utf8",
|
|
26272
26696
|
timeout: 3e3,
|
|
26273
26697
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -26286,7 +26710,7 @@ async function waitForPidExit(pid, timeoutMs) {
|
|
|
26286
26710
|
while (Date.now() - start < timeoutMs) {
|
|
26287
26711
|
try {
|
|
26288
26712
|
process.kill(pid, 0);
|
|
26289
|
-
await new Promise((
|
|
26713
|
+
await new Promise((resolve17) => setTimeout(resolve17, 250));
|
|
26290
26714
|
} catch {
|
|
26291
26715
|
return;
|
|
26292
26716
|
}
|
|
@@ -26383,7 +26807,7 @@ async function runDaemonUpgradeHelper(payload) {
|
|
|
26383
26807
|
cleanupStaleGlobalInstallDirs(payload.packageName, installCommand.surface);
|
|
26384
26808
|
const spec = `${payload.packageName}@${payload.targetVersion || "latest"}`;
|
|
26385
26809
|
appendUpgradeLog(`Installing ${spec}`);
|
|
26386
|
-
const installOutput =
|
|
26810
|
+
const installOutput = execFileSync3(
|
|
26387
26811
|
installCommand.command,
|
|
26388
26812
|
installCommand.args,
|
|
26389
26813
|
{
|
|
@@ -26397,7 +26821,7 @@ async function runDaemonUpgradeHelper(payload) {
|
|
|
26397
26821
|
appendUpgradeLog(installOutput.trim());
|
|
26398
26822
|
}
|
|
26399
26823
|
if (process.platform === "win32") {
|
|
26400
|
-
await new Promise((
|
|
26824
|
+
await new Promise((resolve17) => setTimeout(resolve17, 500));
|
|
26401
26825
|
cleanupStaleGlobalInstallDirs(payload.packageName, installCommand.surface);
|
|
26402
26826
|
appendUpgradeLog("Post-install staging cleanup complete");
|
|
26403
26827
|
}
|
|
@@ -26434,8 +26858,9 @@ async function maybeRunDaemonUpgradeHelperFromEnv() {
|
|
|
26434
26858
|
// src/commands/router.ts
|
|
26435
26859
|
init_mesh_work_queue();
|
|
26436
26860
|
import { homedir as homedir19, hostname as osHostname } from "os";
|
|
26437
|
-
import { basename as pathBasename, join as pathJoin, resolve as
|
|
26861
|
+
import { basename as pathBasename, join as pathJoin, resolve as pathResolve2 } from "path";
|
|
26438
26862
|
import * as fs11 from "fs";
|
|
26863
|
+
import { execFileSync as execFileSync4 } from "child_process";
|
|
26439
26864
|
var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
|
|
26440
26865
|
var CHANNEL_SERVER_URL = {
|
|
26441
26866
|
stable: "https://api.adhf.dev",
|
|
@@ -27147,6 +27572,16 @@ function finalizeMeshNodeStatus(args) {
|
|
|
27147
27572
|
if (machineStatus) status.machineStatus = machineStatus;
|
|
27148
27573
|
}
|
|
27149
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
|
+
}
|
|
27150
27585
|
const connectionState = readStringValue(readObjectRecord(status.connection).state);
|
|
27151
27586
|
status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || connectionState === "connected" || isSelfNode);
|
|
27152
27587
|
}
|
|
@@ -27288,6 +27723,40 @@ function collectLiveMeshSessionRecords(args) {
|
|
|
27288
27723
|
}
|
|
27289
27724
|
return matches;
|
|
27290
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
|
+
}
|
|
27291
27760
|
function applyCachedInlineMeshNodeStatus(status, node, options) {
|
|
27292
27761
|
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
27293
27762
|
const liveGit = buildInlineMeshTransitGitStatus(node);
|
|
@@ -27373,14 +27842,14 @@ function resolveRefineryAutoPublishSubmoduleMainCommits(mesh, workspace) {
|
|
|
27373
27842
|
return { enabled: false };
|
|
27374
27843
|
}
|
|
27375
27844
|
async function computeGitPatchId(cwd, fromRef, toRef) {
|
|
27376
|
-
const { execFileSync:
|
|
27377
|
-
const diff =
|
|
27845
|
+
const { execFileSync: execFileSync5 } = await import("child_process");
|
|
27846
|
+
const diff = execFileSync5("git", ["diff", "--patch", "--full-index", fromRef, toRef], {
|
|
27378
27847
|
cwd,
|
|
27379
27848
|
encoding: "utf8",
|
|
27380
27849
|
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
|
|
27381
27850
|
});
|
|
27382
27851
|
if (!diff.trim()) return "";
|
|
27383
|
-
const patchId =
|
|
27852
|
+
const patchId = execFileSync5("git", ["patch-id", "--stable"], {
|
|
27384
27853
|
cwd,
|
|
27385
27854
|
input: diff,
|
|
27386
27855
|
encoding: "utf8",
|
|
@@ -27391,8 +27860,8 @@ async function computeGitPatchId(cwd, fromRef, toRef) {
|
|
|
27391
27860
|
async function runMeshRefinePatchEquivalenceGate(repoRoot, baseHead, branchHead) {
|
|
27392
27861
|
const startedAt = Date.now();
|
|
27393
27862
|
try {
|
|
27394
|
-
const { execFileSync:
|
|
27395
|
-
const git = (args) =>
|
|
27863
|
+
const { execFileSync: execFileSync5 } = await import("child_process");
|
|
27864
|
+
const git = (args) => execFileSync5("git", args, {
|
|
27396
27865
|
cwd: repoRoot,
|
|
27397
27866
|
encoding: "utf8",
|
|
27398
27867
|
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
|
|
@@ -27436,6 +27905,135 @@ async function runMeshRefinePatchEquivalenceGate(repoRoot, baseHead, branchHead)
|
|
|
27436
27905
|
durationMs: Date.now() - startedAt,
|
|
27437
27906
|
error: e?.message || String(e),
|
|
27438
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),
|
|
27439
28037
|
stderr: truncateValidationOutput(e?.stderr)
|
|
27440
28038
|
};
|
|
27441
28039
|
}
|
|
@@ -27444,10 +28042,10 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
27444
28042
|
const startedAt = Date.now();
|
|
27445
28043
|
const entries = [];
|
|
27446
28044
|
try {
|
|
27447
|
-
const { execFile:
|
|
27448
|
-
const { promisify:
|
|
27449
|
-
const execFileAsync3 =
|
|
27450
|
-
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) => {
|
|
27451
28049
|
const { stdout } = await execFileAsync3("git", args, {
|
|
27452
28050
|
cwd,
|
|
27453
28051
|
encoding: "utf8",
|
|
@@ -27458,8 +28056,8 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
27458
28056
|
return String(stdout || "");
|
|
27459
28057
|
};
|
|
27460
28058
|
const verifyRemoteMainContainsCommit = async (submodulePath, commit, branch = "main") => {
|
|
27461
|
-
await
|
|
27462
|
-
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}`]);
|
|
27463
28061
|
};
|
|
27464
28062
|
const publishCommitToRemoteMain = async (submodulePath, commit, branch = "main") => {
|
|
27465
28063
|
const refspec = `${commit}:refs/heads/${branch}`;
|
|
@@ -27475,21 +28073,21 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
27475
28073
|
const importCommitFromWorktreeSubmodule = async (submodulePath, worktreeSubmodulePath, commit) => {
|
|
27476
28074
|
if (!fs11.existsSync(worktreeSubmodulePath)) return false;
|
|
27477
28075
|
try {
|
|
27478
|
-
await
|
|
28076
|
+
await runGit3(worktreeSubmodulePath, ["cat-file", "-e", `${commit}^{commit}`]);
|
|
27479
28077
|
} catch {
|
|
27480
28078
|
return false;
|
|
27481
28079
|
}
|
|
27482
|
-
await
|
|
27483
|
-
await
|
|
28080
|
+
await runGit3(submodulePath, ["-c", "protocol.file.allow=always", "fetch", worktreeSubmodulePath, commit]);
|
|
28081
|
+
await runGit3(submodulePath, ["cat-file", "-e", `${commit}^{commit}`]);
|
|
27484
28082
|
return true;
|
|
27485
28083
|
};
|
|
27486
|
-
const treeOutput = await
|
|
28084
|
+
const treeOutput = await runGit3(repoRoot, ["ls-tree", "-r", "-z", mergedTree]);
|
|
27487
28085
|
const gitlinks = treeOutput.split("\0").filter(Boolean).map((record) => {
|
|
27488
28086
|
const match = /^160000\s+commit\s+([0-9a-f]{40})\t(.+)$/.exec(record);
|
|
27489
28087
|
return match ? { commit: match[1], path: match[2] } : null;
|
|
27490
28088
|
}).filter((entry) => !!entry);
|
|
27491
28089
|
for (const gitlink of gitlinks) {
|
|
27492
|
-
const submodulePath =
|
|
28090
|
+
const submodulePath = pathResolve2(repoRoot, gitlink.path);
|
|
27493
28091
|
const entry = {
|
|
27494
28092
|
path: gitlink.path,
|
|
27495
28093
|
commit: gitlink.commit,
|
|
@@ -27509,7 +28107,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
27509
28107
|
}
|
|
27510
28108
|
entry.checkedLocal = true;
|
|
27511
28109
|
try {
|
|
27512
|
-
await
|
|
28110
|
+
await runGit3(submodulePath, ["cat-file", "-e", `${gitlink.commit}^{commit}`]);
|
|
27513
28111
|
entry.localReachable = true;
|
|
27514
28112
|
} catch {
|
|
27515
28113
|
entry.localReachable = false;
|
|
@@ -27517,7 +28115,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
27517
28115
|
try {
|
|
27518
28116
|
const imported = await importCommitFromWorktreeSubmodule(
|
|
27519
28117
|
submodulePath,
|
|
27520
|
-
|
|
28118
|
+
pathResolve2(options.worktreeRoot, gitlink.path),
|
|
27521
28119
|
gitlink.commit
|
|
27522
28120
|
);
|
|
27523
28121
|
if (imported) {
|
|
@@ -27533,7 +28131,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
27533
28131
|
entry.remote = "origin";
|
|
27534
28132
|
let remoteUrl = "";
|
|
27535
28133
|
try {
|
|
27536
|
-
remoteUrl = (await
|
|
28134
|
+
remoteUrl = (await runGit3(submodulePath, ["remote", "get-url", "origin"])).trim();
|
|
27537
28135
|
if (!remoteUrl) throw new Error("origin remote has no URL");
|
|
27538
28136
|
entry.remoteUrl = remoteUrl;
|
|
27539
28137
|
} catch {
|
|
@@ -27648,9 +28246,9 @@ function buildMeshRefineValidationPlan(mesh, workspace) {
|
|
|
27648
28246
|
};
|
|
27649
28247
|
}
|
|
27650
28248
|
async function runMeshRefineValidationGate(mesh, workspace) {
|
|
27651
|
-
const { execFile:
|
|
27652
|
-
const { promisify:
|
|
27653
|
-
const execFileAsync3 =
|
|
28249
|
+
const { execFile: execFile4 } = await import("child_process");
|
|
28250
|
+
const { promisify: promisify7 } = await import("util");
|
|
28251
|
+
const execFileAsync3 = promisify7(execFile4);
|
|
27654
28252
|
const selection = resolveMeshRefineValidationPlan(mesh, workspace);
|
|
27655
28253
|
const summary = {
|
|
27656
28254
|
status: "skipped",
|
|
@@ -27694,14 +28292,14 @@ async function runMeshRefineValidationGate(mesh, workspace) {
|
|
|
27694
28292
|
};
|
|
27695
28293
|
for (const candidate of selection.bootstrapCommands) {
|
|
27696
28294
|
const startedAt = Date.now();
|
|
27697
|
-
const cwd = candidate.cwd ?
|
|
28295
|
+
const cwd = candidate.cwd ? pathResolve2(workspace, candidate.cwd) : workspace;
|
|
27698
28296
|
const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
|
|
27699
28297
|
try {
|
|
27700
28298
|
const result = await execFileAsync3(candidate.command, candidate.args, {
|
|
27701
28299
|
cwd,
|
|
27702
28300
|
encoding: "utf8",
|
|
27703
28301
|
timeout,
|
|
27704
|
-
maxBuffer: REFINE_VALIDATION_OUTPUT_LIMIT_BYTES,
|
|
28302
|
+
maxBuffer: candidate.outputLimitBytes || REFINE_VALIDATION_OUTPUT_LIMIT_BYTES,
|
|
27705
28303
|
env: { ...process.env, CI: process.env.CI || "1", ...candidate.env || {} }
|
|
27706
28304
|
});
|
|
27707
28305
|
summary.bootstrapCommandsRun.push(commandRecord(candidate, cwd, startedAt, result, true, { exitCode: 0 }));
|
|
@@ -27720,7 +28318,7 @@ async function runMeshRefineValidationGate(mesh, workspace) {
|
|
|
27720
28318
|
}
|
|
27721
28319
|
for (const candidate of selection.commands) {
|
|
27722
28320
|
const startedAt = Date.now();
|
|
27723
|
-
const cwd = candidate.cwd ?
|
|
28321
|
+
const cwd = candidate.cwd ? pathResolve2(workspace, candidate.cwd) : workspace;
|
|
27724
28322
|
const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
|
|
27725
28323
|
if (selection.bootstrapCommands.length === 0 && isPackageManagerValidation(candidate) && dependenciesLikelyMissing(cwd)) {
|
|
27726
28324
|
summary.commandsRun.push(commandRecord(candidate, cwd, startedAt, {
|
|
@@ -27740,7 +28338,7 @@ async function runMeshRefineValidationGate(mesh, workspace) {
|
|
|
27740
28338
|
cwd,
|
|
27741
28339
|
encoding: "utf8",
|
|
27742
28340
|
timeout,
|
|
27743
|
-
maxBuffer: REFINE_VALIDATION_OUTPUT_LIMIT_BYTES,
|
|
28341
|
+
maxBuffer: candidate.outputLimitBytes || REFINE_VALIDATION_OUTPUT_LIMIT_BYTES,
|
|
27744
28342
|
env: { ...process.env, CI: process.env.CI || "1", ...candidate.env || {} }
|
|
27745
28343
|
});
|
|
27746
28344
|
summary.commandsRun.push(commandRecord(candidate, cwd, startedAt, result, true, { exitCode: 0 }));
|
|
@@ -27765,7 +28363,7 @@ async function runMeshRefineValidationGate(mesh, workspace) {
|
|
|
27765
28363
|
return summary;
|
|
27766
28364
|
}
|
|
27767
28365
|
function loadYamlModule() {
|
|
27768
|
-
return
|
|
28366
|
+
return yaml3;
|
|
27769
28367
|
}
|
|
27770
28368
|
function getMcpServersKey(format) {
|
|
27771
28369
|
return format === "hermes_config_yaml" ? "mcp_servers" : "mcpServers";
|
|
@@ -27788,7 +28386,7 @@ function loadHermesCoordinatorBaseConfig(targetConfigPath) {
|
|
|
27788
28386
|
const sourceHome = resolveHermesUserHome();
|
|
27789
28387
|
const sourceConfigPath = pathJoin(sourceHome, "config.yaml");
|
|
27790
28388
|
if (!fs11.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
27791
|
-
if (
|
|
28389
|
+
if (pathResolve2(sourceConfigPath) === pathResolve2(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
27792
28390
|
const parsed = parseMeshCoordinatorMcpConfig(fs11.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
|
|
27793
28391
|
const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
|
|
27794
28392
|
return { config: baseConfig, sourceHome, sourceConfigPath };
|
|
@@ -27822,7 +28420,7 @@ function stripHermesCoordinatorTempModelProviderOverrides(config) {
|
|
|
27822
28420
|
return sanitized;
|
|
27823
28421
|
}
|
|
27824
28422
|
function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
|
|
27825
|
-
if (
|
|
28423
|
+
if (pathResolve2(sourceHome) === pathResolve2(targetHome)) return;
|
|
27826
28424
|
for (const fileName of [".env", "auth.json"]) {
|
|
27827
28425
|
const sourcePath = pathJoin(sourceHome, fileName);
|
|
27828
28426
|
const targetPath = pathJoin(targetHome, fileName);
|
|
@@ -28207,7 +28805,7 @@ var DaemonCommandRouter = class {
|
|
|
28207
28805
|
}
|
|
28208
28806
|
const { resolveWorktreePath: resolveWorktreePath2, listWorktrees: listWorktrees2, removeWorktree: removeWorktree2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
|
|
28209
28807
|
const normalizePath = (value) => {
|
|
28210
|
-
const resolved =
|
|
28808
|
+
const resolved = pathResolve2(value);
|
|
28211
28809
|
try {
|
|
28212
28810
|
return fs11.realpathSync(resolved);
|
|
28213
28811
|
} catch {
|
|
@@ -28281,10 +28879,10 @@ var DaemonCommandRouter = class {
|
|
|
28281
28879
|
if (metadataStatus === "merged_to_main" || metadataStatus === "cleanup_candidate") {
|
|
28282
28880
|
return { allow: true, status: metadataStatus, source: "node_branch_convergence" };
|
|
28283
28881
|
}
|
|
28284
|
-
const { execFile:
|
|
28285
|
-
const { promisify:
|
|
28286
|
-
const execFileAsync3 =
|
|
28287
|
-
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) => {
|
|
28288
28886
|
const { stdout } = await execFileAsync3("git", gitArgs, {
|
|
28289
28887
|
cwd,
|
|
28290
28888
|
encoding: "utf8",
|
|
@@ -28296,14 +28894,14 @@ var DaemonCommandRouter = class {
|
|
|
28296
28894
|
};
|
|
28297
28895
|
let head = "";
|
|
28298
28896
|
try {
|
|
28299
|
-
head = await
|
|
28897
|
+
head = await runGit3(["rev-parse", "HEAD"], args.workspace);
|
|
28300
28898
|
} catch (e) {
|
|
28301
28899
|
return { allow: false, error: `could not resolve worktree HEAD: ${e?.message || e}` };
|
|
28302
28900
|
}
|
|
28303
28901
|
if (!head) return { allow: false, error: "worktree HEAD is empty" };
|
|
28304
28902
|
const candidateRefs = [];
|
|
28305
28903
|
try {
|
|
28306
|
-
const defaultBranch = await
|
|
28904
|
+
const defaultBranch = await runGit3(["branch", "--show-current"], args.repoRoot);
|
|
28307
28905
|
if (defaultBranch) {
|
|
28308
28906
|
candidateRefs.push(defaultBranch, `origin/${defaultBranch}`);
|
|
28309
28907
|
}
|
|
@@ -28317,13 +28915,13 @@ var DaemonCommandRouter = class {
|
|
|
28317
28915
|
seen.add(ref);
|
|
28318
28916
|
let commit = "";
|
|
28319
28917
|
try {
|
|
28320
|
-
commit = await
|
|
28918
|
+
commit = await runGit3(["rev-parse", "--verify", `${ref}^{commit}`], args.repoRoot);
|
|
28321
28919
|
} catch {
|
|
28322
28920
|
continue;
|
|
28323
28921
|
}
|
|
28324
28922
|
checkedRefs.push(ref);
|
|
28325
28923
|
try {
|
|
28326
|
-
await
|
|
28924
|
+
await runGit3(["merge-base", "--is-ancestor", head, commit], args.repoRoot);
|
|
28327
28925
|
return { allow: true, status: "merged_to_default_ref", source: "git_merge_base", ref };
|
|
28328
28926
|
} catch {
|
|
28329
28927
|
}
|
|
@@ -28715,9 +29313,9 @@ var DaemonCommandRouter = class {
|
|
|
28715
29313
|
const sourceNode = node.clonedFromNodeId ? mesh?.nodes.find((n) => n.id === node.clonedFromNodeId || n.nodeId === node.clonedFromNodeId) : mesh?.nodes.find((n) => !n.isLocalWorktree);
|
|
28716
29314
|
const repoRoot = sourceNode?.repoRoot || sourceNode?.workspace;
|
|
28717
29315
|
if (!repoRoot) return { success: false, error: "Source node repoRoot not found", refineStages };
|
|
28718
|
-
const { execFile:
|
|
28719
|
-
const { promisify:
|
|
28720
|
-
const execFileAsync3 =
|
|
29316
|
+
const { execFile: execFile4 } = await import("child_process");
|
|
29317
|
+
const { promisify: promisify7 } = await import("util");
|
|
29318
|
+
const execFileAsync3 = promisify7(execFile4);
|
|
28721
29319
|
const resolveStarted = Date.now();
|
|
28722
29320
|
const { stdout: branchStdout } = await execFileAsync3("git", ["branch", "--show-current"], { cwd: node.workspace, encoding: "utf8" });
|
|
28723
29321
|
const branch = branchStdout.trim();
|
|
@@ -28784,7 +29382,8 @@ var DaemonCommandRouter = class {
|
|
|
28784
29382
|
equivalent: patchEquivalence.equivalent,
|
|
28785
29383
|
expectedPatchId: patchEquivalence.expectedPatchId,
|
|
28786
29384
|
actualPatchId: patchEquivalence.actualPatchId,
|
|
28787
|
-
error: patchEquivalence.error
|
|
29385
|
+
error: patchEquivalence.error,
|
|
29386
|
+
actionableHint: patchEquivalence.actionableHint
|
|
28788
29387
|
});
|
|
28789
29388
|
if (!patchEquivalence.equivalent) {
|
|
28790
29389
|
return {
|
|
@@ -28943,6 +29542,49 @@ var DaemonCommandRouter = class {
|
|
|
28943
29542
|
}
|
|
28944
29543
|
};
|
|
28945
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
|
+
}
|
|
28946
29588
|
const cleanupStarted = Date.now();
|
|
28947
29589
|
const removeResult = await this.execute("remove_mesh_node", {
|
|
28948
29590
|
meshId,
|
|
@@ -28962,7 +29604,7 @@ var DaemonCommandRouter = class {
|
|
|
28962
29604
|
appendLedgerEntry2(meshId, {
|
|
28963
29605
|
kind: "node_removed",
|
|
28964
29606
|
nodeId,
|
|
28965
|
-
payload: { refined: true, mergedBranch: branch, into: baseBranch, validationSummary, patchEquivalence, submoduleReachability }
|
|
29607
|
+
payload: { refined: true, mergedBranch: branch, into: baseBranch, validationSummary, patchEquivalence, submoduleReachability, submoduleAlignment }
|
|
28966
29608
|
});
|
|
28967
29609
|
recordMeshRefineStage(refineStages, "ledger", "passed", ledgerStarted);
|
|
28968
29610
|
} catch (e) {
|
|
@@ -28977,6 +29619,7 @@ var DaemonCommandRouter = class {
|
|
|
28977
29619
|
removed: removeResult?.success !== false,
|
|
28978
29620
|
validation: "passed",
|
|
28979
29621
|
patchEquivalence: "passed",
|
|
29622
|
+
submoduleAlignment: submoduleAlignment.status,
|
|
28980
29623
|
status: removeResult?.success === false ? "merged_cleanup_failed" : "merged"
|
|
28981
29624
|
};
|
|
28982
29625
|
if (removeResult?.success === false) {
|
|
@@ -28991,6 +29634,7 @@ var DaemonCommandRouter = class {
|
|
|
28991
29634
|
validationSummary,
|
|
28992
29635
|
patchEquivalence,
|
|
28993
29636
|
submoduleReachability,
|
|
29637
|
+
submoduleAlignment,
|
|
28994
29638
|
mergeResult,
|
|
28995
29639
|
refineStages,
|
|
28996
29640
|
...ledgerError ? { ledgerError } : {},
|
|
@@ -29006,6 +29650,7 @@ var DaemonCommandRouter = class {
|
|
|
29006
29650
|
validationSummary,
|
|
29007
29651
|
patchEquivalence,
|
|
29008
29652
|
submoduleReachability,
|
|
29653
|
+
submoduleAlignment,
|
|
29009
29654
|
mergeResult,
|
|
29010
29655
|
refineStages,
|
|
29011
29656
|
...ledgerError ? { ledgerError } : {},
|
|
@@ -30088,6 +30733,12 @@ var DaemonCommandRouter = class {
|
|
|
30088
30733
|
success: true,
|
|
30089
30734
|
schema: MESH_REFINE_CONFIG_SCHEMA,
|
|
30090
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
|
+
},
|
|
30091
30742
|
sourceOfTruth: "repo mesh/refine config",
|
|
30092
30743
|
heuristicRole: "suggestions_only_not_execution_path"
|
|
30093
30744
|
};
|
|
@@ -30282,8 +30933,8 @@ var DaemonCommandRouter = class {
|
|
|
30282
30933
|
const initSubmodules = sourceNode.policy?.initSubmodulesOnClone !== false;
|
|
30283
30934
|
if (initSubmodules) {
|
|
30284
30935
|
try {
|
|
30285
|
-
const { runGit:
|
|
30286
|
-
await
|
|
30936
|
+
const { runGit: runGit3 } = await Promise.resolve().then(() => (init_git_executor(), git_executor_exports));
|
|
30937
|
+
await runGit3(
|
|
30287
30938
|
{ workspace: result.worktreePath, repoRoot: result.worktreePath, isGitRepo: true },
|
|
30288
30939
|
["submodule", "update", "--init", "--recursive"],
|
|
30289
30940
|
{ timeoutMs: 12e4 }
|
|
@@ -30292,12 +30943,35 @@ var DaemonCommandRouter = class {
|
|
|
30292
30943
|
console.warn("[mesh] Submodule init failed for worktree:", subErr.message);
|
|
30293
30944
|
}
|
|
30294
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
|
+
}
|
|
30295
30956
|
try {
|
|
30296
30957
|
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
30297
30958
|
appendLedgerEntry2(meshId, {
|
|
30298
30959
|
kind: "node_cloned",
|
|
30299
30960
|
nodeId: node.id,
|
|
30300
|
-
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
|
+
}
|
|
30301
30975
|
});
|
|
30302
30976
|
} catch {
|
|
30303
30977
|
}
|
|
@@ -30305,7 +30979,8 @@ var DaemonCommandRouter = class {
|
|
|
30305
30979
|
success: true,
|
|
30306
30980
|
node,
|
|
30307
30981
|
worktreePath: result.worktreePath,
|
|
30308
|
-
branch: result.branch
|
|
30982
|
+
branch: result.branch,
|
|
30983
|
+
worktreeBootstrap: bootstrapState
|
|
30309
30984
|
};
|
|
30310
30985
|
} catch (e) {
|
|
30311
30986
|
return { success: false, error: e.message };
|
|
@@ -30533,7 +31208,7 @@ ${block2}`);
|
|
|
30533
31208
|
workspace
|
|
30534
31209
|
};
|
|
30535
31210
|
}
|
|
30536
|
-
const { existsSync:
|
|
31211
|
+
const { existsSync: existsSync28, readFileSync: readFileSync21, writeFileSync: writeFileSync14, copyFileSync: copyFileSync4, mkdirSync: mkdirSync18 } = await import("fs");
|
|
30537
31212
|
const { dirname: dirname9 } = await import("path");
|
|
30538
31213
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
30539
31214
|
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
@@ -30576,14 +31251,14 @@ ${block2}`);
|
|
|
30576
31251
|
if (hermesManualFallback) return returnManualFallback(message);
|
|
30577
31252
|
return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
|
|
30578
31253
|
}
|
|
30579
|
-
const hadExistingMcpConfig =
|
|
31254
|
+
const hadExistingMcpConfig = existsSync28(mcpConfigPath);
|
|
30580
31255
|
let existingMcpConfig = hermesBaseConfig?.config || {};
|
|
30581
31256
|
if (hermesBaseConfig) {
|
|
30582
31257
|
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname9(mcpConfigPath));
|
|
30583
31258
|
}
|
|
30584
31259
|
if (hadExistingMcpConfig) {
|
|
30585
31260
|
try {
|
|
30586
|
-
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(
|
|
31261
|
+
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync21(mcpConfigPath, "utf-8"), configFormat);
|
|
30587
31262
|
const existingCoordinatorConfig = hermesManualFallback ? stripHermesCoordinatorTempModelProviderOverrides(parsedExistingMcpConfig) : parsedExistingMcpConfig;
|
|
30588
31263
|
existingMcpConfig = { ...existingMcpConfig, ...existingCoordinatorConfig };
|
|
30589
31264
|
copyFileSync4(mcpConfigPath, mcpConfigPath + ".backup");
|
|
@@ -30695,6 +31370,7 @@ ${block2}`);
|
|
|
30695
31370
|
const queueSummary = getMeshQueueStats2(meshId);
|
|
30696
31371
|
const { readLedgerEntries: readLedgerEntries2, getLedgerSummary: getLedgerSummary2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
30697
31372
|
const ledgerEntries = readLedgerEntries2(meshId, { tail: 20 });
|
|
31373
|
+
const asyncRefineLedgerEntries = readLedgerEntries2(meshId, { tail: 100 });
|
|
30698
31374
|
const ledgerSummary = getLedgerSummary2(meshId);
|
|
30699
31375
|
const sessionHostRecords = this.deps.sessionHostControl?.listSessions ? await this.deps.sessionHostControl.listSessions().catch(() => []) : [];
|
|
30700
31376
|
const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
|
|
@@ -30957,6 +31633,20 @@ ${block2}`);
|
|
|
30957
31633
|
nodeStatuses.push(status);
|
|
30958
31634
|
}
|
|
30959
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
|
+
});
|
|
30960
31650
|
const statusResult = {
|
|
30961
31651
|
success: true,
|
|
30962
31652
|
meshId: mesh.id,
|
|
@@ -30988,12 +31678,15 @@ ${block2}`);
|
|
|
30988
31678
|
partialNodeFailures: effectiveDirectTruth.unavailableNodeIds
|
|
30989
31679
|
}
|
|
30990
31680
|
} : {},
|
|
30991
|
-
historicalEvidenceOnly: ["recoveryHints", "ledger.summary", "queue.summary"]
|
|
31681
|
+
historicalEvidenceOnly: ["recoveryHints", "ledger.summary", "queue.summary", "historicalSessions"]
|
|
30992
31682
|
},
|
|
30993
31683
|
branchConvergenceSummary: summarizeInlineMeshBranchConvergence(nodeStatuses),
|
|
31684
|
+
...previewFreshness ? { previewFreshness, deployFreshness: previewFreshness } : {},
|
|
30994
31685
|
nodes: nodeStatuses,
|
|
30995
31686
|
queue: { tasks: queue, summary: queueSummary },
|
|
30996
31687
|
ledger: { entries: ledgerEntries, summary: ledgerSummary },
|
|
31688
|
+
...asyncRefineJobs.length > 0 ? { asyncRefineJobs } : {},
|
|
31689
|
+
...historicalSessions ? { historicalSessions } : {},
|
|
30997
31690
|
...pendingCoordinatorEvents.length > 0 ? { pendingCoordinatorEvents } : {}
|
|
30998
31691
|
};
|
|
30999
31692
|
const { pendingCoordinatorEvents: _pendingCoordinatorEvents, ...cacheableStatusResult } = statusResult;
|
|
@@ -31644,7 +32337,7 @@ var ProviderStreamAdapter = class {
|
|
|
31644
32337
|
const beforeCount = this.messageCount(before);
|
|
31645
32338
|
const beforeSignature = this.lastMessageSignature(before);
|
|
31646
32339
|
for (let attempt = 0; attempt < 12; attempt += 1) {
|
|
31647
|
-
await new Promise((
|
|
32340
|
+
await new Promise((resolve17) => setTimeout(resolve17, 250));
|
|
31648
32341
|
let state;
|
|
31649
32342
|
try {
|
|
31650
32343
|
state = await this.readChat(evaluate);
|
|
@@ -31666,7 +32359,7 @@ var ProviderStreamAdapter = class {
|
|
|
31666
32359
|
if (this.messageCount(first) > 0 || this.lastMessageSignature(first)) {
|
|
31667
32360
|
return first;
|
|
31668
32361
|
}
|
|
31669
|
-
await new Promise((
|
|
32362
|
+
await new Promise((resolve17) => setTimeout(resolve17, 150));
|
|
31670
32363
|
const second = await this.readChat(evaluate);
|
|
31671
32364
|
return this.messageCount(second) >= this.messageCount(first) ? second : first;
|
|
31672
32365
|
}
|
|
@@ -31817,7 +32510,7 @@ var ProviderStreamAdapter = class {
|
|
|
31817
32510
|
if (typeof data.error === "string" && data.error.trim()) return false;
|
|
31818
32511
|
}
|
|
31819
32512
|
for (let attempt = 0; attempt < 6; attempt += 1) {
|
|
31820
|
-
await new Promise((
|
|
32513
|
+
await new Promise((resolve17) => setTimeout(resolve17, 250));
|
|
31821
32514
|
const state = await this.readChat(evaluate);
|
|
31822
32515
|
const title = this.getStateTitle(state);
|
|
31823
32516
|
if (this.titlesMatch(title, sessionId)) return true;
|
|
@@ -32745,13 +33438,13 @@ var VersionArchive = class {
|
|
|
32745
33438
|
}
|
|
32746
33439
|
};
|
|
32747
33440
|
async function runCommand(cmd, timeout = 1e4) {
|
|
32748
|
-
return new Promise((
|
|
33441
|
+
return new Promise((resolve17) => {
|
|
32749
33442
|
exec5(cmd, {
|
|
32750
33443
|
encoding: "utf-8",
|
|
32751
33444
|
timeout
|
|
32752
33445
|
}, (error, stdout) => {
|
|
32753
|
-
if (error) return
|
|
32754
|
-
|
|
33446
|
+
if (error) return resolve17(null);
|
|
33447
|
+
resolve17(stdout.trim());
|
|
32755
33448
|
});
|
|
32756
33449
|
});
|
|
32757
33450
|
}
|
|
@@ -34440,7 +35133,7 @@ function getCliTargetBundle(ctx, type, instanceId) {
|
|
|
34440
35133
|
return { target, instance, adapter };
|
|
34441
35134
|
}
|
|
34442
35135
|
function sleep2(ms) {
|
|
34443
|
-
return new Promise((
|
|
35136
|
+
return new Promise((resolve17) => setTimeout(resolve17, ms));
|
|
34444
35137
|
}
|
|
34445
35138
|
async function waitForCliReady(ctx, type, instanceId, timeoutMs) {
|
|
34446
35139
|
const startedAt = Date.now();
|
|
@@ -36695,15 +37388,15 @@ var DevServer = class _DevServer {
|
|
|
36695
37388
|
this.json(res, 500, { error: e.message });
|
|
36696
37389
|
}
|
|
36697
37390
|
});
|
|
36698
|
-
return new Promise((
|
|
37391
|
+
return new Promise((resolve17, reject) => {
|
|
36699
37392
|
this.server.listen(port, "127.0.0.1", () => {
|
|
36700
37393
|
this.log(`Dev server listening on http://127.0.0.1:${port}`);
|
|
36701
|
-
|
|
37394
|
+
resolve17();
|
|
36702
37395
|
});
|
|
36703
37396
|
this.server.on("error", (e) => {
|
|
36704
37397
|
if (e.code === "EADDRINUSE") {
|
|
36705
37398
|
this.log(`Port ${port} in use, skipping dev server`);
|
|
36706
|
-
|
|
37399
|
+
resolve17();
|
|
36707
37400
|
} else {
|
|
36708
37401
|
reject(e);
|
|
36709
37402
|
}
|
|
@@ -36785,20 +37478,20 @@ var DevServer = class _DevServer {
|
|
|
36785
37478
|
child.stderr?.on("data", (d) => {
|
|
36786
37479
|
stderr += d.toString().slice(0, 2e3);
|
|
36787
37480
|
});
|
|
36788
|
-
await new Promise((
|
|
37481
|
+
await new Promise((resolve17) => {
|
|
36789
37482
|
const timer = setTimeout(() => {
|
|
36790
37483
|
child.kill();
|
|
36791
|
-
|
|
37484
|
+
resolve17();
|
|
36792
37485
|
}, 3e3);
|
|
36793
37486
|
child.on("exit", () => {
|
|
36794
37487
|
clearTimeout(timer);
|
|
36795
|
-
|
|
37488
|
+
resolve17();
|
|
36796
37489
|
});
|
|
36797
37490
|
child.stdout?.once("data", () => {
|
|
36798
37491
|
setTimeout(() => {
|
|
36799
37492
|
child.kill();
|
|
36800
37493
|
clearTimeout(timer);
|
|
36801
|
-
|
|
37494
|
+
resolve17();
|
|
36802
37495
|
}, 500);
|
|
36803
37496
|
});
|
|
36804
37497
|
});
|
|
@@ -37301,14 +37994,14 @@ var DevServer = class _DevServer {
|
|
|
37301
37994
|
child.stderr?.on("data", (d) => {
|
|
37302
37995
|
stderr += d.toString();
|
|
37303
37996
|
});
|
|
37304
|
-
await new Promise((
|
|
37997
|
+
await new Promise((resolve17) => {
|
|
37305
37998
|
const timer = setTimeout(() => {
|
|
37306
37999
|
child.kill();
|
|
37307
|
-
|
|
38000
|
+
resolve17();
|
|
37308
38001
|
}, timeout);
|
|
37309
38002
|
child.on("exit", () => {
|
|
37310
38003
|
clearTimeout(timer);
|
|
37311
|
-
|
|
38004
|
+
resolve17();
|
|
37312
38005
|
});
|
|
37313
38006
|
});
|
|
37314
38007
|
const elapsed = Date.now() - start;
|
|
@@ -37978,14 +38671,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
37978
38671
|
res.end(JSON.stringify(data, null, 2));
|
|
37979
38672
|
}
|
|
37980
38673
|
async readBody(req) {
|
|
37981
|
-
return new Promise((
|
|
38674
|
+
return new Promise((resolve17) => {
|
|
37982
38675
|
let body = "";
|
|
37983
38676
|
req.on("data", (chunk) => body += chunk);
|
|
37984
38677
|
req.on("end", () => {
|
|
37985
38678
|
try {
|
|
37986
|
-
|
|
38679
|
+
resolve17(JSON.parse(body));
|
|
37987
38680
|
} catch {
|
|
37988
|
-
|
|
38681
|
+
resolve17({});
|
|
37989
38682
|
}
|
|
37990
38683
|
});
|
|
37991
38684
|
});
|
|
@@ -38528,7 +39221,7 @@ async function waitForReady(endpoint, timeoutMs = STARTUP_TIMEOUT_MS, requiredRe
|
|
|
38528
39221
|
const deadline = Date.now() + timeoutMs;
|
|
38529
39222
|
while (Date.now() < deadline) {
|
|
38530
39223
|
if (await canConnect(endpoint, requiredRequestTypes)) return;
|
|
38531
|
-
await new Promise((
|
|
39224
|
+
await new Promise((resolve17) => setTimeout(resolve17, STARTUP_POLL_MS));
|
|
38532
39225
|
}
|
|
38533
39226
|
throw new Error(`Session host did not become ready within ${timeoutMs}ms`);
|
|
38534
39227
|
}
|
|
@@ -38579,7 +39272,7 @@ function shouldAutoRestoreHostedSessionsOnStartup(env = process.env) {
|
|
|
38579
39272
|
|
|
38580
39273
|
// src/installer.ts
|
|
38581
39274
|
import { exec as exec6 } from "child_process";
|
|
38582
|
-
import { promisify as
|
|
39275
|
+
import { promisify as promisify6 } from "util";
|
|
38583
39276
|
var EXTENSION_CATALOG = [
|
|
38584
39277
|
// AI Agent extensions
|
|
38585
39278
|
{
|
|
@@ -38666,7 +39359,7 @@ var EXTENSION_CATALOG = [
|
|
|
38666
39359
|
apiKeyName: "OpenAI/Anthropic API key"
|
|
38667
39360
|
}
|
|
38668
39361
|
];
|
|
38669
|
-
var execAsync4 =
|
|
39362
|
+
var execAsync4 = promisify6(exec6);
|
|
38670
39363
|
async function isExtensionInstalled(ide, marketplaceId) {
|
|
38671
39364
|
if (!ide.cliCommand) return false;
|
|
38672
39365
|
try {
|
|
@@ -38708,10 +39401,10 @@ async function installExtension(ide, extension) {
|
|
|
38708
39401
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
38709
39402
|
const fs17 = await import("fs");
|
|
38710
39403
|
fs17.writeFileSync(vsixPath, buffer);
|
|
38711
|
-
return new Promise((
|
|
39404
|
+
return new Promise((resolve17) => {
|
|
38712
39405
|
const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
|
|
38713
39406
|
exec6(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
|
|
38714
|
-
|
|
39407
|
+
resolve17({
|
|
38715
39408
|
extensionId: extension.id,
|
|
38716
39409
|
marketplaceId: extension.marketplaceId,
|
|
38717
39410
|
success: !error,
|
|
@@ -38724,11 +39417,11 @@ async function installExtension(ide, extension) {
|
|
|
38724
39417
|
} catch (e) {
|
|
38725
39418
|
}
|
|
38726
39419
|
}
|
|
38727
|
-
return new Promise((
|
|
39420
|
+
return new Promise((resolve17) => {
|
|
38728
39421
|
const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
|
|
38729
39422
|
exec6(cmd, { timeout: 6e4 }, (error, stdout, stderr) => {
|
|
38730
39423
|
if (error) {
|
|
38731
|
-
|
|
39424
|
+
resolve17({
|
|
38732
39425
|
extensionId: extension.id,
|
|
38733
39426
|
marketplaceId: extension.marketplaceId,
|
|
38734
39427
|
success: false,
|
|
@@ -38736,7 +39429,7 @@ async function installExtension(ide, extension) {
|
|
|
38736
39429
|
error: stderr || error.message
|
|
38737
39430
|
});
|
|
38738
39431
|
} else {
|
|
38739
|
-
|
|
39432
|
+
resolve17({
|
|
38740
39433
|
extensionId: extension.id,
|
|
38741
39434
|
marketplaceId: extension.marketplaceId,
|
|
38742
39435
|
success: true,
|
|
@@ -39110,6 +39803,8 @@ export {
|
|
|
39110
39803
|
MAX_LEDGER_SLICE_LIMIT,
|
|
39111
39804
|
MESH_REFINE_CONFIG_LOCATIONS,
|
|
39112
39805
|
MESH_REFINE_CONFIG_SCHEMA,
|
|
39806
|
+
MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS,
|
|
39807
|
+
MESH_WORKTREE_BOOTSTRAP_CONFIG_SCHEMA,
|
|
39113
39808
|
MIN_GIT_WORKSPACE_POLL_INTERVAL_MS,
|
|
39114
39809
|
MIN_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS,
|
|
39115
39810
|
MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS,
|
|
@@ -39130,10 +39825,12 @@ export {
|
|
|
39130
39825
|
buildChatMessage,
|
|
39131
39826
|
buildChatMessageSignature,
|
|
39132
39827
|
buildChatTailDeliverySignature,
|
|
39828
|
+
buildCompactStaleDirectWorkSummary,
|
|
39133
39829
|
buildCoordinatorSystemPrompt,
|
|
39134
39830
|
buildMachineInfo,
|
|
39135
39831
|
buildMeshActiveWork,
|
|
39136
39832
|
buildMeshActiveWorkSummary,
|
|
39833
|
+
buildMeshAsyncRefineJobs,
|
|
39137
39834
|
buildMeshHostRequiredFailure,
|
|
39138
39835
|
buildMeshLedgerReconciliationEvidence,
|
|
39139
39836
|
buildMeshLedgerReplicaEvidence,
|
|
@@ -39242,6 +39939,7 @@ export {
|
|
|
39242
39939
|
listWorktrees,
|
|
39243
39940
|
loadConfig,
|
|
39244
39941
|
loadMeshRefineConfig,
|
|
39942
|
+
loadMeshWorktreeBootstrapConfig,
|
|
39245
39943
|
loadState,
|
|
39246
39944
|
logCommand,
|
|
39247
39945
|
markSetupComplete,
|
|
@@ -39293,6 +39991,7 @@ export {
|
|
|
39293
39991
|
resolveWorktreePath,
|
|
39294
39992
|
runAsyncBatch,
|
|
39295
39993
|
runGit,
|
|
39994
|
+
runMeshWorktreeBootstrap,
|
|
39296
39995
|
saveConfig,
|
|
39297
39996
|
saveState,
|
|
39298
39997
|
setDebugRuntimeConfig,
|
|
@@ -39314,6 +40013,7 @@ export {
|
|
|
39314
40013
|
updateTaskStatus,
|
|
39315
40014
|
upsertSavedProviderSession,
|
|
39316
40015
|
validateMeshRefineConfig,
|
|
39317
|
-
validateMeshTaskModeRequest
|
|
40016
|
+
validateMeshTaskModeRequest,
|
|
40017
|
+
validateMeshWorktreeBootstrapConfig
|
|
39318
40018
|
};
|
|
39319
40019
|
//# sourceMappingURL=index.mjs.map
|