@adhdev/daemon-core 0.9.82-rc.165 → 0.9.82-rc.167
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/commands/handler.d.ts +61 -17
- package/dist/index.js +1315 -756
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1313 -754
- package/dist/index.mjs.map +1 -1
- package/dist/providers/external-sources.d.ts +71 -0
- package/dist/providers/provider-loader.d.ts +7 -3
- package/dist/providers/provider-trust.d.ts +31 -0
- package/dist/providers/sdk/v1/builders/cli/parse-approval.d.ts +1 -0
- package/dist/providers/sdk/v1/index.d.ts +1 -1
- package/dist/providers/sdk/v1/validators/manifest.d.ts +1 -1
- package/dist/providers/sdk/v1/validators/taint.d.ts +1 -1
- package/dist/shared-types.d.ts +27 -1
- package/package.json +1 -1
- package/src/commands/cli-manager.ts +19 -0
- package/src/commands/handler.ts +286 -24
- package/src/mesh/mesh-events.ts +19 -1
- package/src/providers/cli-provider-instance.ts +1 -1
- package/src/providers/external-sources.ts +218 -0
- package/src/providers/provider-loader.ts +159 -23
- package/src/providers/provider-trust.ts +114 -0
- package/src/providers/sdk/v1/builders/cli/parse-approval.ts +7 -2
- package/src/providers/sdk/v1/index.ts +1 -1
- package/src/providers/sdk/v1/sandbox/require-whitelist.ts +1 -1
- package/src/providers/sdk/v1/schemas/primitives/tui-modal-v1.json +6 -0
- package/src/providers/sdk/v1/validators/manifest.ts +1 -1
- package/src/providers/sdk/v1/validators/taint.ts +1 -1
- package/src/shared-types.ts +33 -1
- package/src/status/snapshot.ts +49 -14
package/dist/index.js
CHANGED
|
@@ -106,8 +106,8 @@ function normalizeGitOutput(value) {
|
|
|
106
106
|
return String(value).replace(/\r\n/g, "\n");
|
|
107
107
|
}
|
|
108
108
|
function isPathInside(parent, child) {
|
|
109
|
-
const
|
|
110
|
-
return
|
|
109
|
+
const relative5 = path.relative(path.resolve(parent), path.resolve(child));
|
|
110
|
+
return relative5 === "" || !relative5.startsWith("..") && !path.isAbsolute(relative5);
|
|
111
111
|
}
|
|
112
112
|
async function validateWorkspace(workspace) {
|
|
113
113
|
if (typeof workspace !== "string" || workspace.length === 0 || workspace.includes("\0")) {
|
|
@@ -770,10 +770,10 @@ function getMeshConfigPath() {
|
|
|
770
770
|
return (0, import_path2.join)(getConfigDir(), "meshes.json");
|
|
771
771
|
}
|
|
772
772
|
function loadMeshConfig() {
|
|
773
|
-
const
|
|
774
|
-
if (!(0, import_fs2.existsSync)(
|
|
773
|
+
const path40 = getMeshConfigPath();
|
|
774
|
+
if (!(0, import_fs2.existsSync)(path40)) return { meshes: [] };
|
|
775
775
|
try {
|
|
776
|
-
const raw = JSON.parse((0, import_fs2.readFileSync)(
|
|
776
|
+
const raw = JSON.parse((0, import_fs2.readFileSync)(path40, "utf-8"));
|
|
777
777
|
if (!raw || !Array.isArray(raw.meshes)) return { meshes: [] };
|
|
778
778
|
return raw;
|
|
779
779
|
} catch {
|
|
@@ -781,16 +781,16 @@ function loadMeshConfig() {
|
|
|
781
781
|
}
|
|
782
782
|
}
|
|
783
783
|
function saveMeshConfig(config) {
|
|
784
|
-
const
|
|
785
|
-
(0, import_fs2.writeFileSync)(
|
|
784
|
+
const path40 = getMeshConfigPath();
|
|
785
|
+
(0, import_fs2.writeFileSync)(path40, JSON.stringify(config, null, 2), { encoding: "utf-8", mode: 384 });
|
|
786
786
|
}
|
|
787
787
|
function normalizeRepoIdentity(remoteUrl) {
|
|
788
788
|
let identity = remoteUrl.trim();
|
|
789
789
|
if (identity.startsWith("http://") || identity.startsWith("https://")) {
|
|
790
790
|
try {
|
|
791
791
|
const url = new URL(identity);
|
|
792
|
-
const
|
|
793
|
-
return `${url.hostname}/${
|
|
792
|
+
const path40 = url.pathname.replace(/^\//, "").replace(/\.git$/, "");
|
|
793
|
+
return `${url.hostname}/${path40}`;
|
|
794
794
|
} catch {
|
|
795
795
|
}
|
|
796
796
|
}
|
|
@@ -1718,8 +1718,8 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
1718
1718
|
}
|
|
1719
1719
|
const serverName = mcpConfig.serverName?.trim() || DEFAULT_SERVER_NAME;
|
|
1720
1720
|
if (mcpConfig.mode === "auto_import") {
|
|
1721
|
-
const
|
|
1722
|
-
if (!
|
|
1721
|
+
const path40 = mcpConfig.path?.trim();
|
|
1722
|
+
if (!path40) {
|
|
1723
1723
|
return { kind: "unsupported", reason: "Provider auto-import MCP config is missing a config path" };
|
|
1724
1724
|
}
|
|
1725
1725
|
const mcpServer = resolveAdhdevMcpServerLaunch({
|
|
@@ -1737,7 +1737,7 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
1737
1737
|
return {
|
|
1738
1738
|
kind: "auto_import",
|
|
1739
1739
|
serverName,
|
|
1740
|
-
configPath: resolveMcpConfigPath(
|
|
1740
|
+
configPath: resolveMcpConfigPath(path40, workspace),
|
|
1741
1741
|
configFormat: mcpConfig.format,
|
|
1742
1742
|
mcpServer
|
|
1743
1743
|
};
|
|
@@ -1894,8 +1894,8 @@ function stripCoordinatorWrapperFile(filePath) {
|
|
|
1894
1894
|
const remaining = (existing.slice(0, openIdx) + existing.slice(closeIdx + CLOSE.length)).replace(/^\s*\n+/, "").replace(/\n+\s*$/, "");
|
|
1895
1895
|
if (!remaining.trim()) {
|
|
1896
1896
|
try {
|
|
1897
|
-
const
|
|
1898
|
-
|
|
1897
|
+
const fs28 = require("fs");
|
|
1898
|
+
fs28.unlinkSync(filePath);
|
|
1899
1899
|
} catch {
|
|
1900
1900
|
}
|
|
1901
1901
|
} else {
|
|
@@ -2033,10 +2033,10 @@ function rotateArchiveFile(meshId, archivePath) {
|
|
|
2033
2033
|
}
|
|
2034
2034
|
}
|
|
2035
2035
|
function readArchivedCounts(meshId) {
|
|
2036
|
-
const
|
|
2037
|
-
if (!(0, import_fs6.existsSync)(
|
|
2036
|
+
const path40 = getArchivedCountsPath(meshId);
|
|
2037
|
+
if (!(0, import_fs6.existsSync)(path40)) return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
|
|
2038
2038
|
try {
|
|
2039
|
-
return JSON.parse((0, import_fs6.readFileSync)(
|
|
2039
|
+
return JSON.parse((0, import_fs6.readFileSync)(path40, "utf-8"));
|
|
2040
2040
|
} catch {
|
|
2041
2041
|
return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
|
|
2042
2042
|
}
|
|
@@ -2691,10 +2691,10 @@ var init_beads_db = __esm({
|
|
|
2691
2691
|
this.migratedMeshIds.add(meshId);
|
|
2692
2692
|
const count = this.db.prepare("SELECT COUNT(*) AS count FROM mesh_queue WHERE mesh_id = ?").get(meshId);
|
|
2693
2693
|
if (count.count > 0) return;
|
|
2694
|
-
const
|
|
2695
|
-
if (!(0, import_fs7.existsSync)(
|
|
2694
|
+
const path40 = legacyQueuePath(meshId);
|
|
2695
|
+
if (!(0, import_fs7.existsSync)(path40)) return;
|
|
2696
2696
|
try {
|
|
2697
|
-
const entries = JSON.parse((0, import_fs7.readFileSync)(
|
|
2697
|
+
const entries = JSON.parse((0, import_fs7.readFileSync)(path40, "utf-8"));
|
|
2698
2698
|
if (!Array.isArray(entries)) return;
|
|
2699
2699
|
const insert = this.db.prepare(`
|
|
2700
2700
|
INSERT OR REPLACE INTO mesh_queue (
|
|
@@ -3404,10 +3404,10 @@ function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
|
|
|
3404
3404
|
if (!meshId) return [];
|
|
3405
3405
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
3406
3406
|
const events = [];
|
|
3407
|
-
for (const
|
|
3408
|
-
if (!(0, import_fs9.existsSync)(
|
|
3407
|
+
for (const path40 of paths) {
|
|
3408
|
+
if (!(0, import_fs9.existsSync)(path40)) continue;
|
|
3409
3409
|
try {
|
|
3410
|
-
const raw = (0, import_fs9.readFileSync)(
|
|
3410
|
+
const raw = (0, import_fs9.readFileSync)(path40, "utf-8");
|
|
3411
3411
|
const parsed = raw.split("\n").filter(Boolean).flatMap((line) => {
|
|
3412
3412
|
try {
|
|
3413
3413
|
return [JSON.parse(line)];
|
|
@@ -3415,7 +3415,7 @@ function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
|
|
|
3415
3415
|
return [];
|
|
3416
3416
|
}
|
|
3417
3417
|
});
|
|
3418
|
-
const filtered = coordinatorDaemonId &&
|
|
3418
|
+
const filtered = coordinatorDaemonId && path40 === getPendingEventsPath(meshId) ? parsed.filter((e) => !e.targetCoordinatorDaemonId || e.targetCoordinatorDaemonId === coordinatorDaemonId) : parsed;
|
|
3419
3419
|
events.push(...filtered);
|
|
3420
3420
|
} catch {
|
|
3421
3421
|
}
|
|
@@ -3484,13 +3484,13 @@ function reconcilePendingMeshCoordinatorEvents(meshId, events) {
|
|
|
3484
3484
|
...backfilled
|
|
3485
3485
|
];
|
|
3486
3486
|
}
|
|
3487
|
-
function trimPendingEventsIfNeeded(
|
|
3487
|
+
function trimPendingEventsIfNeeded(path40) {
|
|
3488
3488
|
try {
|
|
3489
|
-
if (!(0, import_fs9.existsSync)(
|
|
3490
|
-
if ((0, import_fs9.statSync)(
|
|
3491
|
-
const lines = (0, import_fs9.readFileSync)(
|
|
3489
|
+
if (!(0, import_fs9.existsSync)(path40)) return;
|
|
3490
|
+
if ((0, import_fs9.statSync)(path40).size <= MAX_PENDING_EVENTS_BYTES) return;
|
|
3491
|
+
const lines = (0, import_fs9.readFileSync)(path40, "utf-8").split("\n").filter(Boolean);
|
|
3492
3492
|
if (lines.length <= MAX_PENDING_EVENTS_KEEP) return;
|
|
3493
|
-
(0, import_fs9.writeFileSync)(
|
|
3493
|
+
(0, import_fs9.writeFileSync)(path40, lines.slice(-MAX_PENDING_EVENTS_KEEP).join("\n") + "\n", "utf-8");
|
|
3494
3494
|
} catch {
|
|
3495
3495
|
}
|
|
3496
3496
|
}
|
|
@@ -3504,19 +3504,19 @@ function queuePendingMeshCoordinatorEvent(event) {
|
|
|
3504
3504
|
LOG.info("MeshEvents", `Suppressed duplicate pending ${event.event} for mesh ${event.meshId}`);
|
|
3505
3505
|
return true;
|
|
3506
3506
|
}
|
|
3507
|
-
const
|
|
3508
|
-
trimPendingEventsIfNeeded(
|
|
3509
|
-
(0, import_fs9.appendFileSync)(
|
|
3507
|
+
const path40 = getPendingEventsPath(event.meshId, event.targetCoordinatorDaemonId);
|
|
3508
|
+
trimPendingEventsIfNeeded(path40);
|
|
3509
|
+
(0, import_fs9.appendFileSync)(path40, JSON.stringify(event) + "\n", "utf-8");
|
|
3510
3510
|
return true;
|
|
3511
3511
|
} catch (e) {
|
|
3512
3512
|
LOG.warn("MeshEvents", `Failed to persist pending coordinator event: ${e?.message || e}`);
|
|
3513
3513
|
return false;
|
|
3514
3514
|
}
|
|
3515
3515
|
}
|
|
3516
|
-
function atomicDrainFile(
|
|
3517
|
-
const tmpPath = `${
|
|
3516
|
+
function atomicDrainFile(path40) {
|
|
3517
|
+
const tmpPath = `${path40}.draining`;
|
|
3518
3518
|
try {
|
|
3519
|
-
(0, import_fs9.renameSync)(
|
|
3519
|
+
(0, import_fs9.renameSync)(path40, tmpPath);
|
|
3520
3520
|
} catch {
|
|
3521
3521
|
return null;
|
|
3522
3522
|
}
|
|
@@ -3539,8 +3539,8 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
3539
3539
|
if (!meshId) return [];
|
|
3540
3540
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
3541
3541
|
const all = [];
|
|
3542
|
-
for (const
|
|
3543
|
-
const content = atomicDrainFile(
|
|
3542
|
+
for (const path40 of paths) {
|
|
3543
|
+
const content = atomicDrainFile(path40);
|
|
3544
3544
|
if (!content) continue;
|
|
3545
3545
|
const parsed = content.split("\n").filter(Boolean).flatMap((line) => {
|
|
3546
3546
|
try {
|
|
@@ -3549,7 +3549,7 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
3549
3549
|
return [];
|
|
3550
3550
|
}
|
|
3551
3551
|
});
|
|
3552
|
-
const filtered = coordinatorDaemonId &&
|
|
3552
|
+
const filtered = coordinatorDaemonId && path40 === getPendingEventsPath(meshId) ? parsed.filter((e) => !e.targetCoordinatorDaemonId || e.targetCoordinatorDaemonId === coordinatorDaemonId) : parsed;
|
|
3553
3553
|
all.push(...filtered);
|
|
3554
3554
|
}
|
|
3555
3555
|
if (all.length === 0) return [];
|
|
@@ -3562,9 +3562,9 @@ function getPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
3562
3562
|
function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
3563
3563
|
if (!meshId) return;
|
|
3564
3564
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
3565
|
-
for (const
|
|
3566
|
-
if ((0, import_fs9.existsSync)(
|
|
3567
|
-
(0, import_fs9.unlinkSync)(
|
|
3565
|
+
for (const path40 of paths) {
|
|
3566
|
+
if ((0, import_fs9.existsSync)(path40)) try {
|
|
3567
|
+
(0, import_fs9.unlinkSync)(path40);
|
|
3568
3568
|
} catch {
|
|
3569
3569
|
}
|
|
3570
3570
|
}
|
|
@@ -3699,6 +3699,20 @@ function hasDispatchAfterTerminal(meshId, sessionId, terminalId) {
|
|
|
3699
3699
|
}
|
|
3700
3700
|
return false;
|
|
3701
3701
|
}
|
|
3702
|
+
function hasUnterminalDirectDispatchLedgerEntry(meshId, sessionId) {
|
|
3703
|
+
const entries = readLedgerEntries(meshId, { tail: 200 });
|
|
3704
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
3705
|
+
const entry = entries[i];
|
|
3706
|
+
if (entry.sessionId !== sessionId) continue;
|
|
3707
|
+
if (entry.kind === "task_completed" || entry.kind === "task_failed" || entry.kind === "task_stalled") {
|
|
3708
|
+
return false;
|
|
3709
|
+
}
|
|
3710
|
+
if (entry.kind === "task_dispatched" && entry.payload?.source === "direct") {
|
|
3711
|
+
return true;
|
|
3712
|
+
}
|
|
3713
|
+
}
|
|
3714
|
+
return false;
|
|
3715
|
+
}
|
|
3702
3716
|
function buildLongGeneratingCompletionReconciliation(args) {
|
|
3703
3717
|
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
3704
3718
|
const nodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
|
|
@@ -4566,7 +4580,7 @@ function setupMeshEventForwarding(components) {
|
|
|
4566
4580
|
if (coordinatorMeshId) {
|
|
4567
4581
|
try {
|
|
4568
4582
|
const activeDispatches = getActiveDirectDispatches(coordinatorMeshId);
|
|
4569
|
-
if (activeDispatches.some((d) => d.sessionId === instanceId)) {
|
|
4583
|
+
if (activeDispatches.some((d) => d.sessionId === instanceId) || hasUnterminalDirectDispatchLedgerEntry(coordinatorMeshId, instanceId)) {
|
|
4570
4584
|
meshIdFromDirectDispatch = coordinatorMeshId;
|
|
4571
4585
|
}
|
|
4572
4586
|
} catch {
|
|
@@ -4690,6 +4704,56 @@ var init_debug_config = __esm({
|
|
|
4690
4704
|
}
|
|
4691
4705
|
});
|
|
4692
4706
|
|
|
4707
|
+
// src/providers/provider-trust.ts
|
|
4708
|
+
var provider_trust_exports = {};
|
|
4709
|
+
__export(provider_trust_exports, {
|
|
4710
|
+
classifyTrust: () => classifyTrust,
|
|
4711
|
+
describeTrust: () => describeTrust,
|
|
4712
|
+
inspectManifestShape: () => inspectManifestShape,
|
|
4713
|
+
requiresConfirmation: () => requiresConfirmation
|
|
4714
|
+
});
|
|
4715
|
+
function inspectManifestShape(manifest) {
|
|
4716
|
+
const hasTui = !!manifest.tui && typeof manifest.tui === "object" && Object.keys(manifest.tui).length > 0;
|
|
4717
|
+
const hasOverrides = !!manifest.overrides && typeof manifest.overrides === "object" && !Array.isArray(manifest.overrides) && Object.keys(manifest.overrides).length > 0;
|
|
4718
|
+
const compat = Array.isArray(manifest.compatibility) ? manifest.compatibility : [];
|
|
4719
|
+
const compatHasScriptDir = compat.some((entry) => typeof entry?.scriptDir === "string");
|
|
4720
|
+
const hasScriptDir = compatHasScriptDir || typeof manifest.defaultScriptDir === "string";
|
|
4721
|
+
return { hasTui, hasOverrides, hasScriptDir };
|
|
4722
|
+
}
|
|
4723
|
+
function classifyTrust(layer, shape) {
|
|
4724
|
+
const isSpecOnly = !shape.hasTui && !shape.hasOverrides && !shape.hasScriptDir;
|
|
4725
|
+
switch (layer) {
|
|
4726
|
+
case "user":
|
|
4727
|
+
return "user-custom";
|
|
4728
|
+
case "upstream":
|
|
4729
|
+
return isSpecOnly ? "trusted" : "trusted-with-scripts";
|
|
4730
|
+
case "external":
|
|
4731
|
+
return isSpecOnly ? "external-safe" : "external-untrusted";
|
|
4732
|
+
}
|
|
4733
|
+
}
|
|
4734
|
+
function requiresConfirmation(trust) {
|
|
4735
|
+
return trust === "external-untrusted";
|
|
4736
|
+
}
|
|
4737
|
+
function describeTrust(trust) {
|
|
4738
|
+
switch (trust) {
|
|
4739
|
+
case "user-custom":
|
|
4740
|
+
return "Hand-authored in ~/.adhdev/providers/. Runs your own code.";
|
|
4741
|
+
case "trusted":
|
|
4742
|
+
return "Official, declarative-only manifest from the ADHDev registry.";
|
|
4743
|
+
case "trusted-with-scripts":
|
|
4744
|
+
return "Official manifest from the ADHDev registry. Ships JavaScript hooks executed by the daemon.";
|
|
4745
|
+
case "external-safe":
|
|
4746
|
+
return "Manifest from a 3rd-party git source you added. Declarative-only \u2014 the daemon never runs JS from this source.";
|
|
4747
|
+
case "external-untrusted":
|
|
4748
|
+
return "Manifest from a 3rd-party git source you added. Ships JavaScript that the daemon will execute. Treat as untrusted code \u2014 review the source before enabling.";
|
|
4749
|
+
}
|
|
4750
|
+
}
|
|
4751
|
+
var init_provider_trust = __esm({
|
|
4752
|
+
"src/providers/provider-trust.ts"() {
|
|
4753
|
+
"use strict";
|
|
4754
|
+
}
|
|
4755
|
+
});
|
|
4756
|
+
|
|
4693
4757
|
// src/providers/sdk/v1/schemas/cli/provider.schema.json
|
|
4694
4758
|
var provider_schema_default;
|
|
4695
4759
|
var init_provider_schema = __esm({
|
|
@@ -5193,7 +5257,7 @@ function getCliValidator() {
|
|
|
5193
5257
|
return _cliValidator;
|
|
5194
5258
|
}
|
|
5195
5259
|
function formatIssue(err) {
|
|
5196
|
-
const
|
|
5260
|
+
const path40 = err.instancePath || "";
|
|
5197
5261
|
const params = err.params;
|
|
5198
5262
|
let message = err.message || "validation failed";
|
|
5199
5263
|
let allowed;
|
|
@@ -5211,7 +5275,7 @@ function formatIssue(err) {
|
|
|
5211
5275
|
} else if (err.keyword === "type") {
|
|
5212
5276
|
message = `must be ${params.type}`;
|
|
5213
5277
|
}
|
|
5214
|
-
return { path:
|
|
5278
|
+
return { path: path40, keyword: err.keyword, message, ...allowed !== void 0 ? { allowed } : {} };
|
|
5215
5279
|
}
|
|
5216
5280
|
function validateCliProviderManifest(manifest) {
|
|
5217
5281
|
const validator = getCliValidator();
|
|
@@ -5238,6 +5302,156 @@ var init_manifest = __esm({
|
|
|
5238
5302
|
}
|
|
5239
5303
|
});
|
|
5240
5304
|
|
|
5305
|
+
// src/providers/external-sources.ts
|
|
5306
|
+
var external_sources_exports = {};
|
|
5307
|
+
__export(external_sources_exports, {
|
|
5308
|
+
activeFilePath: () => activeFilePath,
|
|
5309
|
+
deriveSourceName: () => deriveSourceName,
|
|
5310
|
+
externalRoot: () => externalRoot,
|
|
5311
|
+
inventoryExternalSources: () => inventoryExternalSources,
|
|
5312
|
+
loadExternalSources: () => loadExternalSources,
|
|
5313
|
+
loadProvidersActive: () => loadProvidersActive,
|
|
5314
|
+
resolveActiveSource: () => resolveActiveSource,
|
|
5315
|
+
saveExternalSources: () => saveExternalSources,
|
|
5316
|
+
saveProvidersActive: () => saveProvidersActive,
|
|
5317
|
+
sourcesFilePath: () => sourcesFilePath,
|
|
5318
|
+
sourcesProviding: () => sourcesProviding
|
|
5319
|
+
});
|
|
5320
|
+
function adhdevDir() {
|
|
5321
|
+
return path15.join(os10.homedir(), ".adhdev");
|
|
5322
|
+
}
|
|
5323
|
+
function externalRoot() {
|
|
5324
|
+
return path15.join(adhdevDir(), "external");
|
|
5325
|
+
}
|
|
5326
|
+
function sourcesFilePath() {
|
|
5327
|
+
return path15.join(adhdevDir(), SOURCES_FILENAME);
|
|
5328
|
+
}
|
|
5329
|
+
function activeFilePath() {
|
|
5330
|
+
return path15.join(adhdevDir(), ACTIVE_FILENAME);
|
|
5331
|
+
}
|
|
5332
|
+
function ensureAdhdevDir() {
|
|
5333
|
+
const d = adhdevDir();
|
|
5334
|
+
if (!fs8.existsSync(d)) fs8.mkdirSync(d, { recursive: true });
|
|
5335
|
+
}
|
|
5336
|
+
function loadExternalSources() {
|
|
5337
|
+
const p = sourcesFilePath();
|
|
5338
|
+
if (!fs8.existsSync(p)) return { schema: 1, sources: [] };
|
|
5339
|
+
try {
|
|
5340
|
+
const raw = JSON.parse(fs8.readFileSync(p, "utf-8"));
|
|
5341
|
+
if (!raw || typeof raw !== "object") return { schema: 1, sources: [] };
|
|
5342
|
+
const sources = Array.isArray(raw.sources) ? raw.sources.filter(isValidSource) : [];
|
|
5343
|
+
return { schema: 1, sources };
|
|
5344
|
+
} catch {
|
|
5345
|
+
return { schema: 1, sources: [] };
|
|
5346
|
+
}
|
|
5347
|
+
}
|
|
5348
|
+
function saveExternalSources(file) {
|
|
5349
|
+
ensureAdhdevDir();
|
|
5350
|
+
const tmp = sourcesFilePath() + ".tmp";
|
|
5351
|
+
fs8.writeFileSync(tmp, JSON.stringify(file, null, 2) + "\n", "utf-8");
|
|
5352
|
+
fs8.renameSync(tmp, sourcesFilePath());
|
|
5353
|
+
}
|
|
5354
|
+
function loadProvidersActive() {
|
|
5355
|
+
const p = activeFilePath();
|
|
5356
|
+
if (!fs8.existsSync(p)) return { schema: 1, active: {} };
|
|
5357
|
+
try {
|
|
5358
|
+
const raw = JSON.parse(fs8.readFileSync(p, "utf-8"));
|
|
5359
|
+
if (!raw || typeof raw !== "object") return { schema: 1, active: {} };
|
|
5360
|
+
const active = raw.active && typeof raw.active === "object" ? raw.active : {};
|
|
5361
|
+
return { schema: 1, active };
|
|
5362
|
+
} catch {
|
|
5363
|
+
return { schema: 1, active: {} };
|
|
5364
|
+
}
|
|
5365
|
+
}
|
|
5366
|
+
function saveProvidersActive(file) {
|
|
5367
|
+
ensureAdhdevDir();
|
|
5368
|
+
const tmp = activeFilePath() + ".tmp";
|
|
5369
|
+
fs8.writeFileSync(tmp, JSON.stringify(file, null, 2) + "\n", "utf-8");
|
|
5370
|
+
fs8.renameSync(tmp, activeFilePath());
|
|
5371
|
+
}
|
|
5372
|
+
function isValidSource(x) {
|
|
5373
|
+
if (!x || typeof x !== "object") return false;
|
|
5374
|
+
const s = x;
|
|
5375
|
+
return typeof s.name === "string" && s.name.length > 0 && typeof s.url === "string" && s.url.length > 0 && typeof s.ref === "string" && s.ref.length > 0 && typeof s.addedAt === "string";
|
|
5376
|
+
}
|
|
5377
|
+
function deriveSourceName(url) {
|
|
5378
|
+
const m = url.match(/[/:]([^/:]+)\/([^/]+?)(?:\.git)?$/);
|
|
5379
|
+
if (!m) return "@source";
|
|
5380
|
+
const owner = m[1].toLowerCase().replace(/[^a-z0-9_-]/g, "-");
|
|
5381
|
+
const repo = m[2].toLowerCase().replace(/[^a-z0-9_-]/g, "-");
|
|
5382
|
+
return `@${owner}-${repo}`;
|
|
5383
|
+
}
|
|
5384
|
+
function inventoryExternalSources() {
|
|
5385
|
+
const root = externalRoot();
|
|
5386
|
+
if (!fs8.existsSync(root)) return [];
|
|
5387
|
+
const out = [];
|
|
5388
|
+
let entries;
|
|
5389
|
+
try {
|
|
5390
|
+
entries = fs8.readdirSync(root, { withFileTypes: true });
|
|
5391
|
+
} catch {
|
|
5392
|
+
return [];
|
|
5393
|
+
}
|
|
5394
|
+
for (const sourceEntry of entries) {
|
|
5395
|
+
if (!sourceEntry.isDirectory()) continue;
|
|
5396
|
+
const sourceName = sourceEntry.name;
|
|
5397
|
+
const sourceDir = path15.join(root, sourceName);
|
|
5398
|
+
const providers = {};
|
|
5399
|
+
let categoryEntries;
|
|
5400
|
+
try {
|
|
5401
|
+
categoryEntries = fs8.readdirSync(sourceDir, { withFileTypes: true });
|
|
5402
|
+
} catch {
|
|
5403
|
+
continue;
|
|
5404
|
+
}
|
|
5405
|
+
for (const categoryEntry of categoryEntries) {
|
|
5406
|
+
if (!categoryEntry.isDirectory()) continue;
|
|
5407
|
+
const category = categoryEntry.name;
|
|
5408
|
+
const categoryDir = path15.join(sourceDir, category);
|
|
5409
|
+
let typeEntries;
|
|
5410
|
+
try {
|
|
5411
|
+
typeEntries = fs8.readdirSync(categoryDir, { withFileTypes: true });
|
|
5412
|
+
} catch {
|
|
5413
|
+
continue;
|
|
5414
|
+
}
|
|
5415
|
+
const types = [];
|
|
5416
|
+
for (const typeEntry of typeEntries) {
|
|
5417
|
+
if (!typeEntry.isDirectory()) continue;
|
|
5418
|
+
const typeDir = path15.join(categoryDir, typeEntry.name);
|
|
5419
|
+
const hasV1 = fs8.existsSync(path15.join(typeDir, "provider.v1.json"));
|
|
5420
|
+
const hasV0 = fs8.existsSync(path15.join(typeDir, "provider.json"));
|
|
5421
|
+
if (hasV1 || hasV0) types.push(typeEntry.name);
|
|
5422
|
+
}
|
|
5423
|
+
if (types.length > 0) providers[category] = types;
|
|
5424
|
+
}
|
|
5425
|
+
out.push({ sourceName, providers });
|
|
5426
|
+
}
|
|
5427
|
+
return out;
|
|
5428
|
+
}
|
|
5429
|
+
function sourcesProviding(category, type) {
|
|
5430
|
+
const inventory = inventoryExternalSources();
|
|
5431
|
+
return inventory.filter((s) => (s.providers[category] || []).includes(type)).map((s) => s.sourceName);
|
|
5432
|
+
}
|
|
5433
|
+
function resolveActiveSource(category, type, activeFile) {
|
|
5434
|
+
const candidates = sourcesProviding(category, type);
|
|
5435
|
+
if (candidates.length === 0) return { source: null, ambiguous: false, candidates };
|
|
5436
|
+
if (candidates.length === 1) return { source: candidates[0], ambiguous: false, candidates };
|
|
5437
|
+
const explicit = (activeFile ?? loadProvidersActive()).active[type];
|
|
5438
|
+
if (explicit && candidates.includes(explicit)) {
|
|
5439
|
+
return { source: explicit, ambiguous: false, candidates };
|
|
5440
|
+
}
|
|
5441
|
+
return { source: candidates[0], ambiguous: true, candidates };
|
|
5442
|
+
}
|
|
5443
|
+
var fs8, os10, path15, SOURCES_FILENAME, ACTIVE_FILENAME;
|
|
5444
|
+
var init_external_sources = __esm({
|
|
5445
|
+
"src/providers/external-sources.ts"() {
|
|
5446
|
+
"use strict";
|
|
5447
|
+
fs8 = __toESM(require("fs"));
|
|
5448
|
+
os10 = __toESM(require("os"));
|
|
5449
|
+
path15 = __toESM(require("path"));
|
|
5450
|
+
SOURCES_FILENAME = "providers-sources.json";
|
|
5451
|
+
ACTIVE_FILENAME = "providers-active.json";
|
|
5452
|
+
}
|
|
5453
|
+
});
|
|
5454
|
+
|
|
5241
5455
|
// src/cli-adapters/terminal-backends/ghostty-vt-backend.ts
|
|
5242
5456
|
function isModuleNotFoundError(error, ref) {
|
|
5243
5457
|
if (!(error instanceof Error)) return false;
|
|
@@ -5533,11 +5747,11 @@ function loadNodePty() {
|
|
|
5533
5747
|
}
|
|
5534
5748
|
return cachedPty;
|
|
5535
5749
|
}
|
|
5536
|
-
var
|
|
5750
|
+
var os11, cachedPty, NodePtyRuntimeTransport, NodePtyTransportFactory;
|
|
5537
5751
|
var init_pty_transport = __esm({
|
|
5538
5752
|
"src/cli-adapters/pty-transport.ts"() {
|
|
5539
5753
|
"use strict";
|
|
5540
|
-
|
|
5754
|
+
os11 = __toESM(require("os"));
|
|
5541
5755
|
init_spawn_env();
|
|
5542
5756
|
NodePtyRuntimeTransport = class {
|
|
5543
5757
|
constructor(handle) {
|
|
@@ -5574,11 +5788,11 @@ var init_pty_transport = __esm({
|
|
|
5574
5788
|
let cwd = options.cwd;
|
|
5575
5789
|
if (cwd) {
|
|
5576
5790
|
try {
|
|
5577
|
-
const
|
|
5578
|
-
const stat2 =
|
|
5579
|
-
if (!stat2.isDirectory()) cwd =
|
|
5791
|
+
const fs28 = require("fs");
|
|
5792
|
+
const stat2 = fs28.statSync(cwd);
|
|
5793
|
+
if (!stat2.isDirectory()) cwd = os11.homedir();
|
|
5580
5794
|
} catch {
|
|
5581
|
-
cwd =
|
|
5795
|
+
cwd = os11.homedir();
|
|
5582
5796
|
}
|
|
5583
5797
|
}
|
|
5584
5798
|
const handle = pty.spawn(command, args, {
|
|
@@ -5670,21 +5884,21 @@ function buildCliScreenSnapshot(text) {
|
|
|
5670
5884
|
function findBinary(name) {
|
|
5671
5885
|
const trimmed = String(name || "").trim();
|
|
5672
5886
|
if (!trimmed) return trimmed;
|
|
5673
|
-
const expanded = trimmed.startsWith("~") ?
|
|
5674
|
-
if (
|
|
5675
|
-
return
|
|
5887
|
+
const expanded = trimmed.startsWith("~") ? path16.join(os12.homedir(), trimmed.slice(1)) : trimmed;
|
|
5888
|
+
if (path16.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
|
|
5889
|
+
return path16.isAbsolute(expanded) ? expanded : path16.resolve(expanded);
|
|
5676
5890
|
}
|
|
5677
|
-
const isWin =
|
|
5678
|
-
const paths = (process.env.PATH || "").split(
|
|
5891
|
+
const isWin = os12.platform() === "win32";
|
|
5892
|
+
const paths = (process.env.PATH || "").split(path16.delimiter);
|
|
5679
5893
|
const exes = isWin ? [".exe", ".cmd", ".bat", ""] : [""];
|
|
5680
5894
|
for (const p of paths) {
|
|
5681
5895
|
if (!p) continue;
|
|
5682
5896
|
for (const ext of exes) {
|
|
5683
|
-
const fullPath =
|
|
5897
|
+
const fullPath = path16.join(p, trimmed + ext);
|
|
5684
5898
|
try {
|
|
5685
|
-
const
|
|
5686
|
-
if (
|
|
5687
|
-
const stat2 =
|
|
5899
|
+
const fs28 = require("fs");
|
|
5900
|
+
if (fs28.existsSync(fullPath)) {
|
|
5901
|
+
const stat2 = fs28.statSync(fullPath);
|
|
5688
5902
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
5689
5903
|
return fullPath;
|
|
5690
5904
|
}
|
|
@@ -5696,14 +5910,14 @@ function findBinary(name) {
|
|
|
5696
5910
|
return isWin ? `${trimmed}.cmd` : trimmed;
|
|
5697
5911
|
}
|
|
5698
5912
|
function isScriptBinary(binaryPath) {
|
|
5699
|
-
if (!
|
|
5913
|
+
if (!path16.isAbsolute(binaryPath)) return false;
|
|
5700
5914
|
try {
|
|
5701
|
-
const
|
|
5702
|
-
const resolved =
|
|
5915
|
+
const fs28 = require("fs");
|
|
5916
|
+
const resolved = fs28.realpathSync(binaryPath);
|
|
5703
5917
|
const head = Buffer.alloc(8);
|
|
5704
|
-
const fd =
|
|
5705
|
-
|
|
5706
|
-
|
|
5918
|
+
const fd = fs28.openSync(resolved, "r");
|
|
5919
|
+
fs28.readSync(fd, head, 0, 8, 0);
|
|
5920
|
+
fs28.closeSync(fd);
|
|
5707
5921
|
let i = 0;
|
|
5708
5922
|
if (head[0] === 239 && head[1] === 187 && head[2] === 191) i = 3;
|
|
5709
5923
|
return head[i] === 35 && head[i + 1] === 33;
|
|
@@ -5712,14 +5926,14 @@ function isScriptBinary(binaryPath) {
|
|
|
5712
5926
|
}
|
|
5713
5927
|
}
|
|
5714
5928
|
function looksLikeMachOOrElf(filePath) {
|
|
5715
|
-
if (!
|
|
5929
|
+
if (!path16.isAbsolute(filePath)) return false;
|
|
5716
5930
|
try {
|
|
5717
|
-
const
|
|
5718
|
-
const resolved =
|
|
5931
|
+
const fs28 = require("fs");
|
|
5932
|
+
const resolved = fs28.realpathSync(filePath);
|
|
5719
5933
|
const buf = Buffer.alloc(8);
|
|
5720
|
-
const fd =
|
|
5721
|
-
|
|
5722
|
-
|
|
5934
|
+
const fd = fs28.openSync(resolved, "r");
|
|
5935
|
+
fs28.readSync(fd, buf, 0, 8, 0);
|
|
5936
|
+
fs28.closeSync(fd);
|
|
5723
5937
|
let i = 0;
|
|
5724
5938
|
if (buf[0] === 239 && buf[1] === 187 && buf[2] === 191) i = 3;
|
|
5725
5939
|
const b = buf.subarray(i);
|
|
@@ -5735,7 +5949,7 @@ function looksLikeMachOOrElf(filePath) {
|
|
|
5735
5949
|
}
|
|
5736
5950
|
function shSingleQuote(arg) {
|
|
5737
5951
|
if (/^[a-zA-Z0-9@%_+=:,./-]+$/.test(arg)) return arg;
|
|
5738
|
-
if (
|
|
5952
|
+
if (os12.platform() === "win32") {
|
|
5739
5953
|
return `"${arg.replace(/"/g, '""')}"`;
|
|
5740
5954
|
}
|
|
5741
5955
|
return `'${arg.replace(/'/g, `'\\''`)}'`;
|
|
@@ -5801,12 +6015,12 @@ function normalizeCliProviderForRuntime(raw) {
|
|
|
5801
6015
|
}
|
|
5802
6016
|
};
|
|
5803
6017
|
}
|
|
5804
|
-
var
|
|
6018
|
+
var os12, path16, TerminalTranscriptAccumulator, buildCliSpawnEnv;
|
|
5805
6019
|
var init_provider_cli_shared = __esm({
|
|
5806
6020
|
"src/cli-adapters/provider-cli-shared.ts"() {
|
|
5807
6021
|
"use strict";
|
|
5808
|
-
|
|
5809
|
-
|
|
6022
|
+
os12 = __toESM(require("os"));
|
|
6023
|
+
path16 = __toESM(require("path"));
|
|
5810
6024
|
init_spawn_env();
|
|
5811
6025
|
TerminalTranscriptAccumulator = class {
|
|
5812
6026
|
lines = [[]];
|
|
@@ -6202,12 +6416,14 @@ function scopeLines(spec, lines, questionIndex) {
|
|
|
6202
6416
|
function extractButtons(spec, lines, windowStart, windowEnd) {
|
|
6203
6417
|
const buttonRe = compile3(spec.buttonPattern, spec.buttonFlags ?? "m");
|
|
6204
6418
|
const out = [];
|
|
6419
|
+
const labelGroup = Number.isInteger(spec.buttonLabelGroup) && (spec.buttonLabelGroup ?? 0) > 0 ? spec.buttonLabelGroup : 1;
|
|
6205
6420
|
let i = windowStart;
|
|
6206
6421
|
while (i < windowEnd) {
|
|
6207
6422
|
const line = lines[i];
|
|
6208
6423
|
const m = buttonRe.exec(line);
|
|
6209
|
-
|
|
6210
|
-
|
|
6424
|
+
const captured = m?.[labelGroup] ?? (labelGroup === 1 && m && m.length > 2 ? m[m.length - 1] : void 0);
|
|
6425
|
+
if (m && captured) {
|
|
6426
|
+
let label = captured.trim();
|
|
6211
6427
|
if (spec.continuationLines) {
|
|
6212
6428
|
let j = i + 1;
|
|
6213
6429
|
while (j < windowEnd) {
|
|
@@ -7695,15 +7911,15 @@ function resolveCliSpawnPlan(options) {
|
|
|
7695
7911
|
const { spawn: spawnConfig } = provider;
|
|
7696
7912
|
const configuredCommand = typeof runtimeSettings.executablePath === "string" && runtimeSettings.executablePath.trim() ? runtimeSettings.executablePath.trim() : spawnConfig.command;
|
|
7697
7913
|
const binaryPath = findBinary(configuredCommand);
|
|
7698
|
-
const isWin =
|
|
7914
|
+
const isWin = os13.platform() === "win32";
|
|
7699
7915
|
const allArgs = [...spawnConfig.args, ...extraArgs].map(
|
|
7700
7916
|
(arg) => typeof arg === "string" ? arg.replace(/\{\{workingDir\}\}/g, workingDir) : arg
|
|
7701
7917
|
);
|
|
7702
7918
|
let shellCmd;
|
|
7703
7919
|
let shellArgs;
|
|
7704
|
-
const useShellUnix = !isWin && (!!spawnConfig.shell || !
|
|
7920
|
+
const useShellUnix = !isWin && (!!spawnConfig.shell || !path17.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
|
|
7705
7921
|
const isCmdShim = isWin && /\.(cmd|bat)$/i.test(binaryPath);
|
|
7706
|
-
const useShellWin = !!spawnConfig.shell || isCmdShim || !
|
|
7922
|
+
const useShellWin = !!spawnConfig.shell || isCmdShim || !path17.isAbsolute(binaryPath) || isScriptBinary(binaryPath);
|
|
7707
7923
|
const useShell = isWin ? useShellWin : useShellUnix;
|
|
7708
7924
|
if (useShell) {
|
|
7709
7925
|
shellCmd = isWin ? "cmd.exe" : process.env.SHELL || "/bin/zsh";
|
|
@@ -7779,12 +7995,12 @@ function respondToCliTerminalQueries(options) {
|
|
|
7779
7995
|
}
|
|
7780
7996
|
return "";
|
|
7781
7997
|
}
|
|
7782
|
-
var
|
|
7998
|
+
var os13, path17, import_session_host_core2;
|
|
7783
7999
|
var init_provider_cli_runtime = __esm({
|
|
7784
8000
|
"src/cli-adapters/provider-cli-runtime.ts"() {
|
|
7785
8001
|
"use strict";
|
|
7786
|
-
|
|
7787
|
-
|
|
8002
|
+
os13 = __toESM(require("os"));
|
|
8003
|
+
path17 = __toESM(require("path"));
|
|
7788
8004
|
import_session_host_core2 = require("@adhdev/session-host-core");
|
|
7789
8005
|
init_provider_cli_shared();
|
|
7790
8006
|
}
|
|
@@ -7805,11 +8021,11 @@ function appendBoundedText(current, chunk, maxChars) {
|
|
|
7805
8021
|
if (current.length <= keepFromCurrent) return current + chunk;
|
|
7806
8022
|
return current.slice(-keepFromCurrent) + chunk;
|
|
7807
8023
|
}
|
|
7808
|
-
var
|
|
8024
|
+
var os14, ProviderCliAdapter;
|
|
7809
8025
|
var init_provider_cli_adapter = __esm({
|
|
7810
8026
|
"src/cli-adapters/provider-cli-adapter.ts"() {
|
|
7811
8027
|
"use strict";
|
|
7812
|
-
|
|
8028
|
+
os14 = __toESM(require("os"));
|
|
7813
8029
|
init_logger();
|
|
7814
8030
|
init_debug_config();
|
|
7815
8031
|
init_terminal_screen();
|
|
@@ -7830,7 +8046,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
7830
8046
|
this.transportFactory = transportFactory;
|
|
7831
8047
|
this.cliType = provider.type;
|
|
7832
8048
|
this.cliName = provider.name;
|
|
7833
|
-
this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/,
|
|
8049
|
+
this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/, os14.homedir()) : workingDir;
|
|
7834
8050
|
const resolvedConfig = resolveCliAdapterConfig(provider);
|
|
7835
8051
|
this.timeouts = resolvedConfig.timeouts;
|
|
7836
8052
|
this.approvalKeys = resolvedConfig.approvalKeys;
|
|
@@ -9977,7 +10193,7 @@ __export(loader_exports, {
|
|
|
9977
10193
|
function loadSpec(sourcePath) {
|
|
9978
10194
|
let raw;
|
|
9979
10195
|
try {
|
|
9980
|
-
const text =
|
|
10196
|
+
const text = fs9.readFileSync(sourcePath, "utf8");
|
|
9981
10197
|
raw = JSON.parse(text);
|
|
9982
10198
|
} catch (err) {
|
|
9983
10199
|
return { ok: false, errors: [`Failed to read spec: ${err.message}`], sourcePath };
|
|
@@ -10053,14 +10269,14 @@ function compileRegex2(source, flags, where, errs) {
|
|
|
10053
10269
|
}
|
|
10054
10270
|
}
|
|
10055
10271
|
function resolveSpecPath(providerDir) {
|
|
10056
|
-
return
|
|
10272
|
+
return path18.join(providerDir, "spec.json");
|
|
10057
10273
|
}
|
|
10058
|
-
var
|
|
10274
|
+
var fs9, path18, import_ajv, ajv, validate;
|
|
10059
10275
|
var init_loader = __esm({
|
|
10060
10276
|
"src/providers/spec/loader.ts"() {
|
|
10061
10277
|
"use strict";
|
|
10062
|
-
|
|
10063
|
-
|
|
10278
|
+
fs9 = __toESM(require("fs"));
|
|
10279
|
+
path18 = __toESM(require("path"));
|
|
10064
10280
|
import_ajv = __toESM(require("ajv"));
|
|
10065
10281
|
init_schema_gen();
|
|
10066
10282
|
ajv = new import_ajv.default({ allErrors: true, strict: false });
|
|
@@ -10216,7 +10432,7 @@ function _getRegisteredRoots() {
|
|
|
10216
10432
|
}
|
|
10217
10433
|
function canonicalize(p) {
|
|
10218
10434
|
try {
|
|
10219
|
-
const resolved =
|
|
10435
|
+
const resolved = path24.resolve(p);
|
|
10220
10436
|
try {
|
|
10221
10437
|
return nodeFs.realpathSync.native ? nodeFs.realpathSync.native(resolved) : nodeFs.realpathSync(resolved);
|
|
10222
10438
|
} catch {
|
|
@@ -10236,7 +10452,7 @@ function isCallerInsideGatedRoot(callerFilename) {
|
|
|
10236
10452
|
}
|
|
10237
10453
|
for (const root of _gatedRoots) {
|
|
10238
10454
|
if (normalized === root.rootPath) return root;
|
|
10239
|
-
if (normalized.startsWith(root.rootPath +
|
|
10455
|
+
if (normalized.startsWith(root.rootPath + path24.sep)) return root;
|
|
10240
10456
|
}
|
|
10241
10457
|
return null;
|
|
10242
10458
|
}
|
|
@@ -10255,16 +10471,16 @@ function ensureInstalled() {
|
|
|
10255
10471
|
};
|
|
10256
10472
|
}
|
|
10257
10473
|
function gatedRequire(request, parent, isMain, gated, originalLoad) {
|
|
10258
|
-
if (request.startsWith("./") || request.startsWith("../") ||
|
|
10474
|
+
if (request.startsWith("./") || request.startsWith("../") || path24.isAbsolute(request)) {
|
|
10259
10475
|
let resolved;
|
|
10260
10476
|
try {
|
|
10261
|
-
const callerRequire = parent?.filename ? (0, import_node_module2.createRequire)(parent.filename) : (0, import_node_module2.createRequire)(
|
|
10477
|
+
const callerRequire = parent?.filename ? (0, import_node_module2.createRequire)(parent.filename) : (0, import_node_module2.createRequire)(path24.join(gated.rootPath, "__entry__.js"));
|
|
10262
10478
|
resolved = callerRequire.resolve(request);
|
|
10263
10479
|
} catch {
|
|
10264
10480
|
return originalLoad.call(this, request, parent, isMain);
|
|
10265
10481
|
}
|
|
10266
10482
|
const resolvedCanon = canonicalize(resolved) || resolved;
|
|
10267
|
-
if (!(resolvedCanon === gated.rootPath || resolvedCanon.startsWith(gated.rootPath +
|
|
10483
|
+
if (!(resolvedCanon === gated.rootPath || resolvedCanon.startsWith(gated.rootPath + path24.sep))) {
|
|
10268
10484
|
denyRequire(request, parent, `relative path escapes provider root (resolved to ${resolvedCanon})`);
|
|
10269
10485
|
}
|
|
10270
10486
|
return originalLoad.call(this, request, parent, isMain);
|
|
@@ -10288,11 +10504,11 @@ function denyRequire(request, parent, reason) {
|
|
|
10288
10504
|
err.callerFilename = caller;
|
|
10289
10505
|
throw err;
|
|
10290
10506
|
}
|
|
10291
|
-
var
|
|
10507
|
+
var path24, import_node_module2, nodeFs, nodeChildProcess, SAFE_STDLIB, SHIMMED_STDLIB, ALL_GATED_STDLIB, FS_READ_ONLY_MEMBERS, FS_PROMISES_READ_ONLY_MEMBERS, FS_SHIM, CHILD_PROCESS_SHIM, DANGEROUS_PROCESS_METHODS, _processGloballyHardened, _originalProcessMethods, PROCESS_SHIM, _gatedRoots, _installed, PROVIDER_REQUIRE_POLICY;
|
|
10292
10508
|
var init_require_whitelist = __esm({
|
|
10293
10509
|
"src/providers/sdk/v1/sandbox/require-whitelist.ts"() {
|
|
10294
10510
|
"use strict";
|
|
10295
|
-
|
|
10511
|
+
path24 = __toESM(require("path"));
|
|
10296
10512
|
import_node_module2 = require("module");
|
|
10297
10513
|
nodeFs = __toESM(require("fs"));
|
|
10298
10514
|
nodeChildProcess = __toESM(require("child_process"));
|
|
@@ -10402,7 +10618,7 @@ function executeJsonl(src, input) {
|
|
|
10402
10618
|
} else {
|
|
10403
10619
|
let stat2 = null;
|
|
10404
10620
|
try {
|
|
10405
|
-
stat2 =
|
|
10621
|
+
stat2 = fs13.statSync(resolved);
|
|
10406
10622
|
} catch {
|
|
10407
10623
|
return null;
|
|
10408
10624
|
}
|
|
@@ -10421,7 +10637,7 @@ function executeJsonl(src, input) {
|
|
|
10421
10637
|
const v = jsonPathGet(lines[0], src.session_id_path);
|
|
10422
10638
|
if (typeof v === "string" && v) providerSessionId = v;
|
|
10423
10639
|
} else if (src.session_id_from === "filename_uuid" || !src.session_id_from) {
|
|
10424
|
-
const m =
|
|
10640
|
+
const m = path25.basename(sourcePath).match(UUID_RE);
|
|
10425
10641
|
if (m) providerSessionId = m[1];
|
|
10426
10642
|
}
|
|
10427
10643
|
const requested = input.providerSessionId || "";
|
|
@@ -10446,7 +10662,7 @@ function executeJsonl(src, input) {
|
|
|
10446
10662
|
function readJsonlLines(p) {
|
|
10447
10663
|
let text;
|
|
10448
10664
|
try {
|
|
10449
|
-
text =
|
|
10665
|
+
text = fs13.readFileSync(p, "utf8");
|
|
10450
10666
|
} catch {
|
|
10451
10667
|
return [];
|
|
10452
10668
|
}
|
|
@@ -10463,7 +10679,7 @@ function readJsonlLines(p) {
|
|
|
10463
10679
|
}
|
|
10464
10680
|
function executeSqlite(src, input) {
|
|
10465
10681
|
const resolved = expandPath2(src.path, input);
|
|
10466
|
-
if (!resolved || !
|
|
10682
|
+
if (!resolved || !fs13.existsSync(resolved)) return null;
|
|
10467
10683
|
let Database;
|
|
10468
10684
|
try {
|
|
10469
10685
|
Database = require("better-sqlite3");
|
|
@@ -10522,19 +10738,19 @@ function expandPath2(template, input) {
|
|
|
10522
10738
|
if (!template) return null;
|
|
10523
10739
|
let out = template;
|
|
10524
10740
|
if (out.startsWith("~/") || out === "~") {
|
|
10525
|
-
out =
|
|
10741
|
+
out = path25.join(os18.homedir(), out.slice(2));
|
|
10526
10742
|
}
|
|
10527
10743
|
out = out.replace(/\$\{([A-Z_][A-Z0-9_]*)(?::-(.*?))?\}/g, (_m, name, fallback) => {
|
|
10528
10744
|
const v = input.envOverrides?.[name] ?? process.env[name];
|
|
10529
10745
|
return v != null && v !== "" ? v : fallback ?? "";
|
|
10530
10746
|
});
|
|
10531
|
-
if (out.startsWith("~/")) out =
|
|
10747
|
+
if (out.startsWith("~/")) out = path25.join(os18.homedir(), out.slice(2));
|
|
10532
10748
|
const now = /* @__PURE__ */ new Date();
|
|
10533
10749
|
const workspaceRaw = input.workspace ?? "";
|
|
10534
10750
|
let workspaceResolved = workspaceRaw;
|
|
10535
10751
|
if (workspaceRaw) {
|
|
10536
10752
|
try {
|
|
10537
|
-
workspaceResolved =
|
|
10753
|
+
workspaceResolved = fs13.realpathSync(workspaceRaw);
|
|
10538
10754
|
} catch {
|
|
10539
10755
|
}
|
|
10540
10756
|
}
|
|
@@ -10576,20 +10792,20 @@ function expandDirGlob(template) {
|
|
|
10576
10792
|
for (const d of dirs) {
|
|
10577
10793
|
let entries;
|
|
10578
10794
|
try {
|
|
10579
|
-
entries =
|
|
10795
|
+
entries = fs13.readdirSync(d, { withFileTypes: true });
|
|
10580
10796
|
} catch {
|
|
10581
10797
|
continue;
|
|
10582
10798
|
}
|
|
10583
10799
|
for (const e of entries) {
|
|
10584
|
-
if (e.isDirectory() && re.test(e.name)) next.push(
|
|
10800
|
+
if (e.isDirectory() && re.test(e.name)) next.push(path25.join(d, e.name));
|
|
10585
10801
|
}
|
|
10586
10802
|
}
|
|
10587
10803
|
} else {
|
|
10588
10804
|
for (const d of dirs) {
|
|
10589
|
-
const candidate =
|
|
10805
|
+
const candidate = path25.join(d, seg);
|
|
10590
10806
|
let stat2 = null;
|
|
10591
10807
|
try {
|
|
10592
|
-
stat2 =
|
|
10808
|
+
stat2 = fs13.statSync(candidate);
|
|
10593
10809
|
} catch {
|
|
10594
10810
|
continue;
|
|
10595
10811
|
}
|
|
@@ -10603,13 +10819,13 @@ function expandDirGlob(template) {
|
|
|
10603
10819
|
function walkAllDirs(root, out) {
|
|
10604
10820
|
let entries;
|
|
10605
10821
|
try {
|
|
10606
|
-
entries =
|
|
10822
|
+
entries = fs13.readdirSync(root, { withFileTypes: true });
|
|
10607
10823
|
} catch {
|
|
10608
10824
|
return;
|
|
10609
10825
|
}
|
|
10610
10826
|
out.push(root);
|
|
10611
10827
|
for (const e of entries) {
|
|
10612
|
-
if (e.isDirectory()) walkAllDirs(
|
|
10828
|
+
if (e.isDirectory()) walkAllDirs(path25.join(root, e.name), out);
|
|
10613
10829
|
}
|
|
10614
10830
|
}
|
|
10615
10831
|
function newestRecentFileAcrossGlob(template, pattern, windowMs, sessionFloorMs = 0) {
|
|
@@ -10619,13 +10835,13 @@ function newestRecentFileAcrossGlob(template, pattern, windowMs, sessionFloorMs
|
|
|
10619
10835
|
for (const d of dirs) {
|
|
10620
10836
|
let entries;
|
|
10621
10837
|
try {
|
|
10622
|
-
entries =
|
|
10838
|
+
entries = fs13.readdirSync(d, { withFileTypes: true });
|
|
10623
10839
|
} catch {
|
|
10624
10840
|
continue;
|
|
10625
10841
|
}
|
|
10626
10842
|
for (const e of entries) {
|
|
10627
10843
|
if (!e.isFile() || !pattern.test(e.name)) continue;
|
|
10628
|
-
const p =
|
|
10844
|
+
const p = path25.join(d, e.name);
|
|
10629
10845
|
const mtime = safeMtimeMs(p);
|
|
10630
10846
|
if (mtime < cutoff) continue;
|
|
10631
10847
|
if (!best || mtime > best.mtime) best = { p, mtime };
|
|
@@ -10636,7 +10852,7 @@ function newestRecentFileAcrossGlob(template, pattern, windowMs, sessionFloorMs
|
|
|
10636
10852
|
function newestRecentFile(dir, pattern, windowMs, sessionFloorMs = 0) {
|
|
10637
10853
|
let entries;
|
|
10638
10854
|
try {
|
|
10639
|
-
entries =
|
|
10855
|
+
entries = fs13.readdirSync(dir, { withFileTypes: true });
|
|
10640
10856
|
} catch {
|
|
10641
10857
|
return null;
|
|
10642
10858
|
}
|
|
@@ -10644,7 +10860,7 @@ function newestRecentFile(dir, pattern, windowMs, sessionFloorMs = 0) {
|
|
|
10644
10860
|
let best = null;
|
|
10645
10861
|
for (const e of entries) {
|
|
10646
10862
|
if (!e.isFile() || !pattern.test(e.name)) continue;
|
|
10647
|
-
const p =
|
|
10863
|
+
const p = path25.join(dir, e.name);
|
|
10648
10864
|
const mtime = safeMtimeMs(p);
|
|
10649
10865
|
if (mtime < cutoff) continue;
|
|
10650
10866
|
if (!best || mtime > best.mtime) best = { p, mtime };
|
|
@@ -10653,7 +10869,7 @@ function newestRecentFile(dir, pattern, windowMs, sessionFloorMs = 0) {
|
|
|
10653
10869
|
}
|
|
10654
10870
|
function safeMtimeMs(p) {
|
|
10655
10871
|
try {
|
|
10656
|
-
return Math.floor(
|
|
10872
|
+
return Math.floor(fs13.statSync(p).mtimeMs);
|
|
10657
10873
|
} catch {
|
|
10658
10874
|
return 0;
|
|
10659
10875
|
}
|
|
@@ -10857,13 +11073,13 @@ function evalTerm(t, record) {
|
|
|
10857
11073
|
}
|
|
10858
11074
|
return t.negate ? !result : result;
|
|
10859
11075
|
}
|
|
10860
|
-
var
|
|
11076
|
+
var fs13, os18, path25, UUID_RE;
|
|
10861
11077
|
var init_native_history_executor = __esm({
|
|
10862
11078
|
"src/providers/spec/native-history-executor.ts"() {
|
|
10863
11079
|
"use strict";
|
|
10864
|
-
|
|
10865
|
-
|
|
10866
|
-
|
|
11080
|
+
fs13 = __toESM(require("fs"));
|
|
11081
|
+
os18 = __toESM(require("os"));
|
|
11082
|
+
path25 = __toESM(require("path"));
|
|
10867
11083
|
UUID_RE = /([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i;
|
|
10868
11084
|
}
|
|
10869
11085
|
});
|
|
@@ -10881,7 +11097,7 @@ function extractTimestampValue(value) {
|
|
|
10881
11097
|
}
|
|
10882
11098
|
function statMtimeMs(filePath) {
|
|
10883
11099
|
try {
|
|
10884
|
-
return
|
|
11100
|
+
return fs14.statSync(filePath).mtimeMs;
|
|
10885
11101
|
} catch {
|
|
10886
11102
|
return 0;
|
|
10887
11103
|
}
|
|
@@ -10951,7 +11167,7 @@ function extractUserContentParts(content) {
|
|
|
10951
11167
|
function parseTranscriptFile(filePath, sessionId, workspaceFallback) {
|
|
10952
11168
|
let raw;
|
|
10953
11169
|
try {
|
|
10954
|
-
raw =
|
|
11170
|
+
raw = fs14.readFileSync(filePath, "utf-8");
|
|
10955
11171
|
} catch {
|
|
10956
11172
|
return [];
|
|
10957
11173
|
}
|
|
@@ -11024,10 +11240,10 @@ function parseTranscriptFile(filePath, sessionId, workspaceFallback) {
|
|
|
11024
11240
|
return records;
|
|
11025
11241
|
}
|
|
11026
11242
|
function readSession(sessionPath) {
|
|
11027
|
-
if (!sessionPath || !
|
|
11028
|
-
const basename12 =
|
|
11243
|
+
if (!sessionPath || !path26.isAbsolute(sessionPath)) return null;
|
|
11244
|
+
const basename12 = path26.basename(sessionPath, ".jsonl");
|
|
11029
11245
|
if (!isSafeSessionId(basename12)) return null;
|
|
11030
|
-
if (!
|
|
11246
|
+
if (!fs14.existsSync(sessionPath)) return null;
|
|
11031
11247
|
const sourceMtimeMs = statMtimeMs(sessionPath);
|
|
11032
11248
|
const messages = parseTranscriptFile(sessionPath, basename12);
|
|
11033
11249
|
if (messages.length === 0) return null;
|
|
@@ -11043,12 +11259,12 @@ function readSession(sessionPath) {
|
|
|
11043
11259
|
workspace
|
|
11044
11260
|
};
|
|
11045
11261
|
}
|
|
11046
|
-
var
|
|
11262
|
+
var fs14, path26;
|
|
11047
11263
|
var init_claude_cli_transcript = __esm({
|
|
11048
11264
|
"src/providers/native-history/claude-cli-transcript.ts"() {
|
|
11049
11265
|
"use strict";
|
|
11050
|
-
|
|
11051
|
-
|
|
11266
|
+
fs14 = __toESM(require("fs"));
|
|
11267
|
+
path26 = __toESM(require("path"));
|
|
11052
11268
|
}
|
|
11053
11269
|
});
|
|
11054
11270
|
|
|
@@ -11065,7 +11281,7 @@ function extractTimestampValue2(value) {
|
|
|
11065
11281
|
}
|
|
11066
11282
|
function statMtimeMs2(filePath) {
|
|
11067
11283
|
try {
|
|
11068
|
-
return
|
|
11284
|
+
return fs15.statSync(filePath).mtimeMs;
|
|
11069
11285
|
} catch {
|
|
11070
11286
|
return 0;
|
|
11071
11287
|
}
|
|
@@ -11133,7 +11349,7 @@ function extractToolOutputContent(payload) {
|
|
|
11133
11349
|
}
|
|
11134
11350
|
function readSessionMeta(filePath) {
|
|
11135
11351
|
try {
|
|
11136
|
-
const firstLine =
|
|
11352
|
+
const firstLine = fs15.readFileSync(filePath, "utf-8").split("\n").find(Boolean);
|
|
11137
11353
|
if (!firstLine) return null;
|
|
11138
11354
|
const parsed = JSON.parse(firstLine);
|
|
11139
11355
|
if (String(parsed.type ?? "") !== "session_meta") return null;
|
|
@@ -11145,7 +11361,7 @@ function readSessionMeta(filePath) {
|
|
|
11145
11361
|
function parseSessionFile(filePath, sessionId, workspaceFallback) {
|
|
11146
11362
|
let raw;
|
|
11147
11363
|
try {
|
|
11148
|
-
raw =
|
|
11364
|
+
raw = fs15.readFileSync(filePath, "utf-8");
|
|
11149
11365
|
} catch {
|
|
11150
11366
|
return [];
|
|
11151
11367
|
}
|
|
@@ -11239,11 +11455,11 @@ function parseSessionFile(filePath, sessionId, workspaceFallback) {
|
|
|
11239
11455
|
return records;
|
|
11240
11456
|
}
|
|
11241
11457
|
function readSession2(sessionPath) {
|
|
11242
|
-
if (!sessionPath || !
|
|
11243
|
-
if (!
|
|
11458
|
+
if (!sessionPath || !path27.isAbsolute(sessionPath)) return null;
|
|
11459
|
+
if (!fs15.existsSync(sessionPath)) return null;
|
|
11244
11460
|
const meta = readSessionMeta(sessionPath);
|
|
11245
11461
|
const metaId = String(meta?.id ?? "").trim();
|
|
11246
|
-
const basename12 =
|
|
11462
|
+
const basename12 = path27.basename(sessionPath, ".jsonl");
|
|
11247
11463
|
const uuidMatch = basename12.match(/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i);
|
|
11248
11464
|
const filenameUuid = uuidMatch ? uuidMatch[1] : "";
|
|
11249
11465
|
if (metaId && filenameUuid && metaId !== filenameUuid) return null;
|
|
@@ -11265,12 +11481,12 @@ function readSession2(sessionPath) {
|
|
|
11265
11481
|
workspace
|
|
11266
11482
|
};
|
|
11267
11483
|
}
|
|
11268
|
-
var
|
|
11484
|
+
var fs15, path27;
|
|
11269
11485
|
var init_codex_cli_transcript = __esm({
|
|
11270
11486
|
"src/providers/native-history/codex-cli-transcript.ts"() {
|
|
11271
11487
|
"use strict";
|
|
11272
|
-
|
|
11273
|
-
|
|
11488
|
+
fs15 = __toESM(require("fs"));
|
|
11489
|
+
path27 = __toESM(require("path"));
|
|
11274
11490
|
}
|
|
11275
11491
|
});
|
|
11276
11492
|
|
|
@@ -11287,7 +11503,7 @@ function extractTimestampValue3(value) {
|
|
|
11287
11503
|
}
|
|
11288
11504
|
function statMtimeMs3(filePath) {
|
|
11289
11505
|
try {
|
|
11290
|
-
return
|
|
11506
|
+
return fs16.statSync(filePath).mtimeMs;
|
|
11291
11507
|
} catch {
|
|
11292
11508
|
return 0;
|
|
11293
11509
|
}
|
|
@@ -11296,13 +11512,13 @@ function isUuidLike(value) {
|
|
|
11296
11512
|
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
|
|
11297
11513
|
}
|
|
11298
11514
|
function antigravityRoot() {
|
|
11299
|
-
return
|
|
11515
|
+
return path28.join(os19.homedir(), ".gemini", "antigravity-cli");
|
|
11300
11516
|
}
|
|
11301
11517
|
function historyJsonlPath() {
|
|
11302
|
-
return
|
|
11518
|
+
return path28.join(antigravityRoot(), "history.jsonl");
|
|
11303
11519
|
}
|
|
11304
11520
|
function brainRoot() {
|
|
11305
|
-
return
|
|
11521
|
+
return path28.join(antigravityRoot(), "brain");
|
|
11306
11522
|
}
|
|
11307
11523
|
function extractUserRequestContent(content) {
|
|
11308
11524
|
const raw = content.trim();
|
|
@@ -11318,7 +11534,7 @@ function antigravityRowKind(rowType) {
|
|
|
11318
11534
|
function parseBrainTranscript(filePath, sessionId, workspace) {
|
|
11319
11535
|
let raw;
|
|
11320
11536
|
try {
|
|
11321
|
-
raw =
|
|
11537
|
+
raw = fs16.readFileSync(filePath, "utf-8");
|
|
11322
11538
|
} catch {
|
|
11323
11539
|
return null;
|
|
11324
11540
|
}
|
|
@@ -11378,7 +11594,7 @@ function readHistoryRows() {
|
|
|
11378
11594
|
const sourcePath = historyJsonlPath();
|
|
11379
11595
|
let lines = [];
|
|
11380
11596
|
try {
|
|
11381
|
-
lines =
|
|
11597
|
+
lines = fs16.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
|
|
11382
11598
|
} catch {
|
|
11383
11599
|
return [];
|
|
11384
11600
|
}
|
|
@@ -11425,7 +11641,7 @@ function extractStringsFromBuffer(buf) {
|
|
|
11425
11641
|
function parsePbFile(filePath, sessionId) {
|
|
11426
11642
|
let buf;
|
|
11427
11643
|
try {
|
|
11428
|
-
buf =
|
|
11644
|
+
buf = fs16.readFileSync(filePath);
|
|
11429
11645
|
} catch {
|
|
11430
11646
|
return null;
|
|
11431
11647
|
}
|
|
@@ -11448,13 +11664,13 @@ function parsePbFile(filePath, sessionId) {
|
|
|
11448
11664
|
];
|
|
11449
11665
|
}
|
|
11450
11666
|
function readSession3(sessionPath, sessionId, workspace) {
|
|
11451
|
-
if (!sessionPath || !
|
|
11452
|
-
if (!
|
|
11667
|
+
if (!sessionPath || !path28.isAbsolute(sessionPath)) return null;
|
|
11668
|
+
if (!fs16.existsSync(sessionPath)) return null;
|
|
11453
11669
|
const sourceMtimeMs = statMtimeMs3(sessionPath);
|
|
11454
11670
|
const brainRootPath = brainRoot();
|
|
11455
|
-
if (sessionPath.startsWith(brainRootPath +
|
|
11456
|
-
const
|
|
11457
|
-
const uuidFromPath =
|
|
11671
|
+
if (sessionPath.startsWith(brainRootPath + path28.sep) && sessionPath.endsWith(".jsonl")) {
|
|
11672
|
+
const relative5 = sessionPath.slice(brainRootPath.length + 1);
|
|
11673
|
+
const uuidFromPath = relative5.split(path28.sep)[0];
|
|
11458
11674
|
const resolvedSessionId = sessionId || (isUuidLike(uuidFromPath) ? uuidFromPath : "");
|
|
11459
11675
|
if (!resolvedSessionId) return null;
|
|
11460
11676
|
const messages = parseBrainTranscript(sessionPath, resolvedSessionId, workspace);
|
|
@@ -11470,7 +11686,7 @@ function readSession3(sessionPath, sessionId, workspace) {
|
|
|
11470
11686
|
};
|
|
11471
11687
|
}
|
|
11472
11688
|
if (sessionPath.endsWith(".pb")) {
|
|
11473
|
-
const pbSessionId = sessionId ||
|
|
11689
|
+
const pbSessionId = sessionId || path28.basename(sessionPath, ".pb");
|
|
11474
11690
|
if (!isUuidLike(pbSessionId)) return null;
|
|
11475
11691
|
const messages = parsePbFile(sessionPath, pbSessionId);
|
|
11476
11692
|
if (!messages || messages.length === 0) return null;
|
|
@@ -11484,7 +11700,7 @@ function readSession3(sessionPath, sessionId, workspace) {
|
|
|
11484
11700
|
partialReason: "antigravity_cli_pb_raw_text_extraction"
|
|
11485
11701
|
};
|
|
11486
11702
|
}
|
|
11487
|
-
if (
|
|
11703
|
+
if (path28.basename(sessionPath) === "history.jsonl") {
|
|
11488
11704
|
const resolvedSessionId = sessionId || "";
|
|
11489
11705
|
if (!resolvedSessionId || !isUuidLike(resolvedSessionId)) return null;
|
|
11490
11706
|
const rows = readHistoryRows().filter((r) => r.conversationId === resolvedSessionId);
|
|
@@ -11529,13 +11745,13 @@ function readSession3(sessionPath, sessionId, workspace) {
|
|
|
11529
11745
|
}
|
|
11530
11746
|
return null;
|
|
11531
11747
|
}
|
|
11532
|
-
var
|
|
11748
|
+
var fs16, path28, os19, MIN_PRINTABLE_RUN;
|
|
11533
11749
|
var init_antigravity_cli_transcript = __esm({
|
|
11534
11750
|
"src/providers/native-history/antigravity-cli-transcript.ts"() {
|
|
11535
11751
|
"use strict";
|
|
11536
|
-
|
|
11537
|
-
|
|
11538
|
-
|
|
11752
|
+
fs16 = __toESM(require("fs"));
|
|
11753
|
+
path28 = __toESM(require("path"));
|
|
11754
|
+
os19 = __toESM(require("os"));
|
|
11539
11755
|
MIN_PRINTABLE_RUN = 8;
|
|
11540
11756
|
}
|
|
11541
11757
|
});
|
|
@@ -11543,13 +11759,13 @@ var init_antigravity_cli_transcript = __esm({
|
|
|
11543
11759
|
// src/providers/native-history/hermes-cli-transcript.ts
|
|
11544
11760
|
function statMtimeMs4(p) {
|
|
11545
11761
|
try {
|
|
11546
|
-
return Math.floor(
|
|
11762
|
+
return Math.floor(fs17.statSync(p).mtimeMs);
|
|
11547
11763
|
} catch {
|
|
11548
11764
|
return 0;
|
|
11549
11765
|
}
|
|
11550
11766
|
}
|
|
11551
11767
|
function openDb() {
|
|
11552
|
-
if (!
|
|
11768
|
+
if (!fs17.existsSync(HERMES_STATE_DB)) return null;
|
|
11553
11769
|
try {
|
|
11554
11770
|
const Database = require("better-sqlite3");
|
|
11555
11771
|
return new Database(HERMES_STATE_DB, { readonly: true, fileMustExist: true });
|
|
@@ -11606,10 +11822,10 @@ function readSession4(sessionPath) {
|
|
|
11606
11822
|
}
|
|
11607
11823
|
}
|
|
11608
11824
|
}
|
|
11609
|
-
if (!
|
|
11825
|
+
if (!path29.isAbsolute(sessionPath) || !fs17.existsSync(sessionPath)) return null;
|
|
11610
11826
|
let raw;
|
|
11611
11827
|
try {
|
|
11612
|
-
raw = JSON.parse(
|
|
11828
|
+
raw = JSON.parse(fs17.readFileSync(sessionPath, "utf8"));
|
|
11613
11829
|
} catch {
|
|
11614
11830
|
return null;
|
|
11615
11831
|
}
|
|
@@ -11632,7 +11848,7 @@ function readSession4(sessionPath) {
|
|
|
11632
11848
|
});
|
|
11633
11849
|
}
|
|
11634
11850
|
if (messages.length === 0) return null;
|
|
11635
|
-
const sessionId = typeof raw.session_id === "string" && raw.session_id ? raw.session_id :
|
|
11851
|
+
const sessionId = typeof raw.session_id === "string" && raw.session_id ? raw.session_id : path29.basename(sessionPath, ".json").replace(/^session_/, "");
|
|
11636
11852
|
return {
|
|
11637
11853
|
messages,
|
|
11638
11854
|
providerSessionId: sessionId,
|
|
@@ -11649,15 +11865,15 @@ function normalizeHermesRole(r) {
|
|
|
11649
11865
|
if (s === "tool" || s === "tool_result" || s === "function") return "assistant";
|
|
11650
11866
|
return "system";
|
|
11651
11867
|
}
|
|
11652
|
-
var
|
|
11868
|
+
var fs17, path29, os20, HERMES_STATE_DB, HERMES_LEGACY_SESSIONS_DIR;
|
|
11653
11869
|
var init_hermes_cli_transcript = __esm({
|
|
11654
11870
|
"src/providers/native-history/hermes-cli-transcript.ts"() {
|
|
11655
11871
|
"use strict";
|
|
11656
|
-
|
|
11657
|
-
|
|
11658
|
-
|
|
11659
|
-
HERMES_STATE_DB =
|
|
11660
|
-
HERMES_LEGACY_SESSIONS_DIR =
|
|
11872
|
+
fs17 = __toESM(require("fs"));
|
|
11873
|
+
path29 = __toESM(require("path"));
|
|
11874
|
+
os20 = __toESM(require("os"));
|
|
11875
|
+
HERMES_STATE_DB = path29.join(os20.homedir(), ".hermes", "state.db");
|
|
11876
|
+
HERMES_LEGACY_SESSIONS_DIR = path29.join(os20.homedir(), ".hermes", "sessions");
|
|
11661
11877
|
}
|
|
11662
11878
|
});
|
|
11663
11879
|
|
|
@@ -11705,26 +11921,26 @@ function resolveSourcePath(reader, workspace, sessionId) {
|
|
|
11705
11921
|
}
|
|
11706
11922
|
}
|
|
11707
11923
|
function resolveClaudePath(workspace, sessionId) {
|
|
11708
|
-
const dir =
|
|
11709
|
-
if (!
|
|
11924
|
+
const dir = path30.join(os21.homedir(), ".claude", "projects", cwdAsDashes(workspace));
|
|
11925
|
+
if (!fs18.existsSync(dir)) return null;
|
|
11710
11926
|
if (sessionId) {
|
|
11711
|
-
const candidate =
|
|
11712
|
-
if (
|
|
11927
|
+
const candidate = path30.join(dir, `${sessionId}.jsonl`);
|
|
11928
|
+
if (fs18.existsSync(candidate)) return candidate;
|
|
11713
11929
|
}
|
|
11714
11930
|
return null;
|
|
11715
11931
|
}
|
|
11716
11932
|
function resolveCodexPath(workspace) {
|
|
11717
11933
|
void workspace;
|
|
11718
11934
|
const now = /* @__PURE__ */ new Date();
|
|
11719
|
-
const dir =
|
|
11720
|
-
|
|
11935
|
+
const dir = path30.join(
|
|
11936
|
+
os21.homedir(),
|
|
11721
11937
|
".codex",
|
|
11722
11938
|
"sessions",
|
|
11723
11939
|
String(now.getUTCFullYear()),
|
|
11724
11940
|
String(now.getUTCMonth() + 1).padStart(2, "0"),
|
|
11725
11941
|
String(now.getUTCDate()).padStart(2, "0")
|
|
11726
11942
|
);
|
|
11727
|
-
if (
|
|
11943
|
+
if (fs18.existsSync(dir)) {
|
|
11728
11944
|
const f = newestRecentFile2(dir, /\.jsonl$/);
|
|
11729
11945
|
if (f) return f;
|
|
11730
11946
|
}
|
|
@@ -11732,23 +11948,23 @@ function resolveCodexPath(workspace) {
|
|
|
11732
11948
|
}
|
|
11733
11949
|
function resolveAntigravityPath(workspace) {
|
|
11734
11950
|
void workspace;
|
|
11735
|
-
const brainRoot2 =
|
|
11736
|
-
if (!
|
|
11951
|
+
const brainRoot2 = path30.join(os21.homedir(), ".gemini", "antigravity-cli", "brain");
|
|
11952
|
+
if (!fs18.existsSync(brainRoot2)) return null;
|
|
11737
11953
|
const cutoff = Date.now() - RECENT_WINDOW_MS;
|
|
11738
|
-
const entries =
|
|
11954
|
+
const entries = fs18.readdirSync(brainRoot2, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => ({ p: path30.join(brainRoot2, e.name), mtime: safeMtime(path30.join(brainRoot2, e.name)) })).filter((e) => e.mtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
11739
11955
|
for (const e of entries) {
|
|
11740
|
-
const t =
|
|
11741
|
-
if (
|
|
11956
|
+
const t = path30.join(e.p, ".system_generated", "logs", "transcript.jsonl");
|
|
11957
|
+
if (fs18.existsSync(t)) return t;
|
|
11742
11958
|
}
|
|
11743
11959
|
return null;
|
|
11744
11960
|
}
|
|
11745
11961
|
function resolveHermesPath(workspace, sessionId) {
|
|
11746
11962
|
void workspace;
|
|
11747
11963
|
void sessionId;
|
|
11748
|
-
const dbPath =
|
|
11749
|
-
if (
|
|
11750
|
-
const dir =
|
|
11751
|
-
if (!
|
|
11964
|
+
const dbPath = path30.join(os21.homedir(), ".hermes", "state.db");
|
|
11965
|
+
if (fs18.existsSync(dbPath)) return dbPath;
|
|
11966
|
+
const dir = path30.join(os21.homedir(), ".hermes", "sessions");
|
|
11967
|
+
if (!fs18.existsSync(dir)) return null;
|
|
11752
11968
|
return newestRecentFile2(dir, /^session_.*\.json$/);
|
|
11753
11969
|
}
|
|
11754
11970
|
function readByReader(reader, sourcePath, sessionId, workspace) {
|
|
@@ -11770,7 +11986,7 @@ function cwdAsDashes(cwd) {
|
|
|
11770
11986
|
function newestRecentFile2(dir, pattern) {
|
|
11771
11987
|
try {
|
|
11772
11988
|
const cutoff = Date.now() - RECENT_WINDOW_MS;
|
|
11773
|
-
const entries =
|
|
11989
|
+
const entries = fs18.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && pattern.test(e.name)).map((e) => ({ p: path30.join(dir, e.name), mtime: safeMtime(path30.join(dir, e.name)) })).filter((e) => e.mtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
11774
11990
|
return entries[0]?.p ?? null;
|
|
11775
11991
|
} catch {
|
|
11776
11992
|
return null;
|
|
@@ -11778,7 +11994,7 @@ function newestRecentFile2(dir, pattern) {
|
|
|
11778
11994
|
}
|
|
11779
11995
|
function safeMtime(p) {
|
|
11780
11996
|
try {
|
|
11781
|
-
return Math.floor(
|
|
11997
|
+
return Math.floor(fs18.statSync(p).mtimeMs);
|
|
11782
11998
|
} catch {
|
|
11783
11999
|
return 0;
|
|
11784
12000
|
}
|
|
@@ -11790,13 +12006,13 @@ function normalizeRole2(r) {
|
|
|
11790
12006
|
if (s === "tool" || s === "tool_result" || s === "function") return "assistant";
|
|
11791
12007
|
return "system";
|
|
11792
12008
|
}
|
|
11793
|
-
var
|
|
12009
|
+
var fs18, os21, path30, RECENT_WINDOW_MS;
|
|
11794
12010
|
var init_dispatcher = __esm({
|
|
11795
12011
|
"src/providers/native-history/dispatcher.ts"() {
|
|
11796
12012
|
"use strict";
|
|
11797
|
-
|
|
11798
|
-
|
|
11799
|
-
|
|
12013
|
+
fs18 = __toESM(require("fs"));
|
|
12014
|
+
os21 = __toESM(require("os"));
|
|
12015
|
+
path30 = __toESM(require("path"));
|
|
11800
12016
|
init_claude_cli_transcript();
|
|
11801
12017
|
init_codex_cli_transcript();
|
|
11802
12018
|
init_antigravity_cli_transcript();
|
|
@@ -12339,12 +12555,12 @@ function parseSubmoduleStatusOutput(output, repoRoot, ignorePaths) {
|
|
|
12339
12555
|
if (!match) continue;
|
|
12340
12556
|
const prefix = match[1];
|
|
12341
12557
|
const commit = match[2];
|
|
12342
|
-
const
|
|
12343
|
-
if (ignoreSet.has(
|
|
12558
|
+
const path40 = match[3];
|
|
12559
|
+
if (ignoreSet.has(path40)) continue;
|
|
12344
12560
|
submodules.push({
|
|
12345
|
-
path:
|
|
12561
|
+
path: path40,
|
|
12346
12562
|
commit,
|
|
12347
|
-
repoPath: repoRoot + "/" +
|
|
12563
|
+
repoPath: repoRoot + "/" + path40,
|
|
12348
12564
|
dirty: prefix === "+",
|
|
12349
12565
|
outOfSync: prefix === "-",
|
|
12350
12566
|
lastCheckedAt: Date.now()
|
|
@@ -13848,10 +14064,10 @@ function getRegistryPath() {
|
|
|
13848
14064
|
return (0, import_path3.join)(getDaemonDataDir(), "mesh-coordinators.json");
|
|
13849
14065
|
}
|
|
13850
14066
|
function loadMeshCoordinatorRegistry() {
|
|
13851
|
-
const
|
|
13852
|
-
if (!(0, import_fs3.existsSync)(
|
|
14067
|
+
const path40 = getRegistryPath();
|
|
14068
|
+
if (!(0, import_fs3.existsSync)(path40)) return;
|
|
13853
14069
|
try {
|
|
13854
|
-
const raw = JSON.parse((0, import_fs3.readFileSync)(
|
|
14070
|
+
const raw = JSON.parse((0, import_fs3.readFileSync)(path40, "utf-8"));
|
|
13855
14071
|
if (!Array.isArray(raw)) return;
|
|
13856
14072
|
_registry.clear();
|
|
13857
14073
|
for (const entry of raw) {
|
|
@@ -14070,8 +14286,8 @@ function validateMeshRefineConfig(config, source = "inline") {
|
|
|
14070
14286
|
if (rejectedCommands.length) errors.push("one or more validation commands are invalid");
|
|
14071
14287
|
return { valid: errors.length === 0, errors, bootstrapCommands, commands, rejectedCommands };
|
|
14072
14288
|
}
|
|
14073
|
-
function parseConfigText(
|
|
14074
|
-
if (/\.json$/i.test(
|
|
14289
|
+
function parseConfigText(path40, text) {
|
|
14290
|
+
if (/\.json$/i.test(path40)) return JSON.parse(text);
|
|
14075
14291
|
return yaml.load(text);
|
|
14076
14292
|
}
|
|
14077
14293
|
function loadMeshRefineConfig(mesh, workspace) {
|
|
@@ -14082,16 +14298,16 @@ function loadMeshRefineConfig(mesh, workspace) {
|
|
|
14082
14298
|
if (!validation.valid) return { source: "mesh.policy.refineConfig", sourceType: "invalid", error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
14083
14299
|
return { config: inline, source: "mesh.policy.refineConfig", sourceType: "mesh_policy" };
|
|
14084
14300
|
}
|
|
14085
|
-
for (const
|
|
14086
|
-
const configPath = (0, import_path4.join)(workspace,
|
|
14301
|
+
for (const relative5 of MESH_REFINE_CONFIG_LOCATIONS) {
|
|
14302
|
+
const configPath = (0, import_path4.join)(workspace, relative5);
|
|
14087
14303
|
if (!(0, import_fs4.existsSync)(configPath)) continue;
|
|
14088
14304
|
try {
|
|
14089
14305
|
const parsed = parseConfigText(configPath, (0, import_fs4.readFileSync)(configPath, "utf-8"));
|
|
14090
|
-
const validation = validateMeshRefineConfig(parsed,
|
|
14091
|
-
if (!validation.valid) return { source:
|
|
14092
|
-
return { config: parsed, source:
|
|
14306
|
+
const validation = validateMeshRefineConfig(parsed, relative5);
|
|
14307
|
+
if (!validation.valid) return { source: relative5, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
14308
|
+
return { config: parsed, source: relative5, sourceType: "repo_file", path: configPath };
|
|
14093
14309
|
} catch (error) {
|
|
14094
|
-
return { source:
|
|
14310
|
+
return { source: relative5, sourceType: "invalid", path: configPath, error: error?.message || String(error) };
|
|
14095
14311
|
}
|
|
14096
14312
|
}
|
|
14097
14313
|
return {
|
|
@@ -14224,8 +14440,8 @@ var MESH_WORKTREE_BOOTSTRAP_CONFIG_SCHEMA = {
|
|
|
14224
14440
|
var DEFAULT_TIMEOUT_MS2 = 12e4;
|
|
14225
14441
|
var DEFAULT_OUTPUT_LIMIT_BYTES = 128 * 1024;
|
|
14226
14442
|
var OUTPUT_SUMMARY_CHARS = 2e3;
|
|
14227
|
-
function parseConfigText2(
|
|
14228
|
-
if (/\.json$/i.test(
|
|
14443
|
+
function parseConfigText2(path40, text) {
|
|
14444
|
+
if (/\.json$/i.test(path40)) return JSON.parse(text);
|
|
14229
14445
|
return yaml2.load(text);
|
|
14230
14446
|
}
|
|
14231
14447
|
function truncateOutput(value) {
|
|
@@ -14265,16 +14481,16 @@ function loadMeshWorktreeBootstrapConfig(mesh, workspace) {
|
|
|
14265
14481
|
if (!validation.valid) return { source: "mesh.policy.worktreeBootstrapConfig", sourceType: "invalid", error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
14266
14482
|
return { config: inline, source: "mesh.policy.worktreeBootstrapConfig", sourceType: "mesh_policy" };
|
|
14267
14483
|
}
|
|
14268
|
-
for (const
|
|
14269
|
-
const configPath = (0, import_path5.join)(workspace,
|
|
14484
|
+
for (const relative5 of MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS) {
|
|
14485
|
+
const configPath = (0, import_path5.join)(workspace, relative5);
|
|
14270
14486
|
if (!(0, import_fs5.existsSync)(configPath)) continue;
|
|
14271
14487
|
try {
|
|
14272
14488
|
const parsed = parseConfigText2(configPath, (0, import_fs5.readFileSync)(configPath, "utf-8"));
|
|
14273
|
-
const validation = validateMeshWorktreeBootstrapConfig(parsed,
|
|
14274
|
-
if (!validation.valid) return { source:
|
|
14275
|
-
return { config: parsed, source:
|
|
14489
|
+
const validation = validateMeshWorktreeBootstrapConfig(parsed, relative5);
|
|
14490
|
+
if (!validation.valid) return { source: relative5, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
14491
|
+
return { config: parsed, source: relative5, sourceType: "repo_file", path: configPath };
|
|
14276
14492
|
} catch (error) {
|
|
14277
|
-
return { source:
|
|
14493
|
+
return { source: relative5, sourceType: "invalid", path: configPath, error: error?.message || String(error) };
|
|
14278
14494
|
}
|
|
14279
14495
|
}
|
|
14280
14496
|
return { source: "unavailable", sourceType: "unavailable", error: `No worktree bootstrap config found. Checked: ${MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS.join(", ")}` };
|
|
@@ -15515,17 +15731,17 @@ function checkPathExists(paths) {
|
|
|
15515
15731
|
return null;
|
|
15516
15732
|
}
|
|
15517
15733
|
async function detectIDEs(providerLoader) {
|
|
15518
|
-
const
|
|
15734
|
+
const os29 = (0, import_os2.platform)();
|
|
15519
15735
|
const results = [];
|
|
15520
15736
|
for (const def of getMergedDefinitions()) {
|
|
15521
15737
|
const cliPath = findCliCommand(providerLoader?.getIdeCliCommand(def.id, def.cli) || def.cli);
|
|
15522
|
-
const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[
|
|
15738
|
+
const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[os29] || []) || []);
|
|
15523
15739
|
let resolvedCli = cliPath;
|
|
15524
|
-
if (!resolvedCli && appPath &&
|
|
15740
|
+
if (!resolvedCli && appPath && os29 === "darwin") {
|
|
15525
15741
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
15526
15742
|
if ((0, import_fs11.existsSync)(bundledCli)) resolvedCli = bundledCli;
|
|
15527
15743
|
}
|
|
15528
|
-
if (!resolvedCli && appPath &&
|
|
15744
|
+
if (!resolvedCli && appPath && os29 === "win32") {
|
|
15529
15745
|
const { dirname: dirname11 } = await import("path");
|
|
15530
15746
|
const appDir = dirname11(appPath);
|
|
15531
15747
|
const candidates = [
|
|
@@ -15542,7 +15758,7 @@ async function detectIDEs(providerLoader) {
|
|
|
15542
15758
|
}
|
|
15543
15759
|
}
|
|
15544
15760
|
}
|
|
15545
|
-
const installed =
|
|
15761
|
+
const installed = os29 === "darwin" ? !!(resolvedCli || appPath) : !!resolvedCli;
|
|
15546
15762
|
const version = resolvedCli ? await getIdeVersion(resolvedCli) : null;
|
|
15547
15763
|
results.push({
|
|
15548
15764
|
id: def.id,
|
|
@@ -25924,6 +26140,14 @@ var DaemonCommandHandler = class {
|
|
|
25924
26140
|
return this.handleCheckProviderUpdates(args);
|
|
25925
26141
|
case "list_installed_providers":
|
|
25926
26142
|
return this.handleListInstalledProviders(args);
|
|
26143
|
+
case "add_provider_source":
|
|
26144
|
+
return this.handleAddProviderSource(args);
|
|
26145
|
+
case "remove_provider_source":
|
|
26146
|
+
return this.handleRemoveProviderSource(args);
|
|
26147
|
+
case "list_provider_sources":
|
|
26148
|
+
return this.handleListProviderSources(args);
|
|
26149
|
+
case "set_active_provider_source":
|
|
26150
|
+
return this.handleSetActiveProviderSource(args);
|
|
25927
26151
|
// ─── Stream commands (stream-commands.ts) ───────────
|
|
25928
26152
|
case "select_session":
|
|
25929
26153
|
return handleSelectSession(this, args);
|
|
@@ -25987,49 +26211,62 @@ var DaemonCommandHandler = class {
|
|
|
25987
26211
|
return { success: false, error: "ProviderLoader not initialized" };
|
|
25988
26212
|
}
|
|
25989
26213
|
/**
|
|
25990
|
-
* Return per-provider availability so
|
|
25991
|
-
* "Installed" badges. Reuses the existing detection state from
|
|
26214
|
+
* Return per-provider availability so the dashboard's provider catalog
|
|
26215
|
+
* can show "Installed" badges. Reuses the existing detection state from
|
|
25992
26216
|
* ProviderLoader.getMachineProviderStatus() — no probing is triggered.
|
|
25993
26217
|
*/
|
|
25994
26218
|
handleListProviderAvailability(_args) {
|
|
25995
26219
|
if (!this._ctx.providerLoader) {
|
|
25996
26220
|
return { success: false, error: "ProviderLoader not initialized" };
|
|
25997
26221
|
}
|
|
26222
|
+
const { describeTrust: describeTrust2, requiresConfirmation: requiresConfirmation2 } = (init_provider_trust(), __toCommonJS(provider_trust_exports));
|
|
25998
26223
|
const loader = this._ctx.providerLoader;
|
|
25999
26224
|
const items = loader.getAll().map((provider) => {
|
|
26000
26225
|
const machineConfig = loader.getMachineProviderConfig(provider.type);
|
|
26001
26226
|
const lastDetection = machineConfig.lastDetection;
|
|
26227
|
+
const trust = provider._sourceTrust ?? "trusted";
|
|
26228
|
+
const layer = provider._sourceLayer ?? "upstream";
|
|
26229
|
+
const sourceName = provider._sourceName ?? null;
|
|
26002
26230
|
return {
|
|
26003
26231
|
type: provider.type,
|
|
26004
26232
|
category: provider.category,
|
|
26005
26233
|
status: loader.getMachineProviderStatus(provider.type),
|
|
26006
26234
|
installed: lastDetection?.ok === true,
|
|
26007
26235
|
detectedPath: lastDetection?.path ?? null,
|
|
26008
|
-
checkedAt: lastDetection?.checkedAt ?? null
|
|
26236
|
+
checkedAt: lastDetection?.checkedAt ?? null,
|
|
26237
|
+
trust,
|
|
26238
|
+
trustDescription: describeTrust2(trust),
|
|
26239
|
+
requiresConfirmation: requiresConfirmation2(trust),
|
|
26240
|
+
sourceLayer: layer,
|
|
26241
|
+
sourceName
|
|
26009
26242
|
};
|
|
26010
26243
|
});
|
|
26011
26244
|
return { success: true, providers: items };
|
|
26012
26245
|
}
|
|
26013
26246
|
/**
|
|
26014
|
-
* Compute the *
|
|
26015
|
-
*
|
|
26016
|
-
*
|
|
26017
|
-
*
|
|
26018
|
-
*
|
|
26019
|
-
*
|
|
26247
|
+
* Compute the *upstream cache root*. install_provider_manifest writes
|
|
26248
|
+
* official-registry manifests here so the daemon's standard upstream
|
|
26249
|
+
* layer picks them up — no special handling needed at load time, and
|
|
26250
|
+
* the manifests inherit the official-trust badge instead of the
|
|
26251
|
+
* untrusted-external one.
|
|
26252
|
+
*
|
|
26253
|
+
* Path matches ProviderLoader.upstreamDir but we recompute it from
|
|
26254
|
+
* homedir() so this method stays usable in dev where userDir can
|
|
26255
|
+
* point at a sibling git checkout.
|
|
26020
26256
|
*/
|
|
26021
|
-
|
|
26022
|
-
const
|
|
26023
|
-
const
|
|
26024
|
-
return
|
|
26257
|
+
getUpstreamInstallRoot() {
|
|
26258
|
+
const os29 = require("os");
|
|
26259
|
+
const path40 = require("path");
|
|
26260
|
+
return path40.join(os29.homedir(), ".adhdev", "providers", ".upstream");
|
|
26025
26261
|
}
|
|
26026
26262
|
/**
|
|
26027
26263
|
* Download a single provider manifest from the registry and write it to
|
|
26028
|
-
* ~/.adhdev/
|
|
26264
|
+
* ~/.adhdev/providers/.upstream/{category}/{type}/provider.json.
|
|
26029
26265
|
*
|
|
26030
|
-
* Used by
|
|
26031
|
-
*
|
|
26032
|
-
* the
|
|
26266
|
+
* Used by standalone onboarding to seed the upstream cache with the
|
|
26267
|
+
* default provider set on first launch. Verifies SHA-256 checksum
|
|
26268
|
+
* against the registry meta before persisting. Refuses to write
|
|
26269
|
+
* outside the upstream root.
|
|
26033
26270
|
*
|
|
26034
26271
|
* Args: { type: string, category?: string, version?: string }
|
|
26035
26272
|
* If category/version are omitted, looks up the latest from the registry.
|
|
@@ -26044,8 +26281,8 @@ var DaemonCommandHandler = class {
|
|
|
26044
26281
|
return { success: false, error: "invalid type" };
|
|
26045
26282
|
}
|
|
26046
26283
|
const https = require("https");
|
|
26047
|
-
const
|
|
26048
|
-
const
|
|
26284
|
+
const fs28 = require("fs");
|
|
26285
|
+
const path40 = require("path");
|
|
26049
26286
|
const crypto6 = require("crypto");
|
|
26050
26287
|
const REGISTRY = "https://api.adhf.dev/api/v1/registry";
|
|
26051
26288
|
function fetchText(url, timeoutMs) {
|
|
@@ -26082,13 +26319,13 @@ var DaemonCommandHandler = class {
|
|
|
26082
26319
|
if (actualChecksum !== meta.checksum) {
|
|
26083
26320
|
return { success: false, error: `checksum mismatch: expected ${meta.checksum}, got ${actualChecksum}` };
|
|
26084
26321
|
}
|
|
26085
|
-
const installRoot = this.
|
|
26086
|
-
const installRootResolved =
|
|
26087
|
-
const targetDir =
|
|
26088
|
-
if (!targetDir.startsWith(installRootResolved +
|
|
26089
|
-
return { success: false, error: "install path escaped
|
|
26322
|
+
const installRoot = this.getUpstreamInstallRoot();
|
|
26323
|
+
const installRootResolved = path40.resolve(installRoot);
|
|
26324
|
+
const targetDir = path40.resolve(path40.join(installRoot, category, type));
|
|
26325
|
+
if (!targetDir.startsWith(installRootResolved + path40.sep)) {
|
|
26326
|
+
return { success: false, error: "install path escaped upstream root" };
|
|
26090
26327
|
}
|
|
26091
|
-
|
|
26328
|
+
fs28.mkdirSync(targetDir, { recursive: true });
|
|
26092
26329
|
let manifestProbe = {};
|
|
26093
26330
|
try {
|
|
26094
26331
|
manifestProbe = JSON.parse(manifestBody);
|
|
@@ -26112,8 +26349,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26112
26349
|
}
|
|
26113
26350
|
}
|
|
26114
26351
|
const targetFile = isV1 ? "provider.v1.json" : "provider.json";
|
|
26115
|
-
const targetPath =
|
|
26116
|
-
|
|
26352
|
+
const targetPath = path40.join(targetDir, targetFile);
|
|
26353
|
+
fs28.writeFileSync(targetPath, manifestBody, "utf-8");
|
|
26117
26354
|
const manifestJson = JSON.parse(manifestBody);
|
|
26118
26355
|
const scriptFetch = await this.fetchProviderSources(
|
|
26119
26356
|
manifestJson,
|
|
@@ -26161,6 +26398,10 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26161
26398
|
if (Array.isArray(manifest.compatibility)) {
|
|
26162
26399
|
for (const c of manifest.compatibility) {
|
|
26163
26400
|
if (typeof c?.scriptDir === "string") scriptDirs.add(c.scriptDir);
|
|
26401
|
+
if (typeof c?.spec === "string" && c.spec.includes("/")) {
|
|
26402
|
+
const dir = c.spec.substring(0, c.spec.lastIndexOf("/"));
|
|
26403
|
+
if (dir) scriptDirs.add(dir);
|
|
26404
|
+
}
|
|
26164
26405
|
}
|
|
26165
26406
|
}
|
|
26166
26407
|
if (manifest.overrides && typeof manifest.overrides === "object" && !Array.isArray(manifest.overrides)) {
|
|
@@ -26179,8 +26420,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26179
26420
|
const repo = source.repo;
|
|
26180
26421
|
const ref = source.ref;
|
|
26181
26422
|
const https = require("https");
|
|
26182
|
-
const
|
|
26183
|
-
const
|
|
26423
|
+
const fs28 = require("fs");
|
|
26424
|
+
const path40 = require("path");
|
|
26184
26425
|
function fetchJson(url, timeoutMs) {
|
|
26185
26426
|
return new Promise((resolve23, reject) => {
|
|
26186
26427
|
const req = https.get(url, {
|
|
@@ -26236,9 +26477,9 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26236
26477
|
}
|
|
26237
26478
|
let fetchedCount = 0;
|
|
26238
26479
|
const sharedDirRel = `${category}/_shared`;
|
|
26239
|
-
const sharedTargetDir =
|
|
26240
|
-
const installRootResolved =
|
|
26241
|
-
if (sharedTargetDir.startsWith(installRootResolved +
|
|
26480
|
+
const sharedTargetDir = path40.resolve(path40.join(targetDir, "../_shared"));
|
|
26481
|
+
const installRootResolved = path40.resolve(path40.join(targetDir, "../.."));
|
|
26482
|
+
if (sharedTargetDir.startsWith(installRootResolved + path40.sep)) {
|
|
26242
26483
|
const sharedStack = [sharedDirRel];
|
|
26243
26484
|
while (sharedStack.length) {
|
|
26244
26485
|
const relDir = sharedStack.pop();
|
|
@@ -26261,10 +26502,10 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26261
26502
|
try {
|
|
26262
26503
|
const body = await fetchBinary(entry.download_url, 3e4);
|
|
26263
26504
|
const relInside = entry.path.startsWith(sharedDirRel + "/") ? entry.path.slice(sharedDirRel.length + 1) : entry.path;
|
|
26264
|
-
const outPath =
|
|
26265
|
-
if (!outPath.startsWith(
|
|
26266
|
-
|
|
26267
|
-
|
|
26505
|
+
const outPath = path40.resolve(path40.join(sharedTargetDir, relInside));
|
|
26506
|
+
if (!outPath.startsWith(path40.resolve(sharedTargetDir) + path40.sep)) continue;
|
|
26507
|
+
fs28.mkdirSync(path40.dirname(outPath), { recursive: true });
|
|
26508
|
+
fs28.writeFileSync(outPath, body);
|
|
26268
26509
|
fetchedCount++;
|
|
26269
26510
|
} catch (e) {
|
|
26270
26511
|
errors.push(`fetch shared ${entry.path}: ${e?.message ?? e}`);
|
|
@@ -26297,13 +26538,13 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26297
26538
|
try {
|
|
26298
26539
|
const body = await fetchBinary(entry.download_url, 3e4);
|
|
26299
26540
|
const relInsideProvider = entry.path.startsWith(subdir + "/") ? entry.path.slice(subdir.length + 1) : entry.path;
|
|
26300
|
-
const outPath =
|
|
26301
|
-
if (!outPath.startsWith(
|
|
26541
|
+
const outPath = path40.resolve(path40.join(targetDir, relInsideProvider));
|
|
26542
|
+
if (!outPath.startsWith(path40.resolve(targetDir) + path40.sep)) {
|
|
26302
26543
|
errors.push(`refusing to write outside targetDir: ${entry.path}`);
|
|
26303
26544
|
continue;
|
|
26304
26545
|
}
|
|
26305
|
-
|
|
26306
|
-
|
|
26546
|
+
fs28.mkdirSync(path40.dirname(outPath), { recursive: true });
|
|
26547
|
+
fs28.writeFileSync(outPath, body);
|
|
26307
26548
|
fetchedCount++;
|
|
26308
26549
|
} catch (e) {
|
|
26309
26550
|
errors.push(`fetch ${entry.path}: ${e?.message ?? e}`);
|
|
@@ -26314,9 +26555,12 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26314
26555
|
return { fetchedCount, source: `${repo}@${ref}`, errors };
|
|
26315
26556
|
}
|
|
26316
26557
|
/**
|
|
26317
|
-
* Remove a provider manifest from the
|
|
26318
|
-
* (~/.adhdev/
|
|
26319
|
-
* outside that root.
|
|
26558
|
+
* Remove a provider manifest from the upstream cache root
|
|
26559
|
+
* (~/.adhdev/providers/.upstream/{category}/{type}/). Refuses to touch
|
|
26560
|
+
* anything outside that root. Used by onboarding to opt out of a
|
|
26561
|
+
* provider the user doesn't want; the dashboard no longer exposes a
|
|
26562
|
+
* per-provider uninstall button (external sources are removed as a
|
|
26563
|
+
* whole via remove_provider_source).
|
|
26320
26564
|
*/
|
|
26321
26565
|
async handleUninstallProviderManifest(args) {
|
|
26322
26566
|
const type = typeof args?.type === "string" ? args.type : "";
|
|
@@ -26328,19 +26572,19 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26328
26572
|
if (!["cli", "ide", "extension", "acp"].includes(category)) {
|
|
26329
26573
|
return { success: false, error: `unknown category: ${category}` };
|
|
26330
26574
|
}
|
|
26331
|
-
const
|
|
26332
|
-
const
|
|
26575
|
+
const fs28 = require("fs");
|
|
26576
|
+
const path40 = require("path");
|
|
26333
26577
|
try {
|
|
26334
|
-
const installRoot = this.
|
|
26335
|
-
const installRootResolved =
|
|
26336
|
-
const targetDir =
|
|
26337
|
-
if (!targetDir.startsWith(installRootResolved +
|
|
26338
|
-
return { success: false, error: "refusing to delete outside
|
|
26578
|
+
const installRoot = this.getUpstreamInstallRoot();
|
|
26579
|
+
const installRootResolved = path40.resolve(installRoot);
|
|
26580
|
+
const targetDir = path40.resolve(path40.join(installRoot, category, type));
|
|
26581
|
+
if (!targetDir.startsWith(installRootResolved + path40.sep)) {
|
|
26582
|
+
return { success: false, error: "refusing to delete outside upstream root" };
|
|
26339
26583
|
}
|
|
26340
|
-
if (!
|
|
26584
|
+
if (!fs28.existsSync(targetDir)) {
|
|
26341
26585
|
return { success: false, error: "not installed" };
|
|
26342
26586
|
}
|
|
26343
|
-
|
|
26587
|
+
fs28.rmSync(targetDir, { recursive: true, force: true });
|
|
26344
26588
|
if (this._ctx.providerLoader) {
|
|
26345
26589
|
this._ctx.providerLoader.reload();
|
|
26346
26590
|
this._ctx.providerLoader.registerToDetector();
|
|
@@ -26351,33 +26595,33 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26351
26595
|
}
|
|
26352
26596
|
}
|
|
26353
26597
|
/**
|
|
26354
|
-
* Return everything currently installed in
|
|
26598
|
+
* Return everything currently installed in the upstream cache with its
|
|
26355
26599
|
* version. This is the "what does this daemon have" answer used both by
|
|
26356
26600
|
* the UI and by the update checker.
|
|
26357
26601
|
*/
|
|
26358
26602
|
handleListInstalledProviders(_args) {
|
|
26359
|
-
const
|
|
26360
|
-
const
|
|
26361
|
-
const installRoot = this.
|
|
26362
|
-
if (!
|
|
26603
|
+
const fs28 = require("fs");
|
|
26604
|
+
const path40 = require("path");
|
|
26605
|
+
const installRoot = this.getUpstreamInstallRoot();
|
|
26606
|
+
if (!fs28.existsSync(installRoot)) return { success: true, providers: [] };
|
|
26363
26607
|
const CATEGORIES = ["cli", "ide", "extension", "acp"];
|
|
26364
26608
|
const items = [];
|
|
26365
26609
|
for (const category of CATEGORIES) {
|
|
26366
|
-
const categoryDir =
|
|
26367
|
-
if (!
|
|
26610
|
+
const categoryDir = path40.join(installRoot, category);
|
|
26611
|
+
if (!fs28.existsSync(categoryDir)) continue;
|
|
26368
26612
|
let entries;
|
|
26369
26613
|
try {
|
|
26370
|
-
entries =
|
|
26614
|
+
entries = fs28.readdirSync(categoryDir);
|
|
26371
26615
|
} catch {
|
|
26372
26616
|
continue;
|
|
26373
26617
|
}
|
|
26374
26618
|
for (const type of entries) {
|
|
26375
|
-
const v1Path =
|
|
26376
|
-
const v0Path =
|
|
26377
|
-
const manifestPath =
|
|
26619
|
+
const v1Path = path40.join(categoryDir, type, "provider.v1.json");
|
|
26620
|
+
const v0Path = path40.join(categoryDir, type, "provider.json");
|
|
26621
|
+
const manifestPath = fs28.existsSync(v1Path) ? v1Path : fs28.existsSync(v0Path) ? v0Path : null;
|
|
26378
26622
|
if (!manifestPath) continue;
|
|
26379
26623
|
try {
|
|
26380
|
-
const m = JSON.parse(
|
|
26624
|
+
const m = JSON.parse(fs28.readFileSync(manifestPath, "utf-8"));
|
|
26381
26625
|
items.push({
|
|
26382
26626
|
type,
|
|
26383
26627
|
category,
|
|
@@ -26454,6 +26698,196 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26454
26698
|
);
|
|
26455
26699
|
return { success: true, providers: checks };
|
|
26456
26700
|
}
|
|
26701
|
+
// ─── External provider sources (3rd-party git URLs) ──────────────
|
|
26702
|
+
/**
|
|
26703
|
+
* Register a new external provider source. The daemon clones the repo
|
|
26704
|
+
* to ~/.adhdev/external/<name>/, walks it once to detect provided
|
|
26705
|
+
* types, and surfaces any conflicts with already-installed types so
|
|
26706
|
+
* the dashboard can ask the user how to resolve them.
|
|
26707
|
+
*
|
|
26708
|
+
* Args: { url: string, ref?: string, name?: string }
|
|
26709
|
+
* - url: https://, git@, or any git-cloneable URL
|
|
26710
|
+
* - ref: branch/tag/commit (default "main")
|
|
26711
|
+
* - name: short identifier (default derived from URL)
|
|
26712
|
+
*
|
|
26713
|
+
* Returns: { source, providers, conflicts }
|
|
26714
|
+
* - conflicts: list of types this new source provides that another
|
|
26715
|
+
* source already exposes. UI uses this to prompt for active-source
|
|
26716
|
+
* selection before the load takes effect.
|
|
26717
|
+
*/
|
|
26718
|
+
async handleAddProviderSource(args) {
|
|
26719
|
+
const url = typeof args?.url === "string" ? args.url.trim() : "";
|
|
26720
|
+
if (!url) return { success: false, error: "url is required" };
|
|
26721
|
+
const ref = typeof args?.ref === "string" && args.ref.trim() ? args.ref.trim() : "main";
|
|
26722
|
+
if (url.startsWith("-")) return { success: false, error: 'url must not start with "-"' };
|
|
26723
|
+
if (ref.startsWith("-")) return { success: false, error: 'ref must not start with "-"' };
|
|
26724
|
+
if (!/^(https?:\/\/|git@[a-z0-9._-]+:)[a-z0-9._@:/~\-]+$/i.test(url)) {
|
|
26725
|
+
return { success: false, error: "url must be https://\u2026 or git@host:\u2026 and contain only URL-safe characters" };
|
|
26726
|
+
}
|
|
26727
|
+
if (!/^[A-Za-z0-9._/-]+$/.test(ref)) {
|
|
26728
|
+
return { success: false, error: "ref must contain only [A-Za-z0-9._/-]" };
|
|
26729
|
+
}
|
|
26730
|
+
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
26731
|
+
const requestedName = typeof args?.name === "string" && args.name.trim() ? args.name.trim() : ext.deriveSourceName(url);
|
|
26732
|
+
if (!/^@[a-z0-9_-]+$/i.test(requestedName)) {
|
|
26733
|
+
return { success: false, error: "name must match @[a-z0-9_-]+" };
|
|
26734
|
+
}
|
|
26735
|
+
const fs28 = require("fs");
|
|
26736
|
+
const path40 = require("path");
|
|
26737
|
+
const { spawnSync: spawnSync2 } = require("child_process");
|
|
26738
|
+
const file = ext.loadExternalSources();
|
|
26739
|
+
if (file.sources.some((s) => s.name === requestedName)) {
|
|
26740
|
+
return { success: false, error: `source name "${requestedName}" is already registered` };
|
|
26741
|
+
}
|
|
26742
|
+
if (file.sources.some((s) => s.url === url && s.ref === ref)) {
|
|
26743
|
+
return { success: false, error: `source url+ref already registered (use a different name to track another ref)` };
|
|
26744
|
+
}
|
|
26745
|
+
const sourceDir = path40.join(ext.externalRoot(), requestedName);
|
|
26746
|
+
if (!fs28.existsSync(ext.externalRoot())) fs28.mkdirSync(ext.externalRoot(), { recursive: true });
|
|
26747
|
+
if (fs28.existsSync(sourceDir)) {
|
|
26748
|
+
return { success: false, error: `directory already exists: ${sourceDir} (rename or remove first)` };
|
|
26749
|
+
}
|
|
26750
|
+
const clone = spawnSync2("git", ["clone", "--depth=1", "--branch", ref, "--", url, sourceDir], {
|
|
26751
|
+
encoding: "utf-8",
|
|
26752
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
26753
|
+
timeout: 6e4
|
|
26754
|
+
});
|
|
26755
|
+
if (clone.status !== 0) {
|
|
26756
|
+
try {
|
|
26757
|
+
fs28.rmSync(sourceDir, { recursive: true, force: true });
|
|
26758
|
+
} catch {
|
|
26759
|
+
}
|
|
26760
|
+
return { success: false, error: `git clone failed: ${(clone.stderr || clone.stdout || "").trim() || "unknown error"}` };
|
|
26761
|
+
}
|
|
26762
|
+
const source = {
|
|
26763
|
+
name: requestedName,
|
|
26764
|
+
url,
|
|
26765
|
+
ref,
|
|
26766
|
+
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
26767
|
+
};
|
|
26768
|
+
ext.saveExternalSources({ schema: 1, sources: [...file.sources, source] });
|
|
26769
|
+
const inventory = ext.inventoryExternalSources();
|
|
26770
|
+
const conflicts = [];
|
|
26771
|
+
const newEntry = inventory.find((e) => e.sourceName === requestedName);
|
|
26772
|
+
if (newEntry) {
|
|
26773
|
+
for (const [category, types] of Object.entries(newEntry.providers)) {
|
|
26774
|
+
for (const type of types) {
|
|
26775
|
+
const sources = ext.sourcesProviding(category, type);
|
|
26776
|
+
if (sources.length > 1) conflicts.push({ category, type, sources });
|
|
26777
|
+
}
|
|
26778
|
+
}
|
|
26779
|
+
}
|
|
26780
|
+
if (this._ctx.providerLoader) {
|
|
26781
|
+
this._ctx.providerLoader.reload();
|
|
26782
|
+
this._ctx.providerLoader.registerToDetector();
|
|
26783
|
+
}
|
|
26784
|
+
return {
|
|
26785
|
+
success: true,
|
|
26786
|
+
source,
|
|
26787
|
+
providers: newEntry?.providers ?? {},
|
|
26788
|
+
conflicts
|
|
26789
|
+
};
|
|
26790
|
+
}
|
|
26791
|
+
/**
|
|
26792
|
+
* Remove a registered external source. Deletes the clone directory and
|
|
26793
|
+
* any active-source entry pointing to it.
|
|
26794
|
+
*
|
|
26795
|
+
* Args: { name: string }
|
|
26796
|
+
*/
|
|
26797
|
+
async handleRemoveProviderSource(args) {
|
|
26798
|
+
const name = typeof args?.name === "string" ? args.name.trim() : "";
|
|
26799
|
+
if (!name) return { success: false, error: "name is required" };
|
|
26800
|
+
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
26801
|
+
const fs28 = require("fs");
|
|
26802
|
+
const path40 = require("path");
|
|
26803
|
+
const file = ext.loadExternalSources();
|
|
26804
|
+
const match = file.sources.find((s) => s.name === name);
|
|
26805
|
+
if (!match) return { success: false, error: `source "${name}" not registered` };
|
|
26806
|
+
const sourceDir = path40.join(ext.externalRoot(), name);
|
|
26807
|
+
if (fs28.existsSync(sourceDir)) {
|
|
26808
|
+
try {
|
|
26809
|
+
fs28.rmSync(sourceDir, { recursive: true, force: true });
|
|
26810
|
+
} catch (e) {
|
|
26811
|
+
return { success: false, error: `failed to delete ${sourceDir}: ${e?.message || e}` };
|
|
26812
|
+
}
|
|
26813
|
+
}
|
|
26814
|
+
ext.saveExternalSources({
|
|
26815
|
+
schema: 1,
|
|
26816
|
+
sources: file.sources.filter((s) => s.name !== name)
|
|
26817
|
+
});
|
|
26818
|
+
const active = ext.loadProvidersActive();
|
|
26819
|
+
const filteredActive = {};
|
|
26820
|
+
for (const [type, src] of Object.entries(active.active)) {
|
|
26821
|
+
if (src !== name) filteredActive[type] = src;
|
|
26822
|
+
}
|
|
26823
|
+
ext.saveProvidersActive({ schema: 1, active: filteredActive });
|
|
26824
|
+
if (this._ctx.providerLoader) {
|
|
26825
|
+
this._ctx.providerLoader.reload();
|
|
26826
|
+
this._ctx.providerLoader.registerToDetector();
|
|
26827
|
+
}
|
|
26828
|
+
return { success: true, removed: { name } };
|
|
26829
|
+
}
|
|
26830
|
+
/**
|
|
26831
|
+
* List registered external sources + each source's currently installed
|
|
26832
|
+
* providers + the active selection for any conflicting types. Used by
|
|
26833
|
+
* the dashboard's "Sources" tab.
|
|
26834
|
+
*/
|
|
26835
|
+
handleListProviderSources(_args) {
|
|
26836
|
+
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
26837
|
+
const file = ext.loadExternalSources();
|
|
26838
|
+
const inventory = ext.inventoryExternalSources();
|
|
26839
|
+
const active = ext.loadProvidersActive();
|
|
26840
|
+
const sources = file.sources.map((s) => {
|
|
26841
|
+
const inv = inventory.find((e) => e.sourceName === s.name);
|
|
26842
|
+
return {
|
|
26843
|
+
...s,
|
|
26844
|
+
providers: inv?.providers ?? {}
|
|
26845
|
+
};
|
|
26846
|
+
});
|
|
26847
|
+
const conflictMap = /* @__PURE__ */ new Map();
|
|
26848
|
+
for (const inv of inventory) {
|
|
26849
|
+
for (const [category, types] of Object.entries(inv.providers)) {
|
|
26850
|
+
for (const type of types) {
|
|
26851
|
+
const candidates = ext.sourcesProviding(category, type);
|
|
26852
|
+
if (candidates.length > 1 && !conflictMap.has(type)) {
|
|
26853
|
+
conflictMap.set(type, { category, sources: candidates });
|
|
26854
|
+
}
|
|
26855
|
+
}
|
|
26856
|
+
}
|
|
26857
|
+
}
|
|
26858
|
+
const conflicts = [...conflictMap.entries()].map(([type, info]) => ({
|
|
26859
|
+
type,
|
|
26860
|
+
category: info.category,
|
|
26861
|
+
candidates: info.sources,
|
|
26862
|
+
active: active.active[type] ?? null
|
|
26863
|
+
}));
|
|
26864
|
+
return { success: true, sources, conflicts };
|
|
26865
|
+
}
|
|
26866
|
+
/**
|
|
26867
|
+
* Pick which source's copy of a conflicting provider type is active.
|
|
26868
|
+
* Other sources' copies stay on disk but the loader ignores them.
|
|
26869
|
+
*
|
|
26870
|
+
* Args: { type: string, sourceName: string }
|
|
26871
|
+
*/
|
|
26872
|
+
handleSetActiveProviderSource(args) {
|
|
26873
|
+
const type = typeof args?.type === "string" ? args.type.trim() : "";
|
|
26874
|
+
const sourceName = typeof args?.sourceName === "string" ? args.sourceName.trim() : "";
|
|
26875
|
+
if (!type || !sourceName) return { success: false, error: "type and sourceName are required" };
|
|
26876
|
+
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
26877
|
+
const inventory = ext.inventoryExternalSources();
|
|
26878
|
+
const entry = inventory.find((e) => e.sourceName === sourceName);
|
|
26879
|
+
if (!entry) return { success: false, error: `source "${sourceName}" not found` };
|
|
26880
|
+
const provided = Object.values(entry.providers).some((types) => types.includes(type));
|
|
26881
|
+
if (!provided) return { success: false, error: `source "${sourceName}" does not provide type "${type}"` };
|
|
26882
|
+
const active = ext.loadProvidersActive();
|
|
26883
|
+
active.active[type] = sourceName;
|
|
26884
|
+
ext.saveProvidersActive(active);
|
|
26885
|
+
if (this._ctx.providerLoader) {
|
|
26886
|
+
this._ctx.providerLoader.reload();
|
|
26887
|
+
this._ctx.providerLoader.registerToDetector();
|
|
26888
|
+
}
|
|
26889
|
+
return { success: true, type, sourceName };
|
|
26890
|
+
}
|
|
26457
26891
|
// ─── DevServer HTTP proxy helpers ─────────────────
|
|
26458
26892
|
// These bridge WS commands to the DevServer REST API (localhost:19280)
|
|
26459
26893
|
async proxyDevServerPost(args, endpoint) {
|
|
@@ -26546,8 +26980,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26546
26980
|
};
|
|
26547
26981
|
|
|
26548
26982
|
// src/commands/cli-manager.ts
|
|
26549
|
-
var
|
|
26550
|
-
var
|
|
26983
|
+
var os17 = __toESM(require("os"));
|
|
26984
|
+
var path23 = __toESM(require("path"));
|
|
26551
26985
|
var crypto5 = __toESM(require("crypto"));
|
|
26552
26986
|
var import_fs12 = require("fs");
|
|
26553
26987
|
var import_child_process5 = require("child_process");
|
|
@@ -26557,21 +26991,21 @@ init_cli_detector();
|
|
|
26557
26991
|
init_config();
|
|
26558
26992
|
|
|
26559
26993
|
// src/providers/cli-provider-instance.ts
|
|
26560
|
-
var
|
|
26561
|
-
var
|
|
26994
|
+
var os16 = __toESM(require("os"));
|
|
26995
|
+
var path21 = __toESM(require("path"));
|
|
26562
26996
|
var crypto4 = __toESM(require("crypto"));
|
|
26563
|
-
var
|
|
26997
|
+
var fs12 = __toESM(require("fs"));
|
|
26564
26998
|
var import_node_module = require("module");
|
|
26565
26999
|
|
|
26566
27000
|
// src/providers/spec/route.ts
|
|
26567
|
-
var
|
|
26568
|
-
var
|
|
27001
|
+
var fs11 = __toESM(require("fs"));
|
|
27002
|
+
var path20 = __toESM(require("path"));
|
|
26569
27003
|
init_provider_cli_adapter();
|
|
26570
27004
|
|
|
26571
27005
|
// src/providers/spec/driver.ts
|
|
26572
|
-
var
|
|
26573
|
-
var
|
|
26574
|
-
var
|
|
27006
|
+
var fs10 = __toESM(require("fs"));
|
|
27007
|
+
var os15 = __toESM(require("os"));
|
|
27008
|
+
var path19 = __toESM(require("path"));
|
|
26575
27009
|
|
|
26576
27010
|
// src/providers/spec/adapter.ts
|
|
26577
27011
|
var xtermHeadlessNs = __toESM(require("@xterm/headless"));
|
|
@@ -26948,7 +27382,7 @@ var SpecDriver = class {
|
|
|
26948
27382
|
}
|
|
26949
27383
|
armSpecWatcher() {
|
|
26950
27384
|
try {
|
|
26951
|
-
this.specWatcher =
|
|
27385
|
+
this.specWatcher = fs10.watch(this.opts.specPath, { persistent: false }, () => {
|
|
26952
27386
|
const res = loadSpec(this.opts.specPath);
|
|
26953
27387
|
if (!res.ok) {
|
|
26954
27388
|
this.emit({ kind: "spec_error", errors: res.errors });
|
|
@@ -27041,7 +27475,7 @@ var SpecDriver = class {
|
|
|
27041
27475
|
}
|
|
27042
27476
|
fireDelegate(d) {
|
|
27043
27477
|
const ev = this.currentEval;
|
|
27044
|
-
const task = d.task_template.replace(/\{node\}/g,
|
|
27478
|
+
const task = d.task_template.replace(/\{node\}/g, os15.hostname()).replace(/\{state\.label\}/g, ev?.state.label ?? "").replace(/\{state\.title\}/g, ev?.state.title ?? "").replace(/\{duration_ms\}/g, String(d.after_duration_ms ?? 0));
|
|
27045
27479
|
this.emit({ kind: "delegate", id: d.id, task });
|
|
27046
27480
|
}
|
|
27047
27481
|
// ────────────────────────────────────────────────────────────────────
|
|
@@ -27110,9 +27544,9 @@ var SpecDriver = class {
|
|
|
27110
27544
|
const ctl = (this.spec.control_bar ?? []).find((c) => c.action.type === "attach_image");
|
|
27111
27545
|
if (!ctl || ctl.action.type !== "attach_image") return;
|
|
27112
27546
|
const ext = guessExt(mime);
|
|
27113
|
-
const tmp =
|
|
27547
|
+
const tmp = path19.join(os15.tmpdir(), `adhdev-attach-${Date.now()}${ext}`);
|
|
27114
27548
|
try {
|
|
27115
|
-
|
|
27549
|
+
fs10.writeFileSync(tmp, Buffer.from(blob, "base64"));
|
|
27116
27550
|
} catch {
|
|
27117
27551
|
return;
|
|
27118
27552
|
}
|
|
@@ -27440,14 +27874,14 @@ init_logger();
|
|
|
27440
27874
|
function createCliAdapter(provider, workingDir, cliArgs, extraEnv, transportFactory) {
|
|
27441
27875
|
const resolvedSpecPath = provider._resolvedSpecPath;
|
|
27442
27876
|
const dir = provider._resolvedProviderDir;
|
|
27443
|
-
let specPath = resolvedSpecPath &&
|
|
27877
|
+
let specPath = resolvedSpecPath && fs11.existsSync(resolvedSpecPath) ? resolvedSpecPath : void 0;
|
|
27444
27878
|
if (!specPath && dir) {
|
|
27445
|
-
const legacy =
|
|
27446
|
-
if (
|
|
27879
|
+
const legacy = path20.join(dir, "spec.json");
|
|
27880
|
+
if (fs11.existsSync(legacy)) specPath = legacy;
|
|
27447
27881
|
}
|
|
27448
27882
|
if (specPath) {
|
|
27449
27883
|
try {
|
|
27450
|
-
LOG.info("spec-route", `[${provider.type}] routing through SpecCliAdapter (${
|
|
27884
|
+
LOG.info("spec-route", `[${provider.type}] routing through SpecCliAdapter (${path20.relative(dir || "", specPath) || specPath})`);
|
|
27451
27885
|
return new SpecCliAdapter(specPath, workingDir, cliArgs, extraEnv, transportFactory);
|
|
27452
27886
|
} catch (err) {
|
|
27453
27887
|
LOG.warn("spec-route", `[${provider.type}] spec invalid, falling back to ProviderCliAdapter: ${err.message}`);
|
|
@@ -27508,7 +27942,7 @@ function filePathFromUri(uri) {
|
|
|
27508
27942
|
return uri.slice("file://".length);
|
|
27509
27943
|
}
|
|
27510
27944
|
}
|
|
27511
|
-
if (
|
|
27945
|
+
if (path21.isAbsolute(uri)) return uri;
|
|
27512
27946
|
return null;
|
|
27513
27947
|
}
|
|
27514
27948
|
function extensionForImageMime(mimeType) {
|
|
@@ -27523,9 +27957,9 @@ function materializeImageDataPart(part, index, dir) {
|
|
|
27523
27957
|
if (!part.data) return null;
|
|
27524
27958
|
const rawData = part.data.includes(",") ? part.data.split(",").pop() || "" : part.data;
|
|
27525
27959
|
if (!rawData) return null;
|
|
27526
|
-
|
|
27527
|
-
const filePath =
|
|
27528
|
-
|
|
27960
|
+
fs12.mkdirSync(dir, { recursive: true });
|
|
27961
|
+
const filePath = path21.join(dir, safeInputImageBasename(index, part.mimeType));
|
|
27962
|
+
fs12.writeFileSync(filePath, Buffer.from(rawData, "base64"));
|
|
27529
27963
|
cleanupStaleMaterializedImages(dir);
|
|
27530
27964
|
return filePath;
|
|
27531
27965
|
}
|
|
@@ -27537,14 +27971,14 @@ function cleanupStaleMaterializedImages(dir) {
|
|
|
27537
27971
|
if (now - lastMaterializedImageCleanupAt < MATERIALIZED_IMAGE_CLEANUP_INTERVAL_MS) return;
|
|
27538
27972
|
lastMaterializedImageCleanupAt = now;
|
|
27539
27973
|
try {
|
|
27540
|
-
const entries =
|
|
27974
|
+
const entries = fs12.readdirSync(dir);
|
|
27541
27975
|
for (const entry of entries) {
|
|
27542
27976
|
if (!entry.startsWith("adhdev-input-image-")) continue;
|
|
27543
|
-
const fullPath =
|
|
27977
|
+
const fullPath = path21.join(dir, entry);
|
|
27544
27978
|
try {
|
|
27545
|
-
const stat2 =
|
|
27979
|
+
const stat2 = fs12.statSync(fullPath);
|
|
27546
27980
|
if (now - stat2.mtimeMs > MATERIALIZED_IMAGE_MAX_AGE_MS) {
|
|
27547
|
-
|
|
27981
|
+
fs12.unlinkSync(fullPath);
|
|
27548
27982
|
}
|
|
27549
27983
|
} catch {
|
|
27550
27984
|
}
|
|
@@ -27563,7 +27997,7 @@ function buildCliStructuredInputPrompt(input, options = {}) {
|
|
|
27563
27997
|
const promptParts = [];
|
|
27564
27998
|
const imageRefs = [];
|
|
27565
27999
|
const resourceRefs = [];
|
|
27566
|
-
const materializeDir = options.materializeDir ||
|
|
28000
|
+
const materializeDir = options.materializeDir || path21.join(os16.tmpdir(), "adhdev-input-media");
|
|
27567
28001
|
input.parts.forEach((part, index) => {
|
|
27568
28002
|
if (part.type === "text" && part.text.trim()) {
|
|
27569
28003
|
promptParts.push(part.text.trim());
|
|
@@ -27630,7 +28064,7 @@ function buildIncrementalHistoryAppendMessages(previousMessages, currentMessages
|
|
|
27630
28064
|
var CachedDatabaseSync = null;
|
|
27631
28065
|
function getDatabaseSync() {
|
|
27632
28066
|
if (CachedDatabaseSync) return CachedDatabaseSync;
|
|
27633
|
-
const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(
|
|
28067
|
+
const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(path21.join(process.cwd(), "__adhdev_sqlite_loader__.js"));
|
|
27634
28068
|
const sqliteModule = requireFn(`node:${"sqlite"}`);
|
|
27635
28069
|
CachedDatabaseSync = sqliteModule.DatabaseSync;
|
|
27636
28070
|
if (!CachedDatabaseSync) {
|
|
@@ -27784,10 +28218,10 @@ var CliProviderInstance = class {
|
|
|
27784
28218
|
* Replaces the previously duplicated probeOpenCode/Codex/Goose functions.
|
|
27785
28219
|
*/
|
|
27786
28220
|
probeSessionIdFromConfig(probe) {
|
|
27787
|
-
const resolvedDbPath = probe.dbPath.replace(/^~/,
|
|
28221
|
+
const resolvedDbPath = probe.dbPath.replace(/^~/, os16.homedir());
|
|
27788
28222
|
const now = Date.now();
|
|
27789
28223
|
if (this.cachedSqliteDbMissingUntil > now) return null;
|
|
27790
|
-
if (!
|
|
28224
|
+
if (!fs12.existsSync(resolvedDbPath)) {
|
|
27791
28225
|
this.cachedSqliteDbMissingUntil = now + 1e4;
|
|
27792
28226
|
return null;
|
|
27793
28227
|
}
|
|
@@ -27979,7 +28413,7 @@ var CliProviderInstance = class {
|
|
|
27979
28413
|
};
|
|
27980
28414
|
}
|
|
27981
28415
|
getSessionModalState(sessionId) {
|
|
27982
|
-
const adapterStatus = this.adapter.getStatus({ allowParse:
|
|
28416
|
+
const adapterStatus = this.adapter.getStatus({ allowParse: true });
|
|
27983
28417
|
const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
|
|
27984
28418
|
const visibleStatus = autoApproveActive ? "generating" : adapterStatus.status;
|
|
27985
28419
|
const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
|
|
@@ -28889,7 +29323,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
28889
29323
|
};
|
|
28890
29324
|
addDir(this.workingDir);
|
|
28891
29325
|
try {
|
|
28892
|
-
addDir(
|
|
29326
|
+
addDir(fs12.realpathSync.native(this.workingDir));
|
|
28893
29327
|
} catch {
|
|
28894
29328
|
}
|
|
28895
29329
|
return Array.from(dirs);
|
|
@@ -28926,7 +29360,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
28926
29360
|
};
|
|
28927
29361
|
|
|
28928
29362
|
// src/providers/acp-provider-instance.ts
|
|
28929
|
-
var
|
|
29363
|
+
var path22 = __toESM(require("path"));
|
|
28930
29364
|
var import_stream = require("stream");
|
|
28931
29365
|
var import_child_process4 = require("child_process");
|
|
28932
29366
|
var import_sdk = require("@agentclientprotocol/sdk");
|
|
@@ -29701,7 +30135,7 @@ var AcpProviderInstance = class {
|
|
|
29701
30135
|
return b.uri ? {
|
|
29702
30136
|
type: "resource_link",
|
|
29703
30137
|
uri: b.uri,
|
|
29704
|
-
name:
|
|
30138
|
+
name: path22.basename(b.uri),
|
|
29705
30139
|
mimeType: b.mimeType,
|
|
29706
30140
|
...b.transcript ? { description: b.transcript } : {}
|
|
29707
30141
|
} : { type: "text", text: b.transcript || `[Video attachment: ${b.mimeType}]` };
|
|
@@ -30159,11 +30593,11 @@ function shouldRestoreHostedRuntime(record, managerTag) {
|
|
|
30159
30593
|
// src/commands/cli-manager.ts
|
|
30160
30594
|
function isExplicitCommand(command) {
|
|
30161
30595
|
const trimmed = command.trim();
|
|
30162
|
-
return
|
|
30596
|
+
return path23.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
|
|
30163
30597
|
}
|
|
30164
30598
|
function expandExecutable(command) {
|
|
30165
30599
|
const trimmed = command.trim();
|
|
30166
|
-
return trimmed.startsWith("~") ?
|
|
30600
|
+
return trimmed.startsWith("~") ? path23.join(os17.homedir(), trimmed.slice(1)) : trimmed;
|
|
30167
30601
|
}
|
|
30168
30602
|
function commandExists(command) {
|
|
30169
30603
|
const trimmed = command.trim();
|
|
@@ -30290,10 +30724,10 @@ function hasCliArg(args, flag) {
|
|
|
30290
30724
|
return args.some((arg) => arg === flag || arg.startsWith(`${flag}=`));
|
|
30291
30725
|
}
|
|
30292
30726
|
function ensureEmptyDelegatedMcpConfig(workspace) {
|
|
30293
|
-
const baseDir =
|
|
30727
|
+
const baseDir = path23.join(os17.tmpdir(), "adhdev-delegated-agent-empty-mcp");
|
|
30294
30728
|
(0, import_fs12.mkdirSync)(baseDir, { recursive: true });
|
|
30295
|
-
const workspaceHash = crypto5.createHash("sha256").update(
|
|
30296
|
-
const filePath =
|
|
30729
|
+
const workspaceHash = crypto5.createHash("sha256").update(path23.resolve(workspace || os17.tmpdir())).digest("hex").slice(0, 16);
|
|
30730
|
+
const filePath = path23.join(baseDir, `${workspaceHash}.json`);
|
|
30297
30731
|
(0, import_fs12.writeFileSync)(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
|
|
30298
30732
|
return filePath;
|
|
30299
30733
|
}
|
|
@@ -30587,7 +31021,7 @@ var DaemonCliManager = class {
|
|
|
30587
31021
|
async startSession(cliType, workingDir, cliArgs, initialModel, options) {
|
|
30588
31022
|
const trimmed = (workingDir || "").trim();
|
|
30589
31023
|
if (!trimmed) throw new Error("working directory required");
|
|
30590
|
-
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/,
|
|
31024
|
+
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os17.homedir()) : path23.resolve(trimmed);
|
|
30591
31025
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
30592
31026
|
const rawProvider = this.providerLoader.getByAlias(cliType);
|
|
30593
31027
|
const provider = rawProvider ? this.providerLoader.resolve(normalizedType) || rawProvider : void 0;
|
|
@@ -30972,6 +31406,20 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
30972
31406
|
cliArgs: args?.cliArgs,
|
|
30973
31407
|
env: args?.env
|
|
30974
31408
|
}) : null;
|
|
31409
|
+
const provLookup = this.providerLoader.getMeta(this.providerLoader.resolveAlias(cliType));
|
|
31410
|
+
const provTrust = provLookup?._sourceTrust;
|
|
31411
|
+
if (provTrust === "external-untrusted" && args?.confirmExternalUntrusted !== true) {
|
|
31412
|
+
return {
|
|
31413
|
+
success: false,
|
|
31414
|
+
error: "untrusted_external_provider",
|
|
31415
|
+
provider: {
|
|
31416
|
+
type: provLookup?.type ?? cliType,
|
|
31417
|
+
sourceName: provLookup?._sourceName ?? null,
|
|
31418
|
+
trust: provTrust
|
|
31419
|
+
},
|
|
31420
|
+
hint: "Resend launch_cli with confirmExternalUntrusted=true after the user explicitly approves running JavaScript from this 3rd-party source."
|
|
31421
|
+
};
|
|
31422
|
+
}
|
|
30975
31423
|
const started = await this.startSession(
|
|
30976
31424
|
cliType,
|
|
30977
31425
|
dir,
|
|
@@ -31158,13 +31606,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
31158
31606
|
// src/launch.ts
|
|
31159
31607
|
var import_child_process6 = require("child_process");
|
|
31160
31608
|
var net = __toESM(require("net"));
|
|
31161
|
-
var
|
|
31162
|
-
var
|
|
31609
|
+
var os23 = __toESM(require("os"));
|
|
31610
|
+
var path32 = __toESM(require("path"));
|
|
31163
31611
|
|
|
31164
31612
|
// src/providers/provider-loader.ts
|
|
31165
|
-
var
|
|
31166
|
-
var
|
|
31167
|
-
var
|
|
31613
|
+
var fs19 = __toESM(require("fs"));
|
|
31614
|
+
var path31 = __toESM(require("path"));
|
|
31615
|
+
var os22 = __toESM(require("os"));
|
|
31168
31616
|
var chokidar = __toESM(require("chokidar"));
|
|
31169
31617
|
init_logger();
|
|
31170
31618
|
|
|
@@ -31498,6 +31946,7 @@ function validateControl(control, errors) {
|
|
|
31498
31946
|
}
|
|
31499
31947
|
|
|
31500
31948
|
// src/providers/provider-loader.ts
|
|
31949
|
+
init_external_sources();
|
|
31501
31950
|
function registerProviderScriptRootSafely(root) {
|
|
31502
31951
|
if (!root || typeof root !== "string") return;
|
|
31503
31952
|
try {
|
|
@@ -31537,9 +31986,9 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31537
31986
|
static siblingStderrLogged = /* @__PURE__ */ new Set();
|
|
31538
31987
|
static looksLikeProviderRoot(candidate) {
|
|
31539
31988
|
try {
|
|
31540
|
-
if (!
|
|
31989
|
+
if (!fs19.existsSync(candidate) || !fs19.statSync(candidate).isDirectory()) return false;
|
|
31541
31990
|
return ["ide", "extension", "cli", "acp"].some(
|
|
31542
|
-
(category) =>
|
|
31991
|
+
(category) => fs19.existsSync(path31.join(candidate, category))
|
|
31543
31992
|
);
|
|
31544
31993
|
} catch {
|
|
31545
31994
|
return false;
|
|
@@ -31547,20 +31996,20 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31547
31996
|
}
|
|
31548
31997
|
static hasProviderRootMarker(candidate) {
|
|
31549
31998
|
try {
|
|
31550
|
-
return
|
|
31999
|
+
return fs19.existsSync(path31.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
|
|
31551
32000
|
} catch {
|
|
31552
32001
|
return false;
|
|
31553
32002
|
}
|
|
31554
32003
|
}
|
|
31555
32004
|
detectDefaultUserDir() {
|
|
31556
|
-
const fallback =
|
|
32005
|
+
const fallback = path31.join(os22.homedir(), ".adhdev", "providers");
|
|
31557
32006
|
const envOptIn = process.env[_ProviderLoader.SIBLING_ENV_VAR] === "1";
|
|
31558
32007
|
const visited = /* @__PURE__ */ new Set();
|
|
31559
32008
|
for (const start of this.probeStarts) {
|
|
31560
|
-
let current =
|
|
32009
|
+
let current = path31.resolve(start);
|
|
31561
32010
|
while (!visited.has(current)) {
|
|
31562
32011
|
visited.add(current);
|
|
31563
|
-
const siblingCandidate =
|
|
32012
|
+
const siblingCandidate = path31.join(path31.dirname(current), _ProviderLoader.REPO_PROVIDER_DIRNAME);
|
|
31564
32013
|
if (_ProviderLoader.looksLikeProviderRoot(siblingCandidate)) {
|
|
31565
32014
|
const hasMarker = _ProviderLoader.hasProviderRootMarker(siblingCandidate);
|
|
31566
32015
|
if (envOptIn || hasMarker) {
|
|
@@ -31582,7 +32031,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31582
32031
|
return { path: siblingCandidate, source };
|
|
31583
32032
|
}
|
|
31584
32033
|
}
|
|
31585
|
-
const parent =
|
|
32034
|
+
const parent = path31.dirname(current);
|
|
31586
32035
|
if (parent === current) break;
|
|
31587
32036
|
current = parent;
|
|
31588
32037
|
}
|
|
@@ -31592,17 +32041,34 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31592
32041
|
constructor(options) {
|
|
31593
32042
|
this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
|
|
31594
32043
|
this.probeStarts = options?.probeStarts ?? [process.cwd(), __dirname];
|
|
31595
|
-
this.defaultProvidersDir =
|
|
32044
|
+
this.defaultProvidersDir = path31.join(os22.homedir(), ".adhdev", "providers");
|
|
31596
32045
|
const detected = this.detectDefaultUserDir();
|
|
31597
32046
|
this.userDir = detected.path;
|
|
31598
32047
|
this.userDirSource = detected.source;
|
|
31599
|
-
this.upstreamDir =
|
|
32048
|
+
this.upstreamDir = path31.join(this.defaultProvidersDir, ".upstream");
|
|
31600
32049
|
this.disableUpstream = false;
|
|
31601
32050
|
this.applySourceConfig({
|
|
31602
32051
|
userDir: options?.userDir,
|
|
31603
32052
|
sourceMode: options?.sourceMode,
|
|
31604
32053
|
disableUpstream: options?.disableUpstream
|
|
31605
32054
|
});
|
|
32055
|
+
this.migrateMarketplaceDirToExternal();
|
|
32056
|
+
}
|
|
32057
|
+
migrateMarketplaceDirToExternal() {
|
|
32058
|
+
try {
|
|
32059
|
+
const home = os22.homedir();
|
|
32060
|
+
const oldDir = path31.join(home, ".adhdev", "marketplace");
|
|
32061
|
+
const newDir = path31.join(home, ".adhdev", "external");
|
|
32062
|
+
if (!fs19.existsSync(oldDir)) return;
|
|
32063
|
+
if (fs19.existsSync(newDir)) {
|
|
32064
|
+
this.log(`Migration skipped: both ~/.adhdev/marketplace and ~/.adhdev/external exist (marketplace dir is now inert and can be removed manually).`);
|
|
32065
|
+
return;
|
|
32066
|
+
}
|
|
32067
|
+
fs19.renameSync(oldDir, newDir);
|
|
32068
|
+
this.log(`Migrated ~/.adhdev/marketplace \u2192 ~/.adhdev/external (one-time rename after provider source-layer cleanup).`);
|
|
32069
|
+
} catch (e) {
|
|
32070
|
+
this.log(`Marketplace\u2192external migration failed: ${e?.message || e}`);
|
|
32071
|
+
}
|
|
31606
32072
|
}
|
|
31607
32073
|
log(msg) {
|
|
31608
32074
|
this.logFn(`[ProviderLoader] ${msg}`);
|
|
@@ -31628,8 +32094,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31628
32094
|
* Highest-priority editable overrides come first.
|
|
31629
32095
|
*/
|
|
31630
32096
|
getProviderRoots() {
|
|
31631
|
-
const
|
|
31632
|
-
return [this.userDir,
|
|
32097
|
+
const externalDir = path31.join(os22.homedir(), ".adhdev", "external");
|
|
32098
|
+
return [this.userDir, externalDir, this.upstreamDir];
|
|
31633
32099
|
}
|
|
31634
32100
|
getSourceConfig() {
|
|
31635
32101
|
return {
|
|
@@ -31656,7 +32122,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31656
32122
|
this.userDir = detected.path;
|
|
31657
32123
|
this.userDirSource = detected.source;
|
|
31658
32124
|
}
|
|
31659
|
-
this.upstreamDir =
|
|
32125
|
+
this.upstreamDir = path31.join(this.defaultProvidersDir, ".upstream");
|
|
31660
32126
|
this.disableUpstream = this.sourceMode === "no-upstream";
|
|
31661
32127
|
if (this.explicitProviderDir) {
|
|
31662
32128
|
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
@@ -31670,7 +32136,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31670
32136
|
* Canonical provider directory shape for a given root.
|
|
31671
32137
|
*/
|
|
31672
32138
|
getProviderDir(root, category, type) {
|
|
31673
|
-
return
|
|
32139
|
+
return path31.join(root, category, type);
|
|
31674
32140
|
}
|
|
31675
32141
|
/**
|
|
31676
32142
|
* Canonical user override directory for a provider.
|
|
@@ -31697,20 +32163,23 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31697
32163
|
resolveProviderFile(type, ...segments) {
|
|
31698
32164
|
const dir = this.findProviderDirInternal(type);
|
|
31699
32165
|
if (!dir) return null;
|
|
31700
|
-
return
|
|
32166
|
+
return path31.join(dir, ...segments);
|
|
31701
32167
|
}
|
|
31702
32168
|
/**
|
|
31703
32169
|
* Load all providers (3-tier priority)
|
|
31704
|
-
* 1.
|
|
31705
|
-
* 2.
|
|
31706
|
-
*
|
|
32170
|
+
* 1. ~/.adhdev/providers/.upstream/ — official git, auto-synced
|
|
32171
|
+
* 2. ~/.adhdev/external/ — 3rd-party git sources, user-added,
|
|
32172
|
+
* bundled providers may include arbitrary JS (untrusted by default)
|
|
32173
|
+
* 3. ~/.adhdev/providers/ (excluding .upstream) — user-authored customs,
|
|
32174
|
+
* always wins
|
|
32175
|
+
* Highest priority listed last (overwrites earlier loads).
|
|
31707
32176
|
* If .upstream/ is empty, call fetchLatest() before loadAll().
|
|
31708
32177
|
*/
|
|
31709
32178
|
loadAll() {
|
|
31710
32179
|
this.providers.clear();
|
|
31711
32180
|
this.providerAvailability.clear();
|
|
31712
32181
|
let upstreamCount = 0;
|
|
31713
|
-
if (!this.disableUpstream &&
|
|
32182
|
+
if (!this.disableUpstream && fs19.existsSync(this.upstreamDir)) {
|
|
31714
32183
|
upstreamCount = this.loadDir(this.upstreamDir);
|
|
31715
32184
|
if (upstreamCount > 0) {
|
|
31716
32185
|
this.log(`Loaded ${upstreamCount} upstream providers (auto-updated)`);
|
|
@@ -31718,14 +32187,60 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31718
32187
|
} else if (this.disableUpstream) {
|
|
31719
32188
|
this.log("Upstream loading disabled (sourceMode=no-upstream)");
|
|
31720
32189
|
}
|
|
31721
|
-
const
|
|
31722
|
-
if (
|
|
31723
|
-
const
|
|
31724
|
-
|
|
31725
|
-
|
|
32190
|
+
const externalDir = path31.join(os22.homedir(), ".adhdev", "external");
|
|
32191
|
+
if (fs19.existsSync(externalDir)) {
|
|
32192
|
+
const rootEntries = (() => {
|
|
32193
|
+
try {
|
|
32194
|
+
return fs19.readdirSync(externalDir, { withFileTypes: true });
|
|
32195
|
+
} catch {
|
|
32196
|
+
return [];
|
|
32197
|
+
}
|
|
32198
|
+
})();
|
|
32199
|
+
const KNOWN_CATEGORIES = /* @__PURE__ */ new Set(["cli", "ide", "extension", "acp"]);
|
|
32200
|
+
const looksLegacy = rootEntries.some((e) => e.isDirectory() && KNOWN_CATEGORIES.has(e.name));
|
|
32201
|
+
if (looksLegacy) {
|
|
32202
|
+
const externalCount = this.loadDir(externalDir);
|
|
32203
|
+
if (externalCount > 0) {
|
|
32204
|
+
this.log(`Loaded ${externalCount} external providers (legacy unnamed source)`);
|
|
32205
|
+
}
|
|
32206
|
+
} else {
|
|
32207
|
+
const activeFile = loadProvidersActive();
|
|
32208
|
+
let totalLoaded = 0;
|
|
32209
|
+
const ambiguousTypes = [];
|
|
32210
|
+
for (const sourceEntry of rootEntries) {
|
|
32211
|
+
if (!sourceEntry.isDirectory()) continue;
|
|
32212
|
+
const sourceDir = path31.join(externalDir, sourceEntry.name);
|
|
32213
|
+
const sourceLoaded = this.loadDir(sourceDir);
|
|
32214
|
+
if (sourceLoaded > 0) {
|
|
32215
|
+
totalLoaded += sourceLoaded;
|
|
32216
|
+
this.log(`Loaded ${sourceLoaded} providers from external source "${sourceEntry.name}"`);
|
|
32217
|
+
}
|
|
32218
|
+
}
|
|
32219
|
+
for (const [type] of this.providers) {
|
|
32220
|
+
const prov = this.providers.get(type);
|
|
32221
|
+
if (!prov) continue;
|
|
32222
|
+
const resolved = resolveActiveSource(prov.category, type, activeFile);
|
|
32223
|
+
if (resolved.candidates.length <= 1) continue;
|
|
32224
|
+
if (resolved.ambiguous) {
|
|
32225
|
+
ambiguousTypes.push({ type, chosen: resolved.source ?? "?", candidates: resolved.candidates });
|
|
32226
|
+
}
|
|
32227
|
+
if (resolved.source && resolved.source !== "?") {
|
|
32228
|
+
const sourceDir = path31.join(externalDir, resolved.source);
|
|
32229
|
+
const reloadCount = this.loadDir(sourceDir);
|
|
32230
|
+
if (reloadCount === 0) {
|
|
32231
|
+
this.log(`Active source "${resolved.source}" no longer provides ${type}`);
|
|
32232
|
+
}
|
|
32233
|
+
}
|
|
32234
|
+
}
|
|
32235
|
+
if (totalLoaded > 0) {
|
|
32236
|
+
this.log(`Loaded ${totalLoaded} external providers (3rd-party sources)`);
|
|
32237
|
+
}
|
|
32238
|
+
for (const a of ambiguousTypes) {
|
|
32239
|
+
this.log(`Ambiguous provider "${a.type}" \u2014 provided by [${a.candidates.join(", ")}], defaulted to "${a.chosen}". Set the active source from the dashboard to silence this warning.`);
|
|
32240
|
+
}
|
|
31726
32241
|
}
|
|
31727
32242
|
}
|
|
31728
|
-
if (
|
|
32243
|
+
if (fs19.existsSync(this.userDir)) {
|
|
31729
32244
|
const userCount = this.loadDir(this.userDir, [".upstream"]);
|
|
31730
32245
|
if (userCount > 0) {
|
|
31731
32246
|
this.log(`Loaded ${userCount} user custom providers (never auto-updated)`);
|
|
@@ -31740,10 +32255,10 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31740
32255
|
* Check if upstream directory exists and has providers.
|
|
31741
32256
|
*/
|
|
31742
32257
|
hasUpstream() {
|
|
31743
|
-
if (!
|
|
32258
|
+
if (!fs19.existsSync(this.upstreamDir)) return false;
|
|
31744
32259
|
try {
|
|
31745
|
-
return
|
|
31746
|
-
(d) =>
|
|
32260
|
+
return fs19.readdirSync(this.upstreamDir).some(
|
|
32261
|
+
(d) => fs19.statSync(path31.join(this.upstreamDir, d)).isDirectory()
|
|
31747
32262
|
);
|
|
31748
32263
|
} catch {
|
|
31749
32264
|
return false;
|
|
@@ -32241,8 +32756,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32241
32756
|
resolved._resolvedScriptDir = entry.scriptDir;
|
|
32242
32757
|
resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
|
|
32243
32758
|
if (providerDir) {
|
|
32244
|
-
const fullDir =
|
|
32245
|
-
resolved._resolvedScriptsPath =
|
|
32759
|
+
const fullDir = path31.join(providerDir, entry.scriptDir);
|
|
32760
|
+
resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
|
|
32246
32761
|
}
|
|
32247
32762
|
matched = true;
|
|
32248
32763
|
}
|
|
@@ -32260,8 +32775,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32260
32775
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
32261
32776
|
resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
|
|
32262
32777
|
if (providerDir) {
|
|
32263
|
-
const fullDir =
|
|
32264
|
-
resolved._resolvedScriptsPath =
|
|
32778
|
+
const fullDir = path31.join(providerDir, base.defaultScriptDir);
|
|
32779
|
+
resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
|
|
32265
32780
|
}
|
|
32266
32781
|
}
|
|
32267
32782
|
resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
|
|
@@ -32278,8 +32793,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32278
32793
|
resolved._resolvedScriptDir = dirOverride;
|
|
32279
32794
|
resolved._resolvedScriptsSource = `versions:${range}`;
|
|
32280
32795
|
if (providerDir) {
|
|
32281
|
-
const fullDir =
|
|
32282
|
-
resolved._resolvedScriptsPath =
|
|
32796
|
+
const fullDir = path31.join(providerDir, dirOverride);
|
|
32797
|
+
resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
|
|
32283
32798
|
}
|
|
32284
32799
|
}
|
|
32285
32800
|
} else if (override.scripts) {
|
|
@@ -32295,8 +32810,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32295
32810
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
32296
32811
|
resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
|
|
32297
32812
|
if (providerDir) {
|
|
32298
|
-
const fullDir =
|
|
32299
|
-
resolved._resolvedScriptsPath =
|
|
32813
|
+
const fullDir = path31.join(providerDir, base.defaultScriptDir);
|
|
32814
|
+
resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
|
|
32300
32815
|
}
|
|
32301
32816
|
}
|
|
32302
32817
|
}
|
|
@@ -32313,13 +32828,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32313
32828
|
if (providerDir2) {
|
|
32314
32829
|
for (const [scriptName, override] of Object.entries(base.overrides)) {
|
|
32315
32830
|
if (!override || typeof override.path !== "string") continue;
|
|
32316
|
-
const fullPath =
|
|
32317
|
-
if (!
|
|
32831
|
+
const fullPath = path31.join(providerDir2, override.path);
|
|
32832
|
+
if (!fs19.existsSync(fullPath)) {
|
|
32318
32833
|
this.log(` [overrides] ${base.type}: ${scriptName} path not found: ${fullPath}`);
|
|
32319
32834
|
continue;
|
|
32320
32835
|
}
|
|
32321
32836
|
try {
|
|
32322
|
-
registerProviderScriptRootSafely(
|
|
32837
|
+
registerProviderScriptRootSafely(path31.dirname(path31.dirname(providerDir2)));
|
|
32323
32838
|
delete require.cache[require.resolve(fullPath)];
|
|
32324
32839
|
const fn = require(fullPath);
|
|
32325
32840
|
const target = typeof fn === "function" ? fn : fn && fn[scriptName];
|
|
@@ -32344,19 +32859,19 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32344
32859
|
}
|
|
32345
32860
|
if (providerDir) {
|
|
32346
32861
|
try {
|
|
32347
|
-
const
|
|
32348
|
-
const
|
|
32862
|
+
const fs28 = require("fs");
|
|
32863
|
+
const path40 = require("path");
|
|
32349
32864
|
const candidates = [];
|
|
32350
32865
|
if (Array.isArray(base.compatibility)) {
|
|
32351
32866
|
for (const entry of base.compatibility) {
|
|
32352
32867
|
if (typeof entry?.spec !== "string") continue;
|
|
32353
32868
|
const matches = !entry.ideVersion || currentVersion && this.matchesVersion(currentVersion, entry.ideVersion) || !currentVersion;
|
|
32354
|
-
if (matches) candidates.push(
|
|
32869
|
+
if (matches) candidates.push(path40.join(providerDir, entry.spec));
|
|
32355
32870
|
}
|
|
32356
32871
|
}
|
|
32357
|
-
candidates.push(
|
|
32358
|
-
candidates.push(
|
|
32359
|
-
const specPath = candidates.find((p) =>
|
|
32872
|
+
candidates.push(path40.join(providerDir, "specs", "default.json"));
|
|
32873
|
+
candidates.push(path40.join(providerDir, "spec.json"));
|
|
32874
|
+
const specPath = candidates.find((p) => fs28.existsSync(p));
|
|
32360
32875
|
if (specPath) {
|
|
32361
32876
|
resolved._resolvedSpecPath = specPath;
|
|
32362
32877
|
const { loadSpec: loadSpec2 } = (init_loader(), __toCommonJS(loader_exports));
|
|
@@ -32385,10 +32900,10 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32385
32900
|
format = `spec-${nh.source.kind}`;
|
|
32386
32901
|
reader = (input) => executeNativeHistory2(nh, input);
|
|
32387
32902
|
} else if (nh.override_path) {
|
|
32388
|
-
const overrideFile =
|
|
32389
|
-
if (
|
|
32903
|
+
const overrideFile = path40.resolve(providerDir, nh.override_path);
|
|
32904
|
+
if (fs28.existsSync(overrideFile)) {
|
|
32390
32905
|
try {
|
|
32391
|
-
registerProviderScriptRootSafely(
|
|
32906
|
+
registerProviderScriptRootSafely(path40.dirname(path40.dirname(providerDir)));
|
|
32392
32907
|
delete require.cache[require.resolve(overrideFile)];
|
|
32393
32908
|
const mod = require(overrideFile);
|
|
32394
32909
|
const fn = typeof mod === "function" ? mod : mod && typeof mod.default === "function" ? mod.default : null;
|
|
@@ -32432,16 +32947,16 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32432
32947
|
this.debugLog(`[loadScriptsFromDir] ${type}: providerDir not found`);
|
|
32433
32948
|
return null;
|
|
32434
32949
|
}
|
|
32435
|
-
const dir =
|
|
32436
|
-
if (!
|
|
32950
|
+
const dir = path31.join(providerDir, scriptDir);
|
|
32951
|
+
if (!fs19.existsSync(dir)) {
|
|
32437
32952
|
this.debugLog(`[loadScriptsFromDir] ${type}: dir not found: ${dir}`);
|
|
32438
32953
|
return null;
|
|
32439
32954
|
}
|
|
32440
|
-
registerProviderScriptRootSafely(
|
|
32955
|
+
registerProviderScriptRootSafely(path31.dirname(path31.dirname(providerDir)));
|
|
32441
32956
|
const cached = this.scriptsCache.get(dir);
|
|
32442
32957
|
if (cached) return cached;
|
|
32443
|
-
const scriptsJs =
|
|
32444
|
-
if (
|
|
32958
|
+
const scriptsJs = path31.join(dir, "scripts.js");
|
|
32959
|
+
if (fs19.existsSync(scriptsJs)) {
|
|
32445
32960
|
try {
|
|
32446
32961
|
delete require.cache[require.resolve(scriptsJs)];
|
|
32447
32962
|
const loaded = require(scriptsJs);
|
|
@@ -32462,9 +32977,9 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32462
32977
|
watch() {
|
|
32463
32978
|
this.stopWatch();
|
|
32464
32979
|
const watchDir = (dir) => {
|
|
32465
|
-
if (!
|
|
32980
|
+
if (!fs19.existsSync(dir)) {
|
|
32466
32981
|
try {
|
|
32467
|
-
|
|
32982
|
+
fs19.mkdirSync(dir, { recursive: true });
|
|
32468
32983
|
} catch {
|
|
32469
32984
|
return;
|
|
32470
32985
|
}
|
|
@@ -32485,7 +33000,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32485
33000
|
if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
|
|
32486
33001
|
if (reloadTimer) clearTimeout(reloadTimer);
|
|
32487
33002
|
reloadTimer = setTimeout(() => {
|
|
32488
|
-
this.log(`File changed: ${
|
|
33003
|
+
this.log(`File changed: ${path31.basename(filePath)}, reloading...`);
|
|
32489
33004
|
this.reload();
|
|
32490
33005
|
}, 300);
|
|
32491
33006
|
}
|
|
@@ -32553,11 +33068,11 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32553
33068
|
}
|
|
32554
33069
|
this.log(`Registry sync starting (${_ProviderLoader.REGISTRY_BASE_URL})...`);
|
|
32555
33070
|
const https = require("https");
|
|
32556
|
-
const regMetaPath =
|
|
33071
|
+
const regMetaPath = path31.join(this.upstreamDir, _ProviderLoader.REGISTRY_META_FILE);
|
|
32557
33072
|
let cachedChecksums = {};
|
|
32558
33073
|
try {
|
|
32559
|
-
if (
|
|
32560
|
-
cachedChecksums = JSON.parse(
|
|
33074
|
+
if (fs19.existsSync(regMetaPath)) {
|
|
33075
|
+
cachedChecksums = JSON.parse(fs19.readFileSync(regMetaPath, "utf-8")).checksums ?? {};
|
|
32561
33076
|
}
|
|
32562
33077
|
} catch {
|
|
32563
33078
|
}
|
|
@@ -32611,15 +33126,15 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32611
33126
|
this.log(`\u26A0 Registry checksum mismatch for ${type}@${version} \u2014 skipping`);
|
|
32612
33127
|
continue;
|
|
32613
33128
|
}
|
|
32614
|
-
const providerDir =
|
|
32615
|
-
|
|
32616
|
-
|
|
33129
|
+
const providerDir = path31.join(this.upstreamDir, category, type);
|
|
33130
|
+
fs19.mkdirSync(providerDir, { recursive: true });
|
|
33131
|
+
fs19.writeFileSync(path31.join(providerDir, "provider.json"), manifestBody, "utf-8");
|
|
32617
33132
|
cachedChecksums[cacheKey] = checksum;
|
|
32618
33133
|
updatedCount++;
|
|
32619
33134
|
this.log(`\u2713 Registry updated: ${category}/${type}@${version}`);
|
|
32620
33135
|
}
|
|
32621
|
-
|
|
32622
|
-
|
|
33136
|
+
fs19.mkdirSync(this.upstreamDir, { recursive: true });
|
|
33137
|
+
fs19.writeFileSync(regMetaPath, JSON.stringify({
|
|
32623
33138
|
checksums: cachedChecksums,
|
|
32624
33139
|
syncedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
32625
33140
|
providerCount: list.providers.length
|
|
@@ -32640,12 +33155,12 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32640
33155
|
const { exec: exec7 } = require("child_process");
|
|
32641
33156
|
const { promisify: promisify7 } = require("util");
|
|
32642
33157
|
const execAsync5 = promisify7(exec7);
|
|
32643
|
-
const metaPath =
|
|
33158
|
+
const metaPath = path31.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
32644
33159
|
let prevEtag = "";
|
|
32645
33160
|
let prevTimestamp = 0;
|
|
32646
33161
|
try {
|
|
32647
|
-
if (
|
|
32648
|
-
const meta = JSON.parse(
|
|
33162
|
+
if (fs19.existsSync(metaPath)) {
|
|
33163
|
+
const meta = JSON.parse(fs19.readFileSync(metaPath, "utf-8"));
|
|
32649
33164
|
prevEtag = meta.etag || "";
|
|
32650
33165
|
prevTimestamp = meta.timestamp || 0;
|
|
32651
33166
|
}
|
|
@@ -32700,39 +33215,39 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32700
33215
|
return { updated: false };
|
|
32701
33216
|
}
|
|
32702
33217
|
this.log("Downloading latest providers from GitHub...");
|
|
32703
|
-
const tmpTar =
|
|
32704
|
-
const tmpExtract =
|
|
33218
|
+
const tmpTar = path31.join(os22.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
|
|
33219
|
+
const tmpExtract = path31.join(os22.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
|
|
32705
33220
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
32706
|
-
|
|
33221
|
+
fs19.mkdirSync(tmpExtract, { recursive: true });
|
|
32707
33222
|
await execAsync5(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
32708
|
-
const extracted =
|
|
33223
|
+
const extracted = fs19.readdirSync(tmpExtract);
|
|
32709
33224
|
const rootDir = extracted.find(
|
|
32710
|
-
(d) =>
|
|
33225
|
+
(d) => fs19.statSync(path31.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
|
|
32711
33226
|
);
|
|
32712
33227
|
if (!rootDir) throw new Error("Unexpected tarball structure");
|
|
32713
|
-
const sourceDir =
|
|
33228
|
+
const sourceDir = path31.join(tmpExtract, rootDir);
|
|
32714
33229
|
const backupDir = this.upstreamDir + ".bak";
|
|
32715
|
-
if (
|
|
32716
|
-
if (
|
|
32717
|
-
|
|
33230
|
+
if (fs19.existsSync(this.upstreamDir)) {
|
|
33231
|
+
if (fs19.existsSync(backupDir)) fs19.rmSync(backupDir, { recursive: true, force: true });
|
|
33232
|
+
fs19.renameSync(this.upstreamDir, backupDir);
|
|
32718
33233
|
}
|
|
32719
33234
|
try {
|
|
32720
33235
|
this.copyDirRecursive(sourceDir, this.upstreamDir);
|
|
32721
33236
|
this.writeMeta(metaPath, etag || `ts-${Date.now()}`, Date.now());
|
|
32722
|
-
if (
|
|
33237
|
+
if (fs19.existsSync(backupDir)) fs19.rmSync(backupDir, { recursive: true, force: true });
|
|
32723
33238
|
} catch (e) {
|
|
32724
|
-
if (
|
|
32725
|
-
if (
|
|
32726
|
-
|
|
33239
|
+
if (fs19.existsSync(backupDir)) {
|
|
33240
|
+
if (fs19.existsSync(this.upstreamDir)) fs19.rmSync(this.upstreamDir, { recursive: true, force: true });
|
|
33241
|
+
fs19.renameSync(backupDir, this.upstreamDir);
|
|
32727
33242
|
}
|
|
32728
33243
|
throw e;
|
|
32729
33244
|
}
|
|
32730
33245
|
try {
|
|
32731
|
-
|
|
33246
|
+
fs19.rmSync(tmpTar, { force: true });
|
|
32732
33247
|
} catch {
|
|
32733
33248
|
}
|
|
32734
33249
|
try {
|
|
32735
|
-
|
|
33250
|
+
fs19.rmSync(tmpExtract, { recursive: true, force: true });
|
|
32736
33251
|
} catch {
|
|
32737
33252
|
}
|
|
32738
33253
|
const upstreamCount = this.countProviders(this.upstreamDir);
|
|
@@ -32764,7 +33279,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32764
33279
|
reject(new Error(`HTTP ${res.statusCode}`));
|
|
32765
33280
|
return;
|
|
32766
33281
|
}
|
|
32767
|
-
const ws =
|
|
33282
|
+
const ws = fs19.createWriteStream(destPath);
|
|
32768
33283
|
res.pipe(ws);
|
|
32769
33284
|
ws.on("finish", () => {
|
|
32770
33285
|
ws.close();
|
|
@@ -32783,22 +33298,22 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32783
33298
|
}
|
|
32784
33299
|
/** Recursive directory copy */
|
|
32785
33300
|
copyDirRecursive(src, dest) {
|
|
32786
|
-
|
|
32787
|
-
for (const entry of
|
|
32788
|
-
const srcPath =
|
|
32789
|
-
const destPath =
|
|
33301
|
+
fs19.mkdirSync(dest, { recursive: true });
|
|
33302
|
+
for (const entry of fs19.readdirSync(src, { withFileTypes: true })) {
|
|
33303
|
+
const srcPath = path31.join(src, entry.name);
|
|
33304
|
+
const destPath = path31.join(dest, entry.name);
|
|
32790
33305
|
if (entry.isDirectory()) {
|
|
32791
33306
|
this.copyDirRecursive(srcPath, destPath);
|
|
32792
33307
|
} else {
|
|
32793
|
-
|
|
33308
|
+
fs19.copyFileSync(srcPath, destPath);
|
|
32794
33309
|
}
|
|
32795
33310
|
}
|
|
32796
33311
|
}
|
|
32797
33312
|
/** .meta.json save */
|
|
32798
33313
|
writeMeta(metaPath, etag, timestamp) {
|
|
32799
33314
|
try {
|
|
32800
|
-
|
|
32801
|
-
|
|
33315
|
+
fs19.mkdirSync(path31.dirname(metaPath), { recursive: true });
|
|
33316
|
+
fs19.writeFileSync(metaPath, JSON.stringify({
|
|
32802
33317
|
etag,
|
|
32803
33318
|
timestamp,
|
|
32804
33319
|
lastCheck: new Date(timestamp).toISOString(),
|
|
@@ -32809,15 +33324,15 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32809
33324
|
}
|
|
32810
33325
|
/** Count provider files (provider.v1.json or provider.json — at most one per dir). */
|
|
32811
33326
|
countProviders(dir) {
|
|
32812
|
-
if (!
|
|
33327
|
+
if (!fs19.existsSync(dir)) return 0;
|
|
32813
33328
|
let count = 0;
|
|
32814
33329
|
const scan = (d) => {
|
|
32815
33330
|
try {
|
|
32816
|
-
const entries =
|
|
33331
|
+
const entries = fs19.readdirSync(d, { withFileTypes: true });
|
|
32817
33332
|
const hasManifest = entries.some((e) => e.name === "provider.v1.json" || e.name === "provider.json");
|
|
32818
33333
|
if (hasManifest) count++;
|
|
32819
33334
|
for (const entry of entries) {
|
|
32820
|
-
if (entry.isDirectory()) scan(
|
|
33335
|
+
if (entry.isDirectory()) scan(path31.join(d, entry.name));
|
|
32821
33336
|
}
|
|
32822
33337
|
} catch {
|
|
32823
33338
|
}
|
|
@@ -33043,13 +33558,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
33043
33558
|
if (!provider) return null;
|
|
33044
33559
|
const cat = provider.category;
|
|
33045
33560
|
const searchRoots = this.getProviderRoots();
|
|
33046
|
-
const hasManifest = (dir) =>
|
|
33561
|
+
const hasManifest = (dir) => fs19.existsSync(path31.join(dir, "provider.v1.json")) || fs19.existsSync(path31.join(dir, "provider.json"));
|
|
33047
33562
|
const readManifestType = (dir) => {
|
|
33048
33563
|
for (const file of ["provider.v1.json", "provider.json"]) {
|
|
33049
|
-
const p =
|
|
33050
|
-
if (!
|
|
33564
|
+
const p = path31.join(dir, file);
|
|
33565
|
+
if (!fs19.existsSync(p)) continue;
|
|
33051
33566
|
try {
|
|
33052
|
-
const data = JSON.parse(
|
|
33567
|
+
const data = JSON.parse(fs19.readFileSync(p, "utf-8"));
|
|
33053
33568
|
if (typeof data?.type === "string") return data.type;
|
|
33054
33569
|
} catch {
|
|
33055
33570
|
}
|
|
@@ -33057,15 +33572,15 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
33057
33572
|
return null;
|
|
33058
33573
|
};
|
|
33059
33574
|
for (const root of searchRoots) {
|
|
33060
|
-
if (!
|
|
33575
|
+
if (!fs19.existsSync(root)) continue;
|
|
33061
33576
|
const candidate = this.getProviderDir(root, cat, type);
|
|
33062
33577
|
if (hasManifest(candidate)) return candidate;
|
|
33063
|
-
const catDir =
|
|
33064
|
-
if (
|
|
33578
|
+
const catDir = path31.join(root, cat);
|
|
33579
|
+
if (fs19.existsSync(catDir)) {
|
|
33065
33580
|
try {
|
|
33066
|
-
for (const entry of
|
|
33581
|
+
for (const entry of fs19.readdirSync(catDir, { withFileTypes: true })) {
|
|
33067
33582
|
if (!entry.isDirectory()) continue;
|
|
33068
|
-
const entryDir =
|
|
33583
|
+
const entryDir = path31.join(catDir, entry.name);
|
|
33069
33584
|
const manifestType = readManifestType(entryDir);
|
|
33070
33585
|
if (manifestType === type) return entryDir;
|
|
33071
33586
|
}
|
|
@@ -33081,8 +33596,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
33081
33596
|
* (template substitution is NOT applied here — scripts.js handles that)
|
|
33082
33597
|
*/
|
|
33083
33598
|
buildScriptWrappersFromDir(dir) {
|
|
33084
|
-
const scriptsJs =
|
|
33085
|
-
if (
|
|
33599
|
+
const scriptsJs = path31.join(dir, "scripts.js");
|
|
33600
|
+
if (fs19.existsSync(scriptsJs)) {
|
|
33086
33601
|
try {
|
|
33087
33602
|
delete require.cache[require.resolve(scriptsJs)];
|
|
33088
33603
|
return require(scriptsJs);
|
|
@@ -33092,13 +33607,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
33092
33607
|
const toCamel = (name) => name.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
|
|
33093
33608
|
const result = {};
|
|
33094
33609
|
try {
|
|
33095
|
-
for (const file of
|
|
33610
|
+
for (const file of fs19.readdirSync(dir)) {
|
|
33096
33611
|
if (!file.endsWith(".js")) continue;
|
|
33097
33612
|
const scriptName = toCamel(file.replace(".js", ""));
|
|
33098
|
-
const filePath =
|
|
33613
|
+
const filePath = path31.join(dir, file);
|
|
33099
33614
|
result[scriptName] = (...args) => {
|
|
33100
33615
|
try {
|
|
33101
|
-
let content =
|
|
33616
|
+
let content = fs19.readFileSync(filePath, "utf-8");
|
|
33102
33617
|
if (args[0] && typeof args[0] === "object") {
|
|
33103
33618
|
for (const [key, val] of Object.entries(args[0])) {
|
|
33104
33619
|
let v = val;
|
|
@@ -33144,12 +33659,12 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
33144
33659
|
* Structure: dir/category/agent-name/provider.{json,js}
|
|
33145
33660
|
*/
|
|
33146
33661
|
loadDir(dir, excludeDirs) {
|
|
33147
|
-
if (!
|
|
33662
|
+
if (!fs19.existsSync(dir)) return 0;
|
|
33148
33663
|
let count = 0;
|
|
33149
33664
|
const scan = (d) => {
|
|
33150
33665
|
let entries;
|
|
33151
33666
|
try {
|
|
33152
|
-
entries =
|
|
33667
|
+
entries = fs19.readdirSync(d, { withFileTypes: true });
|
|
33153
33668
|
} catch {
|
|
33154
33669
|
return;
|
|
33155
33670
|
}
|
|
@@ -33157,9 +33672,9 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
33157
33672
|
const hasJson = entries.some((e) => e.name === "provider.json");
|
|
33158
33673
|
if (hasV1 || hasJson) {
|
|
33159
33674
|
const manifestFile = hasV1 ? "provider.v1.json" : "provider.json";
|
|
33160
|
-
const jsonPath =
|
|
33675
|
+
const jsonPath = path31.join(d, manifestFile);
|
|
33161
33676
|
try {
|
|
33162
|
-
const raw =
|
|
33677
|
+
const raw = fs19.readFileSync(jsonPath, "utf-8");
|
|
33163
33678
|
const mod = JSON.parse(raw);
|
|
33164
33679
|
if (hasV1 && mod?.category === "cli") {
|
|
33165
33680
|
try {
|
|
@@ -33197,10 +33712,10 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
33197
33712
|
this.log(`\u26A0 Invalid provider at ${jsonPath}: ${validation.errors.join("; ")}`);
|
|
33198
33713
|
} else {
|
|
33199
33714
|
const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
|
|
33200
|
-
const scriptsPath =
|
|
33201
|
-
if (!hasCompatibility &&
|
|
33715
|
+
const scriptsPath = path31.join(d, "scripts.js");
|
|
33716
|
+
if (!hasCompatibility && fs19.existsSync(scriptsPath)) {
|
|
33202
33717
|
try {
|
|
33203
|
-
registerProviderScriptRootSafely(
|
|
33718
|
+
registerProviderScriptRootSafely(path31.dirname(path31.dirname(d)));
|
|
33204
33719
|
delete require.cache[require.resolve(scriptsPath)];
|
|
33205
33720
|
const scripts = require(scriptsPath);
|
|
33206
33721
|
normalizedProvider.scripts = scripts;
|
|
@@ -33208,12 +33723,30 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
33208
33723
|
this.log(`\u26A0 Failed to load scripts: ${scriptsPath}: ${e.message}`);
|
|
33209
33724
|
}
|
|
33210
33725
|
}
|
|
33726
|
+
const externalDirAbs = path31.join(os22.homedir(), ".adhdev", "external");
|
|
33727
|
+
const layer = d.startsWith(externalDirAbs) ? "external" : d.startsWith(this.userDir) && !d.includes(".upstream") ? "user" : "upstream";
|
|
33728
|
+
try {
|
|
33729
|
+
const { inspectManifestShape: inspectManifestShape2, classifyTrust: classifyTrust2 } = (init_provider_trust(), __toCommonJS(provider_trust_exports));
|
|
33730
|
+
const shape = inspectManifestShape2(mod);
|
|
33731
|
+
const trust = classifyTrust2(layer, shape);
|
|
33732
|
+
normalizedProvider._sourceLayer = layer;
|
|
33733
|
+
normalizedProvider._sourceTrust = trust;
|
|
33734
|
+
normalizedProvider._manifestShape = shape;
|
|
33735
|
+
if (layer === "external") {
|
|
33736
|
+
const rel = path31.relative(externalDirAbs, d);
|
|
33737
|
+
const firstSeg = rel.split(path31.sep)[0];
|
|
33738
|
+
if (firstSeg && firstSeg !== "..") normalizedProvider._sourceName = firstSeg;
|
|
33739
|
+
}
|
|
33740
|
+
} catch {
|
|
33741
|
+
}
|
|
33211
33742
|
const existed = this.providers.has(normalizedProvider.type);
|
|
33212
33743
|
this.providers.set(normalizedProvider.type, normalizedProvider);
|
|
33213
33744
|
count++;
|
|
33214
|
-
const source =
|
|
33745
|
+
const source = normalizedProvider._sourceLayer ?? "upstream";
|
|
33215
33746
|
const overrideWarning = existed && source === "user" ? " \u26A0 OVERRIDES upstream" : "";
|
|
33216
|
-
|
|
33747
|
+
const sourceName = normalizedProvider._sourceName;
|
|
33748
|
+
const sourceLabel = sourceName ? `${source}/${sourceName}` : source;
|
|
33749
|
+
this.log(` ${existed ? "\u{1F504}" : "\u2705"} ${normalizedProvider.type} (${normalizedProvider.category}) \u2014 ${normalizedProvider.name} [${sourceLabel}]${overrideWarning}`);
|
|
33217
33750
|
}
|
|
33218
33751
|
} catch (e) {
|
|
33219
33752
|
this.log(`\u26A0 Failed to load ${jsonPath}: ${e.message}`);
|
|
@@ -33223,8 +33756,9 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
33223
33756
|
for (const entry of entries) {
|
|
33224
33757
|
if (!entry.isDirectory()) continue;
|
|
33225
33758
|
if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
|
|
33759
|
+
if (d === dir && entry.name === "examples") continue;
|
|
33226
33760
|
if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
|
|
33227
|
-
scan(
|
|
33761
|
+
scan(path31.join(d, entry.name));
|
|
33228
33762
|
}
|
|
33229
33763
|
}
|
|
33230
33764
|
};
|
|
@@ -33422,7 +33956,7 @@ async function isCdpActive(port) {
|
|
|
33422
33956
|
});
|
|
33423
33957
|
}
|
|
33424
33958
|
async function killIdeProcess(ideId) {
|
|
33425
|
-
const plat =
|
|
33959
|
+
const plat = os23.platform();
|
|
33426
33960
|
const appName = getMacAppIdentifiers()[ideId];
|
|
33427
33961
|
const winProcesses = getWinProcessNames()[ideId];
|
|
33428
33962
|
try {
|
|
@@ -33483,7 +34017,7 @@ async function killIdeProcess(ideId) {
|
|
|
33483
34017
|
}
|
|
33484
34018
|
}
|
|
33485
34019
|
async function isIdeRunning(ideId) {
|
|
33486
|
-
const plat =
|
|
34020
|
+
const plat = os23.platform();
|
|
33487
34021
|
try {
|
|
33488
34022
|
if (plat === "darwin") {
|
|
33489
34023
|
const appName = getMacAppIdentifiers()[ideId];
|
|
@@ -33538,7 +34072,7 @@ async function isIdeRunning(ideId) {
|
|
|
33538
34072
|
}
|
|
33539
34073
|
}
|
|
33540
34074
|
async function detectCurrentWorkspace(ideId) {
|
|
33541
|
-
const plat =
|
|
34075
|
+
const plat = os23.platform();
|
|
33542
34076
|
if (plat === "darwin") {
|
|
33543
34077
|
try {
|
|
33544
34078
|
const appName = getMacAppIdentifiers()[ideId];
|
|
@@ -33553,17 +34087,17 @@ async function detectCurrentWorkspace(ideId) {
|
|
|
33553
34087
|
}
|
|
33554
34088
|
} else if (plat === "win32") {
|
|
33555
34089
|
try {
|
|
33556
|
-
const
|
|
34090
|
+
const fs28 = require("fs");
|
|
33557
34091
|
const appNameMap = getMacAppIdentifiers();
|
|
33558
34092
|
const appName = appNameMap[ideId];
|
|
33559
34093
|
if (appName) {
|
|
33560
|
-
const storagePath =
|
|
33561
|
-
process.env.APPDATA ||
|
|
34094
|
+
const storagePath = path32.join(
|
|
34095
|
+
process.env.APPDATA || path32.join(os23.homedir(), "AppData", "Roaming"),
|
|
33562
34096
|
appName,
|
|
33563
34097
|
"storage.json"
|
|
33564
34098
|
);
|
|
33565
|
-
if (
|
|
33566
|
-
const data = JSON.parse(
|
|
34099
|
+
if (fs28.existsSync(storagePath)) {
|
|
34100
|
+
const data = JSON.parse(fs28.readFileSync(storagePath, "utf-8"));
|
|
33567
34101
|
const workspaces = data?.openedPathsList?.workspaces3 || data?.openedPathsList?.entries || [];
|
|
33568
34102
|
if (workspaces.length > 0) {
|
|
33569
34103
|
const recent = workspaces[0];
|
|
@@ -33580,7 +34114,7 @@ async function detectCurrentWorkspace(ideId) {
|
|
|
33580
34114
|
return void 0;
|
|
33581
34115
|
}
|
|
33582
34116
|
async function launchWithCdp(options = {}) {
|
|
33583
|
-
const platform10 =
|
|
34117
|
+
const platform10 = os23.platform();
|
|
33584
34118
|
let targetIde;
|
|
33585
34119
|
const ides = await detectIDEs(getProviderLoader());
|
|
33586
34120
|
if (options.ideId) {
|
|
@@ -33747,14 +34281,14 @@ init_cli_detector();
|
|
|
33747
34281
|
init_logger();
|
|
33748
34282
|
|
|
33749
34283
|
// src/logging/command-log.ts
|
|
33750
|
-
var
|
|
33751
|
-
var
|
|
33752
|
-
var
|
|
33753
|
-
var LOG_DIR2 = process.platform === "win32" ?
|
|
34284
|
+
var fs20 = __toESM(require("fs"));
|
|
34285
|
+
var path33 = __toESM(require("path"));
|
|
34286
|
+
var os24 = __toESM(require("os"));
|
|
34287
|
+
var LOG_DIR2 = process.platform === "win32" ? path33.join(process.env.LOCALAPPDATA || process.env.APPDATA || path33.join(os24.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path33.join(os24.homedir(), "Library", "Logs", "adhdev") : path33.join(os24.homedir(), ".local", "share", "adhdev", "logs");
|
|
33754
34288
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
33755
34289
|
var MAX_DAYS = 7;
|
|
33756
34290
|
try {
|
|
33757
|
-
|
|
34291
|
+
fs20.mkdirSync(LOG_DIR2, { recursive: true });
|
|
33758
34292
|
} catch {
|
|
33759
34293
|
}
|
|
33760
34294
|
var SENSITIVE_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -33788,19 +34322,19 @@ function getDateStr2() {
|
|
|
33788
34322
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
33789
34323
|
}
|
|
33790
34324
|
var currentDate2 = getDateStr2();
|
|
33791
|
-
var currentFile =
|
|
34325
|
+
var currentFile = path33.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
33792
34326
|
var writeCount2 = 0;
|
|
33793
34327
|
function checkRotation() {
|
|
33794
34328
|
const today = getDateStr2();
|
|
33795
34329
|
if (today !== currentDate2) {
|
|
33796
34330
|
currentDate2 = today;
|
|
33797
|
-
currentFile =
|
|
34331
|
+
currentFile = path33.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
33798
34332
|
cleanOldFiles();
|
|
33799
34333
|
}
|
|
33800
34334
|
}
|
|
33801
34335
|
function cleanOldFiles() {
|
|
33802
34336
|
try {
|
|
33803
|
-
const files =
|
|
34337
|
+
const files = fs20.readdirSync(LOG_DIR2).filter((f) => f.startsWith("commands-") && f.endsWith(".jsonl"));
|
|
33804
34338
|
const cutoff = /* @__PURE__ */ new Date();
|
|
33805
34339
|
cutoff.setDate(cutoff.getDate() - MAX_DAYS);
|
|
33806
34340
|
const cutoffStr = cutoff.toISOString().slice(0, 10);
|
|
@@ -33808,7 +34342,7 @@ function cleanOldFiles() {
|
|
|
33808
34342
|
const dateMatch = file.match(/commands-(\d{4}-\d{2}-\d{2})/);
|
|
33809
34343
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
33810
34344
|
try {
|
|
33811
|
-
|
|
34345
|
+
fs20.unlinkSync(path33.join(LOG_DIR2, file));
|
|
33812
34346
|
} catch {
|
|
33813
34347
|
}
|
|
33814
34348
|
}
|
|
@@ -33818,14 +34352,14 @@ function cleanOldFiles() {
|
|
|
33818
34352
|
}
|
|
33819
34353
|
function checkSize() {
|
|
33820
34354
|
try {
|
|
33821
|
-
const stat2 =
|
|
34355
|
+
const stat2 = fs20.statSync(currentFile);
|
|
33822
34356
|
if (stat2.size > MAX_FILE_SIZE) {
|
|
33823
34357
|
const backup = currentFile.replace(".jsonl", ".1.jsonl");
|
|
33824
34358
|
try {
|
|
33825
|
-
|
|
34359
|
+
fs20.unlinkSync(backup);
|
|
33826
34360
|
} catch {
|
|
33827
34361
|
}
|
|
33828
|
-
|
|
34362
|
+
fs20.renameSync(currentFile, backup);
|
|
33829
34363
|
}
|
|
33830
34364
|
} catch {
|
|
33831
34365
|
}
|
|
@@ -33858,14 +34392,14 @@ function logCommand(entry) {
|
|
|
33858
34392
|
...entry.error ? { err: entry.error } : {},
|
|
33859
34393
|
...entry.durationMs !== void 0 ? { ms: entry.durationMs } : {}
|
|
33860
34394
|
});
|
|
33861
|
-
|
|
34395
|
+
fs20.appendFileSync(currentFile, line + "\n");
|
|
33862
34396
|
} catch {
|
|
33863
34397
|
}
|
|
33864
34398
|
}
|
|
33865
34399
|
function getRecentCommands(count = 50) {
|
|
33866
34400
|
try {
|
|
33867
|
-
if (!
|
|
33868
|
-
const content =
|
|
34401
|
+
if (!fs20.existsSync(currentFile)) return [];
|
|
34402
|
+
const content = fs20.readFileSync(currentFile, "utf-8");
|
|
33869
34403
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
33870
34404
|
return lines.slice(-count).map((line) => {
|
|
33871
34405
|
try {
|
|
@@ -33915,10 +34449,10 @@ function runGit2(repoRoot, args) {
|
|
|
33915
34449
|
}
|
|
33916
34450
|
}
|
|
33917
34451
|
function readRecord3(repoRoot) {
|
|
33918
|
-
const
|
|
33919
|
-
if (!(0, import_node_fs4.existsSync)(
|
|
34452
|
+
const path40 = (0, import_node_path2.resolve)(repoRoot, PREVIEW_DEPLOY_RECORD);
|
|
34453
|
+
if (!(0, import_node_fs4.existsSync)(path40)) return null;
|
|
33920
34454
|
try {
|
|
33921
|
-
const parsed = JSON.parse((0, import_node_fs4.readFileSync)(
|
|
34455
|
+
const parsed = JSON.parse((0, import_node_fs4.readFileSync)(path40, "utf8"));
|
|
33922
34456
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
33923
34457
|
} catch {
|
|
33924
34458
|
return null;
|
|
@@ -33980,7 +34514,7 @@ function buildPreviewFreshness(repoRoot) {
|
|
|
33980
34514
|
}
|
|
33981
34515
|
|
|
33982
34516
|
// src/status/snapshot.ts
|
|
33983
|
-
var
|
|
34517
|
+
var os25 = __toESM(require("os"));
|
|
33984
34518
|
init_config();
|
|
33985
34519
|
init_terminal_screen();
|
|
33986
34520
|
init_logger();
|
|
@@ -34019,25 +34553,50 @@ function buildDetectedIdeInfos(detectedIdes, cdpManagers) {
|
|
|
34019
34553
|
}
|
|
34020
34554
|
function buildAvailableProviders(providerLoader) {
|
|
34021
34555
|
const providers = providerLoader.getAvailableProviderInfos?.() || providerLoader.getAll();
|
|
34022
|
-
|
|
34023
|
-
|
|
34024
|
-
|
|
34025
|
-
|
|
34026
|
-
|
|
34027
|
-
|
|
34028
|
-
|
|
34029
|
-
|
|
34030
|
-
|
|
34031
|
-
|
|
34032
|
-
|
|
34033
|
-
|
|
34034
|
-
|
|
34035
|
-
|
|
34556
|
+
let describeTrust2 = () => "";
|
|
34557
|
+
let requiresConfirmation2 = () => false;
|
|
34558
|
+
try {
|
|
34559
|
+
const mod = (init_provider_trust(), __toCommonJS(provider_trust_exports));
|
|
34560
|
+
describeTrust2 = mod.describeTrust;
|
|
34561
|
+
requiresConfirmation2 = mod.requiresConfirmation;
|
|
34562
|
+
} catch {
|
|
34563
|
+
}
|
|
34564
|
+
return providers.map((provider) => {
|
|
34565
|
+
const trust = provider._sourceTrust;
|
|
34566
|
+
const sourceLayer = provider._sourceLayer;
|
|
34567
|
+
const sourceName = provider._sourceName;
|
|
34568
|
+
return {
|
|
34569
|
+
type: provider.type,
|
|
34570
|
+
name: provider.displayName || provider.type,
|
|
34571
|
+
displayName: provider.displayName || provider.type,
|
|
34572
|
+
icon: provider.icon || "\u{1F4BB}",
|
|
34573
|
+
category: provider.category,
|
|
34574
|
+
...provider.installed !== void 0 ? { installed: provider.installed } : {},
|
|
34575
|
+
...provider.detectedPath !== void 0 ? { detectedPath: provider.detectedPath } : {},
|
|
34576
|
+
...provider.enabled !== void 0 ? { enabled: provider.enabled } : {},
|
|
34577
|
+
...provider.machineStatus !== void 0 ? { machineStatus: provider.machineStatus } : {},
|
|
34578
|
+
...provider.lastDetection !== void 0 ? { lastDetection: provider.lastDetection } : {},
|
|
34579
|
+
...provider.lastVerification !== void 0 ? { lastVerification: provider.lastVerification } : {},
|
|
34580
|
+
...provider.meshCoordinator !== void 0 ? { meshCoordinator: provider.meshCoordinator } : {},
|
|
34581
|
+
...trust ? {
|
|
34582
|
+
trust,
|
|
34583
|
+
trustDescription: describeTrust2(trust),
|
|
34584
|
+
requiresConfirmation: requiresConfirmation2(trust)
|
|
34585
|
+
} : {},
|
|
34586
|
+
...sourceLayer ? { sourceLayer } : {},
|
|
34587
|
+
...sourceName ? { sourceName } : {},
|
|
34588
|
+
...provider.providerVersion ? { providerVersion: provider.providerVersion } : {},
|
|
34589
|
+
...provider.binary ? { binary: provider.binary } : {},
|
|
34590
|
+
...provider.status ? { status: provider.status } : {},
|
|
34591
|
+
...provider.details ? { details: provider.details } : {},
|
|
34592
|
+
...provider.links ? { links: provider.links } : {}
|
|
34593
|
+
};
|
|
34594
|
+
});
|
|
34036
34595
|
}
|
|
34037
34596
|
function buildMachineInfo(profile = "full") {
|
|
34038
34597
|
const base = {
|
|
34039
|
-
hostname:
|
|
34040
|
-
platform:
|
|
34598
|
+
hostname: os25.hostname(),
|
|
34599
|
+
platform: os25.platform()
|
|
34041
34600
|
};
|
|
34042
34601
|
if (profile === "live") {
|
|
34043
34602
|
return base;
|
|
@@ -34046,23 +34605,23 @@ function buildMachineInfo(profile = "full") {
|
|
|
34046
34605
|
const memSnap2 = getHostMemorySnapshot();
|
|
34047
34606
|
return {
|
|
34048
34607
|
...base,
|
|
34049
|
-
arch:
|
|
34050
|
-
cpus:
|
|
34608
|
+
arch: os25.arch(),
|
|
34609
|
+
cpus: os25.cpus().length,
|
|
34051
34610
|
totalMem: memSnap2.totalMem,
|
|
34052
|
-
release:
|
|
34611
|
+
release: os25.release()
|
|
34053
34612
|
};
|
|
34054
34613
|
}
|
|
34055
34614
|
const memSnap = getHostMemorySnapshot();
|
|
34056
34615
|
return {
|
|
34057
34616
|
...base,
|
|
34058
|
-
arch:
|
|
34059
|
-
cpus:
|
|
34617
|
+
arch: os25.arch(),
|
|
34618
|
+
cpus: os25.cpus().length,
|
|
34060
34619
|
totalMem: memSnap.totalMem,
|
|
34061
34620
|
freeMem: memSnap.freeMem,
|
|
34062
34621
|
availableMem: memSnap.availableMem,
|
|
34063
|
-
loadavg:
|
|
34064
|
-
uptime:
|
|
34065
|
-
release:
|
|
34622
|
+
loadavg: os25.loadavg(),
|
|
34623
|
+
uptime: os25.uptime(),
|
|
34624
|
+
release: os25.release()
|
|
34066
34625
|
};
|
|
34067
34626
|
}
|
|
34068
34627
|
function parseMessageTime(value) {
|
|
@@ -34303,42 +34862,42 @@ function buildStatusSnapshot(options) {
|
|
|
34303
34862
|
// src/commands/upgrade-helper.ts
|
|
34304
34863
|
var import_child_process7 = require("child_process");
|
|
34305
34864
|
var import_child_process8 = require("child_process");
|
|
34306
|
-
var
|
|
34307
|
-
var
|
|
34308
|
-
var
|
|
34865
|
+
var fs21 = __toESM(require("fs"));
|
|
34866
|
+
var os26 = __toESM(require("os"));
|
|
34867
|
+
var path34 = __toESM(require("path"));
|
|
34309
34868
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
34310
34869
|
function getUpgradeLogPath() {
|
|
34311
|
-
const home =
|
|
34312
|
-
const dir =
|
|
34313
|
-
|
|
34314
|
-
return
|
|
34870
|
+
const home = os26.homedir();
|
|
34871
|
+
const dir = path34.join(home, ".adhdev");
|
|
34872
|
+
fs21.mkdirSync(dir, { recursive: true });
|
|
34873
|
+
return path34.join(dir, "daemon-upgrade.log");
|
|
34315
34874
|
}
|
|
34316
34875
|
function appendUpgradeLog(message) {
|
|
34317
34876
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
|
|
34318
34877
|
`;
|
|
34319
34878
|
try {
|
|
34320
|
-
|
|
34879
|
+
fs21.appendFileSync(getUpgradeLogPath(), line, "utf8");
|
|
34321
34880
|
} catch {
|
|
34322
34881
|
}
|
|
34323
34882
|
}
|
|
34324
34883
|
function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platform) {
|
|
34325
|
-
const binDir =
|
|
34884
|
+
const binDir = path34.dirname(nodeExecutable);
|
|
34326
34885
|
if (platform10 === "win32") {
|
|
34327
|
-
const npmCliPath =
|
|
34328
|
-
if (
|
|
34886
|
+
const npmCliPath = path34.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
|
|
34887
|
+
if (fs21.existsSync(npmCliPath)) {
|
|
34329
34888
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
34330
34889
|
}
|
|
34331
34890
|
for (const candidate of ["npm.exe", "npm"]) {
|
|
34332
|
-
const candidatePath =
|
|
34333
|
-
if (
|
|
34891
|
+
const candidatePath = path34.join(binDir, candidate);
|
|
34892
|
+
if (fs21.existsSync(candidatePath)) {
|
|
34334
34893
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
34335
34894
|
}
|
|
34336
34895
|
}
|
|
34337
34896
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
34338
34897
|
}
|
|
34339
34898
|
for (const candidate of ["npm"]) {
|
|
34340
|
-
const candidatePath =
|
|
34341
|
-
if (
|
|
34899
|
+
const candidatePath = path34.join(binDir, candidate);
|
|
34900
|
+
if (fs21.existsSync(candidatePath)) {
|
|
34342
34901
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
34343
34902
|
}
|
|
34344
34903
|
}
|
|
@@ -34348,22 +34907,22 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
34348
34907
|
if (!currentCliPath) return null;
|
|
34349
34908
|
let resolvedPath = currentCliPath;
|
|
34350
34909
|
try {
|
|
34351
|
-
resolvedPath =
|
|
34910
|
+
resolvedPath = fs21.realpathSync.native(currentCliPath);
|
|
34352
34911
|
} catch {
|
|
34353
34912
|
}
|
|
34354
34913
|
let currentDir = resolvedPath;
|
|
34355
34914
|
try {
|
|
34356
|
-
if (
|
|
34357
|
-
currentDir =
|
|
34915
|
+
if (fs21.statSync(resolvedPath).isFile()) {
|
|
34916
|
+
currentDir = path34.dirname(resolvedPath);
|
|
34358
34917
|
}
|
|
34359
34918
|
} catch {
|
|
34360
|
-
currentDir =
|
|
34919
|
+
currentDir = path34.dirname(resolvedPath);
|
|
34361
34920
|
}
|
|
34362
34921
|
while (true) {
|
|
34363
|
-
const packageJsonPath =
|
|
34922
|
+
const packageJsonPath = path34.join(currentDir, "package.json");
|
|
34364
34923
|
try {
|
|
34365
|
-
if (
|
|
34366
|
-
const parsed = JSON.parse(
|
|
34924
|
+
if (fs21.existsSync(packageJsonPath)) {
|
|
34925
|
+
const parsed = JSON.parse(fs21.readFileSync(packageJsonPath, "utf8"));
|
|
34367
34926
|
if (parsed?.name === packageName) {
|
|
34368
34927
|
const normalized = currentDir.replace(/\\/g, "/");
|
|
34369
34928
|
return normalized.includes("/node_modules/") ? currentDir : null;
|
|
@@ -34371,7 +34930,7 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
34371
34930
|
}
|
|
34372
34931
|
} catch {
|
|
34373
34932
|
}
|
|
34374
|
-
const parentDir =
|
|
34933
|
+
const parentDir = path34.dirname(currentDir);
|
|
34375
34934
|
if (parentDir === currentDir) {
|
|
34376
34935
|
return null;
|
|
34377
34936
|
}
|
|
@@ -34379,13 +34938,13 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
34379
34938
|
}
|
|
34380
34939
|
}
|
|
34381
34940
|
function resolveInstallPrefixFromPackageRoot(packageRoot, packageName) {
|
|
34382
|
-
const nodeModulesDir = packageName.startsWith("@") ?
|
|
34383
|
-
if (
|
|
34941
|
+
const nodeModulesDir = packageName.startsWith("@") ? path34.dirname(path34.dirname(packageRoot)) : path34.dirname(packageRoot);
|
|
34942
|
+
if (path34.basename(nodeModulesDir) !== "node_modules") {
|
|
34384
34943
|
return null;
|
|
34385
34944
|
}
|
|
34386
|
-
const maybeLibDir =
|
|
34387
|
-
if (
|
|
34388
|
-
return
|
|
34945
|
+
const maybeLibDir = path34.dirname(nodeModulesDir);
|
|
34946
|
+
if (path34.basename(maybeLibDir) === "lib") {
|
|
34947
|
+
return path34.dirname(maybeLibDir);
|
|
34389
34948
|
}
|
|
34390
34949
|
return maybeLibDir;
|
|
34391
34950
|
}
|
|
@@ -34500,10 +35059,10 @@ async function waitForPidExit(pid, timeoutMs) {
|
|
|
34500
35059
|
}
|
|
34501
35060
|
}
|
|
34502
35061
|
function stopSessionHostProcesses(appName) {
|
|
34503
|
-
const pidFile =
|
|
35062
|
+
const pidFile = path34.join(os26.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
34504
35063
|
try {
|
|
34505
|
-
if (
|
|
34506
|
-
const pid = Number.parseInt(
|
|
35064
|
+
if (fs21.existsSync(pidFile)) {
|
|
35065
|
+
const pid = Number.parseInt(fs21.readFileSync(pidFile, "utf8").trim(), 10);
|
|
34507
35066
|
if (Number.isFinite(pid) && pid !== process.pid && isManagedSessionHostPid(pid)) {
|
|
34508
35067
|
killPid(pid);
|
|
34509
35068
|
}
|
|
@@ -34511,15 +35070,15 @@ function stopSessionHostProcesses(appName) {
|
|
|
34511
35070
|
} catch {
|
|
34512
35071
|
} finally {
|
|
34513
35072
|
try {
|
|
34514
|
-
|
|
35073
|
+
fs21.unlinkSync(pidFile);
|
|
34515
35074
|
} catch {
|
|
34516
35075
|
}
|
|
34517
35076
|
}
|
|
34518
35077
|
}
|
|
34519
35078
|
function removeDaemonPidFile() {
|
|
34520
|
-
const pidFile =
|
|
35079
|
+
const pidFile = path34.join(os26.homedir(), ".adhdev", "daemon.pid");
|
|
34521
35080
|
try {
|
|
34522
|
-
|
|
35081
|
+
fs21.unlinkSync(pidFile);
|
|
34523
35082
|
} catch {
|
|
34524
35083
|
}
|
|
34525
35084
|
}
|
|
@@ -34528,7 +35087,7 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
34528
35087
|
const npmRoot = String(execNpmCommandSync(["root", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
34529
35088
|
if (!npmRoot) return;
|
|
34530
35089
|
const npmPrefix = surface.installPrefix || String(execNpmCommandSync(["prefix", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
34531
|
-
const binDir = process.platform === "win32" ? npmPrefix :
|
|
35090
|
+
const binDir = process.platform === "win32" ? npmPrefix : path34.join(npmPrefix, "bin");
|
|
34532
35091
|
const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
|
|
34533
35092
|
const binNames = /* @__PURE__ */ new Set([packageBaseName]);
|
|
34534
35093
|
if (pkgName === "@adhdev/daemon-standalone") {
|
|
@@ -34536,25 +35095,25 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
34536
35095
|
}
|
|
34537
35096
|
if (pkgName.startsWith("@")) {
|
|
34538
35097
|
const [scope, name] = pkgName.split("/");
|
|
34539
|
-
const scopeDir =
|
|
34540
|
-
if (!
|
|
34541
|
-
for (const entry of
|
|
35098
|
+
const scopeDir = path34.join(npmRoot, scope);
|
|
35099
|
+
if (!fs21.existsSync(scopeDir)) return;
|
|
35100
|
+
for (const entry of fs21.readdirSync(scopeDir)) {
|
|
34542
35101
|
if (!entry.startsWith(`.${name}-`)) continue;
|
|
34543
|
-
|
|
34544
|
-
appendUpgradeLog(`Removed stale scoped staging dir: ${
|
|
35102
|
+
fs21.rmSync(path34.join(scopeDir, entry), { recursive: true, force: true });
|
|
35103
|
+
appendUpgradeLog(`Removed stale scoped staging dir: ${path34.join(scopeDir, entry)}`);
|
|
34545
35104
|
}
|
|
34546
35105
|
} else {
|
|
34547
|
-
for (const entry of
|
|
35106
|
+
for (const entry of fs21.readdirSync(npmRoot)) {
|
|
34548
35107
|
if (!entry.startsWith(`.${pkgName}-`)) continue;
|
|
34549
|
-
|
|
34550
|
-
appendUpgradeLog(`Removed stale staging dir: ${
|
|
35108
|
+
fs21.rmSync(path34.join(npmRoot, entry), { recursive: true, force: true });
|
|
35109
|
+
appendUpgradeLog(`Removed stale staging dir: ${path34.join(npmRoot, entry)}`);
|
|
34551
35110
|
}
|
|
34552
35111
|
}
|
|
34553
|
-
if (
|
|
34554
|
-
for (const entry of
|
|
35112
|
+
if (fs21.existsSync(binDir)) {
|
|
35113
|
+
for (const entry of fs21.readdirSync(binDir)) {
|
|
34555
35114
|
if (!Array.from(binNames).some((name) => entry.startsWith(`.${name}-`))) continue;
|
|
34556
|
-
|
|
34557
|
-
appendUpgradeLog(`Removed stale bin staging entry: ${
|
|
35115
|
+
fs21.rmSync(path34.join(binDir, entry), { recursive: true, force: true });
|
|
35116
|
+
appendUpgradeLog(`Removed stale bin staging entry: ${path34.join(binDir, entry)}`);
|
|
34558
35117
|
}
|
|
34559
35118
|
}
|
|
34560
35119
|
}
|
|
@@ -34642,7 +35201,7 @@ async function maybeRunDaemonUpgradeHelperFromEnv() {
|
|
|
34642
35201
|
init_mesh_work_queue();
|
|
34643
35202
|
var import_os3 = require("os");
|
|
34644
35203
|
var import_path10 = require("path");
|
|
34645
|
-
var
|
|
35204
|
+
var fs22 = __toESM(require("fs"));
|
|
34646
35205
|
var import_node_child_process5 = require("child_process");
|
|
34647
35206
|
var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
|
|
34648
35207
|
var CHANNEL_SERVER_URL = {
|
|
@@ -34769,12 +35328,12 @@ function readGitSubmodules(value, parentRepoRoot) {
|
|
|
34769
35328
|
if (!Array.isArray(value)) return void 0;
|
|
34770
35329
|
const submodules = value.map((entry) => {
|
|
34771
35330
|
const submodule = readObjectRecord(entry);
|
|
34772
|
-
const
|
|
35331
|
+
const path40 = readStringValue(submodule.path);
|
|
34773
35332
|
const commit = readStringValue(submodule.commit);
|
|
34774
|
-
const repoPath = readStringValue(submodule.repoPath, submodule.repo_root) ?? joinRepoPath(parentRepoRoot,
|
|
34775
|
-
if (!
|
|
35333
|
+
const repoPath = readStringValue(submodule.repoPath, submodule.repo_root) ?? joinRepoPath(parentRepoRoot, path40);
|
|
35334
|
+
if (!path40 || !commit || !repoPath) return null;
|
|
34776
35335
|
return {
|
|
34777
|
-
path:
|
|
35336
|
+
path: path40,
|
|
34778
35337
|
commit,
|
|
34779
35338
|
repoPath,
|
|
34780
35339
|
dirty: readBooleanValue(submodule.dirty) ?? false,
|
|
@@ -35416,7 +35975,7 @@ async function hydrateInlineMeshDirectTruth(args) {
|
|
|
35416
35975
|
if (!isSelfNode && daemonId) unavailableNodeIds.push(nodeId);
|
|
35417
35976
|
continue;
|
|
35418
35977
|
}
|
|
35419
|
-
if (
|
|
35978
|
+
if (fs22.existsSync(workspace)) {
|
|
35420
35979
|
try {
|
|
35421
35980
|
const localGit = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
|
|
35422
35981
|
if (localGit?.isGitRepo) {
|
|
@@ -35501,7 +36060,7 @@ function readLiveMeshNodeWorkspace(args) {
|
|
|
35501
36060
|
}
|
|
35502
36061
|
function collectLiveMeshSessionRecords(args) {
|
|
35503
36062
|
const nodeWorkspace = readStringValue(args.node?.workspace);
|
|
35504
|
-
const nodeIsMissingLocalWorktree = args.node?.isLocalWorktree === true && !!nodeWorkspace && !
|
|
36063
|
+
const nodeIsMissingLocalWorktree = args.node?.isLocalWorktree === true && !!nodeWorkspace && !fs22.existsSync(nodeWorkspace);
|
|
35505
36064
|
const matches = args.liveSessionRecords.filter((record) => {
|
|
35506
36065
|
const recordNodeId = readStringValue(record?.meta?.meshNodeId);
|
|
35507
36066
|
if (recordNodeId && recordNodeId !== args.nodeId) return false;
|
|
@@ -35528,7 +36087,7 @@ function buildHistoricalMeshSessions(args) {
|
|
|
35528
36087
|
const workspace = readStringValue(node?.workspace);
|
|
35529
36088
|
if (nodeId) liveNodeIds.add(nodeId);
|
|
35530
36089
|
if (workspace) liveWorkspaces.add(workspace);
|
|
35531
|
-
if (nodeId && node?.isLocalWorktree === true && workspace && !
|
|
36090
|
+
if (nodeId && node?.isLocalWorktree === true && workspace && !fs22.existsSync(workspace)) {
|
|
35532
36091
|
missingLocalWorktreeNodeIds.add(nodeId);
|
|
35533
36092
|
}
|
|
35534
36093
|
}
|
|
@@ -35727,10 +36286,10 @@ ${e?.stderr || ""}`
|
|
|
35727
36286
|
}
|
|
35728
36287
|
function buildPatchEquivalenceSubmoduleConflictHint(repoRoot, baseHead, branchHead, output) {
|
|
35729
36288
|
if (!/(submodule|160000)/i.test(output) || !/(conflict|failed to merge)/i.test(output)) return void 0;
|
|
35730
|
-
const conflicts = readChangedGitlinkPaths(repoRoot, baseHead, branchHead).map((
|
|
35731
|
-
path:
|
|
35732
|
-
baseCommit: readTreeObject(repoRoot, baseHead,
|
|
35733
|
-
branchCommit: readTreeObject(repoRoot, branchHead,
|
|
36289
|
+
const conflicts = readChangedGitlinkPaths(repoRoot, baseHead, branchHead).map((path40) => ({
|
|
36290
|
+
path: path40,
|
|
36291
|
+
baseCommit: readTreeObject(repoRoot, baseHead, path40),
|
|
36292
|
+
branchCommit: readTreeObject(repoRoot, branchHead, path40)
|
|
35734
36293
|
}));
|
|
35735
36294
|
if (conflicts.length === 0) return void 0;
|
|
35736
36295
|
return {
|
|
@@ -35756,11 +36315,11 @@ function readChangedGitlinkPaths(repoRoot, fromRef, toRef) {
|
|
|
35756
36315
|
if (!line.trim()) continue;
|
|
35757
36316
|
const metaAndPath = line.split(" ");
|
|
35758
36317
|
const meta = metaAndPath[0] || "";
|
|
35759
|
-
const
|
|
35760
|
-
if (!
|
|
36318
|
+
const path40 = metaAndPath[metaAndPath.length - 1]?.trim();
|
|
36319
|
+
if (!path40) continue;
|
|
35761
36320
|
const parts = meta.split(/\s+/);
|
|
35762
36321
|
if (parts[0]?.includes("160000") || parts[1]?.includes("160000")) {
|
|
35763
|
-
paths.add(
|
|
36322
|
+
paths.add(path40);
|
|
35764
36323
|
}
|
|
35765
36324
|
}
|
|
35766
36325
|
return [...paths].sort();
|
|
@@ -35768,9 +36327,9 @@ function readChangedGitlinkPaths(repoRoot, fromRef, toRef) {
|
|
|
35768
36327
|
return [];
|
|
35769
36328
|
}
|
|
35770
36329
|
}
|
|
35771
|
-
function readTreeObject(repoRoot, ref,
|
|
36330
|
+
function readTreeObject(repoRoot, ref, path40) {
|
|
35772
36331
|
try {
|
|
35773
|
-
const output = (0, import_node_child_process5.execFileSync)("git", ["ls-tree", ref, "--",
|
|
36332
|
+
const output = (0, import_node_child_process5.execFileSync)("git", ["ls-tree", ref, "--", path40], {
|
|
35774
36333
|
cwd: repoRoot,
|
|
35775
36334
|
encoding: "utf8",
|
|
35776
36335
|
maxBuffer: 1024 * 1024
|
|
@@ -35783,7 +36342,7 @@ function readTreeObject(repoRoot, ref, path39) {
|
|
|
35783
36342
|
}
|
|
35784
36343
|
async function alignRefinerySubmodulesAfterMerge(repoRoot, previousBaseHead, currentHead, options = {}) {
|
|
35785
36344
|
const startedAt = Date.now();
|
|
35786
|
-
const changedGitlinkPaths = readChangedGitlinkPaths(repoRoot, previousBaseHead, currentHead).filter((
|
|
36345
|
+
const changedGitlinkPaths = readChangedGitlinkPaths(repoRoot, previousBaseHead, currentHead).filter((path40) => !(options.submoduleIgnorePaths || []).includes(path40));
|
|
35787
36346
|
const preStatus = await getGitRepoStatus(repoRoot, {
|
|
35788
36347
|
includeSubmodules: true,
|
|
35789
36348
|
submoduleIgnorePaths: options.submoduleIgnorePaths,
|
|
@@ -35824,7 +36383,7 @@ async function alignRefinerySubmodulesAfterMerge(repoRoot, previousBaseHead, cur
|
|
|
35824
36383
|
changedGitlinkPaths,
|
|
35825
36384
|
outOfSyncPaths,
|
|
35826
36385
|
updatedPaths: updatePaths,
|
|
35827
|
-
verifiedPaths: updatePaths.filter((
|
|
36386
|
+
verifiedPaths: updatePaths.filter((path40) => !remaining.some((submodule) => submodule.path === path40)),
|
|
35828
36387
|
durationMs: Date.now() - startedAt,
|
|
35829
36388
|
command: `git ${commandArgs.join(" ")}`,
|
|
35830
36389
|
stdout: truncateValidationOutput(result.stdout),
|
|
@@ -35879,7 +36438,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
35879
36438
|
return { stdout: String(stdout || ""), stderr: String(stderr || ""), refspec };
|
|
35880
36439
|
};
|
|
35881
36440
|
const importCommitFromWorktreeSubmodule = async (submodulePath, worktreeSubmodulePath, commit) => {
|
|
35882
|
-
if (!
|
|
36441
|
+
if (!fs22.existsSync(worktreeSubmodulePath)) return false;
|
|
35883
36442
|
try {
|
|
35884
36443
|
await runGit3(worktreeSubmodulePath, ["cat-file", "-e", `${commit}^{commit}`]);
|
|
35885
36444
|
} catch {
|
|
@@ -35902,7 +36461,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
35902
36461
|
reachable: false
|
|
35903
36462
|
};
|
|
35904
36463
|
try {
|
|
35905
|
-
if (!
|
|
36464
|
+
if (!fs22.existsSync(submodulePath)) {
|
|
35906
36465
|
entry.error = `Submodule checkout missing at ${gitlink.path}`;
|
|
35907
36466
|
entry.publishRequired = true;
|
|
35908
36467
|
if (options.allowAutoPublishSubmoduleMainCommits === true) {
|
|
@@ -36094,9 +36653,9 @@ async function runMeshRefineValidationGate(mesh, workspace) {
|
|
|
36094
36653
|
return ["npm", "pnpm", "yarn", "bun"].includes(command) && candidate.args.some((arg) => arg === "run" || arg === "test" || arg === "exec");
|
|
36095
36654
|
};
|
|
36096
36655
|
const dependenciesLikelyMissing = (cwd) => {
|
|
36097
|
-
if (!
|
|
36098
|
-
if (
|
|
36099
|
-
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) =>
|
|
36656
|
+
if (!fs22.existsSync((0, import_path10.join)(cwd, "package.json"))) return false;
|
|
36657
|
+
if (fs22.existsSync((0, import_path10.join)(cwd, "node_modules"))) return false;
|
|
36658
|
+
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) => fs22.existsSync((0, import_path10.join)(cwd, lock)));
|
|
36100
36659
|
};
|
|
36101
36660
|
for (const candidate of selection.bootstrapCommands) {
|
|
36102
36661
|
const startedAt = Date.now();
|
|
@@ -36193,9 +36752,9 @@ function resolveHermesUserHome() {
|
|
|
36193
36752
|
function loadHermesCoordinatorBaseConfig(targetConfigPath) {
|
|
36194
36753
|
const sourceHome = resolveHermesUserHome();
|
|
36195
36754
|
const sourceConfigPath = (0, import_path10.join)(sourceHome, "config.yaml");
|
|
36196
|
-
if (!
|
|
36755
|
+
if (!fs22.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
36197
36756
|
if ((0, import_path10.resolve)(sourceConfigPath) === (0, import_path10.resolve)(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
36198
|
-
const parsed = parseMeshCoordinatorMcpConfig(
|
|
36757
|
+
const parsed = parseMeshCoordinatorMcpConfig(fs22.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
|
|
36199
36758
|
const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
|
|
36200
36759
|
return { config: baseConfig, sourceHome, sourceConfigPath };
|
|
36201
36760
|
}
|
|
@@ -36232,9 +36791,9 @@ function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
|
|
|
36232
36791
|
for (const fileName of [".env", "auth.json"]) {
|
|
36233
36792
|
const sourcePath = (0, import_path10.join)(sourceHome, fileName);
|
|
36234
36793
|
const targetPath = (0, import_path10.join)(targetHome, fileName);
|
|
36235
|
-
if (!
|
|
36794
|
+
if (!fs22.existsSync(sourcePath)) continue;
|
|
36236
36795
|
try {
|
|
36237
|
-
|
|
36796
|
+
fs22.copyFileSync(sourcePath, targetPath);
|
|
36238
36797
|
} catch (error) {
|
|
36239
36798
|
LOG.warn("MeshCoordinator", `Could not copy Hermes ${fileName} into isolated coordinator home: ${error?.message || error}`);
|
|
36240
36799
|
}
|
|
@@ -36589,13 +37148,13 @@ var DaemonCommandRouter = class {
|
|
|
36589
37148
|
recoveryHint: "Inspect the mesh node record before removing it, or remove stale metadata manually only after confirming no managed worktree remains."
|
|
36590
37149
|
};
|
|
36591
37150
|
}
|
|
36592
|
-
const worktreeExists =
|
|
37151
|
+
const worktreeExists = fs22.existsSync(workspace);
|
|
36593
37152
|
const sourceNode = args.node?.clonedFromNodeId ? args.mesh?.nodes?.find((n) => n.id === args.node.clonedFromNodeId || n.nodeId === args.node.clonedFromNodeId) : args.mesh?.nodes?.find((n) => !n.isLocalWorktree);
|
|
36594
37153
|
const repoRoot = typeof sourceNode?.repoRoot === "string" && sourceNode.repoRoot.trim() ? sourceNode.repoRoot.trim() : typeof sourceNode?.workspace === "string" && sourceNode.workspace.trim() ? sourceNode.workspace.trim() : "";
|
|
36595
37154
|
if (!worktreeExists) {
|
|
36596
37155
|
return { success: true, skipped: true, removedPath: workspace, repoRoot: repoRoot || void 0, reason: "worktree_path_missing" };
|
|
36597
37156
|
}
|
|
36598
|
-
if (!repoRoot || !
|
|
37157
|
+
if (!repoRoot || !fs22.existsSync(repoRoot)) {
|
|
36599
37158
|
return {
|
|
36600
37159
|
success: false,
|
|
36601
37160
|
code: "mesh_worktree_cleanup_missing_source_repo",
|
|
@@ -36615,7 +37174,7 @@ var DaemonCommandRouter = class {
|
|
|
36615
37174
|
const normalizePath = (value) => {
|
|
36616
37175
|
const resolved = (0, import_path10.resolve)(value);
|
|
36617
37176
|
try {
|
|
36618
|
-
return
|
|
37177
|
+
return fs22.realpathSync(resolved);
|
|
36619
37178
|
} catch {
|
|
36620
37179
|
return resolved;
|
|
36621
37180
|
}
|
|
@@ -37554,8 +38113,8 @@ var DaemonCommandRouter = class {
|
|
|
37554
38113
|
if (sinceTs > 0) {
|
|
37555
38114
|
return { success: true, logs: [], totalBuffered: 0 };
|
|
37556
38115
|
}
|
|
37557
|
-
if (
|
|
37558
|
-
const content =
|
|
38116
|
+
if (fs22.existsSync(LOG_PATH)) {
|
|
38117
|
+
const content = fs22.readFileSync(LOG_PATH, "utf-8");
|
|
37559
38118
|
const allLines = content.split("\n");
|
|
37560
38119
|
const recent = allLines.slice(-count).join("\n");
|
|
37561
38120
|
return { success: true, logs: recent, totalLines: allLines.length };
|
|
@@ -37945,24 +38504,24 @@ var DaemonCommandRouter = class {
|
|
|
37945
38504
|
// Settings page in the dashboard reads/writes via these two
|
|
37946
38505
|
// commands instead of going through fs from the browser.
|
|
37947
38506
|
case "list_coordinator_prompts": {
|
|
37948
|
-
const
|
|
37949
|
-
const
|
|
37950
|
-
const
|
|
37951
|
-
const dir =
|
|
38507
|
+
const fs28 = await import("fs");
|
|
38508
|
+
const path40 = await import("path");
|
|
38509
|
+
const os29 = await import("os");
|
|
38510
|
+
const dir = path40.join(os29.homedir(), ".adhdev", "coordinator-prompts");
|
|
37952
38511
|
const entries = {};
|
|
37953
38512
|
try {
|
|
37954
|
-
if (
|
|
37955
|
-
for (const name of
|
|
38513
|
+
if (fs28.existsSync(dir)) {
|
|
38514
|
+
for (const name of fs28.readdirSync(dir)) {
|
|
37956
38515
|
const matchOverride = name.match(/^([a-zA-Z0-9_.-]+)\.md$/);
|
|
37957
38516
|
const matchAppend = name.match(/^([a-zA-Z0-9_.-]+)\.append\.md$/);
|
|
37958
38517
|
const m = matchAppend || matchOverride;
|
|
37959
38518
|
if (!m) continue;
|
|
37960
38519
|
const isAppend = !!matchAppend;
|
|
37961
38520
|
const key = m[1];
|
|
37962
|
-
const full =
|
|
38521
|
+
const full = path40.join(dir, name);
|
|
37963
38522
|
let content = "";
|
|
37964
38523
|
try {
|
|
37965
|
-
content =
|
|
38524
|
+
content = fs28.readFileSync(full, "utf8");
|
|
37966
38525
|
} catch {
|
|
37967
38526
|
}
|
|
37968
38527
|
if (!entries[key]) entries[key] = { override: "", append: "" };
|
|
@@ -37976,24 +38535,24 @@ var DaemonCommandRouter = class {
|
|
|
37976
38535
|
return { success: true, dir, entries };
|
|
37977
38536
|
}
|
|
37978
38537
|
case "write_coordinator_prompt": {
|
|
37979
|
-
const
|
|
37980
|
-
const
|
|
37981
|
-
const
|
|
38538
|
+
const fs28 = await import("fs");
|
|
38539
|
+
const path40 = await import("path");
|
|
38540
|
+
const os29 = await import("os");
|
|
37982
38541
|
const key = typeof args?.key === "string" ? args.key.trim() : "";
|
|
37983
38542
|
const kind = args?.kind === "append" ? "append" : "override";
|
|
37984
38543
|
const content = typeof args?.content === "string" ? args.content : "";
|
|
37985
38544
|
if (!key || !/^[a-zA-Z0-9_.-]+$/.test(key)) {
|
|
37986
38545
|
return { success: false, error: "key must match [a-zA-Z0-9_.-]+" };
|
|
37987
38546
|
}
|
|
37988
|
-
const dir =
|
|
38547
|
+
const dir = path40.join(os29.homedir(), ".adhdev", "coordinator-prompts");
|
|
37989
38548
|
const filename = kind === "append" ? `${key}.append.md` : `${key}.md`;
|
|
37990
|
-
const full =
|
|
38549
|
+
const full = path40.join(dir, filename);
|
|
37991
38550
|
try {
|
|
37992
|
-
|
|
38551
|
+
fs28.mkdirSync(dir, { recursive: true });
|
|
37993
38552
|
if (content.trim()) {
|
|
37994
|
-
|
|
37995
|
-
} else if (
|
|
37996
|
-
|
|
38553
|
+
fs28.writeFileSync(full, content, { encoding: "utf8", mode: 384 });
|
|
38554
|
+
} else if (fs28.existsSync(full)) {
|
|
38555
|
+
fs28.unlinkSync(full);
|
|
37997
38556
|
}
|
|
37998
38557
|
return { success: true, path: full, kind, key };
|
|
37999
38558
|
} catch (error) {
|
|
@@ -39202,7 +39761,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
39202
39761
|
workspace
|
|
39203
39762
|
};
|
|
39204
39763
|
}
|
|
39205
|
-
const { existsSync:
|
|
39764
|
+
const { existsSync: existsSync39, readFileSync: readFileSync33, writeFileSync: writeFileSync20, copyFileSync: copyFileSync4, mkdirSync: mkdirSync19 } = await import("fs");
|
|
39206
39765
|
const { dirname: dirname11 } = await import("path");
|
|
39207
39766
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
39208
39767
|
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
@@ -39238,21 +39797,21 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
39238
39797
|
};
|
|
39239
39798
|
}
|
|
39240
39799
|
try {
|
|
39241
|
-
|
|
39800
|
+
mkdirSync19(dirname11(mcpConfigPath), { recursive: true });
|
|
39242
39801
|
} catch (error) {
|
|
39243
39802
|
const message = `Could not prepare MCP config path for automatic setup: ${error?.message || error}`;
|
|
39244
39803
|
LOG.error("MeshCoordinator", message);
|
|
39245
39804
|
if (hermesManualFallback) return returnManualFallback(message);
|
|
39246
39805
|
return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
|
|
39247
39806
|
}
|
|
39248
|
-
const hadExistingMcpConfig =
|
|
39807
|
+
const hadExistingMcpConfig = existsSync39(mcpConfigPath);
|
|
39249
39808
|
let existingMcpConfig = hermesBaseConfig?.config || {};
|
|
39250
39809
|
if (hermesBaseConfig) {
|
|
39251
39810
|
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname11(mcpConfigPath));
|
|
39252
39811
|
}
|
|
39253
39812
|
if (hadExistingMcpConfig) {
|
|
39254
39813
|
try {
|
|
39255
|
-
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(
|
|
39814
|
+
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync33(mcpConfigPath, "utf-8"), configFormat);
|
|
39256
39815
|
const existingCoordinatorConfig = hermesManualFallback ? stripHermesCoordinatorTempModelProviderOverrides(parsedExistingMcpConfig) : parsedExistingMcpConfig;
|
|
39257
39816
|
existingMcpConfig = { ...existingMcpConfig, ...existingCoordinatorConfig };
|
|
39258
39817
|
copyFileSync4(mcpConfigPath, mcpConfigPath + ".backup");
|
|
@@ -39275,7 +39834,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
39275
39834
|
}
|
|
39276
39835
|
};
|
|
39277
39836
|
try {
|
|
39278
|
-
|
|
39837
|
+
writeFileSync20(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
|
|
39279
39838
|
} catch (error) {
|
|
39280
39839
|
const message = `Could not write MCP config for automatic setup: ${error?.message || error}`;
|
|
39281
39840
|
LOG.error("MeshCoordinator", message);
|
|
@@ -39554,7 +40113,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
39554
40113
|
}
|
|
39555
40114
|
}
|
|
39556
40115
|
if (workspace) {
|
|
39557
|
-
if (!
|
|
40116
|
+
if (!fs22.existsSync(workspace)) {
|
|
39558
40117
|
const inlineTransitGit = buildInlineMeshTransitGitStatus(node);
|
|
39559
40118
|
let remoteProbeApplied = false;
|
|
39560
40119
|
if (inlineTransitGit) {
|
|
@@ -39667,7 +40226,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
39667
40226
|
const callerCoordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : this.deps.statusInstanceId || void 0;
|
|
39668
40227
|
const pendingCoordinatorEvents = drainPendingMeshCoordinatorEvents(meshId, callerCoordinatorDaemonId);
|
|
39669
40228
|
const previewFreshness = (() => {
|
|
39670
|
-
const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate &&
|
|
40229
|
+
const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate && fs22.existsSync(candidate));
|
|
39671
40230
|
return localRepoRoot ? buildPreviewFreshness(localRepoRoot) : void 0;
|
|
39672
40231
|
})();
|
|
39673
40232
|
const asyncRefineJobs = buildMeshAsyncRefineJobs({
|
|
@@ -41414,12 +41973,12 @@ var ProviderInstanceManager = class {
|
|
|
41414
41973
|
};
|
|
41415
41974
|
|
|
41416
41975
|
// src/providers/version-archive.ts
|
|
41417
|
-
var
|
|
41418
|
-
var
|
|
41419
|
-
var
|
|
41976
|
+
var fs23 = __toESM(require("fs"));
|
|
41977
|
+
var path35 = __toESM(require("path"));
|
|
41978
|
+
var os27 = __toESM(require("os"));
|
|
41420
41979
|
var import_os4 = require("os");
|
|
41421
41980
|
var import_child_process9 = require("child_process");
|
|
41422
|
-
var ARCHIVE_PATH =
|
|
41981
|
+
var ARCHIVE_PATH = path35.join(os27.homedir(), ".adhdev", "version-history.json");
|
|
41423
41982
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
41424
41983
|
var VersionArchive = class {
|
|
41425
41984
|
history = {};
|
|
@@ -41428,8 +41987,8 @@ var VersionArchive = class {
|
|
|
41428
41987
|
}
|
|
41429
41988
|
load() {
|
|
41430
41989
|
try {
|
|
41431
|
-
if (
|
|
41432
|
-
this.history = JSON.parse(
|
|
41990
|
+
if (fs23.existsSync(ARCHIVE_PATH)) {
|
|
41991
|
+
this.history = JSON.parse(fs23.readFileSync(ARCHIVE_PATH, "utf-8"));
|
|
41433
41992
|
}
|
|
41434
41993
|
} catch {
|
|
41435
41994
|
this.history = {};
|
|
@@ -41466,8 +42025,8 @@ var VersionArchive = class {
|
|
|
41466
42025
|
}
|
|
41467
42026
|
save() {
|
|
41468
42027
|
try {
|
|
41469
|
-
|
|
41470
|
-
|
|
42028
|
+
fs23.mkdirSync(path35.dirname(ARCHIVE_PATH), { recursive: true });
|
|
42029
|
+
fs23.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
41471
42030
|
} catch {
|
|
41472
42031
|
}
|
|
41473
42032
|
}
|
|
@@ -41490,10 +42049,10 @@ function findBinary2(name) {
|
|
|
41490
42049
|
for (const p of paths) {
|
|
41491
42050
|
if (!p) continue;
|
|
41492
42051
|
for (const ext of exes) {
|
|
41493
|
-
const fullPath =
|
|
42052
|
+
const fullPath = path35.join(p, name + ext);
|
|
41494
42053
|
try {
|
|
41495
|
-
if (
|
|
41496
|
-
const stat2 =
|
|
42054
|
+
if (fs23.existsSync(fullPath)) {
|
|
42055
|
+
const stat2 = fs23.statSync(fullPath);
|
|
41497
42056
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
41498
42057
|
return fullPath;
|
|
41499
42058
|
}
|
|
@@ -41538,19 +42097,19 @@ async function getVersion(binary, versionCommand) {
|
|
|
41538
42097
|
function checkPathExists2(paths) {
|
|
41539
42098
|
for (const p of paths) {
|
|
41540
42099
|
if (p.includes("*")) {
|
|
41541
|
-
const home =
|
|
41542
|
-
const resolved = p.replace(/\*/g, home.split(
|
|
41543
|
-
if (
|
|
42100
|
+
const home = os27.homedir();
|
|
42101
|
+
const resolved = p.replace(/\*/g, home.split(path35.sep).pop() || "");
|
|
42102
|
+
if (fs23.existsSync(resolved)) return resolved;
|
|
41544
42103
|
} else {
|
|
41545
|
-
if (
|
|
42104
|
+
if (fs23.existsSync(p)) return p;
|
|
41546
42105
|
}
|
|
41547
42106
|
}
|
|
41548
42107
|
return null;
|
|
41549
42108
|
}
|
|
41550
42109
|
async function getMacAppVersion(appPath) {
|
|
41551
42110
|
if ((0, import_os4.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
41552
|
-
const plistPath =
|
|
41553
|
-
if (!
|
|
42111
|
+
const plistPath = path35.join(appPath, "Contents", "Info.plist");
|
|
42112
|
+
if (!fs23.existsSync(plistPath)) return null;
|
|
41554
42113
|
const raw = await runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
41555
42114
|
return raw || null;
|
|
41556
42115
|
}
|
|
@@ -41575,8 +42134,8 @@ async function detectAllVersions(loader, archive) {
|
|
|
41575
42134
|
const cliBin = provider.cli ? findBinary2(provider.cli) : null;
|
|
41576
42135
|
let resolvedBin = cliBin;
|
|
41577
42136
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
41578
|
-
const bundled =
|
|
41579
|
-
if (provider.cli &&
|
|
42137
|
+
const bundled = path35.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
42138
|
+
if (provider.cli && fs23.existsSync(bundled)) resolvedBin = bundled;
|
|
41580
42139
|
}
|
|
41581
42140
|
info.installed = !!(appPath || resolvedBin);
|
|
41582
42141
|
info.path = appPath || null;
|
|
@@ -41615,8 +42174,8 @@ async function detectAllVersions(loader, archive) {
|
|
|
41615
42174
|
|
|
41616
42175
|
// src/daemon/dev-server.ts
|
|
41617
42176
|
var http2 = __toESM(require("http"));
|
|
41618
|
-
var
|
|
41619
|
-
var
|
|
42177
|
+
var fs27 = __toESM(require("fs"));
|
|
42178
|
+
var path39 = __toESM(require("path"));
|
|
41620
42179
|
init_config();
|
|
41621
42180
|
|
|
41622
42181
|
// src/daemon/scaffold-template.ts
|
|
@@ -41966,8 +42525,8 @@ async (params) => {
|
|
|
41966
42525
|
init_logger();
|
|
41967
42526
|
|
|
41968
42527
|
// src/daemon/dev-cdp-handlers.ts
|
|
41969
|
-
var
|
|
41970
|
-
var
|
|
42528
|
+
var fs24 = __toESM(require("fs"));
|
|
42529
|
+
var path36 = __toESM(require("path"));
|
|
41971
42530
|
init_logger();
|
|
41972
42531
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
41973
42532
|
const body = await ctx.readBody(req);
|
|
@@ -42146,18 +42705,18 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
42146
42705
|
return;
|
|
42147
42706
|
}
|
|
42148
42707
|
let scriptsPath = "";
|
|
42149
|
-
const directScripts =
|
|
42150
|
-
if (
|
|
42708
|
+
const directScripts = path36.join(dir, "scripts.js");
|
|
42709
|
+
if (fs24.existsSync(directScripts)) {
|
|
42151
42710
|
scriptsPath = directScripts;
|
|
42152
42711
|
} else {
|
|
42153
|
-
const scriptsDir =
|
|
42154
|
-
if (
|
|
42155
|
-
const versions =
|
|
42156
|
-
return
|
|
42712
|
+
const scriptsDir = path36.join(dir, "scripts");
|
|
42713
|
+
if (fs24.existsSync(scriptsDir)) {
|
|
42714
|
+
const versions = fs24.readdirSync(scriptsDir).filter((d) => {
|
|
42715
|
+
return fs24.statSync(path36.join(scriptsDir, d)).isDirectory();
|
|
42157
42716
|
}).sort().reverse();
|
|
42158
42717
|
for (const ver of versions) {
|
|
42159
|
-
const p =
|
|
42160
|
-
if (
|
|
42718
|
+
const p = path36.join(scriptsDir, ver, "scripts.js");
|
|
42719
|
+
if (fs24.existsSync(p)) {
|
|
42161
42720
|
scriptsPath = p;
|
|
42162
42721
|
break;
|
|
42163
42722
|
}
|
|
@@ -42169,7 +42728,7 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
42169
42728
|
return;
|
|
42170
42729
|
}
|
|
42171
42730
|
try {
|
|
42172
|
-
const source =
|
|
42731
|
+
const source = fs24.readFileSync(scriptsPath, "utf-8");
|
|
42173
42732
|
const hints = {};
|
|
42174
42733
|
const funcRegex = /module\.exports\.(\w+)\s*=\s*function\s+\w+\s*\(params\)/g;
|
|
42175
42734
|
let match;
|
|
@@ -42984,8 +43543,8 @@ async function handleDomContext(ctx, type, req, res) {
|
|
|
42984
43543
|
}
|
|
42985
43544
|
|
|
42986
43545
|
// src/daemon/dev-cli-debug.ts
|
|
42987
|
-
var
|
|
42988
|
-
var
|
|
43546
|
+
var fs25 = __toESM(require("fs"));
|
|
43547
|
+
var path37 = __toESM(require("path"));
|
|
42989
43548
|
function slugifyFixtureName(value) {
|
|
42990
43549
|
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
42991
43550
|
return normalized || `fixture-${Date.now()}`;
|
|
@@ -42995,15 +43554,15 @@ function getCliFixtureDir(ctx, type) {
|
|
|
42995
43554
|
if (!providerDir) {
|
|
42996
43555
|
throw new Error(`Provider directory not found for '${type}'`);
|
|
42997
43556
|
}
|
|
42998
|
-
return
|
|
43557
|
+
return path37.join(providerDir, "fixtures");
|
|
42999
43558
|
}
|
|
43000
43559
|
function readCliFixture(ctx, type, name) {
|
|
43001
43560
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
43002
|
-
const filePath =
|
|
43003
|
-
if (!
|
|
43561
|
+
const filePath = path37.join(fixtureDir, `${name}.json`);
|
|
43562
|
+
if (!fs25.existsSync(filePath)) {
|
|
43004
43563
|
throw new Error(`Fixture not found: ${filePath}`);
|
|
43005
43564
|
}
|
|
43006
|
-
return JSON.parse(
|
|
43565
|
+
return JSON.parse(fs25.readFileSync(filePath, "utf-8"));
|
|
43007
43566
|
}
|
|
43008
43567
|
function getExerciseTranscriptText(result) {
|
|
43009
43568
|
const parts = [];
|
|
@@ -43748,7 +44307,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
43748
44307
|
return;
|
|
43749
44308
|
}
|
|
43750
44309
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
43751
|
-
|
|
44310
|
+
fs25.mkdirSync(fixtureDir, { recursive: true });
|
|
43752
44311
|
const name = slugifyFixtureName(String(body?.name || `${type}-${Date.now()}`));
|
|
43753
44312
|
const result = await runCliExerciseInternal(ctx, { ...request, type });
|
|
43754
44313
|
const fixture = {
|
|
@@ -43775,8 +44334,8 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
43775
44334
|
},
|
|
43776
44335
|
notes: typeof body?.notes === "string" ? body.notes : void 0
|
|
43777
44336
|
};
|
|
43778
|
-
const filePath =
|
|
43779
|
-
|
|
44337
|
+
const filePath = path37.join(fixtureDir, `${name}.json`);
|
|
44338
|
+
fs25.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
|
|
43780
44339
|
ctx.json(res, 200, {
|
|
43781
44340
|
saved: true,
|
|
43782
44341
|
name,
|
|
@@ -43794,14 +44353,14 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
43794
44353
|
async function handleCliFixtureList(ctx, type, _req, res) {
|
|
43795
44354
|
try {
|
|
43796
44355
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
43797
|
-
if (!
|
|
44356
|
+
if (!fs25.existsSync(fixtureDir)) {
|
|
43798
44357
|
ctx.json(res, 200, { fixtures: [], count: 0 });
|
|
43799
44358
|
return;
|
|
43800
44359
|
}
|
|
43801
|
-
const fixtures =
|
|
43802
|
-
const fullPath =
|
|
44360
|
+
const fixtures = fs25.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
|
|
44361
|
+
const fullPath = path37.join(fixtureDir, file);
|
|
43803
44362
|
try {
|
|
43804
|
-
const raw = JSON.parse(
|
|
44363
|
+
const raw = JSON.parse(fs25.readFileSync(fullPath, "utf-8"));
|
|
43805
44364
|
return {
|
|
43806
44365
|
name: raw.name || file.replace(/\.json$/i, ""),
|
|
43807
44366
|
path: fullPath,
|
|
@@ -43934,9 +44493,9 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
43934
44493
|
}
|
|
43935
44494
|
|
|
43936
44495
|
// src/daemon/dev-auto-implement.ts
|
|
43937
|
-
var
|
|
43938
|
-
var
|
|
43939
|
-
var
|
|
44496
|
+
var fs26 = __toESM(require("fs"));
|
|
44497
|
+
var path38 = __toESM(require("path"));
|
|
44498
|
+
var os28 = __toESM(require("os"));
|
|
43940
44499
|
function getAutoImplPid(ctx) {
|
|
43941
44500
|
const pid = ctx.autoImplProcess?.pid;
|
|
43942
44501
|
return typeof pid === "number" && pid > 0 ? pid : null;
|
|
@@ -43982,38 +44541,38 @@ function resolveAutoImplReference(ctx, category, requestedReference, targetType)
|
|
|
43982
44541
|
return fallback?.type || null;
|
|
43983
44542
|
}
|
|
43984
44543
|
function getLatestScriptVersionDir(scriptsDir) {
|
|
43985
|
-
if (!
|
|
43986
|
-
const versions =
|
|
44544
|
+
if (!fs26.existsSync(scriptsDir)) return null;
|
|
44545
|
+
const versions = fs26.readdirSync(scriptsDir).filter((d) => {
|
|
43987
44546
|
try {
|
|
43988
|
-
return
|
|
44547
|
+
return fs26.statSync(path38.join(scriptsDir, d)).isDirectory();
|
|
43989
44548
|
} catch {
|
|
43990
44549
|
return false;
|
|
43991
44550
|
}
|
|
43992
44551
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
43993
44552
|
if (versions.length === 0) return null;
|
|
43994
|
-
return
|
|
44553
|
+
return path38.join(scriptsDir, versions[0]);
|
|
43995
44554
|
}
|
|
43996
44555
|
function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
43997
|
-
const canonicalUserDir =
|
|
43998
|
-
const desiredDir = requestedDir ?
|
|
43999
|
-
const upstreamRoot =
|
|
44000
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
44556
|
+
const canonicalUserDir = path38.resolve(ctx.providerLoader.getUserProviderDir(category, type));
|
|
44557
|
+
const desiredDir = requestedDir ? path38.resolve(requestedDir) : canonicalUserDir;
|
|
44558
|
+
const upstreamRoot = path38.resolve(ctx.providerLoader.getUpstreamDir());
|
|
44559
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path38.sep}`)) {
|
|
44001
44560
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
44002
44561
|
}
|
|
44003
|
-
if (
|
|
44562
|
+
if (path38.basename(desiredDir) !== type) {
|
|
44004
44563
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
44005
44564
|
}
|
|
44006
44565
|
const sourceDir = ctx.findProviderDir(type);
|
|
44007
44566
|
if (!sourceDir) {
|
|
44008
44567
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
44009
44568
|
}
|
|
44010
|
-
if (!
|
|
44011
|
-
|
|
44012
|
-
|
|
44569
|
+
if (!fs26.existsSync(desiredDir)) {
|
|
44570
|
+
fs26.mkdirSync(path38.dirname(desiredDir), { recursive: true });
|
|
44571
|
+
fs26.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
44013
44572
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
44014
44573
|
}
|
|
44015
|
-
const providerJson =
|
|
44016
|
-
if (!
|
|
44574
|
+
const providerJson = path38.join(desiredDir, "provider.json");
|
|
44575
|
+
if (!fs26.existsSync(providerJson)) {
|
|
44017
44576
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
44018
44577
|
}
|
|
44019
44578
|
return { dir: desiredDir };
|
|
@@ -44021,15 +44580,15 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
44021
44580
|
function loadAutoImplReferenceScripts(ctx, referenceType) {
|
|
44022
44581
|
if (!referenceType) return {};
|
|
44023
44582
|
const refDir = ctx.findProviderDir(referenceType);
|
|
44024
|
-
if (!refDir || !
|
|
44583
|
+
if (!refDir || !fs26.existsSync(refDir)) return {};
|
|
44025
44584
|
const referenceScripts = {};
|
|
44026
|
-
const scriptsDir =
|
|
44585
|
+
const scriptsDir = path38.join(refDir, "scripts");
|
|
44027
44586
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
44028
44587
|
if (!latestDir) return referenceScripts;
|
|
44029
|
-
for (const file of
|
|
44588
|
+
for (const file of fs26.readdirSync(latestDir)) {
|
|
44030
44589
|
if (!file.endsWith(".js")) continue;
|
|
44031
44590
|
try {
|
|
44032
|
-
referenceScripts[file] =
|
|
44591
|
+
referenceScripts[file] = fs26.readFileSync(path38.join(latestDir, file), "utf-8");
|
|
44033
44592
|
} catch {
|
|
44034
44593
|
}
|
|
44035
44594
|
}
|
|
@@ -44137,16 +44696,16 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
44137
44696
|
});
|
|
44138
44697
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
44139
44698
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
44140
|
-
const tmpDir =
|
|
44141
|
-
if (!
|
|
44142
|
-
const promptFile =
|
|
44143
|
-
|
|
44699
|
+
const tmpDir = path38.join(os28.tmpdir(), "adhdev-autoimpl");
|
|
44700
|
+
if (!fs26.existsSync(tmpDir)) fs26.mkdirSync(tmpDir, { recursive: true });
|
|
44701
|
+
const promptFile = path38.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
44702
|
+
fs26.writeFileSync(promptFile, prompt, "utf-8");
|
|
44144
44703
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
44145
44704
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
44146
44705
|
const spawn4 = agentProvider?.spawn;
|
|
44147
44706
|
if (!spawn4?.command) {
|
|
44148
44707
|
try {
|
|
44149
|
-
|
|
44708
|
+
fs26.unlinkSync(promptFile);
|
|
44150
44709
|
} catch {
|
|
44151
44710
|
}
|
|
44152
44711
|
ctx.json(res, 400, { error: `Agent '${agent}' has no spawn config. Select a CLI provider with a spawn configuration.` });
|
|
@@ -44248,7 +44807,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
44248
44807
|
} catch {
|
|
44249
44808
|
}
|
|
44250
44809
|
try {
|
|
44251
|
-
|
|
44810
|
+
fs26.unlinkSync(promptFile);
|
|
44252
44811
|
} catch {
|
|
44253
44812
|
}
|
|
44254
44813
|
ctx.log(`Auto-implement (ACP) ${success ? "completed" : "failed"}: ${type} (exit: ${code})`);
|
|
@@ -44292,7 +44851,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
44292
44851
|
const interactiveFlags = ["--yolo", "--interactive", "-i"];
|
|
44293
44852
|
const baseArgs = [...spawn4.args || []].filter((a) => !interactiveFlags.includes(a));
|
|
44294
44853
|
let shellCmd;
|
|
44295
|
-
const isWin =
|
|
44854
|
+
const isWin = os28.platform() === "win32";
|
|
44296
44855
|
const escapeArg = (a) => isWin ? `"${a.replace(/"/g, '""')}"` : `'${a.replace(/'/g, "'\\''")}'`;
|
|
44297
44856
|
const promptMode = autoImpl?.promptMode ?? "stdin";
|
|
44298
44857
|
const extraArgs = autoImpl?.extraArgs ?? [];
|
|
@@ -44331,7 +44890,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
44331
44890
|
try {
|
|
44332
44891
|
const pty = require("node-pty");
|
|
44333
44892
|
ctx.log(`Auto-implement spawn (PTY): ${shellCmd}`);
|
|
44334
|
-
const isWin2 =
|
|
44893
|
+
const isWin2 = os28.platform() === "win32";
|
|
44335
44894
|
child = pty.spawn(isWin2 ? "cmd.exe" : process.env.SHELL || "/bin/zsh", [isWin2 ? "/c" : "-c", shellCmd], {
|
|
44336
44895
|
name: "xterm-256color",
|
|
44337
44896
|
cols: 120,
|
|
@@ -44474,7 +45033,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
44474
45033
|
}
|
|
44475
45034
|
});
|
|
44476
45035
|
try {
|
|
44477
|
-
|
|
45036
|
+
fs26.unlinkSync(promptFile);
|
|
44478
45037
|
} catch {
|
|
44479
45038
|
}
|
|
44480
45039
|
ctx.log(`Auto-implement ${success ? "completed" : "failed"}: ${type} (exit: ${code})${verificationSummary ? ` verify=${verificationSummary.pass ? "pass" : "fail"}` : ""}`);
|
|
@@ -44571,7 +45130,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
44571
45130
|
setMode: "set_mode.js"
|
|
44572
45131
|
};
|
|
44573
45132
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
44574
|
-
const scriptsDir =
|
|
45133
|
+
const scriptsDir = path38.join(providerDir, "scripts");
|
|
44575
45134
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
44576
45135
|
if (latestScriptsDir) {
|
|
44577
45136
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -44579,10 +45138,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
44579
45138
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
44580
45139
|
lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
|
|
44581
45140
|
lines.push("");
|
|
44582
|
-
for (const file of
|
|
45141
|
+
for (const file of fs26.readdirSync(latestScriptsDir)) {
|
|
44583
45142
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
44584
45143
|
try {
|
|
44585
|
-
const content =
|
|
45144
|
+
const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
|
|
44586
45145
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
44587
45146
|
lines.push("```javascript");
|
|
44588
45147
|
lines.push(content);
|
|
@@ -44592,14 +45151,14 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
44592
45151
|
}
|
|
44593
45152
|
}
|
|
44594
45153
|
}
|
|
44595
|
-
const refFiles =
|
|
45154
|
+
const refFiles = fs26.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
44596
45155
|
if (refFiles.length > 0) {
|
|
44597
45156
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
44598
45157
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
44599
45158
|
lines.push("");
|
|
44600
45159
|
for (const file of refFiles) {
|
|
44601
45160
|
try {
|
|
44602
|
-
const content =
|
|
45161
|
+
const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
|
|
44603
45162
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
44604
45163
|
lines.push("```javascript");
|
|
44605
45164
|
lines.push(content);
|
|
@@ -44640,11 +45199,11 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
44640
45199
|
lines.push("");
|
|
44641
45200
|
}
|
|
44642
45201
|
}
|
|
44643
|
-
const docsDir =
|
|
45202
|
+
const docsDir = path38.join(providerDir, "../../docs");
|
|
44644
45203
|
const loadGuide = (name) => {
|
|
44645
45204
|
try {
|
|
44646
|
-
const p =
|
|
44647
|
-
if (
|
|
45205
|
+
const p = path38.join(docsDir, name);
|
|
45206
|
+
if (fs26.existsSync(p)) return fs26.readFileSync(p, "utf-8");
|
|
44648
45207
|
} catch {
|
|
44649
45208
|
}
|
|
44650
45209
|
return null;
|
|
@@ -44880,7 +45439,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
44880
45439
|
parseApproval: "parse_approval.js"
|
|
44881
45440
|
};
|
|
44882
45441
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
44883
|
-
const scriptsDir =
|
|
45442
|
+
const scriptsDir = path38.join(providerDir, "scripts");
|
|
44884
45443
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
44885
45444
|
if (latestScriptsDir) {
|
|
44886
45445
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -44888,11 +45447,11 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
44888
45447
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
44889
45448
|
lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
|
|
44890
45449
|
lines.push("");
|
|
44891
|
-
for (const file of
|
|
45450
|
+
for (const file of fs26.readdirSync(latestScriptsDir)) {
|
|
44892
45451
|
if (!file.endsWith(".js")) continue;
|
|
44893
45452
|
if (!targetFileNames.has(file)) continue;
|
|
44894
45453
|
try {
|
|
44895
|
-
const content =
|
|
45454
|
+
const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
|
|
44896
45455
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
44897
45456
|
lines.push("```javascript");
|
|
44898
45457
|
lines.push(content);
|
|
@@ -44901,14 +45460,14 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
44901
45460
|
} catch {
|
|
44902
45461
|
}
|
|
44903
45462
|
}
|
|
44904
|
-
const refFiles =
|
|
45463
|
+
const refFiles = fs26.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
44905
45464
|
if (refFiles.length > 0) {
|
|
44906
45465
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
44907
45466
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
44908
45467
|
lines.push("");
|
|
44909
45468
|
for (const file of refFiles) {
|
|
44910
45469
|
try {
|
|
44911
|
-
const content =
|
|
45470
|
+
const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
|
|
44912
45471
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
44913
45472
|
lines.push("```javascript");
|
|
44914
45473
|
lines.push(content);
|
|
@@ -44941,11 +45500,11 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
44941
45500
|
lines.push("");
|
|
44942
45501
|
}
|
|
44943
45502
|
}
|
|
44944
|
-
const docsDir =
|
|
45503
|
+
const docsDir = path38.join(providerDir, "../../docs");
|
|
44945
45504
|
const loadGuide = (name) => {
|
|
44946
45505
|
try {
|
|
44947
|
-
const p =
|
|
44948
|
-
if (
|
|
45506
|
+
const p = path38.join(docsDir, name);
|
|
45507
|
+
if (fs26.existsSync(p)) return fs26.readFileSync(p, "utf-8");
|
|
44949
45508
|
} catch {
|
|
44950
45509
|
}
|
|
44951
45510
|
return null;
|
|
@@ -45391,8 +45950,8 @@ var DevServer = class _DevServer {
|
|
|
45391
45950
|
}
|
|
45392
45951
|
getEndpointList() {
|
|
45393
45952
|
return this.routes.map((r) => {
|
|
45394
|
-
const
|
|
45395
|
-
return `${r.method.padEnd(5)} ${
|
|
45953
|
+
const path40 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
|
|
45954
|
+
return `${r.method.padEnd(5)} ${path40}`;
|
|
45396
45955
|
});
|
|
45397
45956
|
}
|
|
45398
45957
|
async start(port = DEV_SERVER_PORT) {
|
|
@@ -45680,12 +46239,12 @@ var DevServer = class _DevServer {
|
|
|
45680
46239
|
// ─── DevConsole SPA ───
|
|
45681
46240
|
getConsoleDistDir() {
|
|
45682
46241
|
const candidates = [
|
|
45683
|
-
|
|
45684
|
-
|
|
45685
|
-
|
|
46242
|
+
path39.resolve(__dirname, "../../web-devconsole/dist"),
|
|
46243
|
+
path39.resolve(__dirname, "../../../web-devconsole/dist"),
|
|
46244
|
+
path39.join(process.cwd(), "packages/web-devconsole/dist")
|
|
45686
46245
|
];
|
|
45687
46246
|
for (const dir of candidates) {
|
|
45688
|
-
if (
|
|
46247
|
+
if (fs27.existsSync(path39.join(dir, "index.html"))) return dir;
|
|
45689
46248
|
}
|
|
45690
46249
|
return null;
|
|
45691
46250
|
}
|
|
@@ -45695,9 +46254,9 @@ var DevServer = class _DevServer {
|
|
|
45695
46254
|
this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
|
|
45696
46255
|
return;
|
|
45697
46256
|
}
|
|
45698
|
-
const htmlPath =
|
|
46257
|
+
const htmlPath = path39.join(distDir, "index.html");
|
|
45699
46258
|
try {
|
|
45700
|
-
const html =
|
|
46259
|
+
const html = fs27.readFileSync(htmlPath, "utf-8");
|
|
45701
46260
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
45702
46261
|
res.end(html);
|
|
45703
46262
|
} catch (e) {
|
|
@@ -45720,15 +46279,15 @@ var DevServer = class _DevServer {
|
|
|
45720
46279
|
this.json(res, 404, { error: "Not found" });
|
|
45721
46280
|
return;
|
|
45722
46281
|
}
|
|
45723
|
-
const safePath =
|
|
45724
|
-
const filePath =
|
|
46282
|
+
const safePath = path39.normalize(pathname).replace(/^\.\.\//, "");
|
|
46283
|
+
const filePath = path39.join(distDir, safePath);
|
|
45725
46284
|
if (!filePath.startsWith(distDir)) {
|
|
45726
46285
|
this.json(res, 403, { error: "Forbidden" });
|
|
45727
46286
|
return;
|
|
45728
46287
|
}
|
|
45729
46288
|
try {
|
|
45730
|
-
const content =
|
|
45731
|
-
const ext =
|
|
46289
|
+
const content = fs27.readFileSync(filePath);
|
|
46290
|
+
const ext = path39.extname(filePath);
|
|
45732
46291
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
45733
46292
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
45734
46293
|
res.end(content);
|
|
@@ -45836,14 +46395,14 @@ var DevServer = class _DevServer {
|
|
|
45836
46395
|
const files = [];
|
|
45837
46396
|
const scan = (d, prefix) => {
|
|
45838
46397
|
try {
|
|
45839
|
-
for (const entry of
|
|
46398
|
+
for (const entry of fs27.readdirSync(d, { withFileTypes: true })) {
|
|
45840
46399
|
if (entry.name.startsWith(".") || entry.name.endsWith(".bak")) continue;
|
|
45841
46400
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
45842
46401
|
if (entry.isDirectory()) {
|
|
45843
46402
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
45844
|
-
scan(
|
|
46403
|
+
scan(path39.join(d, entry.name), rel);
|
|
45845
46404
|
} else {
|
|
45846
|
-
const stat2 =
|
|
46405
|
+
const stat2 = fs27.statSync(path39.join(d, entry.name));
|
|
45847
46406
|
files.push({ path: rel, size: stat2.size, type: "file" });
|
|
45848
46407
|
}
|
|
45849
46408
|
}
|
|
@@ -45866,16 +46425,16 @@ var DevServer = class _DevServer {
|
|
|
45866
46425
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
45867
46426
|
return;
|
|
45868
46427
|
}
|
|
45869
|
-
const fullPath =
|
|
46428
|
+
const fullPath = path39.resolve(dir, path39.normalize(filePath));
|
|
45870
46429
|
if (!fullPath.startsWith(dir)) {
|
|
45871
46430
|
this.json(res, 403, { error: "Forbidden" });
|
|
45872
46431
|
return;
|
|
45873
46432
|
}
|
|
45874
|
-
if (!
|
|
46433
|
+
if (!fs27.existsSync(fullPath) || fs27.statSync(fullPath).isDirectory()) {
|
|
45875
46434
|
this.json(res, 404, { error: `File not found: ${filePath}` });
|
|
45876
46435
|
return;
|
|
45877
46436
|
}
|
|
45878
|
-
const content =
|
|
46437
|
+
const content = fs27.readFileSync(fullPath, "utf-8");
|
|
45879
46438
|
this.json(res, 200, { type, path: filePath, content, lines: content.split("\n").length });
|
|
45880
46439
|
}
|
|
45881
46440
|
/** POST /api/providers/:type/file — write a file { path, content } */
|
|
@@ -45891,15 +46450,15 @@ var DevServer = class _DevServer {
|
|
|
45891
46450
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
45892
46451
|
return;
|
|
45893
46452
|
}
|
|
45894
|
-
const fullPath =
|
|
46453
|
+
const fullPath = path39.resolve(dir, path39.normalize(filePath));
|
|
45895
46454
|
if (!fullPath.startsWith(dir)) {
|
|
45896
46455
|
this.json(res, 403, { error: "Forbidden" });
|
|
45897
46456
|
return;
|
|
45898
46457
|
}
|
|
45899
46458
|
try {
|
|
45900
|
-
if (
|
|
45901
|
-
|
|
45902
|
-
|
|
46459
|
+
if (fs27.existsSync(fullPath)) fs27.copyFileSync(fullPath, fullPath + ".bak");
|
|
46460
|
+
fs27.mkdirSync(path39.dirname(fullPath), { recursive: true });
|
|
46461
|
+
fs27.writeFileSync(fullPath, content, "utf-8");
|
|
45903
46462
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
45904
46463
|
this.providerLoader.reload();
|
|
45905
46464
|
this.json(res, 200, { saved: true, path: filePath, chars: content.length });
|
|
@@ -45915,9 +46474,9 @@ var DevServer = class _DevServer {
|
|
|
45915
46474
|
return;
|
|
45916
46475
|
}
|
|
45917
46476
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
45918
|
-
const p =
|
|
45919
|
-
if (
|
|
45920
|
-
const source =
|
|
46477
|
+
const p = path39.join(dir, name);
|
|
46478
|
+
if (fs27.existsSync(p)) {
|
|
46479
|
+
const source = fs27.readFileSync(p, "utf-8");
|
|
45921
46480
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
45922
46481
|
return;
|
|
45923
46482
|
}
|
|
@@ -45936,11 +46495,11 @@ var DevServer = class _DevServer {
|
|
|
45936
46495
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
45937
46496
|
return;
|
|
45938
46497
|
}
|
|
45939
|
-
const target =
|
|
45940
|
-
const targetPath =
|
|
46498
|
+
const target = fs27.existsSync(path39.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
46499
|
+
const targetPath = path39.join(dir, target);
|
|
45941
46500
|
try {
|
|
45942
|
-
if (
|
|
45943
|
-
|
|
46501
|
+
if (fs27.existsSync(targetPath)) fs27.copyFileSync(targetPath, targetPath + ".bak");
|
|
46502
|
+
fs27.writeFileSync(targetPath, source, "utf-8");
|
|
45944
46503
|
this.log(`Saved provider: ${targetPath} (${source.length} chars)`);
|
|
45945
46504
|
this.providerLoader.reload();
|
|
45946
46505
|
this.json(res, 200, { saved: true, path: targetPath, chars: source.length });
|
|
@@ -46084,21 +46643,21 @@ var DevServer = class _DevServer {
|
|
|
46084
46643
|
}
|
|
46085
46644
|
let targetDir;
|
|
46086
46645
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
46087
|
-
const jsonPath =
|
|
46088
|
-
if (
|
|
46646
|
+
const jsonPath = path39.join(targetDir, "provider.json");
|
|
46647
|
+
if (fs27.existsSync(jsonPath)) {
|
|
46089
46648
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
46090
46649
|
return;
|
|
46091
46650
|
}
|
|
46092
46651
|
try {
|
|
46093
46652
|
const result = generateFiles(type, name, category, { cdpPorts, cli, processName, installPath, binary, extensionId, version, osPaths, processNames });
|
|
46094
|
-
|
|
46095
|
-
|
|
46653
|
+
fs27.mkdirSync(targetDir, { recursive: true });
|
|
46654
|
+
fs27.writeFileSync(jsonPath, result["provider.json"], "utf-8");
|
|
46096
46655
|
const createdFiles = ["provider.json"];
|
|
46097
46656
|
if (result.files) {
|
|
46098
46657
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
46099
|
-
const fullPath =
|
|
46100
|
-
|
|
46101
|
-
|
|
46658
|
+
const fullPath = path39.join(targetDir, relPath);
|
|
46659
|
+
fs27.mkdirSync(path39.dirname(fullPath), { recursive: true });
|
|
46660
|
+
fs27.writeFileSync(fullPath, content, "utf-8");
|
|
46102
46661
|
createdFiles.push(relPath);
|
|
46103
46662
|
}
|
|
46104
46663
|
}
|
|
@@ -46147,38 +46706,38 @@ var DevServer = class _DevServer {
|
|
|
46147
46706
|
}
|
|
46148
46707
|
// ─── Phase 2: Auto-Implement Backend ───
|
|
46149
46708
|
getLatestScriptVersionDir(scriptsDir) {
|
|
46150
|
-
if (!
|
|
46151
|
-
const versions =
|
|
46709
|
+
if (!fs27.existsSync(scriptsDir)) return null;
|
|
46710
|
+
const versions = fs27.readdirSync(scriptsDir).filter((d) => {
|
|
46152
46711
|
try {
|
|
46153
|
-
return
|
|
46712
|
+
return fs27.statSync(path39.join(scriptsDir, d)).isDirectory();
|
|
46154
46713
|
} catch {
|
|
46155
46714
|
return false;
|
|
46156
46715
|
}
|
|
46157
46716
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
46158
46717
|
if (versions.length === 0) return null;
|
|
46159
|
-
return
|
|
46718
|
+
return path39.join(scriptsDir, versions[0]);
|
|
46160
46719
|
}
|
|
46161
46720
|
resolveAutoImplWritableProviderDir(category, type, requestedDir) {
|
|
46162
|
-
const canonicalUserDir =
|
|
46163
|
-
const desiredDir = requestedDir ?
|
|
46164
|
-
const upstreamRoot =
|
|
46165
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
46721
|
+
const canonicalUserDir = path39.resolve(this.providerLoader.getUserProviderDir(category, type));
|
|
46722
|
+
const desiredDir = requestedDir ? path39.resolve(requestedDir) : canonicalUserDir;
|
|
46723
|
+
const upstreamRoot = path39.resolve(this.providerLoader.getUpstreamDir());
|
|
46724
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path39.sep}`)) {
|
|
46166
46725
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
46167
46726
|
}
|
|
46168
|
-
if (
|
|
46727
|
+
if (path39.basename(desiredDir) !== type) {
|
|
46169
46728
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
46170
46729
|
}
|
|
46171
46730
|
const sourceDir = this.findProviderDir(type);
|
|
46172
46731
|
if (!sourceDir) {
|
|
46173
46732
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
46174
46733
|
}
|
|
46175
|
-
if (!
|
|
46176
|
-
|
|
46177
|
-
|
|
46734
|
+
if (!fs27.existsSync(desiredDir)) {
|
|
46735
|
+
fs27.mkdirSync(path39.dirname(desiredDir), { recursive: true });
|
|
46736
|
+
fs27.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
46178
46737
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
46179
46738
|
}
|
|
46180
|
-
const providerJson =
|
|
46181
|
-
if (!
|
|
46739
|
+
const providerJson = path39.join(desiredDir, "provider.json");
|
|
46740
|
+
if (!fs27.existsSync(providerJson)) {
|
|
46182
46741
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
46183
46742
|
}
|
|
46184
46743
|
return { dir: desiredDir };
|
|
@@ -46213,7 +46772,7 @@ var DevServer = class _DevServer {
|
|
|
46213
46772
|
setMode: "set_mode.js"
|
|
46214
46773
|
};
|
|
46215
46774
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
46216
|
-
const scriptsDir =
|
|
46775
|
+
const scriptsDir = path39.join(providerDir, "scripts");
|
|
46217
46776
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
46218
46777
|
if (latestScriptsDir) {
|
|
46219
46778
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -46221,10 +46780,10 @@ var DevServer = class _DevServer {
|
|
|
46221
46780
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
46222
46781
|
lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
|
|
46223
46782
|
lines.push("");
|
|
46224
|
-
for (const file of
|
|
46783
|
+
for (const file of fs27.readdirSync(latestScriptsDir)) {
|
|
46225
46784
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
46226
46785
|
try {
|
|
46227
|
-
const content =
|
|
46786
|
+
const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
46228
46787
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
46229
46788
|
lines.push("```javascript");
|
|
46230
46789
|
lines.push(content);
|
|
@@ -46234,14 +46793,14 @@ var DevServer = class _DevServer {
|
|
|
46234
46793
|
}
|
|
46235
46794
|
}
|
|
46236
46795
|
}
|
|
46237
|
-
const refFiles =
|
|
46796
|
+
const refFiles = fs27.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
46238
46797
|
if (refFiles.length > 0) {
|
|
46239
46798
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
46240
46799
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
46241
46800
|
lines.push("");
|
|
46242
46801
|
for (const file of refFiles) {
|
|
46243
46802
|
try {
|
|
46244
|
-
const content =
|
|
46803
|
+
const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
46245
46804
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
46246
46805
|
lines.push("```javascript");
|
|
46247
46806
|
lines.push(content);
|
|
@@ -46282,11 +46841,11 @@ var DevServer = class _DevServer {
|
|
|
46282
46841
|
lines.push("");
|
|
46283
46842
|
}
|
|
46284
46843
|
}
|
|
46285
|
-
const docsDir =
|
|
46844
|
+
const docsDir = path39.join(providerDir, "../../docs");
|
|
46286
46845
|
const loadGuide = (name) => {
|
|
46287
46846
|
try {
|
|
46288
|
-
const p =
|
|
46289
|
-
if (
|
|
46847
|
+
const p = path39.join(docsDir, name);
|
|
46848
|
+
if (fs27.existsSync(p)) return fs27.readFileSync(p, "utf-8");
|
|
46290
46849
|
} catch {
|
|
46291
46850
|
}
|
|
46292
46851
|
return null;
|
|
@@ -46459,7 +47018,7 @@ var DevServer = class _DevServer {
|
|
|
46459
47018
|
parseApproval: "parse_approval.js"
|
|
46460
47019
|
};
|
|
46461
47020
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
46462
|
-
const scriptsDir =
|
|
47021
|
+
const scriptsDir = path39.join(providerDir, "scripts");
|
|
46463
47022
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
46464
47023
|
if (latestScriptsDir) {
|
|
46465
47024
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -46467,11 +47026,11 @@ var DevServer = class _DevServer {
|
|
|
46467
47026
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
46468
47027
|
lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
|
|
46469
47028
|
lines.push("");
|
|
46470
|
-
for (const file of
|
|
47029
|
+
for (const file of fs27.readdirSync(latestScriptsDir)) {
|
|
46471
47030
|
if (!file.endsWith(".js")) continue;
|
|
46472
47031
|
if (!targetFileNames.has(file)) continue;
|
|
46473
47032
|
try {
|
|
46474
|
-
const content =
|
|
47033
|
+
const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
46475
47034
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
46476
47035
|
lines.push("```javascript");
|
|
46477
47036
|
lines.push(content);
|
|
@@ -46480,14 +47039,14 @@ var DevServer = class _DevServer {
|
|
|
46480
47039
|
} catch {
|
|
46481
47040
|
}
|
|
46482
47041
|
}
|
|
46483
|
-
const refFiles =
|
|
47042
|
+
const refFiles = fs27.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
46484
47043
|
if (refFiles.length > 0) {
|
|
46485
47044
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
46486
47045
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
46487
47046
|
lines.push("");
|
|
46488
47047
|
for (const file of refFiles) {
|
|
46489
47048
|
try {
|
|
46490
|
-
const content =
|
|
47049
|
+
const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
46491
47050
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
46492
47051
|
lines.push("```javascript");
|
|
46493
47052
|
lines.push(content);
|
|
@@ -46520,11 +47079,11 @@ var DevServer = class _DevServer {
|
|
|
46520
47079
|
lines.push("");
|
|
46521
47080
|
}
|
|
46522
47081
|
}
|
|
46523
|
-
const docsDir =
|
|
47082
|
+
const docsDir = path39.join(providerDir, "../../docs");
|
|
46524
47083
|
const loadGuide = (name) => {
|
|
46525
47084
|
try {
|
|
46526
|
-
const p =
|
|
46527
|
-
if (
|
|
47085
|
+
const p = path39.join(docsDir, name);
|
|
47086
|
+
if (fs27.existsSync(p)) return fs27.readFileSync(p, "utf-8");
|
|
46528
47087
|
} catch {
|
|
46529
47088
|
}
|
|
46530
47089
|
return null;
|
|
@@ -47429,8 +47988,8 @@ async function installExtension(ide, extension) {
|
|
|
47429
47988
|
const res = await fetch(extension.vsixUrl);
|
|
47430
47989
|
if (res.ok) {
|
|
47431
47990
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
47432
|
-
const
|
|
47433
|
-
|
|
47991
|
+
const fs28 = await import("fs");
|
|
47992
|
+
fs28.writeFileSync(vsixPath, buffer);
|
|
47434
47993
|
return new Promise((resolve23) => {
|
|
47435
47994
|
const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
|
|
47436
47995
|
(0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
|