@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.mjs
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")) {
|
|
@@ -768,10 +768,10 @@ function getMeshConfigPath() {
|
|
|
768
768
|
return join4(getConfigDir(), "meshes.json");
|
|
769
769
|
}
|
|
770
770
|
function loadMeshConfig() {
|
|
771
|
-
const
|
|
772
|
-
if (!existsSync4(
|
|
771
|
+
const path40 = getMeshConfigPath();
|
|
772
|
+
if (!existsSync4(path40)) return { meshes: [] };
|
|
773
773
|
try {
|
|
774
|
-
const raw = JSON.parse(readFileSync2(
|
|
774
|
+
const raw = JSON.parse(readFileSync2(path40, "utf-8"));
|
|
775
775
|
if (!raw || !Array.isArray(raw.meshes)) return { meshes: [] };
|
|
776
776
|
return raw;
|
|
777
777
|
} catch {
|
|
@@ -779,16 +779,16 @@ function loadMeshConfig() {
|
|
|
779
779
|
}
|
|
780
780
|
}
|
|
781
781
|
function saveMeshConfig(config) {
|
|
782
|
-
const
|
|
783
|
-
writeFileSync2(
|
|
782
|
+
const path40 = getMeshConfigPath();
|
|
783
|
+
writeFileSync2(path40, JSON.stringify(config, null, 2), { encoding: "utf-8", mode: 384 });
|
|
784
784
|
}
|
|
785
785
|
function normalizeRepoIdentity(remoteUrl) {
|
|
786
786
|
let identity = remoteUrl.trim();
|
|
787
787
|
if (identity.startsWith("http://") || identity.startsWith("https://")) {
|
|
788
788
|
try {
|
|
789
789
|
const url = new URL(identity);
|
|
790
|
-
const
|
|
791
|
-
return `${url.hostname}/${
|
|
790
|
+
const path40 = url.pathname.replace(/^\//, "").replace(/\.git$/, "");
|
|
791
|
+
return `${url.hostname}/${path40}`;
|
|
792
792
|
} catch {
|
|
793
793
|
}
|
|
794
794
|
}
|
|
@@ -1717,8 +1717,8 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
1717
1717
|
}
|
|
1718
1718
|
const serverName = mcpConfig.serverName?.trim() || DEFAULT_SERVER_NAME;
|
|
1719
1719
|
if (mcpConfig.mode === "auto_import") {
|
|
1720
|
-
const
|
|
1721
|
-
if (!
|
|
1720
|
+
const path40 = mcpConfig.path?.trim();
|
|
1721
|
+
if (!path40) {
|
|
1722
1722
|
return { kind: "unsupported", reason: "Provider auto-import MCP config is missing a config path" };
|
|
1723
1723
|
}
|
|
1724
1724
|
const mcpServer = resolveAdhdevMcpServerLaunch({
|
|
@@ -1736,7 +1736,7 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
1736
1736
|
return {
|
|
1737
1737
|
kind: "auto_import",
|
|
1738
1738
|
serverName,
|
|
1739
|
-
configPath: resolveMcpConfigPath(
|
|
1739
|
+
configPath: resolveMcpConfigPath(path40, workspace),
|
|
1740
1740
|
configFormat: mcpConfig.format,
|
|
1741
1741
|
mcpServer
|
|
1742
1742
|
};
|
|
@@ -1893,8 +1893,8 @@ function stripCoordinatorWrapperFile(filePath) {
|
|
|
1893
1893
|
const remaining = (existing.slice(0, openIdx) + existing.slice(closeIdx + CLOSE.length)).replace(/^\s*\n+/, "").replace(/\n+\s*$/, "");
|
|
1894
1894
|
if (!remaining.trim()) {
|
|
1895
1895
|
try {
|
|
1896
|
-
const
|
|
1897
|
-
|
|
1896
|
+
const fs28 = __require("fs");
|
|
1897
|
+
fs28.unlinkSync(filePath);
|
|
1898
1898
|
} catch {
|
|
1899
1899
|
}
|
|
1900
1900
|
} else {
|
|
@@ -2032,10 +2032,10 @@ function rotateArchiveFile(meshId, archivePath) {
|
|
|
2032
2032
|
}
|
|
2033
2033
|
}
|
|
2034
2034
|
function readArchivedCounts(meshId) {
|
|
2035
|
-
const
|
|
2036
|
-
if (!existsSync10(
|
|
2035
|
+
const path40 = getArchivedCountsPath(meshId);
|
|
2036
|
+
if (!existsSync10(path40)) return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
|
|
2037
2037
|
try {
|
|
2038
|
-
return JSON.parse(readFileSync8(
|
|
2038
|
+
return JSON.parse(readFileSync8(path40, "utf-8"));
|
|
2039
2039
|
} catch {
|
|
2040
2040
|
return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
|
|
2041
2041
|
}
|
|
@@ -2685,10 +2685,10 @@ var init_beads_db = __esm({
|
|
|
2685
2685
|
this.migratedMeshIds.add(meshId);
|
|
2686
2686
|
const count = this.db.prepare("SELECT COUNT(*) AS count FROM mesh_queue WHERE mesh_id = ?").get(meshId);
|
|
2687
2687
|
if (count.count > 0) return;
|
|
2688
|
-
const
|
|
2689
|
-
if (!existsSync11(
|
|
2688
|
+
const path40 = legacyQueuePath(meshId);
|
|
2689
|
+
if (!existsSync11(path40)) return;
|
|
2690
2690
|
try {
|
|
2691
|
-
const entries = JSON.parse(readFileSync9(
|
|
2691
|
+
const entries = JSON.parse(readFileSync9(path40, "utf-8"));
|
|
2692
2692
|
if (!Array.isArray(entries)) return;
|
|
2693
2693
|
const insert = this.db.prepare(`
|
|
2694
2694
|
INSERT OR REPLACE INTO mesh_queue (
|
|
@@ -3399,10 +3399,10 @@ function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
|
|
|
3399
3399
|
if (!meshId) return [];
|
|
3400
3400
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
3401
3401
|
const events = [];
|
|
3402
|
-
for (const
|
|
3403
|
-
if (!existsSync13(
|
|
3402
|
+
for (const path40 of paths) {
|
|
3403
|
+
if (!existsSync13(path40)) continue;
|
|
3404
3404
|
try {
|
|
3405
|
-
const raw = readFileSync10(
|
|
3405
|
+
const raw = readFileSync10(path40, "utf-8");
|
|
3406
3406
|
const parsed = raw.split("\n").filter(Boolean).flatMap((line) => {
|
|
3407
3407
|
try {
|
|
3408
3408
|
return [JSON.parse(line)];
|
|
@@ -3410,7 +3410,7 @@ function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
|
|
|
3410
3410
|
return [];
|
|
3411
3411
|
}
|
|
3412
3412
|
});
|
|
3413
|
-
const filtered = coordinatorDaemonId &&
|
|
3413
|
+
const filtered = coordinatorDaemonId && path40 === getPendingEventsPath(meshId) ? parsed.filter((e) => !e.targetCoordinatorDaemonId || e.targetCoordinatorDaemonId === coordinatorDaemonId) : parsed;
|
|
3414
3414
|
events.push(...filtered);
|
|
3415
3415
|
} catch {
|
|
3416
3416
|
}
|
|
@@ -3479,13 +3479,13 @@ function reconcilePendingMeshCoordinatorEvents(meshId, events) {
|
|
|
3479
3479
|
...backfilled
|
|
3480
3480
|
];
|
|
3481
3481
|
}
|
|
3482
|
-
function trimPendingEventsIfNeeded(
|
|
3482
|
+
function trimPendingEventsIfNeeded(path40) {
|
|
3483
3483
|
try {
|
|
3484
|
-
if (!existsSync13(
|
|
3485
|
-
if (statSync5(
|
|
3486
|
-
const lines = readFileSync10(
|
|
3484
|
+
if (!existsSync13(path40)) return;
|
|
3485
|
+
if (statSync5(path40).size <= MAX_PENDING_EVENTS_BYTES) return;
|
|
3486
|
+
const lines = readFileSync10(path40, "utf-8").split("\n").filter(Boolean);
|
|
3487
3487
|
if (lines.length <= MAX_PENDING_EVENTS_KEEP) return;
|
|
3488
|
-
writeFileSync6(
|
|
3488
|
+
writeFileSync6(path40, lines.slice(-MAX_PENDING_EVENTS_KEEP).join("\n") + "\n", "utf-8");
|
|
3489
3489
|
} catch {
|
|
3490
3490
|
}
|
|
3491
3491
|
}
|
|
@@ -3499,19 +3499,19 @@ function queuePendingMeshCoordinatorEvent(event) {
|
|
|
3499
3499
|
LOG.info("MeshEvents", `Suppressed duplicate pending ${event.event} for mesh ${event.meshId}`);
|
|
3500
3500
|
return true;
|
|
3501
3501
|
}
|
|
3502
|
-
const
|
|
3503
|
-
trimPendingEventsIfNeeded(
|
|
3504
|
-
appendFileSync2(
|
|
3502
|
+
const path40 = getPendingEventsPath(event.meshId, event.targetCoordinatorDaemonId);
|
|
3503
|
+
trimPendingEventsIfNeeded(path40);
|
|
3504
|
+
appendFileSync2(path40, JSON.stringify(event) + "\n", "utf-8");
|
|
3505
3505
|
return true;
|
|
3506
3506
|
} catch (e) {
|
|
3507
3507
|
LOG.warn("MeshEvents", `Failed to persist pending coordinator event: ${e?.message || e}`);
|
|
3508
3508
|
return false;
|
|
3509
3509
|
}
|
|
3510
3510
|
}
|
|
3511
|
-
function atomicDrainFile(
|
|
3512
|
-
const tmpPath = `${
|
|
3511
|
+
function atomicDrainFile(path40) {
|
|
3512
|
+
const tmpPath = `${path40}.draining`;
|
|
3513
3513
|
try {
|
|
3514
|
-
renameSync3(
|
|
3514
|
+
renameSync3(path40, tmpPath);
|
|
3515
3515
|
} catch {
|
|
3516
3516
|
return null;
|
|
3517
3517
|
}
|
|
@@ -3534,8 +3534,8 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
3534
3534
|
if (!meshId) return [];
|
|
3535
3535
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
3536
3536
|
const all = [];
|
|
3537
|
-
for (const
|
|
3538
|
-
const content = atomicDrainFile(
|
|
3537
|
+
for (const path40 of paths) {
|
|
3538
|
+
const content = atomicDrainFile(path40);
|
|
3539
3539
|
if (!content) continue;
|
|
3540
3540
|
const parsed = content.split("\n").filter(Boolean).flatMap((line) => {
|
|
3541
3541
|
try {
|
|
@@ -3544,7 +3544,7 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
3544
3544
|
return [];
|
|
3545
3545
|
}
|
|
3546
3546
|
});
|
|
3547
|
-
const filtered = coordinatorDaemonId &&
|
|
3547
|
+
const filtered = coordinatorDaemonId && path40 === getPendingEventsPath(meshId) ? parsed.filter((e) => !e.targetCoordinatorDaemonId || e.targetCoordinatorDaemonId === coordinatorDaemonId) : parsed;
|
|
3548
3548
|
all.push(...filtered);
|
|
3549
3549
|
}
|
|
3550
3550
|
if (all.length === 0) return [];
|
|
@@ -3557,9 +3557,9 @@ function getPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
3557
3557
|
function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
3558
3558
|
if (!meshId) return;
|
|
3559
3559
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
3560
|
-
for (const
|
|
3561
|
-
if (existsSync13(
|
|
3562
|
-
unlinkSync2(
|
|
3560
|
+
for (const path40 of paths) {
|
|
3561
|
+
if (existsSync13(path40)) try {
|
|
3562
|
+
unlinkSync2(path40);
|
|
3563
3563
|
} catch {
|
|
3564
3564
|
}
|
|
3565
3565
|
}
|
|
@@ -3694,6 +3694,20 @@ function hasDispatchAfterTerminal(meshId, sessionId, terminalId) {
|
|
|
3694
3694
|
}
|
|
3695
3695
|
return false;
|
|
3696
3696
|
}
|
|
3697
|
+
function hasUnterminalDirectDispatchLedgerEntry(meshId, sessionId) {
|
|
3698
|
+
const entries = readLedgerEntries(meshId, { tail: 200 });
|
|
3699
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
3700
|
+
const entry = entries[i];
|
|
3701
|
+
if (entry.sessionId !== sessionId) continue;
|
|
3702
|
+
if (entry.kind === "task_completed" || entry.kind === "task_failed" || entry.kind === "task_stalled") {
|
|
3703
|
+
return false;
|
|
3704
|
+
}
|
|
3705
|
+
if (entry.kind === "task_dispatched" && entry.payload?.source === "direct") {
|
|
3706
|
+
return true;
|
|
3707
|
+
}
|
|
3708
|
+
}
|
|
3709
|
+
return false;
|
|
3710
|
+
}
|
|
3697
3711
|
function buildLongGeneratingCompletionReconciliation(args) {
|
|
3698
3712
|
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
3699
3713
|
const nodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
|
|
@@ -4561,7 +4575,7 @@ function setupMeshEventForwarding(components) {
|
|
|
4561
4575
|
if (coordinatorMeshId) {
|
|
4562
4576
|
try {
|
|
4563
4577
|
const activeDispatches = getActiveDirectDispatches(coordinatorMeshId);
|
|
4564
|
-
if (activeDispatches.some((d) => d.sessionId === instanceId)) {
|
|
4578
|
+
if (activeDispatches.some((d) => d.sessionId === instanceId) || hasUnterminalDirectDispatchLedgerEntry(coordinatorMeshId, instanceId)) {
|
|
4565
4579
|
meshIdFromDirectDispatch = coordinatorMeshId;
|
|
4566
4580
|
}
|
|
4567
4581
|
} catch {
|
|
@@ -4683,6 +4697,56 @@ var init_debug_config = __esm({
|
|
|
4683
4697
|
}
|
|
4684
4698
|
});
|
|
4685
4699
|
|
|
4700
|
+
// src/providers/provider-trust.ts
|
|
4701
|
+
var provider_trust_exports = {};
|
|
4702
|
+
__export(provider_trust_exports, {
|
|
4703
|
+
classifyTrust: () => classifyTrust,
|
|
4704
|
+
describeTrust: () => describeTrust,
|
|
4705
|
+
inspectManifestShape: () => inspectManifestShape,
|
|
4706
|
+
requiresConfirmation: () => requiresConfirmation
|
|
4707
|
+
});
|
|
4708
|
+
function inspectManifestShape(manifest) {
|
|
4709
|
+
const hasTui = !!manifest.tui && typeof manifest.tui === "object" && Object.keys(manifest.tui).length > 0;
|
|
4710
|
+
const hasOverrides = !!manifest.overrides && typeof manifest.overrides === "object" && !Array.isArray(manifest.overrides) && Object.keys(manifest.overrides).length > 0;
|
|
4711
|
+
const compat = Array.isArray(manifest.compatibility) ? manifest.compatibility : [];
|
|
4712
|
+
const compatHasScriptDir = compat.some((entry) => typeof entry?.scriptDir === "string");
|
|
4713
|
+
const hasScriptDir = compatHasScriptDir || typeof manifest.defaultScriptDir === "string";
|
|
4714
|
+
return { hasTui, hasOverrides, hasScriptDir };
|
|
4715
|
+
}
|
|
4716
|
+
function classifyTrust(layer, shape) {
|
|
4717
|
+
const isSpecOnly = !shape.hasTui && !shape.hasOverrides && !shape.hasScriptDir;
|
|
4718
|
+
switch (layer) {
|
|
4719
|
+
case "user":
|
|
4720
|
+
return "user-custom";
|
|
4721
|
+
case "upstream":
|
|
4722
|
+
return isSpecOnly ? "trusted" : "trusted-with-scripts";
|
|
4723
|
+
case "external":
|
|
4724
|
+
return isSpecOnly ? "external-safe" : "external-untrusted";
|
|
4725
|
+
}
|
|
4726
|
+
}
|
|
4727
|
+
function requiresConfirmation(trust) {
|
|
4728
|
+
return trust === "external-untrusted";
|
|
4729
|
+
}
|
|
4730
|
+
function describeTrust(trust) {
|
|
4731
|
+
switch (trust) {
|
|
4732
|
+
case "user-custom":
|
|
4733
|
+
return "Hand-authored in ~/.adhdev/providers/. Runs your own code.";
|
|
4734
|
+
case "trusted":
|
|
4735
|
+
return "Official, declarative-only manifest from the ADHDev registry.";
|
|
4736
|
+
case "trusted-with-scripts":
|
|
4737
|
+
return "Official manifest from the ADHDev registry. Ships JavaScript hooks executed by the daemon.";
|
|
4738
|
+
case "external-safe":
|
|
4739
|
+
return "Manifest from a 3rd-party git source you added. Declarative-only \u2014 the daemon never runs JS from this source.";
|
|
4740
|
+
case "external-untrusted":
|
|
4741
|
+
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.";
|
|
4742
|
+
}
|
|
4743
|
+
}
|
|
4744
|
+
var init_provider_trust = __esm({
|
|
4745
|
+
"src/providers/provider-trust.ts"() {
|
|
4746
|
+
"use strict";
|
|
4747
|
+
}
|
|
4748
|
+
});
|
|
4749
|
+
|
|
4686
4750
|
// src/providers/sdk/v1/schemas/cli/provider.schema.json
|
|
4687
4751
|
var provider_schema_default;
|
|
4688
4752
|
var init_provider_schema = __esm({
|
|
@@ -5188,7 +5252,7 @@ function getCliValidator() {
|
|
|
5188
5252
|
return _cliValidator;
|
|
5189
5253
|
}
|
|
5190
5254
|
function formatIssue(err) {
|
|
5191
|
-
const
|
|
5255
|
+
const path40 = err.instancePath || "";
|
|
5192
5256
|
const params = err.params;
|
|
5193
5257
|
let message = err.message || "validation failed";
|
|
5194
5258
|
let allowed;
|
|
@@ -5206,7 +5270,7 @@ function formatIssue(err) {
|
|
|
5206
5270
|
} else if (err.keyword === "type") {
|
|
5207
5271
|
message = `must be ${params.type}`;
|
|
5208
5272
|
}
|
|
5209
|
-
return { path:
|
|
5273
|
+
return { path: path40, keyword: err.keyword, message, ...allowed !== void 0 ? { allowed } : {} };
|
|
5210
5274
|
}
|
|
5211
5275
|
function validateCliProviderManifest(manifest) {
|
|
5212
5276
|
const validator = getCliValidator();
|
|
@@ -5231,6 +5295,156 @@ var init_manifest = __esm({
|
|
|
5231
5295
|
}
|
|
5232
5296
|
});
|
|
5233
5297
|
|
|
5298
|
+
// src/providers/external-sources.ts
|
|
5299
|
+
var external_sources_exports = {};
|
|
5300
|
+
__export(external_sources_exports, {
|
|
5301
|
+
activeFilePath: () => activeFilePath,
|
|
5302
|
+
deriveSourceName: () => deriveSourceName,
|
|
5303
|
+
externalRoot: () => externalRoot,
|
|
5304
|
+
inventoryExternalSources: () => inventoryExternalSources,
|
|
5305
|
+
loadExternalSources: () => loadExternalSources,
|
|
5306
|
+
loadProvidersActive: () => loadProvidersActive,
|
|
5307
|
+
resolveActiveSource: () => resolveActiveSource,
|
|
5308
|
+
saveExternalSources: () => saveExternalSources,
|
|
5309
|
+
saveProvidersActive: () => saveProvidersActive,
|
|
5310
|
+
sourcesFilePath: () => sourcesFilePath,
|
|
5311
|
+
sourcesProviding: () => sourcesProviding
|
|
5312
|
+
});
|
|
5313
|
+
import * as fs8 from "fs";
|
|
5314
|
+
import * as os10 from "os";
|
|
5315
|
+
import * as path15 from "path";
|
|
5316
|
+
function adhdevDir() {
|
|
5317
|
+
return path15.join(os10.homedir(), ".adhdev");
|
|
5318
|
+
}
|
|
5319
|
+
function externalRoot() {
|
|
5320
|
+
return path15.join(adhdevDir(), "external");
|
|
5321
|
+
}
|
|
5322
|
+
function sourcesFilePath() {
|
|
5323
|
+
return path15.join(adhdevDir(), SOURCES_FILENAME);
|
|
5324
|
+
}
|
|
5325
|
+
function activeFilePath() {
|
|
5326
|
+
return path15.join(adhdevDir(), ACTIVE_FILENAME);
|
|
5327
|
+
}
|
|
5328
|
+
function ensureAdhdevDir() {
|
|
5329
|
+
const d = adhdevDir();
|
|
5330
|
+
if (!fs8.existsSync(d)) fs8.mkdirSync(d, { recursive: true });
|
|
5331
|
+
}
|
|
5332
|
+
function loadExternalSources() {
|
|
5333
|
+
const p = sourcesFilePath();
|
|
5334
|
+
if (!fs8.existsSync(p)) return { schema: 1, sources: [] };
|
|
5335
|
+
try {
|
|
5336
|
+
const raw = JSON.parse(fs8.readFileSync(p, "utf-8"));
|
|
5337
|
+
if (!raw || typeof raw !== "object") return { schema: 1, sources: [] };
|
|
5338
|
+
const sources = Array.isArray(raw.sources) ? raw.sources.filter(isValidSource) : [];
|
|
5339
|
+
return { schema: 1, sources };
|
|
5340
|
+
} catch {
|
|
5341
|
+
return { schema: 1, sources: [] };
|
|
5342
|
+
}
|
|
5343
|
+
}
|
|
5344
|
+
function saveExternalSources(file) {
|
|
5345
|
+
ensureAdhdevDir();
|
|
5346
|
+
const tmp = sourcesFilePath() + ".tmp";
|
|
5347
|
+
fs8.writeFileSync(tmp, JSON.stringify(file, null, 2) + "\n", "utf-8");
|
|
5348
|
+
fs8.renameSync(tmp, sourcesFilePath());
|
|
5349
|
+
}
|
|
5350
|
+
function loadProvidersActive() {
|
|
5351
|
+
const p = activeFilePath();
|
|
5352
|
+
if (!fs8.existsSync(p)) return { schema: 1, active: {} };
|
|
5353
|
+
try {
|
|
5354
|
+
const raw = JSON.parse(fs8.readFileSync(p, "utf-8"));
|
|
5355
|
+
if (!raw || typeof raw !== "object") return { schema: 1, active: {} };
|
|
5356
|
+
const active = raw.active && typeof raw.active === "object" ? raw.active : {};
|
|
5357
|
+
return { schema: 1, active };
|
|
5358
|
+
} catch {
|
|
5359
|
+
return { schema: 1, active: {} };
|
|
5360
|
+
}
|
|
5361
|
+
}
|
|
5362
|
+
function saveProvidersActive(file) {
|
|
5363
|
+
ensureAdhdevDir();
|
|
5364
|
+
const tmp = activeFilePath() + ".tmp";
|
|
5365
|
+
fs8.writeFileSync(tmp, JSON.stringify(file, null, 2) + "\n", "utf-8");
|
|
5366
|
+
fs8.renameSync(tmp, activeFilePath());
|
|
5367
|
+
}
|
|
5368
|
+
function isValidSource(x) {
|
|
5369
|
+
if (!x || typeof x !== "object") return false;
|
|
5370
|
+
const s = x;
|
|
5371
|
+
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";
|
|
5372
|
+
}
|
|
5373
|
+
function deriveSourceName(url) {
|
|
5374
|
+
const m = url.match(/[/:]([^/:]+)\/([^/]+?)(?:\.git)?$/);
|
|
5375
|
+
if (!m) return "@source";
|
|
5376
|
+
const owner = m[1].toLowerCase().replace(/[^a-z0-9_-]/g, "-");
|
|
5377
|
+
const repo = m[2].toLowerCase().replace(/[^a-z0-9_-]/g, "-");
|
|
5378
|
+
return `@${owner}-${repo}`;
|
|
5379
|
+
}
|
|
5380
|
+
function inventoryExternalSources() {
|
|
5381
|
+
const root = externalRoot();
|
|
5382
|
+
if (!fs8.existsSync(root)) return [];
|
|
5383
|
+
const out = [];
|
|
5384
|
+
let entries;
|
|
5385
|
+
try {
|
|
5386
|
+
entries = fs8.readdirSync(root, { withFileTypes: true });
|
|
5387
|
+
} catch {
|
|
5388
|
+
return [];
|
|
5389
|
+
}
|
|
5390
|
+
for (const sourceEntry of entries) {
|
|
5391
|
+
if (!sourceEntry.isDirectory()) continue;
|
|
5392
|
+
const sourceName = sourceEntry.name;
|
|
5393
|
+
const sourceDir = path15.join(root, sourceName);
|
|
5394
|
+
const providers = {};
|
|
5395
|
+
let categoryEntries;
|
|
5396
|
+
try {
|
|
5397
|
+
categoryEntries = fs8.readdirSync(sourceDir, { withFileTypes: true });
|
|
5398
|
+
} catch {
|
|
5399
|
+
continue;
|
|
5400
|
+
}
|
|
5401
|
+
for (const categoryEntry of categoryEntries) {
|
|
5402
|
+
if (!categoryEntry.isDirectory()) continue;
|
|
5403
|
+
const category = categoryEntry.name;
|
|
5404
|
+
const categoryDir = path15.join(sourceDir, category);
|
|
5405
|
+
let typeEntries;
|
|
5406
|
+
try {
|
|
5407
|
+
typeEntries = fs8.readdirSync(categoryDir, { withFileTypes: true });
|
|
5408
|
+
} catch {
|
|
5409
|
+
continue;
|
|
5410
|
+
}
|
|
5411
|
+
const types = [];
|
|
5412
|
+
for (const typeEntry of typeEntries) {
|
|
5413
|
+
if (!typeEntry.isDirectory()) continue;
|
|
5414
|
+
const typeDir = path15.join(categoryDir, typeEntry.name);
|
|
5415
|
+
const hasV1 = fs8.existsSync(path15.join(typeDir, "provider.v1.json"));
|
|
5416
|
+
const hasV0 = fs8.existsSync(path15.join(typeDir, "provider.json"));
|
|
5417
|
+
if (hasV1 || hasV0) types.push(typeEntry.name);
|
|
5418
|
+
}
|
|
5419
|
+
if (types.length > 0) providers[category] = types;
|
|
5420
|
+
}
|
|
5421
|
+
out.push({ sourceName, providers });
|
|
5422
|
+
}
|
|
5423
|
+
return out;
|
|
5424
|
+
}
|
|
5425
|
+
function sourcesProviding(category, type) {
|
|
5426
|
+
const inventory = inventoryExternalSources();
|
|
5427
|
+
return inventory.filter((s) => (s.providers[category] || []).includes(type)).map((s) => s.sourceName);
|
|
5428
|
+
}
|
|
5429
|
+
function resolveActiveSource(category, type, activeFile) {
|
|
5430
|
+
const candidates = sourcesProviding(category, type);
|
|
5431
|
+
if (candidates.length === 0) return { source: null, ambiguous: false, candidates };
|
|
5432
|
+
if (candidates.length === 1) return { source: candidates[0], ambiguous: false, candidates };
|
|
5433
|
+
const explicit = (activeFile ?? loadProvidersActive()).active[type];
|
|
5434
|
+
if (explicit && candidates.includes(explicit)) {
|
|
5435
|
+
return { source: explicit, ambiguous: false, candidates };
|
|
5436
|
+
}
|
|
5437
|
+
return { source: candidates[0], ambiguous: true, candidates };
|
|
5438
|
+
}
|
|
5439
|
+
var SOURCES_FILENAME, ACTIVE_FILENAME;
|
|
5440
|
+
var init_external_sources = __esm({
|
|
5441
|
+
"src/providers/external-sources.ts"() {
|
|
5442
|
+
"use strict";
|
|
5443
|
+
SOURCES_FILENAME = "providers-sources.json";
|
|
5444
|
+
ACTIVE_FILENAME = "providers-active.json";
|
|
5445
|
+
}
|
|
5446
|
+
});
|
|
5447
|
+
|
|
5234
5448
|
// src/cli-adapters/terminal-backends/ghostty-vt-backend.ts
|
|
5235
5449
|
function isModuleNotFoundError(error, ref) {
|
|
5236
5450
|
if (!(error instanceof Error)) return false;
|
|
@@ -5519,7 +5733,7 @@ var init_spawn_env = __esm({
|
|
|
5519
5733
|
});
|
|
5520
5734
|
|
|
5521
5735
|
// src/cli-adapters/pty-transport.ts
|
|
5522
|
-
import * as
|
|
5736
|
+
import * as os11 from "os";
|
|
5523
5737
|
function loadNodePty() {
|
|
5524
5738
|
if (cachedPty !== void 0) return cachedPty;
|
|
5525
5739
|
try {
|
|
@@ -5570,11 +5784,11 @@ var init_pty_transport = __esm({
|
|
|
5570
5784
|
let cwd = options.cwd;
|
|
5571
5785
|
if (cwd) {
|
|
5572
5786
|
try {
|
|
5573
|
-
const
|
|
5574
|
-
const stat2 =
|
|
5575
|
-
if (!stat2.isDirectory()) cwd =
|
|
5787
|
+
const fs28 = __require("fs");
|
|
5788
|
+
const stat2 = fs28.statSync(cwd);
|
|
5789
|
+
if (!stat2.isDirectory()) cwd = os11.homedir();
|
|
5576
5790
|
} catch {
|
|
5577
|
-
cwd =
|
|
5791
|
+
cwd = os11.homedir();
|
|
5578
5792
|
}
|
|
5579
5793
|
}
|
|
5580
5794
|
const handle = pty.spawn(command, args, {
|
|
@@ -5591,8 +5805,8 @@ var init_pty_transport = __esm({
|
|
|
5591
5805
|
});
|
|
5592
5806
|
|
|
5593
5807
|
// src/cli-adapters/provider-cli-shared.ts
|
|
5594
|
-
import * as
|
|
5595
|
-
import * as
|
|
5808
|
+
import * as os12 from "os";
|
|
5809
|
+
import * as path16 from "path";
|
|
5596
5810
|
function stripAnsi(str) {
|
|
5597
5811
|
return str.replace(/\x1B\][^\x07]*(?:\x07|\x1B\\)/g, "").replace(/\x1B[P^_X][\s\S]*?(?:\x07|\x1B\\)/g, "").replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "");
|
|
5598
5812
|
}
|
|
@@ -5668,21 +5882,21 @@ function buildCliScreenSnapshot(text) {
|
|
|
5668
5882
|
function findBinary(name) {
|
|
5669
5883
|
const trimmed = String(name || "").trim();
|
|
5670
5884
|
if (!trimmed) return trimmed;
|
|
5671
|
-
const expanded = trimmed.startsWith("~") ?
|
|
5672
|
-
if (
|
|
5673
|
-
return
|
|
5885
|
+
const expanded = trimmed.startsWith("~") ? path16.join(os12.homedir(), trimmed.slice(1)) : trimmed;
|
|
5886
|
+
if (path16.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
|
|
5887
|
+
return path16.isAbsolute(expanded) ? expanded : path16.resolve(expanded);
|
|
5674
5888
|
}
|
|
5675
|
-
const isWin =
|
|
5676
|
-
const paths = (process.env.PATH || "").split(
|
|
5889
|
+
const isWin = os12.platform() === "win32";
|
|
5890
|
+
const paths = (process.env.PATH || "").split(path16.delimiter);
|
|
5677
5891
|
const exes = isWin ? [".exe", ".cmd", ".bat", ""] : [""];
|
|
5678
5892
|
for (const p of paths) {
|
|
5679
5893
|
if (!p) continue;
|
|
5680
5894
|
for (const ext of exes) {
|
|
5681
|
-
const fullPath =
|
|
5895
|
+
const fullPath = path16.join(p, trimmed + ext);
|
|
5682
5896
|
try {
|
|
5683
|
-
const
|
|
5684
|
-
if (
|
|
5685
|
-
const stat2 =
|
|
5897
|
+
const fs28 = __require("fs");
|
|
5898
|
+
if (fs28.existsSync(fullPath)) {
|
|
5899
|
+
const stat2 = fs28.statSync(fullPath);
|
|
5686
5900
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
5687
5901
|
return fullPath;
|
|
5688
5902
|
}
|
|
@@ -5694,14 +5908,14 @@ function findBinary(name) {
|
|
|
5694
5908
|
return isWin ? `${trimmed}.cmd` : trimmed;
|
|
5695
5909
|
}
|
|
5696
5910
|
function isScriptBinary(binaryPath) {
|
|
5697
|
-
if (!
|
|
5911
|
+
if (!path16.isAbsolute(binaryPath)) return false;
|
|
5698
5912
|
try {
|
|
5699
|
-
const
|
|
5700
|
-
const resolved =
|
|
5913
|
+
const fs28 = __require("fs");
|
|
5914
|
+
const resolved = fs28.realpathSync(binaryPath);
|
|
5701
5915
|
const head = Buffer.alloc(8);
|
|
5702
|
-
const fd =
|
|
5703
|
-
|
|
5704
|
-
|
|
5916
|
+
const fd = fs28.openSync(resolved, "r");
|
|
5917
|
+
fs28.readSync(fd, head, 0, 8, 0);
|
|
5918
|
+
fs28.closeSync(fd);
|
|
5705
5919
|
let i = 0;
|
|
5706
5920
|
if (head[0] === 239 && head[1] === 187 && head[2] === 191) i = 3;
|
|
5707
5921
|
return head[i] === 35 && head[i + 1] === 33;
|
|
@@ -5710,14 +5924,14 @@ function isScriptBinary(binaryPath) {
|
|
|
5710
5924
|
}
|
|
5711
5925
|
}
|
|
5712
5926
|
function looksLikeMachOOrElf(filePath) {
|
|
5713
|
-
if (!
|
|
5927
|
+
if (!path16.isAbsolute(filePath)) return false;
|
|
5714
5928
|
try {
|
|
5715
|
-
const
|
|
5716
|
-
const resolved =
|
|
5929
|
+
const fs28 = __require("fs");
|
|
5930
|
+
const resolved = fs28.realpathSync(filePath);
|
|
5717
5931
|
const buf = Buffer.alloc(8);
|
|
5718
|
-
const fd =
|
|
5719
|
-
|
|
5720
|
-
|
|
5932
|
+
const fd = fs28.openSync(resolved, "r");
|
|
5933
|
+
fs28.readSync(fd, buf, 0, 8, 0);
|
|
5934
|
+
fs28.closeSync(fd);
|
|
5721
5935
|
let i = 0;
|
|
5722
5936
|
if (buf[0] === 239 && buf[1] === 187 && buf[2] === 191) i = 3;
|
|
5723
5937
|
const b = buf.subarray(i);
|
|
@@ -5733,7 +5947,7 @@ function looksLikeMachOOrElf(filePath) {
|
|
|
5733
5947
|
}
|
|
5734
5948
|
function shSingleQuote(arg) {
|
|
5735
5949
|
if (/^[a-zA-Z0-9@%_+=:,./-]+$/.test(arg)) return arg;
|
|
5736
|
-
if (
|
|
5950
|
+
if (os12.platform() === "win32") {
|
|
5737
5951
|
return `"${arg.replace(/"/g, '""')}"`;
|
|
5738
5952
|
}
|
|
5739
5953
|
return `'${arg.replace(/'/g, `'\\''`)}'`;
|
|
@@ -6198,12 +6412,14 @@ function scopeLines(spec, lines, questionIndex) {
|
|
|
6198
6412
|
function extractButtons(spec, lines, windowStart, windowEnd) {
|
|
6199
6413
|
const buttonRe = compile3(spec.buttonPattern, spec.buttonFlags ?? "m");
|
|
6200
6414
|
const out = [];
|
|
6415
|
+
const labelGroup = Number.isInteger(spec.buttonLabelGroup) && (spec.buttonLabelGroup ?? 0) > 0 ? spec.buttonLabelGroup : 1;
|
|
6201
6416
|
let i = windowStart;
|
|
6202
6417
|
while (i < windowEnd) {
|
|
6203
6418
|
const line = lines[i];
|
|
6204
6419
|
const m = buttonRe.exec(line);
|
|
6205
|
-
|
|
6206
|
-
|
|
6420
|
+
const captured = m?.[labelGroup] ?? (labelGroup === 1 && m && m.length > 2 ? m[m.length - 1] : void 0);
|
|
6421
|
+
if (m && captured) {
|
|
6422
|
+
let label = captured.trim();
|
|
6207
6423
|
if (spec.continuationLines) {
|
|
6208
6424
|
let j = i + 1;
|
|
6209
6425
|
while (j < windowEnd) {
|
|
@@ -7686,23 +7902,23 @@ var init_provider_cli_config = __esm({
|
|
|
7686
7902
|
});
|
|
7687
7903
|
|
|
7688
7904
|
// src/cli-adapters/provider-cli-runtime.ts
|
|
7689
|
-
import * as
|
|
7690
|
-
import * as
|
|
7905
|
+
import * as os13 from "os";
|
|
7906
|
+
import * as path17 from "path";
|
|
7691
7907
|
import { DEFAULT_SESSION_HOST_COLS, DEFAULT_SESSION_HOST_ROWS } from "@adhdev/session-host-core";
|
|
7692
7908
|
function resolveCliSpawnPlan(options) {
|
|
7693
7909
|
const { provider, runtimeSettings, workingDir, extraArgs, extraEnv } = options;
|
|
7694
7910
|
const { spawn: spawnConfig } = provider;
|
|
7695
7911
|
const configuredCommand = typeof runtimeSettings.executablePath === "string" && runtimeSettings.executablePath.trim() ? runtimeSettings.executablePath.trim() : spawnConfig.command;
|
|
7696
7912
|
const binaryPath = findBinary(configuredCommand);
|
|
7697
|
-
const isWin =
|
|
7913
|
+
const isWin = os13.platform() === "win32";
|
|
7698
7914
|
const allArgs = [...spawnConfig.args, ...extraArgs].map(
|
|
7699
7915
|
(arg) => typeof arg === "string" ? arg.replace(/\{\{workingDir\}\}/g, workingDir) : arg
|
|
7700
7916
|
);
|
|
7701
7917
|
let shellCmd;
|
|
7702
7918
|
let shellArgs;
|
|
7703
|
-
const useShellUnix = !isWin && (!!spawnConfig.shell || !
|
|
7919
|
+
const useShellUnix = !isWin && (!!spawnConfig.shell || !path17.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
|
|
7704
7920
|
const isCmdShim = isWin && /\.(cmd|bat)$/i.test(binaryPath);
|
|
7705
|
-
const useShellWin = !!spawnConfig.shell || isCmdShim || !
|
|
7921
|
+
const useShellWin = !!spawnConfig.shell || isCmdShim || !path17.isAbsolute(binaryPath) || isScriptBinary(binaryPath);
|
|
7706
7922
|
const useShell = isWin ? useShellWin : useShellUnix;
|
|
7707
7923
|
if (useShell) {
|
|
7708
7924
|
shellCmd = isWin ? "cmd.exe" : process.env.SHELL || "/bin/zsh";
|
|
@@ -7792,7 +8008,7 @@ __export(provider_cli_adapter_exports, {
|
|
|
7792
8008
|
appendBoundedText: () => appendBoundedText,
|
|
7793
8009
|
normalizeCliProviderForRuntime: () => normalizeCliProviderForRuntime
|
|
7794
8010
|
});
|
|
7795
|
-
import * as
|
|
8011
|
+
import * as os14 from "os";
|
|
7796
8012
|
function appendBoundedText(current, chunk, maxChars) {
|
|
7797
8013
|
if (!chunk) return current.length <= maxChars ? current : current.slice(-maxChars);
|
|
7798
8014
|
if (maxChars <= 0) return "";
|
|
@@ -7825,7 +8041,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
7825
8041
|
this.transportFactory = transportFactory;
|
|
7826
8042
|
this.cliType = provider.type;
|
|
7827
8043
|
this.cliName = provider.name;
|
|
7828
|
-
this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/,
|
|
8044
|
+
this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/, os14.homedir()) : workingDir;
|
|
7829
8045
|
const resolvedConfig = resolveCliAdapterConfig(provider);
|
|
7830
8046
|
this.timeouts = resolvedConfig.timeouts;
|
|
7831
8047
|
this.approvalKeys = resolvedConfig.approvalKeys;
|
|
@@ -9969,13 +10185,13 @@ __export(loader_exports, {
|
|
|
9969
10185
|
loadSpec: () => loadSpec,
|
|
9970
10186
|
resolveSpecPath: () => resolveSpecPath
|
|
9971
10187
|
});
|
|
9972
|
-
import * as
|
|
9973
|
-
import * as
|
|
10188
|
+
import * as fs9 from "fs";
|
|
10189
|
+
import * as path18 from "path";
|
|
9974
10190
|
import Ajv from "ajv";
|
|
9975
10191
|
function loadSpec(sourcePath) {
|
|
9976
10192
|
let raw;
|
|
9977
10193
|
try {
|
|
9978
|
-
const text =
|
|
10194
|
+
const text = fs9.readFileSync(sourcePath, "utf8");
|
|
9979
10195
|
raw = JSON.parse(text);
|
|
9980
10196
|
} catch (err) {
|
|
9981
10197
|
return { ok: false, errors: [`Failed to read spec: ${err.message}`], sourcePath };
|
|
@@ -10051,7 +10267,7 @@ function compileRegex2(source, flags, where, errs) {
|
|
|
10051
10267
|
}
|
|
10052
10268
|
}
|
|
10053
10269
|
function resolveSpecPath(providerDir) {
|
|
10054
|
-
return
|
|
10270
|
+
return path18.join(providerDir, "spec.json");
|
|
10055
10271
|
}
|
|
10056
10272
|
var ajv, validate;
|
|
10057
10273
|
var init_loader = __esm({
|
|
@@ -10074,7 +10290,7 @@ __export(require_whitelist_exports, {
|
|
|
10074
10290
|
registerProviderScriptRoot: () => registerProviderScriptRoot,
|
|
10075
10291
|
unregisterProviderScriptRoot: () => unregisterProviderScriptRoot
|
|
10076
10292
|
});
|
|
10077
|
-
import * as
|
|
10293
|
+
import * as path24 from "path";
|
|
10078
10294
|
import { createRequire as createRequire3 } from "module";
|
|
10079
10295
|
import * as nodeFs from "fs";
|
|
10080
10296
|
import * as nodeChildProcess from "child_process";
|
|
@@ -10215,7 +10431,7 @@ function _getRegisteredRoots() {
|
|
|
10215
10431
|
}
|
|
10216
10432
|
function canonicalize(p) {
|
|
10217
10433
|
try {
|
|
10218
|
-
const resolved =
|
|
10434
|
+
const resolved = path24.resolve(p);
|
|
10219
10435
|
try {
|
|
10220
10436
|
return nodeFs.realpathSync.native ? nodeFs.realpathSync.native(resolved) : nodeFs.realpathSync(resolved);
|
|
10221
10437
|
} catch {
|
|
@@ -10235,7 +10451,7 @@ function isCallerInsideGatedRoot(callerFilename) {
|
|
|
10235
10451
|
}
|
|
10236
10452
|
for (const root of _gatedRoots) {
|
|
10237
10453
|
if (normalized === root.rootPath) return root;
|
|
10238
|
-
if (normalized.startsWith(root.rootPath +
|
|
10454
|
+
if (normalized.startsWith(root.rootPath + path24.sep)) return root;
|
|
10239
10455
|
}
|
|
10240
10456
|
return null;
|
|
10241
10457
|
}
|
|
@@ -10254,16 +10470,16 @@ function ensureInstalled() {
|
|
|
10254
10470
|
};
|
|
10255
10471
|
}
|
|
10256
10472
|
function gatedRequire(request, parent, isMain, gated, originalLoad) {
|
|
10257
|
-
if (request.startsWith("./") || request.startsWith("../") ||
|
|
10473
|
+
if (request.startsWith("./") || request.startsWith("../") || path24.isAbsolute(request)) {
|
|
10258
10474
|
let resolved;
|
|
10259
10475
|
try {
|
|
10260
|
-
const callerRequire = parent?.filename ? createRequire3(parent.filename) : createRequire3(
|
|
10476
|
+
const callerRequire = parent?.filename ? createRequire3(parent.filename) : createRequire3(path24.join(gated.rootPath, "__entry__.js"));
|
|
10261
10477
|
resolved = callerRequire.resolve(request);
|
|
10262
10478
|
} catch {
|
|
10263
10479
|
return originalLoad.call(this, request, parent, isMain);
|
|
10264
10480
|
}
|
|
10265
10481
|
const resolvedCanon = canonicalize(resolved) || resolved;
|
|
10266
|
-
if (!(resolvedCanon === gated.rootPath || resolvedCanon.startsWith(gated.rootPath +
|
|
10482
|
+
if (!(resolvedCanon === gated.rootPath || resolvedCanon.startsWith(gated.rootPath + path24.sep))) {
|
|
10267
10483
|
denyRequire(request, parent, `relative path escapes provider root (resolved to ${resolvedCanon})`);
|
|
10268
10484
|
}
|
|
10269
10485
|
return originalLoad.call(this, request, parent, isMain);
|
|
@@ -10379,9 +10595,9 @@ var native_history_executor_exports = {};
|
|
|
10379
10595
|
__export(native_history_executor_exports, {
|
|
10380
10596
|
executeNativeHistory: () => executeNativeHistory
|
|
10381
10597
|
});
|
|
10382
|
-
import * as
|
|
10383
|
-
import * as
|
|
10384
|
-
import * as
|
|
10598
|
+
import * as fs13 from "fs";
|
|
10599
|
+
import * as os18 from "os";
|
|
10600
|
+
import * as path25 from "path";
|
|
10385
10601
|
function executeNativeHistory(cfg, input) {
|
|
10386
10602
|
if (!cfg?.source) return null;
|
|
10387
10603
|
if (cfg.source.kind === "jsonl") return executeJsonl(cfg.source, input);
|
|
@@ -10400,7 +10616,7 @@ function executeJsonl(src, input) {
|
|
|
10400
10616
|
} else {
|
|
10401
10617
|
let stat2 = null;
|
|
10402
10618
|
try {
|
|
10403
|
-
stat2 =
|
|
10619
|
+
stat2 = fs13.statSync(resolved);
|
|
10404
10620
|
} catch {
|
|
10405
10621
|
return null;
|
|
10406
10622
|
}
|
|
@@ -10419,7 +10635,7 @@ function executeJsonl(src, input) {
|
|
|
10419
10635
|
const v = jsonPathGet(lines[0], src.session_id_path);
|
|
10420
10636
|
if (typeof v === "string" && v) providerSessionId = v;
|
|
10421
10637
|
} else if (src.session_id_from === "filename_uuid" || !src.session_id_from) {
|
|
10422
|
-
const m =
|
|
10638
|
+
const m = path25.basename(sourcePath).match(UUID_RE);
|
|
10423
10639
|
if (m) providerSessionId = m[1];
|
|
10424
10640
|
}
|
|
10425
10641
|
const requested = input.providerSessionId || "";
|
|
@@ -10444,7 +10660,7 @@ function executeJsonl(src, input) {
|
|
|
10444
10660
|
function readJsonlLines(p) {
|
|
10445
10661
|
let text;
|
|
10446
10662
|
try {
|
|
10447
|
-
text =
|
|
10663
|
+
text = fs13.readFileSync(p, "utf8");
|
|
10448
10664
|
} catch {
|
|
10449
10665
|
return [];
|
|
10450
10666
|
}
|
|
@@ -10461,7 +10677,7 @@ function readJsonlLines(p) {
|
|
|
10461
10677
|
}
|
|
10462
10678
|
function executeSqlite(src, input) {
|
|
10463
10679
|
const resolved = expandPath2(src.path, input);
|
|
10464
|
-
if (!resolved || !
|
|
10680
|
+
if (!resolved || !fs13.existsSync(resolved)) return null;
|
|
10465
10681
|
let Database;
|
|
10466
10682
|
try {
|
|
10467
10683
|
Database = __require("better-sqlite3");
|
|
@@ -10520,19 +10736,19 @@ function expandPath2(template, input) {
|
|
|
10520
10736
|
if (!template) return null;
|
|
10521
10737
|
let out = template;
|
|
10522
10738
|
if (out.startsWith("~/") || out === "~") {
|
|
10523
|
-
out =
|
|
10739
|
+
out = path25.join(os18.homedir(), out.slice(2));
|
|
10524
10740
|
}
|
|
10525
10741
|
out = out.replace(/\$\{([A-Z_][A-Z0-9_]*)(?::-(.*?))?\}/g, (_m, name, fallback) => {
|
|
10526
10742
|
const v = input.envOverrides?.[name] ?? process.env[name];
|
|
10527
10743
|
return v != null && v !== "" ? v : fallback ?? "";
|
|
10528
10744
|
});
|
|
10529
|
-
if (out.startsWith("~/")) out =
|
|
10745
|
+
if (out.startsWith("~/")) out = path25.join(os18.homedir(), out.slice(2));
|
|
10530
10746
|
const now = /* @__PURE__ */ new Date();
|
|
10531
10747
|
const workspaceRaw = input.workspace ?? "";
|
|
10532
10748
|
let workspaceResolved = workspaceRaw;
|
|
10533
10749
|
if (workspaceRaw) {
|
|
10534
10750
|
try {
|
|
10535
|
-
workspaceResolved =
|
|
10751
|
+
workspaceResolved = fs13.realpathSync(workspaceRaw);
|
|
10536
10752
|
} catch {
|
|
10537
10753
|
}
|
|
10538
10754
|
}
|
|
@@ -10574,20 +10790,20 @@ function expandDirGlob(template) {
|
|
|
10574
10790
|
for (const d of dirs) {
|
|
10575
10791
|
let entries;
|
|
10576
10792
|
try {
|
|
10577
|
-
entries =
|
|
10793
|
+
entries = fs13.readdirSync(d, { withFileTypes: true });
|
|
10578
10794
|
} catch {
|
|
10579
10795
|
continue;
|
|
10580
10796
|
}
|
|
10581
10797
|
for (const e of entries) {
|
|
10582
|
-
if (e.isDirectory() && re.test(e.name)) next.push(
|
|
10798
|
+
if (e.isDirectory() && re.test(e.name)) next.push(path25.join(d, e.name));
|
|
10583
10799
|
}
|
|
10584
10800
|
}
|
|
10585
10801
|
} else {
|
|
10586
10802
|
for (const d of dirs) {
|
|
10587
|
-
const candidate =
|
|
10803
|
+
const candidate = path25.join(d, seg);
|
|
10588
10804
|
let stat2 = null;
|
|
10589
10805
|
try {
|
|
10590
|
-
stat2 =
|
|
10806
|
+
stat2 = fs13.statSync(candidate);
|
|
10591
10807
|
} catch {
|
|
10592
10808
|
continue;
|
|
10593
10809
|
}
|
|
@@ -10601,13 +10817,13 @@ function expandDirGlob(template) {
|
|
|
10601
10817
|
function walkAllDirs(root, out) {
|
|
10602
10818
|
let entries;
|
|
10603
10819
|
try {
|
|
10604
|
-
entries =
|
|
10820
|
+
entries = fs13.readdirSync(root, { withFileTypes: true });
|
|
10605
10821
|
} catch {
|
|
10606
10822
|
return;
|
|
10607
10823
|
}
|
|
10608
10824
|
out.push(root);
|
|
10609
10825
|
for (const e of entries) {
|
|
10610
|
-
if (e.isDirectory()) walkAllDirs(
|
|
10826
|
+
if (e.isDirectory()) walkAllDirs(path25.join(root, e.name), out);
|
|
10611
10827
|
}
|
|
10612
10828
|
}
|
|
10613
10829
|
function newestRecentFileAcrossGlob(template, pattern, windowMs, sessionFloorMs = 0) {
|
|
@@ -10617,13 +10833,13 @@ function newestRecentFileAcrossGlob(template, pattern, windowMs, sessionFloorMs
|
|
|
10617
10833
|
for (const d of dirs) {
|
|
10618
10834
|
let entries;
|
|
10619
10835
|
try {
|
|
10620
|
-
entries =
|
|
10836
|
+
entries = fs13.readdirSync(d, { withFileTypes: true });
|
|
10621
10837
|
} catch {
|
|
10622
10838
|
continue;
|
|
10623
10839
|
}
|
|
10624
10840
|
for (const e of entries) {
|
|
10625
10841
|
if (!e.isFile() || !pattern.test(e.name)) continue;
|
|
10626
|
-
const p =
|
|
10842
|
+
const p = path25.join(d, e.name);
|
|
10627
10843
|
const mtime = safeMtimeMs(p);
|
|
10628
10844
|
if (mtime < cutoff) continue;
|
|
10629
10845
|
if (!best || mtime > best.mtime) best = { p, mtime };
|
|
@@ -10634,7 +10850,7 @@ function newestRecentFileAcrossGlob(template, pattern, windowMs, sessionFloorMs
|
|
|
10634
10850
|
function newestRecentFile(dir, pattern, windowMs, sessionFloorMs = 0) {
|
|
10635
10851
|
let entries;
|
|
10636
10852
|
try {
|
|
10637
|
-
entries =
|
|
10853
|
+
entries = fs13.readdirSync(dir, { withFileTypes: true });
|
|
10638
10854
|
} catch {
|
|
10639
10855
|
return null;
|
|
10640
10856
|
}
|
|
@@ -10642,7 +10858,7 @@ function newestRecentFile(dir, pattern, windowMs, sessionFloorMs = 0) {
|
|
|
10642
10858
|
let best = null;
|
|
10643
10859
|
for (const e of entries) {
|
|
10644
10860
|
if (!e.isFile() || !pattern.test(e.name)) continue;
|
|
10645
|
-
const p =
|
|
10861
|
+
const p = path25.join(dir, e.name);
|
|
10646
10862
|
const mtime = safeMtimeMs(p);
|
|
10647
10863
|
if (mtime < cutoff) continue;
|
|
10648
10864
|
if (!best || mtime > best.mtime) best = { p, mtime };
|
|
@@ -10651,7 +10867,7 @@ function newestRecentFile(dir, pattern, windowMs, sessionFloorMs = 0) {
|
|
|
10651
10867
|
}
|
|
10652
10868
|
function safeMtimeMs(p) {
|
|
10653
10869
|
try {
|
|
10654
|
-
return Math.floor(
|
|
10870
|
+
return Math.floor(fs13.statSync(p).mtimeMs);
|
|
10655
10871
|
} catch {
|
|
10656
10872
|
return 0;
|
|
10657
10873
|
}
|
|
@@ -10864,8 +11080,8 @@ var init_native_history_executor = __esm({
|
|
|
10864
11080
|
});
|
|
10865
11081
|
|
|
10866
11082
|
// src/providers/native-history/claude-cli-transcript.ts
|
|
10867
|
-
import * as
|
|
10868
|
-
import * as
|
|
11083
|
+
import * as fs14 from "fs";
|
|
11084
|
+
import * as path26 from "path";
|
|
10869
11085
|
function extractTimestampValue(value) {
|
|
10870
11086
|
if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
|
|
10871
11087
|
if (typeof value === "string") {
|
|
@@ -10878,7 +11094,7 @@ function extractTimestampValue(value) {
|
|
|
10878
11094
|
}
|
|
10879
11095
|
function statMtimeMs(filePath) {
|
|
10880
11096
|
try {
|
|
10881
|
-
return
|
|
11097
|
+
return fs14.statSync(filePath).mtimeMs;
|
|
10882
11098
|
} catch {
|
|
10883
11099
|
return 0;
|
|
10884
11100
|
}
|
|
@@ -10948,7 +11164,7 @@ function extractUserContentParts(content) {
|
|
|
10948
11164
|
function parseTranscriptFile(filePath, sessionId, workspaceFallback) {
|
|
10949
11165
|
let raw;
|
|
10950
11166
|
try {
|
|
10951
|
-
raw =
|
|
11167
|
+
raw = fs14.readFileSync(filePath, "utf-8");
|
|
10952
11168
|
} catch {
|
|
10953
11169
|
return [];
|
|
10954
11170
|
}
|
|
@@ -11021,10 +11237,10 @@ function parseTranscriptFile(filePath, sessionId, workspaceFallback) {
|
|
|
11021
11237
|
return records;
|
|
11022
11238
|
}
|
|
11023
11239
|
function readSession(sessionPath) {
|
|
11024
|
-
if (!sessionPath || !
|
|
11025
|
-
const basename12 =
|
|
11240
|
+
if (!sessionPath || !path26.isAbsolute(sessionPath)) return null;
|
|
11241
|
+
const basename12 = path26.basename(sessionPath, ".jsonl");
|
|
11026
11242
|
if (!isSafeSessionId(basename12)) return null;
|
|
11027
|
-
if (!
|
|
11243
|
+
if (!fs14.existsSync(sessionPath)) return null;
|
|
11028
11244
|
const sourceMtimeMs = statMtimeMs(sessionPath);
|
|
11029
11245
|
const messages = parseTranscriptFile(sessionPath, basename12);
|
|
11030
11246
|
if (messages.length === 0) return null;
|
|
@@ -11047,8 +11263,8 @@ var init_claude_cli_transcript = __esm({
|
|
|
11047
11263
|
});
|
|
11048
11264
|
|
|
11049
11265
|
// src/providers/native-history/codex-cli-transcript.ts
|
|
11050
|
-
import * as
|
|
11051
|
-
import * as
|
|
11266
|
+
import * as fs15 from "fs";
|
|
11267
|
+
import * as path27 from "path";
|
|
11052
11268
|
function extractTimestampValue2(value) {
|
|
11053
11269
|
if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
|
|
11054
11270
|
if (typeof value === "string") {
|
|
@@ -11061,7 +11277,7 @@ function extractTimestampValue2(value) {
|
|
|
11061
11277
|
}
|
|
11062
11278
|
function statMtimeMs2(filePath) {
|
|
11063
11279
|
try {
|
|
11064
|
-
return
|
|
11280
|
+
return fs15.statSync(filePath).mtimeMs;
|
|
11065
11281
|
} catch {
|
|
11066
11282
|
return 0;
|
|
11067
11283
|
}
|
|
@@ -11129,7 +11345,7 @@ function extractToolOutputContent(payload) {
|
|
|
11129
11345
|
}
|
|
11130
11346
|
function readSessionMeta(filePath) {
|
|
11131
11347
|
try {
|
|
11132
|
-
const firstLine =
|
|
11348
|
+
const firstLine = fs15.readFileSync(filePath, "utf-8").split("\n").find(Boolean);
|
|
11133
11349
|
if (!firstLine) return null;
|
|
11134
11350
|
const parsed = JSON.parse(firstLine);
|
|
11135
11351
|
if (String(parsed.type ?? "") !== "session_meta") return null;
|
|
@@ -11141,7 +11357,7 @@ function readSessionMeta(filePath) {
|
|
|
11141
11357
|
function parseSessionFile(filePath, sessionId, workspaceFallback) {
|
|
11142
11358
|
let raw;
|
|
11143
11359
|
try {
|
|
11144
|
-
raw =
|
|
11360
|
+
raw = fs15.readFileSync(filePath, "utf-8");
|
|
11145
11361
|
} catch {
|
|
11146
11362
|
return [];
|
|
11147
11363
|
}
|
|
@@ -11235,11 +11451,11 @@ function parseSessionFile(filePath, sessionId, workspaceFallback) {
|
|
|
11235
11451
|
return records;
|
|
11236
11452
|
}
|
|
11237
11453
|
function readSession2(sessionPath) {
|
|
11238
|
-
if (!sessionPath || !
|
|
11239
|
-
if (!
|
|
11454
|
+
if (!sessionPath || !path27.isAbsolute(sessionPath)) return null;
|
|
11455
|
+
if (!fs15.existsSync(sessionPath)) return null;
|
|
11240
11456
|
const meta = readSessionMeta(sessionPath);
|
|
11241
11457
|
const metaId = String(meta?.id ?? "").trim();
|
|
11242
|
-
const basename12 =
|
|
11458
|
+
const basename12 = path27.basename(sessionPath, ".jsonl");
|
|
11243
11459
|
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);
|
|
11244
11460
|
const filenameUuid = uuidMatch ? uuidMatch[1] : "";
|
|
11245
11461
|
if (metaId && filenameUuid && metaId !== filenameUuid) return null;
|
|
@@ -11268,9 +11484,9 @@ var init_codex_cli_transcript = __esm({
|
|
|
11268
11484
|
});
|
|
11269
11485
|
|
|
11270
11486
|
// src/providers/native-history/antigravity-cli-transcript.ts
|
|
11271
|
-
import * as
|
|
11272
|
-
import * as
|
|
11273
|
-
import * as
|
|
11487
|
+
import * as fs16 from "fs";
|
|
11488
|
+
import * as path28 from "path";
|
|
11489
|
+
import * as os19 from "os";
|
|
11274
11490
|
function extractTimestampValue3(value) {
|
|
11275
11491
|
if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
|
|
11276
11492
|
if (typeof value === "string") {
|
|
@@ -11283,7 +11499,7 @@ function extractTimestampValue3(value) {
|
|
|
11283
11499
|
}
|
|
11284
11500
|
function statMtimeMs3(filePath) {
|
|
11285
11501
|
try {
|
|
11286
|
-
return
|
|
11502
|
+
return fs16.statSync(filePath).mtimeMs;
|
|
11287
11503
|
} catch {
|
|
11288
11504
|
return 0;
|
|
11289
11505
|
}
|
|
@@ -11292,13 +11508,13 @@ function isUuidLike(value) {
|
|
|
11292
11508
|
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
|
|
11293
11509
|
}
|
|
11294
11510
|
function antigravityRoot() {
|
|
11295
|
-
return
|
|
11511
|
+
return path28.join(os19.homedir(), ".gemini", "antigravity-cli");
|
|
11296
11512
|
}
|
|
11297
11513
|
function historyJsonlPath() {
|
|
11298
|
-
return
|
|
11514
|
+
return path28.join(antigravityRoot(), "history.jsonl");
|
|
11299
11515
|
}
|
|
11300
11516
|
function brainRoot() {
|
|
11301
|
-
return
|
|
11517
|
+
return path28.join(antigravityRoot(), "brain");
|
|
11302
11518
|
}
|
|
11303
11519
|
function extractUserRequestContent(content) {
|
|
11304
11520
|
const raw = content.trim();
|
|
@@ -11314,7 +11530,7 @@ function antigravityRowKind(rowType) {
|
|
|
11314
11530
|
function parseBrainTranscript(filePath, sessionId, workspace) {
|
|
11315
11531
|
let raw;
|
|
11316
11532
|
try {
|
|
11317
|
-
raw =
|
|
11533
|
+
raw = fs16.readFileSync(filePath, "utf-8");
|
|
11318
11534
|
} catch {
|
|
11319
11535
|
return null;
|
|
11320
11536
|
}
|
|
@@ -11374,7 +11590,7 @@ function readHistoryRows() {
|
|
|
11374
11590
|
const sourcePath = historyJsonlPath();
|
|
11375
11591
|
let lines = [];
|
|
11376
11592
|
try {
|
|
11377
|
-
lines =
|
|
11593
|
+
lines = fs16.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
|
|
11378
11594
|
} catch {
|
|
11379
11595
|
return [];
|
|
11380
11596
|
}
|
|
@@ -11421,7 +11637,7 @@ function extractStringsFromBuffer(buf) {
|
|
|
11421
11637
|
function parsePbFile(filePath, sessionId) {
|
|
11422
11638
|
let buf;
|
|
11423
11639
|
try {
|
|
11424
|
-
buf =
|
|
11640
|
+
buf = fs16.readFileSync(filePath);
|
|
11425
11641
|
} catch {
|
|
11426
11642
|
return null;
|
|
11427
11643
|
}
|
|
@@ -11444,13 +11660,13 @@ function parsePbFile(filePath, sessionId) {
|
|
|
11444
11660
|
];
|
|
11445
11661
|
}
|
|
11446
11662
|
function readSession3(sessionPath, sessionId, workspace) {
|
|
11447
|
-
if (!sessionPath || !
|
|
11448
|
-
if (!
|
|
11663
|
+
if (!sessionPath || !path28.isAbsolute(sessionPath)) return null;
|
|
11664
|
+
if (!fs16.existsSync(sessionPath)) return null;
|
|
11449
11665
|
const sourceMtimeMs = statMtimeMs3(sessionPath);
|
|
11450
11666
|
const brainRootPath = brainRoot();
|
|
11451
|
-
if (sessionPath.startsWith(brainRootPath +
|
|
11452
|
-
const
|
|
11453
|
-
const uuidFromPath =
|
|
11667
|
+
if (sessionPath.startsWith(brainRootPath + path28.sep) && sessionPath.endsWith(".jsonl")) {
|
|
11668
|
+
const relative5 = sessionPath.slice(brainRootPath.length + 1);
|
|
11669
|
+
const uuidFromPath = relative5.split(path28.sep)[0];
|
|
11454
11670
|
const resolvedSessionId = sessionId || (isUuidLike(uuidFromPath) ? uuidFromPath : "");
|
|
11455
11671
|
if (!resolvedSessionId) return null;
|
|
11456
11672
|
const messages = parseBrainTranscript(sessionPath, resolvedSessionId, workspace);
|
|
@@ -11466,7 +11682,7 @@ function readSession3(sessionPath, sessionId, workspace) {
|
|
|
11466
11682
|
};
|
|
11467
11683
|
}
|
|
11468
11684
|
if (sessionPath.endsWith(".pb")) {
|
|
11469
|
-
const pbSessionId = sessionId ||
|
|
11685
|
+
const pbSessionId = sessionId || path28.basename(sessionPath, ".pb");
|
|
11470
11686
|
if (!isUuidLike(pbSessionId)) return null;
|
|
11471
11687
|
const messages = parsePbFile(sessionPath, pbSessionId);
|
|
11472
11688
|
if (!messages || messages.length === 0) return null;
|
|
@@ -11480,7 +11696,7 @@ function readSession3(sessionPath, sessionId, workspace) {
|
|
|
11480
11696
|
partialReason: "antigravity_cli_pb_raw_text_extraction"
|
|
11481
11697
|
};
|
|
11482
11698
|
}
|
|
11483
|
-
if (
|
|
11699
|
+
if (path28.basename(sessionPath) === "history.jsonl") {
|
|
11484
11700
|
const resolvedSessionId = sessionId || "";
|
|
11485
11701
|
if (!resolvedSessionId || !isUuidLike(resolvedSessionId)) return null;
|
|
11486
11702
|
const rows = readHistoryRows().filter((r) => r.conversationId === resolvedSessionId);
|
|
@@ -11534,18 +11750,18 @@ var init_antigravity_cli_transcript = __esm({
|
|
|
11534
11750
|
});
|
|
11535
11751
|
|
|
11536
11752
|
// src/providers/native-history/hermes-cli-transcript.ts
|
|
11537
|
-
import * as
|
|
11538
|
-
import * as
|
|
11539
|
-
import * as
|
|
11753
|
+
import * as fs17 from "fs";
|
|
11754
|
+
import * as path29 from "path";
|
|
11755
|
+
import * as os20 from "os";
|
|
11540
11756
|
function statMtimeMs4(p) {
|
|
11541
11757
|
try {
|
|
11542
|
-
return Math.floor(
|
|
11758
|
+
return Math.floor(fs17.statSync(p).mtimeMs);
|
|
11543
11759
|
} catch {
|
|
11544
11760
|
return 0;
|
|
11545
11761
|
}
|
|
11546
11762
|
}
|
|
11547
11763
|
function openDb() {
|
|
11548
|
-
if (!
|
|
11764
|
+
if (!fs17.existsSync(HERMES_STATE_DB)) return null;
|
|
11549
11765
|
try {
|
|
11550
11766
|
const Database = __require("better-sqlite3");
|
|
11551
11767
|
return new Database(HERMES_STATE_DB, { readonly: true, fileMustExist: true });
|
|
@@ -11602,10 +11818,10 @@ function readSession4(sessionPath) {
|
|
|
11602
11818
|
}
|
|
11603
11819
|
}
|
|
11604
11820
|
}
|
|
11605
|
-
if (!
|
|
11821
|
+
if (!path29.isAbsolute(sessionPath) || !fs17.existsSync(sessionPath)) return null;
|
|
11606
11822
|
let raw;
|
|
11607
11823
|
try {
|
|
11608
|
-
raw = JSON.parse(
|
|
11824
|
+
raw = JSON.parse(fs17.readFileSync(sessionPath, "utf8"));
|
|
11609
11825
|
} catch {
|
|
11610
11826
|
return null;
|
|
11611
11827
|
}
|
|
@@ -11628,7 +11844,7 @@ function readSession4(sessionPath) {
|
|
|
11628
11844
|
});
|
|
11629
11845
|
}
|
|
11630
11846
|
if (messages.length === 0) return null;
|
|
11631
|
-
const sessionId = typeof raw.session_id === "string" && raw.session_id ? raw.session_id :
|
|
11847
|
+
const sessionId = typeof raw.session_id === "string" && raw.session_id ? raw.session_id : path29.basename(sessionPath, ".json").replace(/^session_/, "");
|
|
11632
11848
|
return {
|
|
11633
11849
|
messages,
|
|
11634
11850
|
providerSessionId: sessionId,
|
|
@@ -11649,8 +11865,8 @@ var HERMES_STATE_DB, HERMES_LEGACY_SESSIONS_DIR;
|
|
|
11649
11865
|
var init_hermes_cli_transcript = __esm({
|
|
11650
11866
|
"src/providers/native-history/hermes-cli-transcript.ts"() {
|
|
11651
11867
|
"use strict";
|
|
11652
|
-
HERMES_STATE_DB =
|
|
11653
|
-
HERMES_LEGACY_SESSIONS_DIR =
|
|
11868
|
+
HERMES_STATE_DB = path29.join(os20.homedir(), ".hermes", "state.db");
|
|
11869
|
+
HERMES_LEGACY_SESSIONS_DIR = path29.join(os20.homedir(), ".hermes", "sessions");
|
|
11654
11870
|
}
|
|
11655
11871
|
});
|
|
11656
11872
|
|
|
@@ -11659,9 +11875,9 @@ var dispatcher_exports = {};
|
|
|
11659
11875
|
__export(dispatcher_exports, {
|
|
11660
11876
|
createNativeHistoryDispatcher: () => createNativeHistoryDispatcher
|
|
11661
11877
|
});
|
|
11662
|
-
import * as
|
|
11663
|
-
import * as
|
|
11664
|
-
import * as
|
|
11878
|
+
import * as fs18 from "fs";
|
|
11879
|
+
import * as os21 from "os";
|
|
11880
|
+
import * as path30 from "path";
|
|
11665
11881
|
function createNativeHistoryDispatcher(reader) {
|
|
11666
11882
|
return (input) => {
|
|
11667
11883
|
const workspace = input.workspace || "";
|
|
@@ -11701,26 +11917,26 @@ function resolveSourcePath(reader, workspace, sessionId) {
|
|
|
11701
11917
|
}
|
|
11702
11918
|
}
|
|
11703
11919
|
function resolveClaudePath(workspace, sessionId) {
|
|
11704
|
-
const dir =
|
|
11705
|
-
if (!
|
|
11920
|
+
const dir = path30.join(os21.homedir(), ".claude", "projects", cwdAsDashes(workspace));
|
|
11921
|
+
if (!fs18.existsSync(dir)) return null;
|
|
11706
11922
|
if (sessionId) {
|
|
11707
|
-
const candidate =
|
|
11708
|
-
if (
|
|
11923
|
+
const candidate = path30.join(dir, `${sessionId}.jsonl`);
|
|
11924
|
+
if (fs18.existsSync(candidate)) return candidate;
|
|
11709
11925
|
}
|
|
11710
11926
|
return null;
|
|
11711
11927
|
}
|
|
11712
11928
|
function resolveCodexPath(workspace) {
|
|
11713
11929
|
void workspace;
|
|
11714
11930
|
const now = /* @__PURE__ */ new Date();
|
|
11715
|
-
const dir =
|
|
11716
|
-
|
|
11931
|
+
const dir = path30.join(
|
|
11932
|
+
os21.homedir(),
|
|
11717
11933
|
".codex",
|
|
11718
11934
|
"sessions",
|
|
11719
11935
|
String(now.getUTCFullYear()),
|
|
11720
11936
|
String(now.getUTCMonth() + 1).padStart(2, "0"),
|
|
11721
11937
|
String(now.getUTCDate()).padStart(2, "0")
|
|
11722
11938
|
);
|
|
11723
|
-
if (
|
|
11939
|
+
if (fs18.existsSync(dir)) {
|
|
11724
11940
|
const f = newestRecentFile2(dir, /\.jsonl$/);
|
|
11725
11941
|
if (f) return f;
|
|
11726
11942
|
}
|
|
@@ -11728,23 +11944,23 @@ function resolveCodexPath(workspace) {
|
|
|
11728
11944
|
}
|
|
11729
11945
|
function resolveAntigravityPath(workspace) {
|
|
11730
11946
|
void workspace;
|
|
11731
|
-
const brainRoot2 =
|
|
11732
|
-
if (!
|
|
11947
|
+
const brainRoot2 = path30.join(os21.homedir(), ".gemini", "antigravity-cli", "brain");
|
|
11948
|
+
if (!fs18.existsSync(brainRoot2)) return null;
|
|
11733
11949
|
const cutoff = Date.now() - RECENT_WINDOW_MS;
|
|
11734
|
-
const entries =
|
|
11950
|
+
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);
|
|
11735
11951
|
for (const e of entries) {
|
|
11736
|
-
const t =
|
|
11737
|
-
if (
|
|
11952
|
+
const t = path30.join(e.p, ".system_generated", "logs", "transcript.jsonl");
|
|
11953
|
+
if (fs18.existsSync(t)) return t;
|
|
11738
11954
|
}
|
|
11739
11955
|
return null;
|
|
11740
11956
|
}
|
|
11741
11957
|
function resolveHermesPath(workspace, sessionId) {
|
|
11742
11958
|
void workspace;
|
|
11743
11959
|
void sessionId;
|
|
11744
|
-
const dbPath =
|
|
11745
|
-
if (
|
|
11746
|
-
const dir =
|
|
11747
|
-
if (!
|
|
11960
|
+
const dbPath = path30.join(os21.homedir(), ".hermes", "state.db");
|
|
11961
|
+
if (fs18.existsSync(dbPath)) return dbPath;
|
|
11962
|
+
const dir = path30.join(os21.homedir(), ".hermes", "sessions");
|
|
11963
|
+
if (!fs18.existsSync(dir)) return null;
|
|
11748
11964
|
return newestRecentFile2(dir, /^session_.*\.json$/);
|
|
11749
11965
|
}
|
|
11750
11966
|
function readByReader(reader, sourcePath, sessionId, workspace) {
|
|
@@ -11766,7 +11982,7 @@ function cwdAsDashes(cwd) {
|
|
|
11766
11982
|
function newestRecentFile2(dir, pattern) {
|
|
11767
11983
|
try {
|
|
11768
11984
|
const cutoff = Date.now() - RECENT_WINDOW_MS;
|
|
11769
|
-
const entries =
|
|
11985
|
+
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);
|
|
11770
11986
|
return entries[0]?.p ?? null;
|
|
11771
11987
|
} catch {
|
|
11772
11988
|
return null;
|
|
@@ -11774,7 +11990,7 @@ function newestRecentFile2(dir, pattern) {
|
|
|
11774
11990
|
}
|
|
11775
11991
|
function safeMtime(p) {
|
|
11776
11992
|
try {
|
|
11777
|
-
return Math.floor(
|
|
11993
|
+
return Math.floor(fs18.statSync(p).mtimeMs);
|
|
11778
11994
|
} catch {
|
|
11779
11995
|
return 0;
|
|
11780
11996
|
}
|
|
@@ -12042,12 +12258,12 @@ function parseSubmoduleStatusOutput(output, repoRoot, ignorePaths) {
|
|
|
12042
12258
|
if (!match) continue;
|
|
12043
12259
|
const prefix = match[1];
|
|
12044
12260
|
const commit = match[2];
|
|
12045
|
-
const
|
|
12046
|
-
if (ignoreSet.has(
|
|
12261
|
+
const path40 = match[3];
|
|
12262
|
+
if (ignoreSet.has(path40)) continue;
|
|
12047
12263
|
submodules.push({
|
|
12048
|
-
path:
|
|
12264
|
+
path: path40,
|
|
12049
12265
|
commit,
|
|
12050
|
-
repoPath: repoRoot + "/" +
|
|
12266
|
+
repoPath: repoRoot + "/" + path40,
|
|
12051
12267
|
dirty: prefix === "+",
|
|
12052
12268
|
outOfSync: prefix === "-",
|
|
12053
12269
|
lastCheckedAt: Date.now()
|
|
@@ -13551,10 +13767,10 @@ function getRegistryPath() {
|
|
|
13551
13767
|
return join8(getDaemonDataDir(), "mesh-coordinators.json");
|
|
13552
13768
|
}
|
|
13553
13769
|
function loadMeshCoordinatorRegistry() {
|
|
13554
|
-
const
|
|
13555
|
-
if (!existsSync7(
|
|
13770
|
+
const path40 = getRegistryPath();
|
|
13771
|
+
if (!existsSync7(path40)) return;
|
|
13556
13772
|
try {
|
|
13557
|
-
const raw = JSON.parse(readFileSync5(
|
|
13773
|
+
const raw = JSON.parse(readFileSync5(path40, "utf-8"));
|
|
13558
13774
|
if (!Array.isArray(raw)) return;
|
|
13559
13775
|
_registry.clear();
|
|
13560
13776
|
for (const entry of raw) {
|
|
@@ -13773,8 +13989,8 @@ function validateMeshRefineConfig(config, source = "inline") {
|
|
|
13773
13989
|
if (rejectedCommands.length) errors.push("one or more validation commands are invalid");
|
|
13774
13990
|
return { valid: errors.length === 0, errors, bootstrapCommands, commands, rejectedCommands };
|
|
13775
13991
|
}
|
|
13776
|
-
function parseConfigText(
|
|
13777
|
-
if (/\.json$/i.test(
|
|
13992
|
+
function parseConfigText(path40, text) {
|
|
13993
|
+
if (/\.json$/i.test(path40)) return JSON.parse(text);
|
|
13778
13994
|
return yaml.load(text);
|
|
13779
13995
|
}
|
|
13780
13996
|
function loadMeshRefineConfig(mesh, workspace) {
|
|
@@ -13785,16 +14001,16 @@ function loadMeshRefineConfig(mesh, workspace) {
|
|
|
13785
14001
|
if (!validation.valid) return { source: "mesh.policy.refineConfig", sourceType: "invalid", error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
13786
14002
|
return { config: inline, source: "mesh.policy.refineConfig", sourceType: "mesh_policy" };
|
|
13787
14003
|
}
|
|
13788
|
-
for (const
|
|
13789
|
-
const configPath = join9(workspace,
|
|
14004
|
+
for (const relative5 of MESH_REFINE_CONFIG_LOCATIONS) {
|
|
14005
|
+
const configPath = join9(workspace, relative5);
|
|
13790
14006
|
if (!existsSync8(configPath)) continue;
|
|
13791
14007
|
try {
|
|
13792
14008
|
const parsed = parseConfigText(configPath, readFileSync6(configPath, "utf-8"));
|
|
13793
|
-
const validation = validateMeshRefineConfig(parsed,
|
|
13794
|
-
if (!validation.valid) return { source:
|
|
13795
|
-
return { config: parsed, source:
|
|
14009
|
+
const validation = validateMeshRefineConfig(parsed, relative5);
|
|
14010
|
+
if (!validation.valid) return { source: relative5, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
14011
|
+
return { config: parsed, source: relative5, sourceType: "repo_file", path: configPath };
|
|
13796
14012
|
} catch (error) {
|
|
13797
|
-
return { source:
|
|
14013
|
+
return { source: relative5, sourceType: "invalid", path: configPath, error: error?.message || String(error) };
|
|
13798
14014
|
}
|
|
13799
14015
|
}
|
|
13800
14016
|
return {
|
|
@@ -13927,8 +14143,8 @@ var MESH_WORKTREE_BOOTSTRAP_CONFIG_SCHEMA = {
|
|
|
13927
14143
|
var DEFAULT_TIMEOUT_MS2 = 12e4;
|
|
13928
14144
|
var DEFAULT_OUTPUT_LIMIT_BYTES = 128 * 1024;
|
|
13929
14145
|
var OUTPUT_SUMMARY_CHARS = 2e3;
|
|
13930
|
-
function parseConfigText2(
|
|
13931
|
-
if (/\.json$/i.test(
|
|
14146
|
+
function parseConfigText2(path40, text) {
|
|
14147
|
+
if (/\.json$/i.test(path40)) return JSON.parse(text);
|
|
13932
14148
|
return yaml2.load(text);
|
|
13933
14149
|
}
|
|
13934
14150
|
function truncateOutput(value) {
|
|
@@ -13968,16 +14184,16 @@ function loadMeshWorktreeBootstrapConfig(mesh, workspace) {
|
|
|
13968
14184
|
if (!validation.valid) return { source: "mesh.policy.worktreeBootstrapConfig", sourceType: "invalid", error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
13969
14185
|
return { config: inline, source: "mesh.policy.worktreeBootstrapConfig", sourceType: "mesh_policy" };
|
|
13970
14186
|
}
|
|
13971
|
-
for (const
|
|
13972
|
-
const configPath = join10(workspace,
|
|
14187
|
+
for (const relative5 of MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS) {
|
|
14188
|
+
const configPath = join10(workspace, relative5);
|
|
13973
14189
|
if (!existsSync9(configPath)) continue;
|
|
13974
14190
|
try {
|
|
13975
14191
|
const parsed = parseConfigText2(configPath, readFileSync7(configPath, "utf-8"));
|
|
13976
|
-
const validation = validateMeshWorktreeBootstrapConfig(parsed,
|
|
13977
|
-
if (!validation.valid) return { source:
|
|
13978
|
-
return { config: parsed, source:
|
|
14192
|
+
const validation = validateMeshWorktreeBootstrapConfig(parsed, relative5);
|
|
14193
|
+
if (!validation.valid) return { source: relative5, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
14194
|
+
return { config: parsed, source: relative5, sourceType: "repo_file", path: configPath };
|
|
13979
14195
|
} catch (error) {
|
|
13980
|
-
return { source:
|
|
14196
|
+
return { source: relative5, sourceType: "invalid", path: configPath, error: error?.message || String(error) };
|
|
13981
14197
|
}
|
|
13982
14198
|
}
|
|
13983
14199
|
return { source: "unavailable", sourceType: "unavailable", error: `No worktree bootstrap config found. Checked: ${MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS.join(", ")}` };
|
|
@@ -15218,17 +15434,17 @@ function checkPathExists(paths) {
|
|
|
15218
15434
|
return null;
|
|
15219
15435
|
}
|
|
15220
15436
|
async function detectIDEs(providerLoader) {
|
|
15221
|
-
const
|
|
15437
|
+
const os29 = platform2();
|
|
15222
15438
|
const results = [];
|
|
15223
15439
|
for (const def of getMergedDefinitions()) {
|
|
15224
15440
|
const cliPath = findCliCommand(providerLoader?.getIdeCliCommand(def.id, def.cli) || def.cli);
|
|
15225
|
-
const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[
|
|
15441
|
+
const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[os29] || []) || []);
|
|
15226
15442
|
let resolvedCli = cliPath;
|
|
15227
|
-
if (!resolvedCli && appPath &&
|
|
15443
|
+
if (!resolvedCli && appPath && os29 === "darwin") {
|
|
15228
15444
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
15229
15445
|
if (existsSync15(bundledCli)) resolvedCli = bundledCli;
|
|
15230
15446
|
}
|
|
15231
|
-
if (!resolvedCli && appPath &&
|
|
15447
|
+
if (!resolvedCli && appPath && os29 === "win32") {
|
|
15232
15448
|
const { dirname: dirname11 } = await import("path");
|
|
15233
15449
|
const appDir = dirname11(appPath);
|
|
15234
15450
|
const candidates = [
|
|
@@ -15245,7 +15461,7 @@ async function detectIDEs(providerLoader) {
|
|
|
15245
15461
|
}
|
|
15246
15462
|
}
|
|
15247
15463
|
}
|
|
15248
|
-
const installed =
|
|
15464
|
+
const installed = os29 === "darwin" ? !!(resolvedCli || appPath) : !!resolvedCli;
|
|
15249
15465
|
const version = resolvedCli ? await getIdeVersion(resolvedCli) : null;
|
|
15250
15466
|
results.push({
|
|
15251
15467
|
id: def.id,
|
|
@@ -25627,6 +25843,14 @@ var DaemonCommandHandler = class {
|
|
|
25627
25843
|
return this.handleCheckProviderUpdates(args);
|
|
25628
25844
|
case "list_installed_providers":
|
|
25629
25845
|
return this.handleListInstalledProviders(args);
|
|
25846
|
+
case "add_provider_source":
|
|
25847
|
+
return this.handleAddProviderSource(args);
|
|
25848
|
+
case "remove_provider_source":
|
|
25849
|
+
return this.handleRemoveProviderSource(args);
|
|
25850
|
+
case "list_provider_sources":
|
|
25851
|
+
return this.handleListProviderSources(args);
|
|
25852
|
+
case "set_active_provider_source":
|
|
25853
|
+
return this.handleSetActiveProviderSource(args);
|
|
25630
25854
|
// ─── Stream commands (stream-commands.ts) ───────────
|
|
25631
25855
|
case "select_session":
|
|
25632
25856
|
return handleSelectSession(this, args);
|
|
@@ -25690,49 +25914,62 @@ var DaemonCommandHandler = class {
|
|
|
25690
25914
|
return { success: false, error: "ProviderLoader not initialized" };
|
|
25691
25915
|
}
|
|
25692
25916
|
/**
|
|
25693
|
-
* Return per-provider availability so
|
|
25694
|
-
* "Installed" badges. Reuses the existing detection state from
|
|
25917
|
+
* Return per-provider availability so the dashboard's provider catalog
|
|
25918
|
+
* can show "Installed" badges. Reuses the existing detection state from
|
|
25695
25919
|
* ProviderLoader.getMachineProviderStatus() — no probing is triggered.
|
|
25696
25920
|
*/
|
|
25697
25921
|
handleListProviderAvailability(_args) {
|
|
25698
25922
|
if (!this._ctx.providerLoader) {
|
|
25699
25923
|
return { success: false, error: "ProviderLoader not initialized" };
|
|
25700
25924
|
}
|
|
25925
|
+
const { describeTrust: describeTrust2, requiresConfirmation: requiresConfirmation2 } = (init_provider_trust(), __toCommonJS(provider_trust_exports));
|
|
25701
25926
|
const loader = this._ctx.providerLoader;
|
|
25702
25927
|
const items = loader.getAll().map((provider) => {
|
|
25703
25928
|
const machineConfig = loader.getMachineProviderConfig(provider.type);
|
|
25704
25929
|
const lastDetection = machineConfig.lastDetection;
|
|
25930
|
+
const trust = provider._sourceTrust ?? "trusted";
|
|
25931
|
+
const layer = provider._sourceLayer ?? "upstream";
|
|
25932
|
+
const sourceName = provider._sourceName ?? null;
|
|
25705
25933
|
return {
|
|
25706
25934
|
type: provider.type,
|
|
25707
25935
|
category: provider.category,
|
|
25708
25936
|
status: loader.getMachineProviderStatus(provider.type),
|
|
25709
25937
|
installed: lastDetection?.ok === true,
|
|
25710
25938
|
detectedPath: lastDetection?.path ?? null,
|
|
25711
|
-
checkedAt: lastDetection?.checkedAt ?? null
|
|
25939
|
+
checkedAt: lastDetection?.checkedAt ?? null,
|
|
25940
|
+
trust,
|
|
25941
|
+
trustDescription: describeTrust2(trust),
|
|
25942
|
+
requiresConfirmation: requiresConfirmation2(trust),
|
|
25943
|
+
sourceLayer: layer,
|
|
25944
|
+
sourceName
|
|
25712
25945
|
};
|
|
25713
25946
|
});
|
|
25714
25947
|
return { success: true, providers: items };
|
|
25715
25948
|
}
|
|
25716
25949
|
/**
|
|
25717
|
-
* Compute the *
|
|
25718
|
-
*
|
|
25719
|
-
*
|
|
25720
|
-
*
|
|
25721
|
-
*
|
|
25722
|
-
*
|
|
25950
|
+
* Compute the *upstream cache root*. install_provider_manifest writes
|
|
25951
|
+
* official-registry manifests here so the daemon's standard upstream
|
|
25952
|
+
* layer picks them up — no special handling needed at load time, and
|
|
25953
|
+
* the manifests inherit the official-trust badge instead of the
|
|
25954
|
+
* untrusted-external one.
|
|
25955
|
+
*
|
|
25956
|
+
* Path matches ProviderLoader.upstreamDir but we recompute it from
|
|
25957
|
+
* homedir() so this method stays usable in dev where userDir can
|
|
25958
|
+
* point at a sibling git checkout.
|
|
25723
25959
|
*/
|
|
25724
|
-
|
|
25725
|
-
const
|
|
25726
|
-
const
|
|
25727
|
-
return
|
|
25960
|
+
getUpstreamInstallRoot() {
|
|
25961
|
+
const os29 = __require("os");
|
|
25962
|
+
const path40 = __require("path");
|
|
25963
|
+
return path40.join(os29.homedir(), ".adhdev", "providers", ".upstream");
|
|
25728
25964
|
}
|
|
25729
25965
|
/**
|
|
25730
25966
|
* Download a single provider manifest from the registry and write it to
|
|
25731
|
-
* ~/.adhdev/
|
|
25967
|
+
* ~/.adhdev/providers/.upstream/{category}/{type}/provider.json.
|
|
25732
25968
|
*
|
|
25733
|
-
* Used by
|
|
25734
|
-
*
|
|
25735
|
-
* the
|
|
25969
|
+
* Used by standalone onboarding to seed the upstream cache with the
|
|
25970
|
+
* default provider set on first launch. Verifies SHA-256 checksum
|
|
25971
|
+
* against the registry meta before persisting. Refuses to write
|
|
25972
|
+
* outside the upstream root.
|
|
25736
25973
|
*
|
|
25737
25974
|
* Args: { type: string, category?: string, version?: string }
|
|
25738
25975
|
* If category/version are omitted, looks up the latest from the registry.
|
|
@@ -25747,8 +25984,8 @@ var DaemonCommandHandler = class {
|
|
|
25747
25984
|
return { success: false, error: "invalid type" };
|
|
25748
25985
|
}
|
|
25749
25986
|
const https = __require("https");
|
|
25750
|
-
const
|
|
25751
|
-
const
|
|
25987
|
+
const fs28 = __require("fs");
|
|
25988
|
+
const path40 = __require("path");
|
|
25752
25989
|
const crypto6 = __require("crypto");
|
|
25753
25990
|
const REGISTRY = "https://api.adhf.dev/api/v1/registry";
|
|
25754
25991
|
function fetchText(url, timeoutMs) {
|
|
@@ -25785,13 +26022,13 @@ var DaemonCommandHandler = class {
|
|
|
25785
26022
|
if (actualChecksum !== meta.checksum) {
|
|
25786
26023
|
return { success: false, error: `checksum mismatch: expected ${meta.checksum}, got ${actualChecksum}` };
|
|
25787
26024
|
}
|
|
25788
|
-
const installRoot = this.
|
|
25789
|
-
const installRootResolved =
|
|
25790
|
-
const targetDir =
|
|
25791
|
-
if (!targetDir.startsWith(installRootResolved +
|
|
25792
|
-
return { success: false, error: "install path escaped
|
|
26025
|
+
const installRoot = this.getUpstreamInstallRoot();
|
|
26026
|
+
const installRootResolved = path40.resolve(installRoot);
|
|
26027
|
+
const targetDir = path40.resolve(path40.join(installRoot, category, type));
|
|
26028
|
+
if (!targetDir.startsWith(installRootResolved + path40.sep)) {
|
|
26029
|
+
return { success: false, error: "install path escaped upstream root" };
|
|
25793
26030
|
}
|
|
25794
|
-
|
|
26031
|
+
fs28.mkdirSync(targetDir, { recursive: true });
|
|
25795
26032
|
let manifestProbe = {};
|
|
25796
26033
|
try {
|
|
25797
26034
|
manifestProbe = JSON.parse(manifestBody);
|
|
@@ -25815,8 +26052,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
25815
26052
|
}
|
|
25816
26053
|
}
|
|
25817
26054
|
const targetFile = isV1 ? "provider.v1.json" : "provider.json";
|
|
25818
|
-
const targetPath =
|
|
25819
|
-
|
|
26055
|
+
const targetPath = path40.join(targetDir, targetFile);
|
|
26056
|
+
fs28.writeFileSync(targetPath, manifestBody, "utf-8");
|
|
25820
26057
|
const manifestJson = JSON.parse(manifestBody);
|
|
25821
26058
|
const scriptFetch = await this.fetchProviderSources(
|
|
25822
26059
|
manifestJson,
|
|
@@ -25864,6 +26101,10 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
25864
26101
|
if (Array.isArray(manifest.compatibility)) {
|
|
25865
26102
|
for (const c of manifest.compatibility) {
|
|
25866
26103
|
if (typeof c?.scriptDir === "string") scriptDirs.add(c.scriptDir);
|
|
26104
|
+
if (typeof c?.spec === "string" && c.spec.includes("/")) {
|
|
26105
|
+
const dir = c.spec.substring(0, c.spec.lastIndexOf("/"));
|
|
26106
|
+
if (dir) scriptDirs.add(dir);
|
|
26107
|
+
}
|
|
25867
26108
|
}
|
|
25868
26109
|
}
|
|
25869
26110
|
if (manifest.overrides && typeof manifest.overrides === "object" && !Array.isArray(manifest.overrides)) {
|
|
@@ -25882,8 +26123,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
25882
26123
|
const repo = source.repo;
|
|
25883
26124
|
const ref = source.ref;
|
|
25884
26125
|
const https = __require("https");
|
|
25885
|
-
const
|
|
25886
|
-
const
|
|
26126
|
+
const fs28 = __require("fs");
|
|
26127
|
+
const path40 = __require("path");
|
|
25887
26128
|
function fetchJson(url, timeoutMs) {
|
|
25888
26129
|
return new Promise((resolve23, reject) => {
|
|
25889
26130
|
const req = https.get(url, {
|
|
@@ -25939,9 +26180,9 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
25939
26180
|
}
|
|
25940
26181
|
let fetchedCount = 0;
|
|
25941
26182
|
const sharedDirRel = `${category}/_shared`;
|
|
25942
|
-
const sharedTargetDir =
|
|
25943
|
-
const installRootResolved =
|
|
25944
|
-
if (sharedTargetDir.startsWith(installRootResolved +
|
|
26183
|
+
const sharedTargetDir = path40.resolve(path40.join(targetDir, "../_shared"));
|
|
26184
|
+
const installRootResolved = path40.resolve(path40.join(targetDir, "../.."));
|
|
26185
|
+
if (sharedTargetDir.startsWith(installRootResolved + path40.sep)) {
|
|
25945
26186
|
const sharedStack = [sharedDirRel];
|
|
25946
26187
|
while (sharedStack.length) {
|
|
25947
26188
|
const relDir = sharedStack.pop();
|
|
@@ -25964,10 +26205,10 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
25964
26205
|
try {
|
|
25965
26206
|
const body = await fetchBinary(entry.download_url, 3e4);
|
|
25966
26207
|
const relInside = entry.path.startsWith(sharedDirRel + "/") ? entry.path.slice(sharedDirRel.length + 1) : entry.path;
|
|
25967
|
-
const outPath =
|
|
25968
|
-
if (!outPath.startsWith(
|
|
25969
|
-
|
|
25970
|
-
|
|
26208
|
+
const outPath = path40.resolve(path40.join(sharedTargetDir, relInside));
|
|
26209
|
+
if (!outPath.startsWith(path40.resolve(sharedTargetDir) + path40.sep)) continue;
|
|
26210
|
+
fs28.mkdirSync(path40.dirname(outPath), { recursive: true });
|
|
26211
|
+
fs28.writeFileSync(outPath, body);
|
|
25971
26212
|
fetchedCount++;
|
|
25972
26213
|
} catch (e) {
|
|
25973
26214
|
errors.push(`fetch shared ${entry.path}: ${e?.message ?? e}`);
|
|
@@ -26000,13 +26241,13 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26000
26241
|
try {
|
|
26001
26242
|
const body = await fetchBinary(entry.download_url, 3e4);
|
|
26002
26243
|
const relInsideProvider = entry.path.startsWith(subdir + "/") ? entry.path.slice(subdir.length + 1) : entry.path;
|
|
26003
|
-
const outPath =
|
|
26004
|
-
if (!outPath.startsWith(
|
|
26244
|
+
const outPath = path40.resolve(path40.join(targetDir, relInsideProvider));
|
|
26245
|
+
if (!outPath.startsWith(path40.resolve(targetDir) + path40.sep)) {
|
|
26005
26246
|
errors.push(`refusing to write outside targetDir: ${entry.path}`);
|
|
26006
26247
|
continue;
|
|
26007
26248
|
}
|
|
26008
|
-
|
|
26009
|
-
|
|
26249
|
+
fs28.mkdirSync(path40.dirname(outPath), { recursive: true });
|
|
26250
|
+
fs28.writeFileSync(outPath, body);
|
|
26010
26251
|
fetchedCount++;
|
|
26011
26252
|
} catch (e) {
|
|
26012
26253
|
errors.push(`fetch ${entry.path}: ${e?.message ?? e}`);
|
|
@@ -26017,9 +26258,12 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26017
26258
|
return { fetchedCount, source: `${repo}@${ref}`, errors };
|
|
26018
26259
|
}
|
|
26019
26260
|
/**
|
|
26020
|
-
* Remove a provider manifest from the
|
|
26021
|
-
* (~/.adhdev/
|
|
26022
|
-
* outside that root.
|
|
26261
|
+
* Remove a provider manifest from the upstream cache root
|
|
26262
|
+
* (~/.adhdev/providers/.upstream/{category}/{type}/). Refuses to touch
|
|
26263
|
+
* anything outside that root. Used by onboarding to opt out of a
|
|
26264
|
+
* provider the user doesn't want; the dashboard no longer exposes a
|
|
26265
|
+
* per-provider uninstall button (external sources are removed as a
|
|
26266
|
+
* whole via remove_provider_source).
|
|
26023
26267
|
*/
|
|
26024
26268
|
async handleUninstallProviderManifest(args) {
|
|
26025
26269
|
const type = typeof args?.type === "string" ? args.type : "";
|
|
@@ -26031,19 +26275,19 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26031
26275
|
if (!["cli", "ide", "extension", "acp"].includes(category)) {
|
|
26032
26276
|
return { success: false, error: `unknown category: ${category}` };
|
|
26033
26277
|
}
|
|
26034
|
-
const
|
|
26035
|
-
const
|
|
26278
|
+
const fs28 = __require("fs");
|
|
26279
|
+
const path40 = __require("path");
|
|
26036
26280
|
try {
|
|
26037
|
-
const installRoot = this.
|
|
26038
|
-
const installRootResolved =
|
|
26039
|
-
const targetDir =
|
|
26040
|
-
if (!targetDir.startsWith(installRootResolved +
|
|
26041
|
-
return { success: false, error: "refusing to delete outside
|
|
26281
|
+
const installRoot = this.getUpstreamInstallRoot();
|
|
26282
|
+
const installRootResolved = path40.resolve(installRoot);
|
|
26283
|
+
const targetDir = path40.resolve(path40.join(installRoot, category, type));
|
|
26284
|
+
if (!targetDir.startsWith(installRootResolved + path40.sep)) {
|
|
26285
|
+
return { success: false, error: "refusing to delete outside upstream root" };
|
|
26042
26286
|
}
|
|
26043
|
-
if (!
|
|
26287
|
+
if (!fs28.existsSync(targetDir)) {
|
|
26044
26288
|
return { success: false, error: "not installed" };
|
|
26045
26289
|
}
|
|
26046
|
-
|
|
26290
|
+
fs28.rmSync(targetDir, { recursive: true, force: true });
|
|
26047
26291
|
if (this._ctx.providerLoader) {
|
|
26048
26292
|
this._ctx.providerLoader.reload();
|
|
26049
26293
|
this._ctx.providerLoader.registerToDetector();
|
|
@@ -26054,33 +26298,33 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26054
26298
|
}
|
|
26055
26299
|
}
|
|
26056
26300
|
/**
|
|
26057
|
-
* Return everything currently installed in
|
|
26301
|
+
* Return everything currently installed in the upstream cache with its
|
|
26058
26302
|
* version. This is the "what does this daemon have" answer used both by
|
|
26059
26303
|
* the UI and by the update checker.
|
|
26060
26304
|
*/
|
|
26061
26305
|
handleListInstalledProviders(_args) {
|
|
26062
|
-
const
|
|
26063
|
-
const
|
|
26064
|
-
const installRoot = this.
|
|
26065
|
-
if (!
|
|
26306
|
+
const fs28 = __require("fs");
|
|
26307
|
+
const path40 = __require("path");
|
|
26308
|
+
const installRoot = this.getUpstreamInstallRoot();
|
|
26309
|
+
if (!fs28.existsSync(installRoot)) return { success: true, providers: [] };
|
|
26066
26310
|
const CATEGORIES = ["cli", "ide", "extension", "acp"];
|
|
26067
26311
|
const items = [];
|
|
26068
26312
|
for (const category of CATEGORIES) {
|
|
26069
|
-
const categoryDir =
|
|
26070
|
-
if (!
|
|
26313
|
+
const categoryDir = path40.join(installRoot, category);
|
|
26314
|
+
if (!fs28.existsSync(categoryDir)) continue;
|
|
26071
26315
|
let entries;
|
|
26072
26316
|
try {
|
|
26073
|
-
entries =
|
|
26317
|
+
entries = fs28.readdirSync(categoryDir);
|
|
26074
26318
|
} catch {
|
|
26075
26319
|
continue;
|
|
26076
26320
|
}
|
|
26077
26321
|
for (const type of entries) {
|
|
26078
|
-
const v1Path =
|
|
26079
|
-
const v0Path =
|
|
26080
|
-
const manifestPath =
|
|
26322
|
+
const v1Path = path40.join(categoryDir, type, "provider.v1.json");
|
|
26323
|
+
const v0Path = path40.join(categoryDir, type, "provider.json");
|
|
26324
|
+
const manifestPath = fs28.existsSync(v1Path) ? v1Path : fs28.existsSync(v0Path) ? v0Path : null;
|
|
26081
26325
|
if (!manifestPath) continue;
|
|
26082
26326
|
try {
|
|
26083
|
-
const m = JSON.parse(
|
|
26327
|
+
const m = JSON.parse(fs28.readFileSync(manifestPath, "utf-8"));
|
|
26084
26328
|
items.push({
|
|
26085
26329
|
type,
|
|
26086
26330
|
category,
|
|
@@ -26157,6 +26401,196 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26157
26401
|
);
|
|
26158
26402
|
return { success: true, providers: checks };
|
|
26159
26403
|
}
|
|
26404
|
+
// ─── External provider sources (3rd-party git URLs) ──────────────
|
|
26405
|
+
/**
|
|
26406
|
+
* Register a new external provider source. The daemon clones the repo
|
|
26407
|
+
* to ~/.adhdev/external/<name>/, walks it once to detect provided
|
|
26408
|
+
* types, and surfaces any conflicts with already-installed types so
|
|
26409
|
+
* the dashboard can ask the user how to resolve them.
|
|
26410
|
+
*
|
|
26411
|
+
* Args: { url: string, ref?: string, name?: string }
|
|
26412
|
+
* - url: https://, git@, or any git-cloneable URL
|
|
26413
|
+
* - ref: branch/tag/commit (default "main")
|
|
26414
|
+
* - name: short identifier (default derived from URL)
|
|
26415
|
+
*
|
|
26416
|
+
* Returns: { source, providers, conflicts }
|
|
26417
|
+
* - conflicts: list of types this new source provides that another
|
|
26418
|
+
* source already exposes. UI uses this to prompt for active-source
|
|
26419
|
+
* selection before the load takes effect.
|
|
26420
|
+
*/
|
|
26421
|
+
async handleAddProviderSource(args) {
|
|
26422
|
+
const url = typeof args?.url === "string" ? args.url.trim() : "";
|
|
26423
|
+
if (!url) return { success: false, error: "url is required" };
|
|
26424
|
+
const ref = typeof args?.ref === "string" && args.ref.trim() ? args.ref.trim() : "main";
|
|
26425
|
+
if (url.startsWith("-")) return { success: false, error: 'url must not start with "-"' };
|
|
26426
|
+
if (ref.startsWith("-")) return { success: false, error: 'ref must not start with "-"' };
|
|
26427
|
+
if (!/^(https?:\/\/|git@[a-z0-9._-]+:)[a-z0-9._@:/~\-]+$/i.test(url)) {
|
|
26428
|
+
return { success: false, error: "url must be https://\u2026 or git@host:\u2026 and contain only URL-safe characters" };
|
|
26429
|
+
}
|
|
26430
|
+
if (!/^[A-Za-z0-9._/-]+$/.test(ref)) {
|
|
26431
|
+
return { success: false, error: "ref must contain only [A-Za-z0-9._/-]" };
|
|
26432
|
+
}
|
|
26433
|
+
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
26434
|
+
const requestedName = typeof args?.name === "string" && args.name.trim() ? args.name.trim() : ext.deriveSourceName(url);
|
|
26435
|
+
if (!/^@[a-z0-9_-]+$/i.test(requestedName)) {
|
|
26436
|
+
return { success: false, error: "name must match @[a-z0-9_-]+" };
|
|
26437
|
+
}
|
|
26438
|
+
const fs28 = __require("fs");
|
|
26439
|
+
const path40 = __require("path");
|
|
26440
|
+
const { spawnSync: spawnSync2 } = __require("child_process");
|
|
26441
|
+
const file = ext.loadExternalSources();
|
|
26442
|
+
if (file.sources.some((s) => s.name === requestedName)) {
|
|
26443
|
+
return { success: false, error: `source name "${requestedName}" is already registered` };
|
|
26444
|
+
}
|
|
26445
|
+
if (file.sources.some((s) => s.url === url && s.ref === ref)) {
|
|
26446
|
+
return { success: false, error: `source url+ref already registered (use a different name to track another ref)` };
|
|
26447
|
+
}
|
|
26448
|
+
const sourceDir = path40.join(ext.externalRoot(), requestedName);
|
|
26449
|
+
if (!fs28.existsSync(ext.externalRoot())) fs28.mkdirSync(ext.externalRoot(), { recursive: true });
|
|
26450
|
+
if (fs28.existsSync(sourceDir)) {
|
|
26451
|
+
return { success: false, error: `directory already exists: ${sourceDir} (rename or remove first)` };
|
|
26452
|
+
}
|
|
26453
|
+
const clone = spawnSync2("git", ["clone", "--depth=1", "--branch", ref, "--", url, sourceDir], {
|
|
26454
|
+
encoding: "utf-8",
|
|
26455
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
26456
|
+
timeout: 6e4
|
|
26457
|
+
});
|
|
26458
|
+
if (clone.status !== 0) {
|
|
26459
|
+
try {
|
|
26460
|
+
fs28.rmSync(sourceDir, { recursive: true, force: true });
|
|
26461
|
+
} catch {
|
|
26462
|
+
}
|
|
26463
|
+
return { success: false, error: `git clone failed: ${(clone.stderr || clone.stdout || "").trim() || "unknown error"}` };
|
|
26464
|
+
}
|
|
26465
|
+
const source = {
|
|
26466
|
+
name: requestedName,
|
|
26467
|
+
url,
|
|
26468
|
+
ref,
|
|
26469
|
+
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
26470
|
+
};
|
|
26471
|
+
ext.saveExternalSources({ schema: 1, sources: [...file.sources, source] });
|
|
26472
|
+
const inventory = ext.inventoryExternalSources();
|
|
26473
|
+
const conflicts = [];
|
|
26474
|
+
const newEntry = inventory.find((e) => e.sourceName === requestedName);
|
|
26475
|
+
if (newEntry) {
|
|
26476
|
+
for (const [category, types] of Object.entries(newEntry.providers)) {
|
|
26477
|
+
for (const type of types) {
|
|
26478
|
+
const sources = ext.sourcesProviding(category, type);
|
|
26479
|
+
if (sources.length > 1) conflicts.push({ category, type, sources });
|
|
26480
|
+
}
|
|
26481
|
+
}
|
|
26482
|
+
}
|
|
26483
|
+
if (this._ctx.providerLoader) {
|
|
26484
|
+
this._ctx.providerLoader.reload();
|
|
26485
|
+
this._ctx.providerLoader.registerToDetector();
|
|
26486
|
+
}
|
|
26487
|
+
return {
|
|
26488
|
+
success: true,
|
|
26489
|
+
source,
|
|
26490
|
+
providers: newEntry?.providers ?? {},
|
|
26491
|
+
conflicts
|
|
26492
|
+
};
|
|
26493
|
+
}
|
|
26494
|
+
/**
|
|
26495
|
+
* Remove a registered external source. Deletes the clone directory and
|
|
26496
|
+
* any active-source entry pointing to it.
|
|
26497
|
+
*
|
|
26498
|
+
* Args: { name: string }
|
|
26499
|
+
*/
|
|
26500
|
+
async handleRemoveProviderSource(args) {
|
|
26501
|
+
const name = typeof args?.name === "string" ? args.name.trim() : "";
|
|
26502
|
+
if (!name) return { success: false, error: "name is required" };
|
|
26503
|
+
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
26504
|
+
const fs28 = __require("fs");
|
|
26505
|
+
const path40 = __require("path");
|
|
26506
|
+
const file = ext.loadExternalSources();
|
|
26507
|
+
const match = file.sources.find((s) => s.name === name);
|
|
26508
|
+
if (!match) return { success: false, error: `source "${name}" not registered` };
|
|
26509
|
+
const sourceDir = path40.join(ext.externalRoot(), name);
|
|
26510
|
+
if (fs28.existsSync(sourceDir)) {
|
|
26511
|
+
try {
|
|
26512
|
+
fs28.rmSync(sourceDir, { recursive: true, force: true });
|
|
26513
|
+
} catch (e) {
|
|
26514
|
+
return { success: false, error: `failed to delete ${sourceDir}: ${e?.message || e}` };
|
|
26515
|
+
}
|
|
26516
|
+
}
|
|
26517
|
+
ext.saveExternalSources({
|
|
26518
|
+
schema: 1,
|
|
26519
|
+
sources: file.sources.filter((s) => s.name !== name)
|
|
26520
|
+
});
|
|
26521
|
+
const active = ext.loadProvidersActive();
|
|
26522
|
+
const filteredActive = {};
|
|
26523
|
+
for (const [type, src] of Object.entries(active.active)) {
|
|
26524
|
+
if (src !== name) filteredActive[type] = src;
|
|
26525
|
+
}
|
|
26526
|
+
ext.saveProvidersActive({ schema: 1, active: filteredActive });
|
|
26527
|
+
if (this._ctx.providerLoader) {
|
|
26528
|
+
this._ctx.providerLoader.reload();
|
|
26529
|
+
this._ctx.providerLoader.registerToDetector();
|
|
26530
|
+
}
|
|
26531
|
+
return { success: true, removed: { name } };
|
|
26532
|
+
}
|
|
26533
|
+
/**
|
|
26534
|
+
* List registered external sources + each source's currently installed
|
|
26535
|
+
* providers + the active selection for any conflicting types. Used by
|
|
26536
|
+
* the dashboard's "Sources" tab.
|
|
26537
|
+
*/
|
|
26538
|
+
handleListProviderSources(_args) {
|
|
26539
|
+
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
26540
|
+
const file = ext.loadExternalSources();
|
|
26541
|
+
const inventory = ext.inventoryExternalSources();
|
|
26542
|
+
const active = ext.loadProvidersActive();
|
|
26543
|
+
const sources = file.sources.map((s) => {
|
|
26544
|
+
const inv = inventory.find((e) => e.sourceName === s.name);
|
|
26545
|
+
return {
|
|
26546
|
+
...s,
|
|
26547
|
+
providers: inv?.providers ?? {}
|
|
26548
|
+
};
|
|
26549
|
+
});
|
|
26550
|
+
const conflictMap = /* @__PURE__ */ new Map();
|
|
26551
|
+
for (const inv of inventory) {
|
|
26552
|
+
for (const [category, types] of Object.entries(inv.providers)) {
|
|
26553
|
+
for (const type of types) {
|
|
26554
|
+
const candidates = ext.sourcesProviding(category, type);
|
|
26555
|
+
if (candidates.length > 1 && !conflictMap.has(type)) {
|
|
26556
|
+
conflictMap.set(type, { category, sources: candidates });
|
|
26557
|
+
}
|
|
26558
|
+
}
|
|
26559
|
+
}
|
|
26560
|
+
}
|
|
26561
|
+
const conflicts = [...conflictMap.entries()].map(([type, info]) => ({
|
|
26562
|
+
type,
|
|
26563
|
+
category: info.category,
|
|
26564
|
+
candidates: info.sources,
|
|
26565
|
+
active: active.active[type] ?? null
|
|
26566
|
+
}));
|
|
26567
|
+
return { success: true, sources, conflicts };
|
|
26568
|
+
}
|
|
26569
|
+
/**
|
|
26570
|
+
* Pick which source's copy of a conflicting provider type is active.
|
|
26571
|
+
* Other sources' copies stay on disk but the loader ignores them.
|
|
26572
|
+
*
|
|
26573
|
+
* Args: { type: string, sourceName: string }
|
|
26574
|
+
*/
|
|
26575
|
+
handleSetActiveProviderSource(args) {
|
|
26576
|
+
const type = typeof args?.type === "string" ? args.type.trim() : "";
|
|
26577
|
+
const sourceName = typeof args?.sourceName === "string" ? args.sourceName.trim() : "";
|
|
26578
|
+
if (!type || !sourceName) return { success: false, error: "type and sourceName are required" };
|
|
26579
|
+
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
26580
|
+
const inventory = ext.inventoryExternalSources();
|
|
26581
|
+
const entry = inventory.find((e) => e.sourceName === sourceName);
|
|
26582
|
+
if (!entry) return { success: false, error: `source "${sourceName}" not found` };
|
|
26583
|
+
const provided = Object.values(entry.providers).some((types) => types.includes(type));
|
|
26584
|
+
if (!provided) return { success: false, error: `source "${sourceName}" does not provide type "${type}"` };
|
|
26585
|
+
const active = ext.loadProvidersActive();
|
|
26586
|
+
active.active[type] = sourceName;
|
|
26587
|
+
ext.saveProvidersActive(active);
|
|
26588
|
+
if (this._ctx.providerLoader) {
|
|
26589
|
+
this._ctx.providerLoader.reload();
|
|
26590
|
+
this._ctx.providerLoader.registerToDetector();
|
|
26591
|
+
}
|
|
26592
|
+
return { success: true, type, sourceName };
|
|
26593
|
+
}
|
|
26160
26594
|
// ─── DevServer HTTP proxy helpers ─────────────────
|
|
26161
26595
|
// These bridge WS commands to the DevServer REST API (localhost:19280)
|
|
26162
26596
|
async proxyDevServerPost(args, endpoint) {
|
|
@@ -26252,29 +26686,29 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26252
26686
|
init_provider_cli_adapter();
|
|
26253
26687
|
init_cli_detector();
|
|
26254
26688
|
init_config();
|
|
26255
|
-
import * as
|
|
26256
|
-
import * as
|
|
26689
|
+
import * as os17 from "os";
|
|
26690
|
+
import * as path23 from "path";
|
|
26257
26691
|
import * as crypto5 from "crypto";
|
|
26258
|
-
import { existsSync as
|
|
26692
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync11, writeFileSync as writeFileSync14 } from "fs";
|
|
26259
26693
|
import { execFileSync } from "child_process";
|
|
26260
26694
|
import chalk from "chalk";
|
|
26261
26695
|
|
|
26262
26696
|
// src/providers/cli-provider-instance.ts
|
|
26263
|
-
import * as
|
|
26264
|
-
import * as
|
|
26697
|
+
import * as os16 from "os";
|
|
26698
|
+
import * as path21 from "path";
|
|
26265
26699
|
import * as crypto4 from "crypto";
|
|
26266
|
-
import * as
|
|
26700
|
+
import * as fs12 from "fs";
|
|
26267
26701
|
import { createRequire as createRequire2 } from "module";
|
|
26268
26702
|
|
|
26269
26703
|
// src/providers/spec/route.ts
|
|
26270
26704
|
init_provider_cli_adapter();
|
|
26271
|
-
import * as
|
|
26272
|
-
import * as
|
|
26705
|
+
import * as fs11 from "fs";
|
|
26706
|
+
import * as path20 from "path";
|
|
26273
26707
|
|
|
26274
26708
|
// src/providers/spec/driver.ts
|
|
26275
|
-
import * as
|
|
26276
|
-
import * as
|
|
26277
|
-
import * as
|
|
26709
|
+
import * as fs10 from "fs";
|
|
26710
|
+
import * as os15 from "os";
|
|
26711
|
+
import * as path19 from "path";
|
|
26278
26712
|
|
|
26279
26713
|
// src/providers/spec/adapter.ts
|
|
26280
26714
|
init_pty_transport();
|
|
@@ -26651,7 +27085,7 @@ var SpecDriver = class {
|
|
|
26651
27085
|
}
|
|
26652
27086
|
armSpecWatcher() {
|
|
26653
27087
|
try {
|
|
26654
|
-
this.specWatcher =
|
|
27088
|
+
this.specWatcher = fs10.watch(this.opts.specPath, { persistent: false }, () => {
|
|
26655
27089
|
const res = loadSpec(this.opts.specPath);
|
|
26656
27090
|
if (!res.ok) {
|
|
26657
27091
|
this.emit({ kind: "spec_error", errors: res.errors });
|
|
@@ -26744,7 +27178,7 @@ var SpecDriver = class {
|
|
|
26744
27178
|
}
|
|
26745
27179
|
fireDelegate(d) {
|
|
26746
27180
|
const ev = this.currentEval;
|
|
26747
|
-
const task = d.task_template.replace(/\{node\}/g,
|
|
27181
|
+
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));
|
|
26748
27182
|
this.emit({ kind: "delegate", id: d.id, task });
|
|
26749
27183
|
}
|
|
26750
27184
|
// ────────────────────────────────────────────────────────────────────
|
|
@@ -26813,9 +27247,9 @@ var SpecDriver = class {
|
|
|
26813
27247
|
const ctl = (this.spec.control_bar ?? []).find((c) => c.action.type === "attach_image");
|
|
26814
27248
|
if (!ctl || ctl.action.type !== "attach_image") return;
|
|
26815
27249
|
const ext = guessExt(mime);
|
|
26816
|
-
const tmp =
|
|
27250
|
+
const tmp = path19.join(os15.tmpdir(), `adhdev-attach-${Date.now()}${ext}`);
|
|
26817
27251
|
try {
|
|
26818
|
-
|
|
27252
|
+
fs10.writeFileSync(tmp, Buffer.from(blob, "base64"));
|
|
26819
27253
|
} catch {
|
|
26820
27254
|
return;
|
|
26821
27255
|
}
|
|
@@ -27143,14 +27577,14 @@ init_logger();
|
|
|
27143
27577
|
function createCliAdapter(provider, workingDir, cliArgs, extraEnv, transportFactory) {
|
|
27144
27578
|
const resolvedSpecPath = provider._resolvedSpecPath;
|
|
27145
27579
|
const dir = provider._resolvedProviderDir;
|
|
27146
|
-
let specPath = resolvedSpecPath &&
|
|
27580
|
+
let specPath = resolvedSpecPath && fs11.existsSync(resolvedSpecPath) ? resolvedSpecPath : void 0;
|
|
27147
27581
|
if (!specPath && dir) {
|
|
27148
|
-
const legacy =
|
|
27149
|
-
if (
|
|
27582
|
+
const legacy = path20.join(dir, "spec.json");
|
|
27583
|
+
if (fs11.existsSync(legacy)) specPath = legacy;
|
|
27150
27584
|
}
|
|
27151
27585
|
if (specPath) {
|
|
27152
27586
|
try {
|
|
27153
|
-
LOG.info("spec-route", `[${provider.type}] routing through SpecCliAdapter (${
|
|
27587
|
+
LOG.info("spec-route", `[${provider.type}] routing through SpecCliAdapter (${path20.relative(dir || "", specPath) || specPath})`);
|
|
27154
27588
|
return new SpecCliAdapter(specPath, workingDir, cliArgs, extraEnv, transportFactory);
|
|
27155
27589
|
} catch (err) {
|
|
27156
27590
|
LOG.warn("spec-route", `[${provider.type}] spec invalid, falling back to ProviderCliAdapter: ${err.message}`);
|
|
@@ -27211,7 +27645,7 @@ function filePathFromUri(uri) {
|
|
|
27211
27645
|
return uri.slice("file://".length);
|
|
27212
27646
|
}
|
|
27213
27647
|
}
|
|
27214
|
-
if (
|
|
27648
|
+
if (path21.isAbsolute(uri)) return uri;
|
|
27215
27649
|
return null;
|
|
27216
27650
|
}
|
|
27217
27651
|
function extensionForImageMime(mimeType) {
|
|
@@ -27226,9 +27660,9 @@ function materializeImageDataPart(part, index, dir) {
|
|
|
27226
27660
|
if (!part.data) return null;
|
|
27227
27661
|
const rawData = part.data.includes(",") ? part.data.split(",").pop() || "" : part.data;
|
|
27228
27662
|
if (!rawData) return null;
|
|
27229
|
-
|
|
27230
|
-
const filePath =
|
|
27231
|
-
|
|
27663
|
+
fs12.mkdirSync(dir, { recursive: true });
|
|
27664
|
+
const filePath = path21.join(dir, safeInputImageBasename(index, part.mimeType));
|
|
27665
|
+
fs12.writeFileSync(filePath, Buffer.from(rawData, "base64"));
|
|
27232
27666
|
cleanupStaleMaterializedImages(dir);
|
|
27233
27667
|
return filePath;
|
|
27234
27668
|
}
|
|
@@ -27240,14 +27674,14 @@ function cleanupStaleMaterializedImages(dir) {
|
|
|
27240
27674
|
if (now - lastMaterializedImageCleanupAt < MATERIALIZED_IMAGE_CLEANUP_INTERVAL_MS) return;
|
|
27241
27675
|
lastMaterializedImageCleanupAt = now;
|
|
27242
27676
|
try {
|
|
27243
|
-
const entries =
|
|
27677
|
+
const entries = fs12.readdirSync(dir);
|
|
27244
27678
|
for (const entry of entries) {
|
|
27245
27679
|
if (!entry.startsWith("adhdev-input-image-")) continue;
|
|
27246
|
-
const fullPath =
|
|
27680
|
+
const fullPath = path21.join(dir, entry);
|
|
27247
27681
|
try {
|
|
27248
|
-
const stat2 =
|
|
27682
|
+
const stat2 = fs12.statSync(fullPath);
|
|
27249
27683
|
if (now - stat2.mtimeMs > MATERIALIZED_IMAGE_MAX_AGE_MS) {
|
|
27250
|
-
|
|
27684
|
+
fs12.unlinkSync(fullPath);
|
|
27251
27685
|
}
|
|
27252
27686
|
} catch {
|
|
27253
27687
|
}
|
|
@@ -27266,7 +27700,7 @@ function buildCliStructuredInputPrompt(input, options = {}) {
|
|
|
27266
27700
|
const promptParts = [];
|
|
27267
27701
|
const imageRefs = [];
|
|
27268
27702
|
const resourceRefs = [];
|
|
27269
|
-
const materializeDir = options.materializeDir ||
|
|
27703
|
+
const materializeDir = options.materializeDir || path21.join(os16.tmpdir(), "adhdev-input-media");
|
|
27270
27704
|
input.parts.forEach((part, index) => {
|
|
27271
27705
|
if (part.type === "text" && part.text.trim()) {
|
|
27272
27706
|
promptParts.push(part.text.trim());
|
|
@@ -27333,7 +27767,7 @@ function buildIncrementalHistoryAppendMessages(previousMessages, currentMessages
|
|
|
27333
27767
|
var CachedDatabaseSync = null;
|
|
27334
27768
|
function getDatabaseSync() {
|
|
27335
27769
|
if (CachedDatabaseSync) return CachedDatabaseSync;
|
|
27336
|
-
const requireFn = typeof __require === "function" ? __require : createRequire2(
|
|
27770
|
+
const requireFn = typeof __require === "function" ? __require : createRequire2(path21.join(process.cwd(), "__adhdev_sqlite_loader__.js"));
|
|
27337
27771
|
const sqliteModule = requireFn(`node:${"sqlite"}`);
|
|
27338
27772
|
CachedDatabaseSync = sqliteModule.DatabaseSync;
|
|
27339
27773
|
if (!CachedDatabaseSync) {
|
|
@@ -27487,10 +27921,10 @@ var CliProviderInstance = class {
|
|
|
27487
27921
|
* Replaces the previously duplicated probeOpenCode/Codex/Goose functions.
|
|
27488
27922
|
*/
|
|
27489
27923
|
probeSessionIdFromConfig(probe) {
|
|
27490
|
-
const resolvedDbPath = probe.dbPath.replace(/^~/,
|
|
27924
|
+
const resolvedDbPath = probe.dbPath.replace(/^~/, os16.homedir());
|
|
27491
27925
|
const now = Date.now();
|
|
27492
27926
|
if (this.cachedSqliteDbMissingUntil > now) return null;
|
|
27493
|
-
if (!
|
|
27927
|
+
if (!fs12.existsSync(resolvedDbPath)) {
|
|
27494
27928
|
this.cachedSqliteDbMissingUntil = now + 1e4;
|
|
27495
27929
|
return null;
|
|
27496
27930
|
}
|
|
@@ -27682,7 +28116,7 @@ var CliProviderInstance = class {
|
|
|
27682
28116
|
};
|
|
27683
28117
|
}
|
|
27684
28118
|
getSessionModalState(sessionId) {
|
|
27685
|
-
const adapterStatus = this.adapter.getStatus({ allowParse:
|
|
28119
|
+
const adapterStatus = this.adapter.getStatus({ allowParse: true });
|
|
27686
28120
|
const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
|
|
27687
28121
|
const visibleStatus = autoApproveActive ? "generating" : adapterStatus.status;
|
|
27688
28122
|
const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
|
|
@@ -28592,7 +29026,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
28592
29026
|
};
|
|
28593
29027
|
addDir(this.workingDir);
|
|
28594
29028
|
try {
|
|
28595
|
-
addDir(
|
|
29029
|
+
addDir(fs12.realpathSync.native(this.workingDir));
|
|
28596
29030
|
} catch {
|
|
28597
29031
|
}
|
|
28598
29032
|
return Array.from(dirs);
|
|
@@ -28629,7 +29063,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
28629
29063
|
};
|
|
28630
29064
|
|
|
28631
29065
|
// src/providers/acp-provider-instance.ts
|
|
28632
|
-
import * as
|
|
29066
|
+
import * as path22 from "path";
|
|
28633
29067
|
import { Readable, Writable } from "stream";
|
|
28634
29068
|
import { spawn } from "child_process";
|
|
28635
29069
|
import {
|
|
@@ -29409,7 +29843,7 @@ var AcpProviderInstance = class {
|
|
|
29409
29843
|
return b.uri ? {
|
|
29410
29844
|
type: "resource_link",
|
|
29411
29845
|
uri: b.uri,
|
|
29412
|
-
name:
|
|
29846
|
+
name: path22.basename(b.uri),
|
|
29413
29847
|
mimeType: b.mimeType,
|
|
29414
29848
|
...b.transcript ? { description: b.transcript } : {}
|
|
29415
29849
|
} : { type: "text", text: b.transcript || `[Video attachment: ${b.mimeType}]` };
|
|
@@ -29867,17 +30301,17 @@ function shouldRestoreHostedRuntime(record, managerTag) {
|
|
|
29867
30301
|
// src/commands/cli-manager.ts
|
|
29868
30302
|
function isExplicitCommand(command) {
|
|
29869
30303
|
const trimmed = command.trim();
|
|
29870
|
-
return
|
|
30304
|
+
return path23.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
|
|
29871
30305
|
}
|
|
29872
30306
|
function expandExecutable(command) {
|
|
29873
30307
|
const trimmed = command.trim();
|
|
29874
|
-
return trimmed.startsWith("~") ?
|
|
30308
|
+
return trimmed.startsWith("~") ? path23.join(os17.homedir(), trimmed.slice(1)) : trimmed;
|
|
29875
30309
|
}
|
|
29876
30310
|
function commandExists(command) {
|
|
29877
30311
|
const trimmed = command.trim();
|
|
29878
30312
|
if (!trimmed) return false;
|
|
29879
30313
|
if (isExplicitCommand(trimmed)) {
|
|
29880
|
-
return
|
|
30314
|
+
return existsSync21(expandExecutable(trimmed));
|
|
29881
30315
|
}
|
|
29882
30316
|
try {
|
|
29883
30317
|
execFileSync(process.platform === "win32" ? "where" : "which", [trimmed], {
|
|
@@ -29998,11 +30432,11 @@ function hasCliArg(args, flag) {
|
|
|
29998
30432
|
return args.some((arg) => arg === flag || arg.startsWith(`${flag}=`));
|
|
29999
30433
|
}
|
|
30000
30434
|
function ensureEmptyDelegatedMcpConfig(workspace) {
|
|
30001
|
-
const baseDir =
|
|
30002
|
-
|
|
30003
|
-
const workspaceHash = crypto5.createHash("sha256").update(
|
|
30004
|
-
const filePath =
|
|
30005
|
-
|
|
30435
|
+
const baseDir = path23.join(os17.tmpdir(), "adhdev-delegated-agent-empty-mcp");
|
|
30436
|
+
mkdirSync11(baseDir, { recursive: true });
|
|
30437
|
+
const workspaceHash = crypto5.createHash("sha256").update(path23.resolve(workspace || os17.tmpdir())).digest("hex").slice(0, 16);
|
|
30438
|
+
const filePath = path23.join(baseDir, `${workspaceHash}.json`);
|
|
30439
|
+
writeFileSync14(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
|
|
30006
30440
|
return filePath;
|
|
30007
30441
|
}
|
|
30008
30442
|
function buildCoordinatorDelegatedCliLaunchOptions(input) {
|
|
@@ -30295,7 +30729,7 @@ var DaemonCliManager = class {
|
|
|
30295
30729
|
async startSession(cliType, workingDir, cliArgs, initialModel, options) {
|
|
30296
30730
|
const trimmed = (workingDir || "").trim();
|
|
30297
30731
|
if (!trimmed) throw new Error("working directory required");
|
|
30298
|
-
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/,
|
|
30732
|
+
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os17.homedir()) : path23.resolve(trimmed);
|
|
30299
30733
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
30300
30734
|
const rawProvider = this.providerLoader.getByAlias(cliType);
|
|
30301
30735
|
const provider = rawProvider ? this.providerLoader.resolve(normalizedType) || rawProvider : void 0;
|
|
@@ -30680,6 +31114,20 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
30680
31114
|
cliArgs: args?.cliArgs,
|
|
30681
31115
|
env: args?.env
|
|
30682
31116
|
}) : null;
|
|
31117
|
+
const provLookup = this.providerLoader.getMeta(this.providerLoader.resolveAlias(cliType));
|
|
31118
|
+
const provTrust = provLookup?._sourceTrust;
|
|
31119
|
+
if (provTrust === "external-untrusted" && args?.confirmExternalUntrusted !== true) {
|
|
31120
|
+
return {
|
|
31121
|
+
success: false,
|
|
31122
|
+
error: "untrusted_external_provider",
|
|
31123
|
+
provider: {
|
|
31124
|
+
type: provLookup?.type ?? cliType,
|
|
31125
|
+
sourceName: provLookup?._sourceName ?? null,
|
|
31126
|
+
trust: provTrust
|
|
31127
|
+
},
|
|
31128
|
+
hint: "Resend launch_cli with confirmExternalUntrusted=true after the user explicitly approves running JavaScript from this 3rd-party source."
|
|
31129
|
+
};
|
|
31130
|
+
}
|
|
30683
31131
|
const started = await this.startSession(
|
|
30684
31132
|
cliType,
|
|
30685
31133
|
dir,
|
|
@@ -30866,13 +31314,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
30866
31314
|
// src/launch.ts
|
|
30867
31315
|
import { exec as exec4, spawn as spawn2 } from "child_process";
|
|
30868
31316
|
import * as net from "net";
|
|
30869
|
-
import * as
|
|
30870
|
-
import * as
|
|
31317
|
+
import * as os23 from "os";
|
|
31318
|
+
import * as path32 from "path";
|
|
30871
31319
|
|
|
30872
31320
|
// src/providers/provider-loader.ts
|
|
30873
|
-
import * as
|
|
30874
|
-
import * as
|
|
30875
|
-
import * as
|
|
31321
|
+
import * as fs19 from "fs";
|
|
31322
|
+
import * as path31 from "path";
|
|
31323
|
+
import * as os22 from "os";
|
|
30876
31324
|
import * as chokidar from "chokidar";
|
|
30877
31325
|
init_logger();
|
|
30878
31326
|
|
|
@@ -31206,6 +31654,7 @@ function validateControl(control, errors) {
|
|
|
31206
31654
|
}
|
|
31207
31655
|
|
|
31208
31656
|
// src/providers/provider-loader.ts
|
|
31657
|
+
init_external_sources();
|
|
31209
31658
|
function registerProviderScriptRootSafely(root) {
|
|
31210
31659
|
if (!root || typeof root !== "string") return;
|
|
31211
31660
|
try {
|
|
@@ -31245,9 +31694,9 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31245
31694
|
static siblingStderrLogged = /* @__PURE__ */ new Set();
|
|
31246
31695
|
static looksLikeProviderRoot(candidate) {
|
|
31247
31696
|
try {
|
|
31248
|
-
if (!
|
|
31697
|
+
if (!fs19.existsSync(candidate) || !fs19.statSync(candidate).isDirectory()) return false;
|
|
31249
31698
|
return ["ide", "extension", "cli", "acp"].some(
|
|
31250
|
-
(category) =>
|
|
31699
|
+
(category) => fs19.existsSync(path31.join(candidate, category))
|
|
31251
31700
|
);
|
|
31252
31701
|
} catch {
|
|
31253
31702
|
return false;
|
|
@@ -31255,20 +31704,20 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31255
31704
|
}
|
|
31256
31705
|
static hasProviderRootMarker(candidate) {
|
|
31257
31706
|
try {
|
|
31258
|
-
return
|
|
31707
|
+
return fs19.existsSync(path31.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
|
|
31259
31708
|
} catch {
|
|
31260
31709
|
return false;
|
|
31261
31710
|
}
|
|
31262
31711
|
}
|
|
31263
31712
|
detectDefaultUserDir() {
|
|
31264
|
-
const fallback =
|
|
31713
|
+
const fallback = path31.join(os22.homedir(), ".adhdev", "providers");
|
|
31265
31714
|
const envOptIn = process.env[_ProviderLoader.SIBLING_ENV_VAR] === "1";
|
|
31266
31715
|
const visited = /* @__PURE__ */ new Set();
|
|
31267
31716
|
for (const start of this.probeStarts) {
|
|
31268
|
-
let current =
|
|
31717
|
+
let current = path31.resolve(start);
|
|
31269
31718
|
while (!visited.has(current)) {
|
|
31270
31719
|
visited.add(current);
|
|
31271
|
-
const siblingCandidate =
|
|
31720
|
+
const siblingCandidate = path31.join(path31.dirname(current), _ProviderLoader.REPO_PROVIDER_DIRNAME);
|
|
31272
31721
|
if (_ProviderLoader.looksLikeProviderRoot(siblingCandidate)) {
|
|
31273
31722
|
const hasMarker = _ProviderLoader.hasProviderRootMarker(siblingCandidate);
|
|
31274
31723
|
if (envOptIn || hasMarker) {
|
|
@@ -31290,7 +31739,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31290
31739
|
return { path: siblingCandidate, source };
|
|
31291
31740
|
}
|
|
31292
31741
|
}
|
|
31293
|
-
const parent =
|
|
31742
|
+
const parent = path31.dirname(current);
|
|
31294
31743
|
if (parent === current) break;
|
|
31295
31744
|
current = parent;
|
|
31296
31745
|
}
|
|
@@ -31300,17 +31749,34 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31300
31749
|
constructor(options) {
|
|
31301
31750
|
this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
|
|
31302
31751
|
this.probeStarts = options?.probeStarts ?? [process.cwd(), __dirname];
|
|
31303
|
-
this.defaultProvidersDir =
|
|
31752
|
+
this.defaultProvidersDir = path31.join(os22.homedir(), ".adhdev", "providers");
|
|
31304
31753
|
const detected = this.detectDefaultUserDir();
|
|
31305
31754
|
this.userDir = detected.path;
|
|
31306
31755
|
this.userDirSource = detected.source;
|
|
31307
|
-
this.upstreamDir =
|
|
31756
|
+
this.upstreamDir = path31.join(this.defaultProvidersDir, ".upstream");
|
|
31308
31757
|
this.disableUpstream = false;
|
|
31309
31758
|
this.applySourceConfig({
|
|
31310
31759
|
userDir: options?.userDir,
|
|
31311
31760
|
sourceMode: options?.sourceMode,
|
|
31312
31761
|
disableUpstream: options?.disableUpstream
|
|
31313
31762
|
});
|
|
31763
|
+
this.migrateMarketplaceDirToExternal();
|
|
31764
|
+
}
|
|
31765
|
+
migrateMarketplaceDirToExternal() {
|
|
31766
|
+
try {
|
|
31767
|
+
const home = os22.homedir();
|
|
31768
|
+
const oldDir = path31.join(home, ".adhdev", "marketplace");
|
|
31769
|
+
const newDir = path31.join(home, ".adhdev", "external");
|
|
31770
|
+
if (!fs19.existsSync(oldDir)) return;
|
|
31771
|
+
if (fs19.existsSync(newDir)) {
|
|
31772
|
+
this.log(`Migration skipped: both ~/.adhdev/marketplace and ~/.adhdev/external exist (marketplace dir is now inert and can be removed manually).`);
|
|
31773
|
+
return;
|
|
31774
|
+
}
|
|
31775
|
+
fs19.renameSync(oldDir, newDir);
|
|
31776
|
+
this.log(`Migrated ~/.adhdev/marketplace \u2192 ~/.adhdev/external (one-time rename after provider source-layer cleanup).`);
|
|
31777
|
+
} catch (e) {
|
|
31778
|
+
this.log(`Marketplace\u2192external migration failed: ${e?.message || e}`);
|
|
31779
|
+
}
|
|
31314
31780
|
}
|
|
31315
31781
|
log(msg) {
|
|
31316
31782
|
this.logFn(`[ProviderLoader] ${msg}`);
|
|
@@ -31336,8 +31802,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31336
31802
|
* Highest-priority editable overrides come first.
|
|
31337
31803
|
*/
|
|
31338
31804
|
getProviderRoots() {
|
|
31339
|
-
const
|
|
31340
|
-
return [this.userDir,
|
|
31805
|
+
const externalDir = path31.join(os22.homedir(), ".adhdev", "external");
|
|
31806
|
+
return [this.userDir, externalDir, this.upstreamDir];
|
|
31341
31807
|
}
|
|
31342
31808
|
getSourceConfig() {
|
|
31343
31809
|
return {
|
|
@@ -31364,7 +31830,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31364
31830
|
this.userDir = detected.path;
|
|
31365
31831
|
this.userDirSource = detected.source;
|
|
31366
31832
|
}
|
|
31367
|
-
this.upstreamDir =
|
|
31833
|
+
this.upstreamDir = path31.join(this.defaultProvidersDir, ".upstream");
|
|
31368
31834
|
this.disableUpstream = this.sourceMode === "no-upstream";
|
|
31369
31835
|
if (this.explicitProviderDir) {
|
|
31370
31836
|
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
@@ -31378,7 +31844,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31378
31844
|
* Canonical provider directory shape for a given root.
|
|
31379
31845
|
*/
|
|
31380
31846
|
getProviderDir(root, category, type) {
|
|
31381
|
-
return
|
|
31847
|
+
return path31.join(root, category, type);
|
|
31382
31848
|
}
|
|
31383
31849
|
/**
|
|
31384
31850
|
* Canonical user override directory for a provider.
|
|
@@ -31405,20 +31871,23 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31405
31871
|
resolveProviderFile(type, ...segments) {
|
|
31406
31872
|
const dir = this.findProviderDirInternal(type);
|
|
31407
31873
|
if (!dir) return null;
|
|
31408
|
-
return
|
|
31874
|
+
return path31.join(dir, ...segments);
|
|
31409
31875
|
}
|
|
31410
31876
|
/**
|
|
31411
31877
|
* Load all providers (3-tier priority)
|
|
31412
|
-
* 1.
|
|
31413
|
-
* 2.
|
|
31414
|
-
*
|
|
31878
|
+
* 1. ~/.adhdev/providers/.upstream/ — official git, auto-synced
|
|
31879
|
+
* 2. ~/.adhdev/external/ — 3rd-party git sources, user-added,
|
|
31880
|
+
* bundled providers may include arbitrary JS (untrusted by default)
|
|
31881
|
+
* 3. ~/.adhdev/providers/ (excluding .upstream) — user-authored customs,
|
|
31882
|
+
* always wins
|
|
31883
|
+
* Highest priority listed last (overwrites earlier loads).
|
|
31415
31884
|
* If .upstream/ is empty, call fetchLatest() before loadAll().
|
|
31416
31885
|
*/
|
|
31417
31886
|
loadAll() {
|
|
31418
31887
|
this.providers.clear();
|
|
31419
31888
|
this.providerAvailability.clear();
|
|
31420
31889
|
let upstreamCount = 0;
|
|
31421
|
-
if (!this.disableUpstream &&
|
|
31890
|
+
if (!this.disableUpstream && fs19.existsSync(this.upstreamDir)) {
|
|
31422
31891
|
upstreamCount = this.loadDir(this.upstreamDir);
|
|
31423
31892
|
if (upstreamCount > 0) {
|
|
31424
31893
|
this.log(`Loaded ${upstreamCount} upstream providers (auto-updated)`);
|
|
@@ -31426,14 +31895,60 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31426
31895
|
} else if (this.disableUpstream) {
|
|
31427
31896
|
this.log("Upstream loading disabled (sourceMode=no-upstream)");
|
|
31428
31897
|
}
|
|
31429
|
-
const
|
|
31430
|
-
if (
|
|
31431
|
-
const
|
|
31432
|
-
|
|
31433
|
-
|
|
31898
|
+
const externalDir = path31.join(os22.homedir(), ".adhdev", "external");
|
|
31899
|
+
if (fs19.existsSync(externalDir)) {
|
|
31900
|
+
const rootEntries = (() => {
|
|
31901
|
+
try {
|
|
31902
|
+
return fs19.readdirSync(externalDir, { withFileTypes: true });
|
|
31903
|
+
} catch {
|
|
31904
|
+
return [];
|
|
31905
|
+
}
|
|
31906
|
+
})();
|
|
31907
|
+
const KNOWN_CATEGORIES = /* @__PURE__ */ new Set(["cli", "ide", "extension", "acp"]);
|
|
31908
|
+
const looksLegacy = rootEntries.some((e) => e.isDirectory() && KNOWN_CATEGORIES.has(e.name));
|
|
31909
|
+
if (looksLegacy) {
|
|
31910
|
+
const externalCount = this.loadDir(externalDir);
|
|
31911
|
+
if (externalCount > 0) {
|
|
31912
|
+
this.log(`Loaded ${externalCount} external providers (legacy unnamed source)`);
|
|
31913
|
+
}
|
|
31914
|
+
} else {
|
|
31915
|
+
const activeFile = loadProvidersActive();
|
|
31916
|
+
let totalLoaded = 0;
|
|
31917
|
+
const ambiguousTypes = [];
|
|
31918
|
+
for (const sourceEntry of rootEntries) {
|
|
31919
|
+
if (!sourceEntry.isDirectory()) continue;
|
|
31920
|
+
const sourceDir = path31.join(externalDir, sourceEntry.name);
|
|
31921
|
+
const sourceLoaded = this.loadDir(sourceDir);
|
|
31922
|
+
if (sourceLoaded > 0) {
|
|
31923
|
+
totalLoaded += sourceLoaded;
|
|
31924
|
+
this.log(`Loaded ${sourceLoaded} providers from external source "${sourceEntry.name}"`);
|
|
31925
|
+
}
|
|
31926
|
+
}
|
|
31927
|
+
for (const [type] of this.providers) {
|
|
31928
|
+
const prov = this.providers.get(type);
|
|
31929
|
+
if (!prov) continue;
|
|
31930
|
+
const resolved = resolveActiveSource(prov.category, type, activeFile);
|
|
31931
|
+
if (resolved.candidates.length <= 1) continue;
|
|
31932
|
+
if (resolved.ambiguous) {
|
|
31933
|
+
ambiguousTypes.push({ type, chosen: resolved.source ?? "?", candidates: resolved.candidates });
|
|
31934
|
+
}
|
|
31935
|
+
if (resolved.source && resolved.source !== "?") {
|
|
31936
|
+
const sourceDir = path31.join(externalDir, resolved.source);
|
|
31937
|
+
const reloadCount = this.loadDir(sourceDir);
|
|
31938
|
+
if (reloadCount === 0) {
|
|
31939
|
+
this.log(`Active source "${resolved.source}" no longer provides ${type}`);
|
|
31940
|
+
}
|
|
31941
|
+
}
|
|
31942
|
+
}
|
|
31943
|
+
if (totalLoaded > 0) {
|
|
31944
|
+
this.log(`Loaded ${totalLoaded} external providers (3rd-party sources)`);
|
|
31945
|
+
}
|
|
31946
|
+
for (const a of ambiguousTypes) {
|
|
31947
|
+
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.`);
|
|
31948
|
+
}
|
|
31434
31949
|
}
|
|
31435
31950
|
}
|
|
31436
|
-
if (
|
|
31951
|
+
if (fs19.existsSync(this.userDir)) {
|
|
31437
31952
|
const userCount = this.loadDir(this.userDir, [".upstream"]);
|
|
31438
31953
|
if (userCount > 0) {
|
|
31439
31954
|
this.log(`Loaded ${userCount} user custom providers (never auto-updated)`);
|
|
@@ -31448,10 +31963,10 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31448
31963
|
* Check if upstream directory exists and has providers.
|
|
31449
31964
|
*/
|
|
31450
31965
|
hasUpstream() {
|
|
31451
|
-
if (!
|
|
31966
|
+
if (!fs19.existsSync(this.upstreamDir)) return false;
|
|
31452
31967
|
try {
|
|
31453
|
-
return
|
|
31454
|
-
(d) =>
|
|
31968
|
+
return fs19.readdirSync(this.upstreamDir).some(
|
|
31969
|
+
(d) => fs19.statSync(path31.join(this.upstreamDir, d)).isDirectory()
|
|
31455
31970
|
);
|
|
31456
31971
|
} catch {
|
|
31457
31972
|
return false;
|
|
@@ -31949,8 +32464,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31949
32464
|
resolved._resolvedScriptDir = entry.scriptDir;
|
|
31950
32465
|
resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
|
|
31951
32466
|
if (providerDir) {
|
|
31952
|
-
const fullDir =
|
|
31953
|
-
resolved._resolvedScriptsPath =
|
|
32467
|
+
const fullDir = path31.join(providerDir, entry.scriptDir);
|
|
32468
|
+
resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
|
|
31954
32469
|
}
|
|
31955
32470
|
matched = true;
|
|
31956
32471
|
}
|
|
@@ -31968,8 +32483,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31968
32483
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
31969
32484
|
resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
|
|
31970
32485
|
if (providerDir) {
|
|
31971
|
-
const fullDir =
|
|
31972
|
-
resolved._resolvedScriptsPath =
|
|
32486
|
+
const fullDir = path31.join(providerDir, base.defaultScriptDir);
|
|
32487
|
+
resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
|
|
31973
32488
|
}
|
|
31974
32489
|
}
|
|
31975
32490
|
resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
|
|
@@ -31986,8 +32501,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31986
32501
|
resolved._resolvedScriptDir = dirOverride;
|
|
31987
32502
|
resolved._resolvedScriptsSource = `versions:${range}`;
|
|
31988
32503
|
if (providerDir) {
|
|
31989
|
-
const fullDir =
|
|
31990
|
-
resolved._resolvedScriptsPath =
|
|
32504
|
+
const fullDir = path31.join(providerDir, dirOverride);
|
|
32505
|
+
resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
|
|
31991
32506
|
}
|
|
31992
32507
|
}
|
|
31993
32508
|
} else if (override.scripts) {
|
|
@@ -32003,8 +32518,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32003
32518
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
32004
32519
|
resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
|
|
32005
32520
|
if (providerDir) {
|
|
32006
|
-
const fullDir =
|
|
32007
|
-
resolved._resolvedScriptsPath =
|
|
32521
|
+
const fullDir = path31.join(providerDir, base.defaultScriptDir);
|
|
32522
|
+
resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
|
|
32008
32523
|
}
|
|
32009
32524
|
}
|
|
32010
32525
|
}
|
|
@@ -32021,13 +32536,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32021
32536
|
if (providerDir2) {
|
|
32022
32537
|
for (const [scriptName, override] of Object.entries(base.overrides)) {
|
|
32023
32538
|
if (!override || typeof override.path !== "string") continue;
|
|
32024
|
-
const fullPath =
|
|
32025
|
-
if (!
|
|
32539
|
+
const fullPath = path31.join(providerDir2, override.path);
|
|
32540
|
+
if (!fs19.existsSync(fullPath)) {
|
|
32026
32541
|
this.log(` [overrides] ${base.type}: ${scriptName} path not found: ${fullPath}`);
|
|
32027
32542
|
continue;
|
|
32028
32543
|
}
|
|
32029
32544
|
try {
|
|
32030
|
-
registerProviderScriptRootSafely(
|
|
32545
|
+
registerProviderScriptRootSafely(path31.dirname(path31.dirname(providerDir2)));
|
|
32031
32546
|
delete __require.cache[__require.resolve(fullPath)];
|
|
32032
32547
|
const fn = __require(fullPath);
|
|
32033
32548
|
const target = typeof fn === "function" ? fn : fn && fn[scriptName];
|
|
@@ -32052,19 +32567,19 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32052
32567
|
}
|
|
32053
32568
|
if (providerDir) {
|
|
32054
32569
|
try {
|
|
32055
|
-
const
|
|
32056
|
-
const
|
|
32570
|
+
const fs28 = __require("fs");
|
|
32571
|
+
const path40 = __require("path");
|
|
32057
32572
|
const candidates = [];
|
|
32058
32573
|
if (Array.isArray(base.compatibility)) {
|
|
32059
32574
|
for (const entry of base.compatibility) {
|
|
32060
32575
|
if (typeof entry?.spec !== "string") continue;
|
|
32061
32576
|
const matches = !entry.ideVersion || currentVersion && this.matchesVersion(currentVersion, entry.ideVersion) || !currentVersion;
|
|
32062
|
-
if (matches) candidates.push(
|
|
32577
|
+
if (matches) candidates.push(path40.join(providerDir, entry.spec));
|
|
32063
32578
|
}
|
|
32064
32579
|
}
|
|
32065
|
-
candidates.push(
|
|
32066
|
-
candidates.push(
|
|
32067
|
-
const specPath = candidates.find((p) =>
|
|
32580
|
+
candidates.push(path40.join(providerDir, "specs", "default.json"));
|
|
32581
|
+
candidates.push(path40.join(providerDir, "spec.json"));
|
|
32582
|
+
const specPath = candidates.find((p) => fs28.existsSync(p));
|
|
32068
32583
|
if (specPath) {
|
|
32069
32584
|
resolved._resolvedSpecPath = specPath;
|
|
32070
32585
|
const { loadSpec: loadSpec2 } = (init_loader(), __toCommonJS(loader_exports));
|
|
@@ -32093,10 +32608,10 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32093
32608
|
format = `spec-${nh.source.kind}`;
|
|
32094
32609
|
reader = (input) => executeNativeHistory2(nh, input);
|
|
32095
32610
|
} else if (nh.override_path) {
|
|
32096
|
-
const overrideFile =
|
|
32097
|
-
if (
|
|
32611
|
+
const overrideFile = path40.resolve(providerDir, nh.override_path);
|
|
32612
|
+
if (fs28.existsSync(overrideFile)) {
|
|
32098
32613
|
try {
|
|
32099
|
-
registerProviderScriptRootSafely(
|
|
32614
|
+
registerProviderScriptRootSafely(path40.dirname(path40.dirname(providerDir)));
|
|
32100
32615
|
delete __require.cache[__require.resolve(overrideFile)];
|
|
32101
32616
|
const mod = __require(overrideFile);
|
|
32102
32617
|
const fn = typeof mod === "function" ? mod : mod && typeof mod.default === "function" ? mod.default : null;
|
|
@@ -32140,16 +32655,16 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32140
32655
|
this.debugLog(`[loadScriptsFromDir] ${type}: providerDir not found`);
|
|
32141
32656
|
return null;
|
|
32142
32657
|
}
|
|
32143
|
-
const dir =
|
|
32144
|
-
if (!
|
|
32658
|
+
const dir = path31.join(providerDir, scriptDir);
|
|
32659
|
+
if (!fs19.existsSync(dir)) {
|
|
32145
32660
|
this.debugLog(`[loadScriptsFromDir] ${type}: dir not found: ${dir}`);
|
|
32146
32661
|
return null;
|
|
32147
32662
|
}
|
|
32148
|
-
registerProviderScriptRootSafely(
|
|
32663
|
+
registerProviderScriptRootSafely(path31.dirname(path31.dirname(providerDir)));
|
|
32149
32664
|
const cached = this.scriptsCache.get(dir);
|
|
32150
32665
|
if (cached) return cached;
|
|
32151
|
-
const scriptsJs =
|
|
32152
|
-
if (
|
|
32666
|
+
const scriptsJs = path31.join(dir, "scripts.js");
|
|
32667
|
+
if (fs19.existsSync(scriptsJs)) {
|
|
32153
32668
|
try {
|
|
32154
32669
|
delete __require.cache[__require.resolve(scriptsJs)];
|
|
32155
32670
|
const loaded = __require(scriptsJs);
|
|
@@ -32170,9 +32685,9 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32170
32685
|
watch() {
|
|
32171
32686
|
this.stopWatch();
|
|
32172
32687
|
const watchDir = (dir) => {
|
|
32173
|
-
if (!
|
|
32688
|
+
if (!fs19.existsSync(dir)) {
|
|
32174
32689
|
try {
|
|
32175
|
-
|
|
32690
|
+
fs19.mkdirSync(dir, { recursive: true });
|
|
32176
32691
|
} catch {
|
|
32177
32692
|
return;
|
|
32178
32693
|
}
|
|
@@ -32193,7 +32708,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32193
32708
|
if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
|
|
32194
32709
|
if (reloadTimer) clearTimeout(reloadTimer);
|
|
32195
32710
|
reloadTimer = setTimeout(() => {
|
|
32196
|
-
this.log(`File changed: ${
|
|
32711
|
+
this.log(`File changed: ${path31.basename(filePath)}, reloading...`);
|
|
32197
32712
|
this.reload();
|
|
32198
32713
|
}, 300);
|
|
32199
32714
|
}
|
|
@@ -32261,11 +32776,11 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32261
32776
|
}
|
|
32262
32777
|
this.log(`Registry sync starting (${_ProviderLoader.REGISTRY_BASE_URL})...`);
|
|
32263
32778
|
const https = __require("https");
|
|
32264
|
-
const regMetaPath =
|
|
32779
|
+
const regMetaPath = path31.join(this.upstreamDir, _ProviderLoader.REGISTRY_META_FILE);
|
|
32265
32780
|
let cachedChecksums = {};
|
|
32266
32781
|
try {
|
|
32267
|
-
if (
|
|
32268
|
-
cachedChecksums = JSON.parse(
|
|
32782
|
+
if (fs19.existsSync(regMetaPath)) {
|
|
32783
|
+
cachedChecksums = JSON.parse(fs19.readFileSync(regMetaPath, "utf-8")).checksums ?? {};
|
|
32269
32784
|
}
|
|
32270
32785
|
} catch {
|
|
32271
32786
|
}
|
|
@@ -32319,15 +32834,15 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32319
32834
|
this.log(`\u26A0 Registry checksum mismatch for ${type}@${version} \u2014 skipping`);
|
|
32320
32835
|
continue;
|
|
32321
32836
|
}
|
|
32322
|
-
const providerDir =
|
|
32323
|
-
|
|
32324
|
-
|
|
32837
|
+
const providerDir = path31.join(this.upstreamDir, category, type);
|
|
32838
|
+
fs19.mkdirSync(providerDir, { recursive: true });
|
|
32839
|
+
fs19.writeFileSync(path31.join(providerDir, "provider.json"), manifestBody, "utf-8");
|
|
32325
32840
|
cachedChecksums[cacheKey] = checksum;
|
|
32326
32841
|
updatedCount++;
|
|
32327
32842
|
this.log(`\u2713 Registry updated: ${category}/${type}@${version}`);
|
|
32328
32843
|
}
|
|
32329
|
-
|
|
32330
|
-
|
|
32844
|
+
fs19.mkdirSync(this.upstreamDir, { recursive: true });
|
|
32845
|
+
fs19.writeFileSync(regMetaPath, JSON.stringify({
|
|
32331
32846
|
checksums: cachedChecksums,
|
|
32332
32847
|
syncedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
32333
32848
|
providerCount: list.providers.length
|
|
@@ -32348,12 +32863,12 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32348
32863
|
const { exec: exec7 } = __require("child_process");
|
|
32349
32864
|
const { promisify: promisify7 } = __require("util");
|
|
32350
32865
|
const execAsync5 = promisify7(exec7);
|
|
32351
|
-
const metaPath =
|
|
32866
|
+
const metaPath = path31.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
32352
32867
|
let prevEtag = "";
|
|
32353
32868
|
let prevTimestamp = 0;
|
|
32354
32869
|
try {
|
|
32355
|
-
if (
|
|
32356
|
-
const meta = JSON.parse(
|
|
32870
|
+
if (fs19.existsSync(metaPath)) {
|
|
32871
|
+
const meta = JSON.parse(fs19.readFileSync(metaPath, "utf-8"));
|
|
32357
32872
|
prevEtag = meta.etag || "";
|
|
32358
32873
|
prevTimestamp = meta.timestamp || 0;
|
|
32359
32874
|
}
|
|
@@ -32408,39 +32923,39 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32408
32923
|
return { updated: false };
|
|
32409
32924
|
}
|
|
32410
32925
|
this.log("Downloading latest providers from GitHub...");
|
|
32411
|
-
const tmpTar =
|
|
32412
|
-
const tmpExtract =
|
|
32926
|
+
const tmpTar = path31.join(os22.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
|
|
32927
|
+
const tmpExtract = path31.join(os22.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
|
|
32413
32928
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
32414
|
-
|
|
32929
|
+
fs19.mkdirSync(tmpExtract, { recursive: true });
|
|
32415
32930
|
await execAsync5(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
32416
|
-
const extracted =
|
|
32931
|
+
const extracted = fs19.readdirSync(tmpExtract);
|
|
32417
32932
|
const rootDir = extracted.find(
|
|
32418
|
-
(d) =>
|
|
32933
|
+
(d) => fs19.statSync(path31.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
|
|
32419
32934
|
);
|
|
32420
32935
|
if (!rootDir) throw new Error("Unexpected tarball structure");
|
|
32421
|
-
const sourceDir =
|
|
32936
|
+
const sourceDir = path31.join(tmpExtract, rootDir);
|
|
32422
32937
|
const backupDir = this.upstreamDir + ".bak";
|
|
32423
|
-
if (
|
|
32424
|
-
if (
|
|
32425
|
-
|
|
32938
|
+
if (fs19.existsSync(this.upstreamDir)) {
|
|
32939
|
+
if (fs19.existsSync(backupDir)) fs19.rmSync(backupDir, { recursive: true, force: true });
|
|
32940
|
+
fs19.renameSync(this.upstreamDir, backupDir);
|
|
32426
32941
|
}
|
|
32427
32942
|
try {
|
|
32428
32943
|
this.copyDirRecursive(sourceDir, this.upstreamDir);
|
|
32429
32944
|
this.writeMeta(metaPath, etag || `ts-${Date.now()}`, Date.now());
|
|
32430
|
-
if (
|
|
32945
|
+
if (fs19.existsSync(backupDir)) fs19.rmSync(backupDir, { recursive: true, force: true });
|
|
32431
32946
|
} catch (e) {
|
|
32432
|
-
if (
|
|
32433
|
-
if (
|
|
32434
|
-
|
|
32947
|
+
if (fs19.existsSync(backupDir)) {
|
|
32948
|
+
if (fs19.existsSync(this.upstreamDir)) fs19.rmSync(this.upstreamDir, { recursive: true, force: true });
|
|
32949
|
+
fs19.renameSync(backupDir, this.upstreamDir);
|
|
32435
32950
|
}
|
|
32436
32951
|
throw e;
|
|
32437
32952
|
}
|
|
32438
32953
|
try {
|
|
32439
|
-
|
|
32954
|
+
fs19.rmSync(tmpTar, { force: true });
|
|
32440
32955
|
} catch {
|
|
32441
32956
|
}
|
|
32442
32957
|
try {
|
|
32443
|
-
|
|
32958
|
+
fs19.rmSync(tmpExtract, { recursive: true, force: true });
|
|
32444
32959
|
} catch {
|
|
32445
32960
|
}
|
|
32446
32961
|
const upstreamCount = this.countProviders(this.upstreamDir);
|
|
@@ -32472,7 +32987,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32472
32987
|
reject(new Error(`HTTP ${res.statusCode}`));
|
|
32473
32988
|
return;
|
|
32474
32989
|
}
|
|
32475
|
-
const ws =
|
|
32990
|
+
const ws = fs19.createWriteStream(destPath);
|
|
32476
32991
|
res.pipe(ws);
|
|
32477
32992
|
ws.on("finish", () => {
|
|
32478
32993
|
ws.close();
|
|
@@ -32491,22 +33006,22 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32491
33006
|
}
|
|
32492
33007
|
/** Recursive directory copy */
|
|
32493
33008
|
copyDirRecursive(src, dest) {
|
|
32494
|
-
|
|
32495
|
-
for (const entry of
|
|
32496
|
-
const srcPath =
|
|
32497
|
-
const destPath =
|
|
33009
|
+
fs19.mkdirSync(dest, { recursive: true });
|
|
33010
|
+
for (const entry of fs19.readdirSync(src, { withFileTypes: true })) {
|
|
33011
|
+
const srcPath = path31.join(src, entry.name);
|
|
33012
|
+
const destPath = path31.join(dest, entry.name);
|
|
32498
33013
|
if (entry.isDirectory()) {
|
|
32499
33014
|
this.copyDirRecursive(srcPath, destPath);
|
|
32500
33015
|
} else {
|
|
32501
|
-
|
|
33016
|
+
fs19.copyFileSync(srcPath, destPath);
|
|
32502
33017
|
}
|
|
32503
33018
|
}
|
|
32504
33019
|
}
|
|
32505
33020
|
/** .meta.json save */
|
|
32506
33021
|
writeMeta(metaPath, etag, timestamp) {
|
|
32507
33022
|
try {
|
|
32508
|
-
|
|
32509
|
-
|
|
33023
|
+
fs19.mkdirSync(path31.dirname(metaPath), { recursive: true });
|
|
33024
|
+
fs19.writeFileSync(metaPath, JSON.stringify({
|
|
32510
33025
|
etag,
|
|
32511
33026
|
timestamp,
|
|
32512
33027
|
lastCheck: new Date(timestamp).toISOString(),
|
|
@@ -32517,15 +33032,15 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32517
33032
|
}
|
|
32518
33033
|
/** Count provider files (provider.v1.json or provider.json — at most one per dir). */
|
|
32519
33034
|
countProviders(dir) {
|
|
32520
|
-
if (!
|
|
33035
|
+
if (!fs19.existsSync(dir)) return 0;
|
|
32521
33036
|
let count = 0;
|
|
32522
33037
|
const scan = (d) => {
|
|
32523
33038
|
try {
|
|
32524
|
-
const entries =
|
|
33039
|
+
const entries = fs19.readdirSync(d, { withFileTypes: true });
|
|
32525
33040
|
const hasManifest = entries.some((e) => e.name === "provider.v1.json" || e.name === "provider.json");
|
|
32526
33041
|
if (hasManifest) count++;
|
|
32527
33042
|
for (const entry of entries) {
|
|
32528
|
-
if (entry.isDirectory()) scan(
|
|
33043
|
+
if (entry.isDirectory()) scan(path31.join(d, entry.name));
|
|
32529
33044
|
}
|
|
32530
33045
|
} catch {
|
|
32531
33046
|
}
|
|
@@ -32751,13 +33266,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32751
33266
|
if (!provider) return null;
|
|
32752
33267
|
const cat = provider.category;
|
|
32753
33268
|
const searchRoots = this.getProviderRoots();
|
|
32754
|
-
const hasManifest = (dir) =>
|
|
33269
|
+
const hasManifest = (dir) => fs19.existsSync(path31.join(dir, "provider.v1.json")) || fs19.existsSync(path31.join(dir, "provider.json"));
|
|
32755
33270
|
const readManifestType = (dir) => {
|
|
32756
33271
|
for (const file of ["provider.v1.json", "provider.json"]) {
|
|
32757
|
-
const p =
|
|
32758
|
-
if (!
|
|
33272
|
+
const p = path31.join(dir, file);
|
|
33273
|
+
if (!fs19.existsSync(p)) continue;
|
|
32759
33274
|
try {
|
|
32760
|
-
const data = JSON.parse(
|
|
33275
|
+
const data = JSON.parse(fs19.readFileSync(p, "utf-8"));
|
|
32761
33276
|
if (typeof data?.type === "string") return data.type;
|
|
32762
33277
|
} catch {
|
|
32763
33278
|
}
|
|
@@ -32765,15 +33280,15 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32765
33280
|
return null;
|
|
32766
33281
|
};
|
|
32767
33282
|
for (const root of searchRoots) {
|
|
32768
|
-
if (!
|
|
33283
|
+
if (!fs19.existsSync(root)) continue;
|
|
32769
33284
|
const candidate = this.getProviderDir(root, cat, type);
|
|
32770
33285
|
if (hasManifest(candidate)) return candidate;
|
|
32771
|
-
const catDir =
|
|
32772
|
-
if (
|
|
33286
|
+
const catDir = path31.join(root, cat);
|
|
33287
|
+
if (fs19.existsSync(catDir)) {
|
|
32773
33288
|
try {
|
|
32774
|
-
for (const entry of
|
|
33289
|
+
for (const entry of fs19.readdirSync(catDir, { withFileTypes: true })) {
|
|
32775
33290
|
if (!entry.isDirectory()) continue;
|
|
32776
|
-
const entryDir =
|
|
33291
|
+
const entryDir = path31.join(catDir, entry.name);
|
|
32777
33292
|
const manifestType = readManifestType(entryDir);
|
|
32778
33293
|
if (manifestType === type) return entryDir;
|
|
32779
33294
|
}
|
|
@@ -32789,8 +33304,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32789
33304
|
* (template substitution is NOT applied here — scripts.js handles that)
|
|
32790
33305
|
*/
|
|
32791
33306
|
buildScriptWrappersFromDir(dir) {
|
|
32792
|
-
const scriptsJs =
|
|
32793
|
-
if (
|
|
33307
|
+
const scriptsJs = path31.join(dir, "scripts.js");
|
|
33308
|
+
if (fs19.existsSync(scriptsJs)) {
|
|
32794
33309
|
try {
|
|
32795
33310
|
delete __require.cache[__require.resolve(scriptsJs)];
|
|
32796
33311
|
return __require(scriptsJs);
|
|
@@ -32800,13 +33315,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32800
33315
|
const toCamel = (name) => name.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
|
|
32801
33316
|
const result = {};
|
|
32802
33317
|
try {
|
|
32803
|
-
for (const file of
|
|
33318
|
+
for (const file of fs19.readdirSync(dir)) {
|
|
32804
33319
|
if (!file.endsWith(".js")) continue;
|
|
32805
33320
|
const scriptName = toCamel(file.replace(".js", ""));
|
|
32806
|
-
const filePath =
|
|
33321
|
+
const filePath = path31.join(dir, file);
|
|
32807
33322
|
result[scriptName] = (...args) => {
|
|
32808
33323
|
try {
|
|
32809
|
-
let content =
|
|
33324
|
+
let content = fs19.readFileSync(filePath, "utf-8");
|
|
32810
33325
|
if (args[0] && typeof args[0] === "object") {
|
|
32811
33326
|
for (const [key, val] of Object.entries(args[0])) {
|
|
32812
33327
|
let v = val;
|
|
@@ -32852,12 +33367,12 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32852
33367
|
* Structure: dir/category/agent-name/provider.{json,js}
|
|
32853
33368
|
*/
|
|
32854
33369
|
loadDir(dir, excludeDirs) {
|
|
32855
|
-
if (!
|
|
33370
|
+
if (!fs19.existsSync(dir)) return 0;
|
|
32856
33371
|
let count = 0;
|
|
32857
33372
|
const scan = (d) => {
|
|
32858
33373
|
let entries;
|
|
32859
33374
|
try {
|
|
32860
|
-
entries =
|
|
33375
|
+
entries = fs19.readdirSync(d, { withFileTypes: true });
|
|
32861
33376
|
} catch {
|
|
32862
33377
|
return;
|
|
32863
33378
|
}
|
|
@@ -32865,9 +33380,9 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32865
33380
|
const hasJson = entries.some((e) => e.name === "provider.json");
|
|
32866
33381
|
if (hasV1 || hasJson) {
|
|
32867
33382
|
const manifestFile = hasV1 ? "provider.v1.json" : "provider.json";
|
|
32868
|
-
const jsonPath =
|
|
33383
|
+
const jsonPath = path31.join(d, manifestFile);
|
|
32869
33384
|
try {
|
|
32870
|
-
const raw =
|
|
33385
|
+
const raw = fs19.readFileSync(jsonPath, "utf-8");
|
|
32871
33386
|
const mod = JSON.parse(raw);
|
|
32872
33387
|
if (hasV1 && mod?.category === "cli") {
|
|
32873
33388
|
try {
|
|
@@ -32905,10 +33420,10 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
32905
33420
|
this.log(`\u26A0 Invalid provider at ${jsonPath}: ${validation.errors.join("; ")}`);
|
|
32906
33421
|
} else {
|
|
32907
33422
|
const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
|
|
32908
|
-
const scriptsPath =
|
|
32909
|
-
if (!hasCompatibility &&
|
|
33423
|
+
const scriptsPath = path31.join(d, "scripts.js");
|
|
33424
|
+
if (!hasCompatibility && fs19.existsSync(scriptsPath)) {
|
|
32910
33425
|
try {
|
|
32911
|
-
registerProviderScriptRootSafely(
|
|
33426
|
+
registerProviderScriptRootSafely(path31.dirname(path31.dirname(d)));
|
|
32912
33427
|
delete __require.cache[__require.resolve(scriptsPath)];
|
|
32913
33428
|
const scripts = __require(scriptsPath);
|
|
32914
33429
|
normalizedProvider.scripts = scripts;
|
|
@@ -32916,12 +33431,30 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
32916
33431
|
this.log(`\u26A0 Failed to load scripts: ${scriptsPath}: ${e.message}`);
|
|
32917
33432
|
}
|
|
32918
33433
|
}
|
|
33434
|
+
const externalDirAbs = path31.join(os22.homedir(), ".adhdev", "external");
|
|
33435
|
+
const layer = d.startsWith(externalDirAbs) ? "external" : d.startsWith(this.userDir) && !d.includes(".upstream") ? "user" : "upstream";
|
|
33436
|
+
try {
|
|
33437
|
+
const { inspectManifestShape: inspectManifestShape2, classifyTrust: classifyTrust2 } = (init_provider_trust(), __toCommonJS(provider_trust_exports));
|
|
33438
|
+
const shape = inspectManifestShape2(mod);
|
|
33439
|
+
const trust = classifyTrust2(layer, shape);
|
|
33440
|
+
normalizedProvider._sourceLayer = layer;
|
|
33441
|
+
normalizedProvider._sourceTrust = trust;
|
|
33442
|
+
normalizedProvider._manifestShape = shape;
|
|
33443
|
+
if (layer === "external") {
|
|
33444
|
+
const rel = path31.relative(externalDirAbs, d);
|
|
33445
|
+
const firstSeg = rel.split(path31.sep)[0];
|
|
33446
|
+
if (firstSeg && firstSeg !== "..") normalizedProvider._sourceName = firstSeg;
|
|
33447
|
+
}
|
|
33448
|
+
} catch {
|
|
33449
|
+
}
|
|
32919
33450
|
const existed = this.providers.has(normalizedProvider.type);
|
|
32920
33451
|
this.providers.set(normalizedProvider.type, normalizedProvider);
|
|
32921
33452
|
count++;
|
|
32922
|
-
const source =
|
|
33453
|
+
const source = normalizedProvider._sourceLayer ?? "upstream";
|
|
32923
33454
|
const overrideWarning = existed && source === "user" ? " \u26A0 OVERRIDES upstream" : "";
|
|
32924
|
-
|
|
33455
|
+
const sourceName = normalizedProvider._sourceName;
|
|
33456
|
+
const sourceLabel = sourceName ? `${source}/${sourceName}` : source;
|
|
33457
|
+
this.log(` ${existed ? "\u{1F504}" : "\u2705"} ${normalizedProvider.type} (${normalizedProvider.category}) \u2014 ${normalizedProvider.name} [${sourceLabel}]${overrideWarning}`);
|
|
32925
33458
|
}
|
|
32926
33459
|
} catch (e) {
|
|
32927
33460
|
this.log(`\u26A0 Failed to load ${jsonPath}: ${e.message}`);
|
|
@@ -32931,8 +33464,9 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
32931
33464
|
for (const entry of entries) {
|
|
32932
33465
|
if (!entry.isDirectory()) continue;
|
|
32933
33466
|
if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
|
|
33467
|
+
if (d === dir && entry.name === "examples") continue;
|
|
32934
33468
|
if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
|
|
32935
|
-
scan(
|
|
33469
|
+
scan(path31.join(d, entry.name));
|
|
32936
33470
|
}
|
|
32937
33471
|
}
|
|
32938
33472
|
};
|
|
@@ -33130,7 +33664,7 @@ async function isCdpActive(port) {
|
|
|
33130
33664
|
});
|
|
33131
33665
|
}
|
|
33132
33666
|
async function killIdeProcess(ideId) {
|
|
33133
|
-
const plat =
|
|
33667
|
+
const plat = os23.platform();
|
|
33134
33668
|
const appName = getMacAppIdentifiers()[ideId];
|
|
33135
33669
|
const winProcesses = getWinProcessNames()[ideId];
|
|
33136
33670
|
try {
|
|
@@ -33191,7 +33725,7 @@ async function killIdeProcess(ideId) {
|
|
|
33191
33725
|
}
|
|
33192
33726
|
}
|
|
33193
33727
|
async function isIdeRunning(ideId) {
|
|
33194
|
-
const plat =
|
|
33728
|
+
const plat = os23.platform();
|
|
33195
33729
|
try {
|
|
33196
33730
|
if (plat === "darwin") {
|
|
33197
33731
|
const appName = getMacAppIdentifiers()[ideId];
|
|
@@ -33246,7 +33780,7 @@ async function isIdeRunning(ideId) {
|
|
|
33246
33780
|
}
|
|
33247
33781
|
}
|
|
33248
33782
|
async function detectCurrentWorkspace(ideId) {
|
|
33249
|
-
const plat =
|
|
33783
|
+
const plat = os23.platform();
|
|
33250
33784
|
if (plat === "darwin") {
|
|
33251
33785
|
try {
|
|
33252
33786
|
const appName = getMacAppIdentifiers()[ideId];
|
|
@@ -33261,17 +33795,17 @@ async function detectCurrentWorkspace(ideId) {
|
|
|
33261
33795
|
}
|
|
33262
33796
|
} else if (plat === "win32") {
|
|
33263
33797
|
try {
|
|
33264
|
-
const
|
|
33798
|
+
const fs28 = __require("fs");
|
|
33265
33799
|
const appNameMap = getMacAppIdentifiers();
|
|
33266
33800
|
const appName = appNameMap[ideId];
|
|
33267
33801
|
if (appName) {
|
|
33268
|
-
const storagePath =
|
|
33269
|
-
process.env.APPDATA ||
|
|
33802
|
+
const storagePath = path32.join(
|
|
33803
|
+
process.env.APPDATA || path32.join(os23.homedir(), "AppData", "Roaming"),
|
|
33270
33804
|
appName,
|
|
33271
33805
|
"storage.json"
|
|
33272
33806
|
);
|
|
33273
|
-
if (
|
|
33274
|
-
const data = JSON.parse(
|
|
33807
|
+
if (fs28.existsSync(storagePath)) {
|
|
33808
|
+
const data = JSON.parse(fs28.readFileSync(storagePath, "utf-8"));
|
|
33275
33809
|
const workspaces = data?.openedPathsList?.workspaces3 || data?.openedPathsList?.entries || [];
|
|
33276
33810
|
if (workspaces.length > 0) {
|
|
33277
33811
|
const recent = workspaces[0];
|
|
@@ -33288,7 +33822,7 @@ async function detectCurrentWorkspace(ideId) {
|
|
|
33288
33822
|
return void 0;
|
|
33289
33823
|
}
|
|
33290
33824
|
async function launchWithCdp(options = {}) {
|
|
33291
|
-
const platform10 =
|
|
33825
|
+
const platform10 = os23.platform();
|
|
33292
33826
|
let targetIde;
|
|
33293
33827
|
const ides = await detectIDEs(getProviderLoader());
|
|
33294
33828
|
if (options.ideId) {
|
|
@@ -33455,14 +33989,14 @@ init_cli_detector();
|
|
|
33455
33989
|
init_logger();
|
|
33456
33990
|
|
|
33457
33991
|
// src/logging/command-log.ts
|
|
33458
|
-
import * as
|
|
33459
|
-
import * as
|
|
33460
|
-
import * as
|
|
33461
|
-
var LOG_DIR2 = process.platform === "win32" ?
|
|
33992
|
+
import * as fs20 from "fs";
|
|
33993
|
+
import * as path33 from "path";
|
|
33994
|
+
import * as os24 from "os";
|
|
33995
|
+
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");
|
|
33462
33996
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
33463
33997
|
var MAX_DAYS = 7;
|
|
33464
33998
|
try {
|
|
33465
|
-
|
|
33999
|
+
fs20.mkdirSync(LOG_DIR2, { recursive: true });
|
|
33466
34000
|
} catch {
|
|
33467
34001
|
}
|
|
33468
34002
|
var SENSITIVE_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -33496,19 +34030,19 @@ function getDateStr2() {
|
|
|
33496
34030
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
33497
34031
|
}
|
|
33498
34032
|
var currentDate2 = getDateStr2();
|
|
33499
|
-
var currentFile =
|
|
34033
|
+
var currentFile = path33.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
33500
34034
|
var writeCount2 = 0;
|
|
33501
34035
|
function checkRotation() {
|
|
33502
34036
|
const today = getDateStr2();
|
|
33503
34037
|
if (today !== currentDate2) {
|
|
33504
34038
|
currentDate2 = today;
|
|
33505
|
-
currentFile =
|
|
34039
|
+
currentFile = path33.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
33506
34040
|
cleanOldFiles();
|
|
33507
34041
|
}
|
|
33508
34042
|
}
|
|
33509
34043
|
function cleanOldFiles() {
|
|
33510
34044
|
try {
|
|
33511
|
-
const files =
|
|
34045
|
+
const files = fs20.readdirSync(LOG_DIR2).filter((f) => f.startsWith("commands-") && f.endsWith(".jsonl"));
|
|
33512
34046
|
const cutoff = /* @__PURE__ */ new Date();
|
|
33513
34047
|
cutoff.setDate(cutoff.getDate() - MAX_DAYS);
|
|
33514
34048
|
const cutoffStr = cutoff.toISOString().slice(0, 10);
|
|
@@ -33516,7 +34050,7 @@ function cleanOldFiles() {
|
|
|
33516
34050
|
const dateMatch = file.match(/commands-(\d{4}-\d{2}-\d{2})/);
|
|
33517
34051
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
33518
34052
|
try {
|
|
33519
|
-
|
|
34053
|
+
fs20.unlinkSync(path33.join(LOG_DIR2, file));
|
|
33520
34054
|
} catch {
|
|
33521
34055
|
}
|
|
33522
34056
|
}
|
|
@@ -33526,14 +34060,14 @@ function cleanOldFiles() {
|
|
|
33526
34060
|
}
|
|
33527
34061
|
function checkSize() {
|
|
33528
34062
|
try {
|
|
33529
|
-
const stat2 =
|
|
34063
|
+
const stat2 = fs20.statSync(currentFile);
|
|
33530
34064
|
if (stat2.size > MAX_FILE_SIZE) {
|
|
33531
34065
|
const backup = currentFile.replace(".jsonl", ".1.jsonl");
|
|
33532
34066
|
try {
|
|
33533
|
-
|
|
34067
|
+
fs20.unlinkSync(backup);
|
|
33534
34068
|
} catch {
|
|
33535
34069
|
}
|
|
33536
|
-
|
|
34070
|
+
fs20.renameSync(currentFile, backup);
|
|
33537
34071
|
}
|
|
33538
34072
|
} catch {
|
|
33539
34073
|
}
|
|
@@ -33566,14 +34100,14 @@ function logCommand(entry) {
|
|
|
33566
34100
|
...entry.error ? { err: entry.error } : {},
|
|
33567
34101
|
...entry.durationMs !== void 0 ? { ms: entry.durationMs } : {}
|
|
33568
34102
|
});
|
|
33569
|
-
|
|
34103
|
+
fs20.appendFileSync(currentFile, line + "\n");
|
|
33570
34104
|
} catch {
|
|
33571
34105
|
}
|
|
33572
34106
|
}
|
|
33573
34107
|
function getRecentCommands(count = 50) {
|
|
33574
34108
|
try {
|
|
33575
|
-
if (!
|
|
33576
|
-
const content =
|
|
34109
|
+
if (!fs20.existsSync(currentFile)) return [];
|
|
34110
|
+
const content = fs20.readFileSync(currentFile, "utf-8");
|
|
33577
34111
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
33578
34112
|
return lines.slice(-count).map((line) => {
|
|
33579
34113
|
try {
|
|
@@ -33607,7 +34141,7 @@ init_mesh_host_ownership();
|
|
|
33607
34141
|
|
|
33608
34142
|
// src/mesh/preview-freshness.ts
|
|
33609
34143
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
33610
|
-
import { existsSync as
|
|
34144
|
+
import { existsSync as existsSync30, readFileSync as readFileSync23 } from "fs";
|
|
33611
34145
|
import { resolve as resolve18 } from "path";
|
|
33612
34146
|
var PREVIEW_DEPLOY_RECORD = ".adhdev/preview-deploy.json";
|
|
33613
34147
|
function runGit2(repoRoot, args) {
|
|
@@ -33623,10 +34157,10 @@ function runGit2(repoRoot, args) {
|
|
|
33623
34157
|
}
|
|
33624
34158
|
}
|
|
33625
34159
|
function readRecord3(repoRoot) {
|
|
33626
|
-
const
|
|
33627
|
-
if (!
|
|
34160
|
+
const path40 = resolve18(repoRoot, PREVIEW_DEPLOY_RECORD);
|
|
34161
|
+
if (!existsSync30(path40)) return null;
|
|
33628
34162
|
try {
|
|
33629
|
-
const parsed = JSON.parse(
|
|
34163
|
+
const parsed = JSON.parse(readFileSync23(path40, "utf8"));
|
|
33630
34164
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
33631
34165
|
} catch {
|
|
33632
34166
|
return null;
|
|
@@ -33689,7 +34223,7 @@ function buildPreviewFreshness(repoRoot) {
|
|
|
33689
34223
|
|
|
33690
34224
|
// src/status/snapshot.ts
|
|
33691
34225
|
init_config();
|
|
33692
|
-
import * as
|
|
34226
|
+
import * as os25 from "os";
|
|
33693
34227
|
init_terminal_screen();
|
|
33694
34228
|
init_logger();
|
|
33695
34229
|
var READ_DEBUG_ENABLED = process.argv.includes("--dev") || process.env.ADHDEV_READ_DEBUG === "1";
|
|
@@ -33727,25 +34261,50 @@ function buildDetectedIdeInfos(detectedIdes, cdpManagers) {
|
|
|
33727
34261
|
}
|
|
33728
34262
|
function buildAvailableProviders(providerLoader) {
|
|
33729
34263
|
const providers = providerLoader.getAvailableProviderInfos?.() || providerLoader.getAll();
|
|
33730
|
-
|
|
33731
|
-
|
|
33732
|
-
|
|
33733
|
-
|
|
33734
|
-
|
|
33735
|
-
|
|
33736
|
-
|
|
33737
|
-
|
|
33738
|
-
|
|
33739
|
-
|
|
33740
|
-
|
|
33741
|
-
|
|
33742
|
-
|
|
33743
|
-
|
|
34264
|
+
let describeTrust2 = () => "";
|
|
34265
|
+
let requiresConfirmation2 = () => false;
|
|
34266
|
+
try {
|
|
34267
|
+
const mod = (init_provider_trust(), __toCommonJS(provider_trust_exports));
|
|
34268
|
+
describeTrust2 = mod.describeTrust;
|
|
34269
|
+
requiresConfirmation2 = mod.requiresConfirmation;
|
|
34270
|
+
} catch {
|
|
34271
|
+
}
|
|
34272
|
+
return providers.map((provider) => {
|
|
34273
|
+
const trust = provider._sourceTrust;
|
|
34274
|
+
const sourceLayer = provider._sourceLayer;
|
|
34275
|
+
const sourceName = provider._sourceName;
|
|
34276
|
+
return {
|
|
34277
|
+
type: provider.type,
|
|
34278
|
+
name: provider.displayName || provider.type,
|
|
34279
|
+
displayName: provider.displayName || provider.type,
|
|
34280
|
+
icon: provider.icon || "\u{1F4BB}",
|
|
34281
|
+
category: provider.category,
|
|
34282
|
+
...provider.installed !== void 0 ? { installed: provider.installed } : {},
|
|
34283
|
+
...provider.detectedPath !== void 0 ? { detectedPath: provider.detectedPath } : {},
|
|
34284
|
+
...provider.enabled !== void 0 ? { enabled: provider.enabled } : {},
|
|
34285
|
+
...provider.machineStatus !== void 0 ? { machineStatus: provider.machineStatus } : {},
|
|
34286
|
+
...provider.lastDetection !== void 0 ? { lastDetection: provider.lastDetection } : {},
|
|
34287
|
+
...provider.lastVerification !== void 0 ? { lastVerification: provider.lastVerification } : {},
|
|
34288
|
+
...provider.meshCoordinator !== void 0 ? { meshCoordinator: provider.meshCoordinator } : {},
|
|
34289
|
+
...trust ? {
|
|
34290
|
+
trust,
|
|
34291
|
+
trustDescription: describeTrust2(trust),
|
|
34292
|
+
requiresConfirmation: requiresConfirmation2(trust)
|
|
34293
|
+
} : {},
|
|
34294
|
+
...sourceLayer ? { sourceLayer } : {},
|
|
34295
|
+
...sourceName ? { sourceName } : {},
|
|
34296
|
+
...provider.providerVersion ? { providerVersion: provider.providerVersion } : {},
|
|
34297
|
+
...provider.binary ? { binary: provider.binary } : {},
|
|
34298
|
+
...provider.status ? { status: provider.status } : {},
|
|
34299
|
+
...provider.details ? { details: provider.details } : {},
|
|
34300
|
+
...provider.links ? { links: provider.links } : {}
|
|
34301
|
+
};
|
|
34302
|
+
});
|
|
33744
34303
|
}
|
|
33745
34304
|
function buildMachineInfo(profile = "full") {
|
|
33746
34305
|
const base = {
|
|
33747
|
-
hostname:
|
|
33748
|
-
platform:
|
|
34306
|
+
hostname: os25.hostname(),
|
|
34307
|
+
platform: os25.platform()
|
|
33749
34308
|
};
|
|
33750
34309
|
if (profile === "live") {
|
|
33751
34310
|
return base;
|
|
@@ -33754,23 +34313,23 @@ function buildMachineInfo(profile = "full") {
|
|
|
33754
34313
|
const memSnap2 = getHostMemorySnapshot();
|
|
33755
34314
|
return {
|
|
33756
34315
|
...base,
|
|
33757
|
-
arch:
|
|
33758
|
-
cpus:
|
|
34316
|
+
arch: os25.arch(),
|
|
34317
|
+
cpus: os25.cpus().length,
|
|
33759
34318
|
totalMem: memSnap2.totalMem,
|
|
33760
|
-
release:
|
|
34319
|
+
release: os25.release()
|
|
33761
34320
|
};
|
|
33762
34321
|
}
|
|
33763
34322
|
const memSnap = getHostMemorySnapshot();
|
|
33764
34323
|
return {
|
|
33765
34324
|
...base,
|
|
33766
|
-
arch:
|
|
33767
|
-
cpus:
|
|
34325
|
+
arch: os25.arch(),
|
|
34326
|
+
cpus: os25.cpus().length,
|
|
33768
34327
|
totalMem: memSnap.totalMem,
|
|
33769
34328
|
freeMem: memSnap.freeMem,
|
|
33770
34329
|
availableMem: memSnap.availableMem,
|
|
33771
|
-
loadavg:
|
|
33772
|
-
uptime:
|
|
33773
|
-
release:
|
|
34330
|
+
loadavg: os25.loadavg(),
|
|
34331
|
+
uptime: os25.uptime(),
|
|
34332
|
+
release: os25.release()
|
|
33774
34333
|
};
|
|
33775
34334
|
}
|
|
33776
34335
|
function parseMessageTime(value) {
|
|
@@ -34011,42 +34570,42 @@ function buildStatusSnapshot(options) {
|
|
|
34011
34570
|
// src/commands/upgrade-helper.ts
|
|
34012
34571
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
34013
34572
|
import { spawn as spawn3 } from "child_process";
|
|
34014
|
-
import * as
|
|
34015
|
-
import * as
|
|
34016
|
-
import * as
|
|
34573
|
+
import * as fs21 from "fs";
|
|
34574
|
+
import * as os26 from "os";
|
|
34575
|
+
import * as path34 from "path";
|
|
34017
34576
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
34018
34577
|
function getUpgradeLogPath() {
|
|
34019
|
-
const home =
|
|
34020
|
-
const dir =
|
|
34021
|
-
|
|
34022
|
-
return
|
|
34578
|
+
const home = os26.homedir();
|
|
34579
|
+
const dir = path34.join(home, ".adhdev");
|
|
34580
|
+
fs21.mkdirSync(dir, { recursive: true });
|
|
34581
|
+
return path34.join(dir, "daemon-upgrade.log");
|
|
34023
34582
|
}
|
|
34024
34583
|
function appendUpgradeLog(message) {
|
|
34025
34584
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
|
|
34026
34585
|
`;
|
|
34027
34586
|
try {
|
|
34028
|
-
|
|
34587
|
+
fs21.appendFileSync(getUpgradeLogPath(), line, "utf8");
|
|
34029
34588
|
} catch {
|
|
34030
34589
|
}
|
|
34031
34590
|
}
|
|
34032
34591
|
function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platform) {
|
|
34033
|
-
const binDir =
|
|
34592
|
+
const binDir = path34.dirname(nodeExecutable);
|
|
34034
34593
|
if (platform10 === "win32") {
|
|
34035
|
-
const npmCliPath =
|
|
34036
|
-
if (
|
|
34594
|
+
const npmCliPath = path34.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
|
|
34595
|
+
if (fs21.existsSync(npmCliPath)) {
|
|
34037
34596
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
34038
34597
|
}
|
|
34039
34598
|
for (const candidate of ["npm.exe", "npm"]) {
|
|
34040
|
-
const candidatePath =
|
|
34041
|
-
if (
|
|
34599
|
+
const candidatePath = path34.join(binDir, candidate);
|
|
34600
|
+
if (fs21.existsSync(candidatePath)) {
|
|
34042
34601
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
34043
34602
|
}
|
|
34044
34603
|
}
|
|
34045
34604
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
34046
34605
|
}
|
|
34047
34606
|
for (const candidate of ["npm"]) {
|
|
34048
|
-
const candidatePath =
|
|
34049
|
-
if (
|
|
34607
|
+
const candidatePath = path34.join(binDir, candidate);
|
|
34608
|
+
if (fs21.existsSync(candidatePath)) {
|
|
34050
34609
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
34051
34610
|
}
|
|
34052
34611
|
}
|
|
@@ -34056,22 +34615,22 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
34056
34615
|
if (!currentCliPath) return null;
|
|
34057
34616
|
let resolvedPath = currentCliPath;
|
|
34058
34617
|
try {
|
|
34059
|
-
resolvedPath =
|
|
34618
|
+
resolvedPath = fs21.realpathSync.native(currentCliPath);
|
|
34060
34619
|
} catch {
|
|
34061
34620
|
}
|
|
34062
34621
|
let currentDir = resolvedPath;
|
|
34063
34622
|
try {
|
|
34064
|
-
if (
|
|
34065
|
-
currentDir =
|
|
34623
|
+
if (fs21.statSync(resolvedPath).isFile()) {
|
|
34624
|
+
currentDir = path34.dirname(resolvedPath);
|
|
34066
34625
|
}
|
|
34067
34626
|
} catch {
|
|
34068
|
-
currentDir =
|
|
34627
|
+
currentDir = path34.dirname(resolvedPath);
|
|
34069
34628
|
}
|
|
34070
34629
|
while (true) {
|
|
34071
|
-
const packageJsonPath =
|
|
34630
|
+
const packageJsonPath = path34.join(currentDir, "package.json");
|
|
34072
34631
|
try {
|
|
34073
|
-
if (
|
|
34074
|
-
const parsed = JSON.parse(
|
|
34632
|
+
if (fs21.existsSync(packageJsonPath)) {
|
|
34633
|
+
const parsed = JSON.parse(fs21.readFileSync(packageJsonPath, "utf8"));
|
|
34075
34634
|
if (parsed?.name === packageName) {
|
|
34076
34635
|
const normalized = currentDir.replace(/\\/g, "/");
|
|
34077
34636
|
return normalized.includes("/node_modules/") ? currentDir : null;
|
|
@@ -34079,7 +34638,7 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
34079
34638
|
}
|
|
34080
34639
|
} catch {
|
|
34081
34640
|
}
|
|
34082
|
-
const parentDir =
|
|
34641
|
+
const parentDir = path34.dirname(currentDir);
|
|
34083
34642
|
if (parentDir === currentDir) {
|
|
34084
34643
|
return null;
|
|
34085
34644
|
}
|
|
@@ -34087,13 +34646,13 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
34087
34646
|
}
|
|
34088
34647
|
}
|
|
34089
34648
|
function resolveInstallPrefixFromPackageRoot(packageRoot, packageName) {
|
|
34090
|
-
const nodeModulesDir = packageName.startsWith("@") ?
|
|
34091
|
-
if (
|
|
34649
|
+
const nodeModulesDir = packageName.startsWith("@") ? path34.dirname(path34.dirname(packageRoot)) : path34.dirname(packageRoot);
|
|
34650
|
+
if (path34.basename(nodeModulesDir) !== "node_modules") {
|
|
34092
34651
|
return null;
|
|
34093
34652
|
}
|
|
34094
|
-
const maybeLibDir =
|
|
34095
|
-
if (
|
|
34096
|
-
return
|
|
34653
|
+
const maybeLibDir = path34.dirname(nodeModulesDir);
|
|
34654
|
+
if (path34.basename(maybeLibDir) === "lib") {
|
|
34655
|
+
return path34.dirname(maybeLibDir);
|
|
34097
34656
|
}
|
|
34098
34657
|
return maybeLibDir;
|
|
34099
34658
|
}
|
|
@@ -34208,10 +34767,10 @@ async function waitForPidExit(pid, timeoutMs) {
|
|
|
34208
34767
|
}
|
|
34209
34768
|
}
|
|
34210
34769
|
function stopSessionHostProcesses(appName) {
|
|
34211
|
-
const pidFile =
|
|
34770
|
+
const pidFile = path34.join(os26.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
34212
34771
|
try {
|
|
34213
|
-
if (
|
|
34214
|
-
const pid = Number.parseInt(
|
|
34772
|
+
if (fs21.existsSync(pidFile)) {
|
|
34773
|
+
const pid = Number.parseInt(fs21.readFileSync(pidFile, "utf8").trim(), 10);
|
|
34215
34774
|
if (Number.isFinite(pid) && pid !== process.pid && isManagedSessionHostPid(pid)) {
|
|
34216
34775
|
killPid(pid);
|
|
34217
34776
|
}
|
|
@@ -34219,15 +34778,15 @@ function stopSessionHostProcesses(appName) {
|
|
|
34219
34778
|
} catch {
|
|
34220
34779
|
} finally {
|
|
34221
34780
|
try {
|
|
34222
|
-
|
|
34781
|
+
fs21.unlinkSync(pidFile);
|
|
34223
34782
|
} catch {
|
|
34224
34783
|
}
|
|
34225
34784
|
}
|
|
34226
34785
|
}
|
|
34227
34786
|
function removeDaemonPidFile() {
|
|
34228
|
-
const pidFile =
|
|
34787
|
+
const pidFile = path34.join(os26.homedir(), ".adhdev", "daemon.pid");
|
|
34229
34788
|
try {
|
|
34230
|
-
|
|
34789
|
+
fs21.unlinkSync(pidFile);
|
|
34231
34790
|
} catch {
|
|
34232
34791
|
}
|
|
34233
34792
|
}
|
|
@@ -34236,7 +34795,7 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
34236
34795
|
const npmRoot = String(execNpmCommandSync(["root", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
34237
34796
|
if (!npmRoot) return;
|
|
34238
34797
|
const npmPrefix = surface.installPrefix || String(execNpmCommandSync(["prefix", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
34239
|
-
const binDir = process.platform === "win32" ? npmPrefix :
|
|
34798
|
+
const binDir = process.platform === "win32" ? npmPrefix : path34.join(npmPrefix, "bin");
|
|
34240
34799
|
const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
|
|
34241
34800
|
const binNames = /* @__PURE__ */ new Set([packageBaseName]);
|
|
34242
34801
|
if (pkgName === "@adhdev/daemon-standalone") {
|
|
@@ -34244,25 +34803,25 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
34244
34803
|
}
|
|
34245
34804
|
if (pkgName.startsWith("@")) {
|
|
34246
34805
|
const [scope, name] = pkgName.split("/");
|
|
34247
|
-
const scopeDir =
|
|
34248
|
-
if (!
|
|
34249
|
-
for (const entry of
|
|
34806
|
+
const scopeDir = path34.join(npmRoot, scope);
|
|
34807
|
+
if (!fs21.existsSync(scopeDir)) return;
|
|
34808
|
+
for (const entry of fs21.readdirSync(scopeDir)) {
|
|
34250
34809
|
if (!entry.startsWith(`.${name}-`)) continue;
|
|
34251
|
-
|
|
34252
|
-
appendUpgradeLog(`Removed stale scoped staging dir: ${
|
|
34810
|
+
fs21.rmSync(path34.join(scopeDir, entry), { recursive: true, force: true });
|
|
34811
|
+
appendUpgradeLog(`Removed stale scoped staging dir: ${path34.join(scopeDir, entry)}`);
|
|
34253
34812
|
}
|
|
34254
34813
|
} else {
|
|
34255
|
-
for (const entry of
|
|
34814
|
+
for (const entry of fs21.readdirSync(npmRoot)) {
|
|
34256
34815
|
if (!entry.startsWith(`.${pkgName}-`)) continue;
|
|
34257
|
-
|
|
34258
|
-
appendUpgradeLog(`Removed stale staging dir: ${
|
|
34816
|
+
fs21.rmSync(path34.join(npmRoot, entry), { recursive: true, force: true });
|
|
34817
|
+
appendUpgradeLog(`Removed stale staging dir: ${path34.join(npmRoot, entry)}`);
|
|
34259
34818
|
}
|
|
34260
34819
|
}
|
|
34261
|
-
if (
|
|
34262
|
-
for (const entry of
|
|
34820
|
+
if (fs21.existsSync(binDir)) {
|
|
34821
|
+
for (const entry of fs21.readdirSync(binDir)) {
|
|
34263
34822
|
if (!Array.from(binNames).some((name) => entry.startsWith(`.${name}-`))) continue;
|
|
34264
|
-
|
|
34265
|
-
appendUpgradeLog(`Removed stale bin staging entry: ${
|
|
34823
|
+
fs21.rmSync(path34.join(binDir, entry), { recursive: true, force: true });
|
|
34824
|
+
appendUpgradeLog(`Removed stale bin staging entry: ${path34.join(binDir, entry)}`);
|
|
34266
34825
|
}
|
|
34267
34826
|
}
|
|
34268
34827
|
}
|
|
@@ -34348,9 +34907,9 @@ async function maybeRunDaemonUpgradeHelperFromEnv() {
|
|
|
34348
34907
|
|
|
34349
34908
|
// src/commands/router.ts
|
|
34350
34909
|
init_mesh_work_queue();
|
|
34351
|
-
import { homedir as
|
|
34910
|
+
import { homedir as homedir25, hostname as osHostname } from "os";
|
|
34352
34911
|
import { basename as pathBasename, join as pathJoin, resolve as pathResolve2 } from "path";
|
|
34353
|
-
import * as
|
|
34912
|
+
import * as fs22 from "fs";
|
|
34354
34913
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
34355
34914
|
var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
|
|
34356
34915
|
var CHANNEL_SERVER_URL = {
|
|
@@ -34477,12 +35036,12 @@ function readGitSubmodules(value, parentRepoRoot) {
|
|
|
34477
35036
|
if (!Array.isArray(value)) return void 0;
|
|
34478
35037
|
const submodules = value.map((entry) => {
|
|
34479
35038
|
const submodule = readObjectRecord(entry);
|
|
34480
|
-
const
|
|
35039
|
+
const path40 = readStringValue(submodule.path);
|
|
34481
35040
|
const commit = readStringValue(submodule.commit);
|
|
34482
|
-
const repoPath = readStringValue(submodule.repoPath, submodule.repo_root) ?? joinRepoPath(parentRepoRoot,
|
|
34483
|
-
if (!
|
|
35041
|
+
const repoPath = readStringValue(submodule.repoPath, submodule.repo_root) ?? joinRepoPath(parentRepoRoot, path40);
|
|
35042
|
+
if (!path40 || !commit || !repoPath) return null;
|
|
34484
35043
|
return {
|
|
34485
|
-
path:
|
|
35044
|
+
path: path40,
|
|
34486
35045
|
commit,
|
|
34487
35046
|
repoPath,
|
|
34488
35047
|
dirty: readBooleanValue(submodule.dirty) ?? false,
|
|
@@ -35124,7 +35683,7 @@ async function hydrateInlineMeshDirectTruth(args) {
|
|
|
35124
35683
|
if (!isSelfNode && daemonId) unavailableNodeIds.push(nodeId);
|
|
35125
35684
|
continue;
|
|
35126
35685
|
}
|
|
35127
|
-
if (
|
|
35686
|
+
if (fs22.existsSync(workspace)) {
|
|
35128
35687
|
try {
|
|
35129
35688
|
const localGit = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
|
|
35130
35689
|
if (localGit?.isGitRepo) {
|
|
@@ -35209,7 +35768,7 @@ function readLiveMeshNodeWorkspace(args) {
|
|
|
35209
35768
|
}
|
|
35210
35769
|
function collectLiveMeshSessionRecords(args) {
|
|
35211
35770
|
const nodeWorkspace = readStringValue(args.node?.workspace);
|
|
35212
|
-
const nodeIsMissingLocalWorktree = args.node?.isLocalWorktree === true && !!nodeWorkspace && !
|
|
35771
|
+
const nodeIsMissingLocalWorktree = args.node?.isLocalWorktree === true && !!nodeWorkspace && !fs22.existsSync(nodeWorkspace);
|
|
35213
35772
|
const matches = args.liveSessionRecords.filter((record) => {
|
|
35214
35773
|
const recordNodeId = readStringValue(record?.meta?.meshNodeId);
|
|
35215
35774
|
if (recordNodeId && recordNodeId !== args.nodeId) return false;
|
|
@@ -35236,7 +35795,7 @@ function buildHistoricalMeshSessions(args) {
|
|
|
35236
35795
|
const workspace = readStringValue(node?.workspace);
|
|
35237
35796
|
if (nodeId) liveNodeIds.add(nodeId);
|
|
35238
35797
|
if (workspace) liveWorkspaces.add(workspace);
|
|
35239
|
-
if (nodeId && node?.isLocalWorktree === true && workspace && !
|
|
35798
|
+
if (nodeId && node?.isLocalWorktree === true && workspace && !fs22.existsSync(workspace)) {
|
|
35240
35799
|
missingLocalWorktreeNodeIds.add(nodeId);
|
|
35241
35800
|
}
|
|
35242
35801
|
}
|
|
@@ -35435,10 +35994,10 @@ ${e?.stderr || ""}`
|
|
|
35435
35994
|
}
|
|
35436
35995
|
function buildPatchEquivalenceSubmoduleConflictHint(repoRoot, baseHead, branchHead, output) {
|
|
35437
35996
|
if (!/(submodule|160000)/i.test(output) || !/(conflict|failed to merge)/i.test(output)) return void 0;
|
|
35438
|
-
const conflicts = readChangedGitlinkPaths(repoRoot, baseHead, branchHead).map((
|
|
35439
|
-
path:
|
|
35440
|
-
baseCommit: readTreeObject(repoRoot, baseHead,
|
|
35441
|
-
branchCommit: readTreeObject(repoRoot, branchHead,
|
|
35997
|
+
const conflicts = readChangedGitlinkPaths(repoRoot, baseHead, branchHead).map((path40) => ({
|
|
35998
|
+
path: path40,
|
|
35999
|
+
baseCommit: readTreeObject(repoRoot, baseHead, path40),
|
|
36000
|
+
branchCommit: readTreeObject(repoRoot, branchHead, path40)
|
|
35442
36001
|
}));
|
|
35443
36002
|
if (conflicts.length === 0) return void 0;
|
|
35444
36003
|
return {
|
|
@@ -35464,11 +36023,11 @@ function readChangedGitlinkPaths(repoRoot, fromRef, toRef) {
|
|
|
35464
36023
|
if (!line.trim()) continue;
|
|
35465
36024
|
const metaAndPath = line.split(" ");
|
|
35466
36025
|
const meta = metaAndPath[0] || "";
|
|
35467
|
-
const
|
|
35468
|
-
if (!
|
|
36026
|
+
const path40 = metaAndPath[metaAndPath.length - 1]?.trim();
|
|
36027
|
+
if (!path40) continue;
|
|
35469
36028
|
const parts = meta.split(/\s+/);
|
|
35470
36029
|
if (parts[0]?.includes("160000") || parts[1]?.includes("160000")) {
|
|
35471
|
-
paths.add(
|
|
36030
|
+
paths.add(path40);
|
|
35472
36031
|
}
|
|
35473
36032
|
}
|
|
35474
36033
|
return [...paths].sort();
|
|
@@ -35476,9 +36035,9 @@ function readChangedGitlinkPaths(repoRoot, fromRef, toRef) {
|
|
|
35476
36035
|
return [];
|
|
35477
36036
|
}
|
|
35478
36037
|
}
|
|
35479
|
-
function readTreeObject(repoRoot, ref,
|
|
36038
|
+
function readTreeObject(repoRoot, ref, path40) {
|
|
35480
36039
|
try {
|
|
35481
|
-
const output = execFileSync5("git", ["ls-tree", ref, "--",
|
|
36040
|
+
const output = execFileSync5("git", ["ls-tree", ref, "--", path40], {
|
|
35482
36041
|
cwd: repoRoot,
|
|
35483
36042
|
encoding: "utf8",
|
|
35484
36043
|
maxBuffer: 1024 * 1024
|
|
@@ -35491,7 +36050,7 @@ function readTreeObject(repoRoot, ref, path39) {
|
|
|
35491
36050
|
}
|
|
35492
36051
|
async function alignRefinerySubmodulesAfterMerge(repoRoot, previousBaseHead, currentHead, options = {}) {
|
|
35493
36052
|
const startedAt = Date.now();
|
|
35494
|
-
const changedGitlinkPaths = readChangedGitlinkPaths(repoRoot, previousBaseHead, currentHead).filter((
|
|
36053
|
+
const changedGitlinkPaths = readChangedGitlinkPaths(repoRoot, previousBaseHead, currentHead).filter((path40) => !(options.submoduleIgnorePaths || []).includes(path40));
|
|
35495
36054
|
const preStatus = await getGitRepoStatus(repoRoot, {
|
|
35496
36055
|
includeSubmodules: true,
|
|
35497
36056
|
submoduleIgnorePaths: options.submoduleIgnorePaths,
|
|
@@ -35532,7 +36091,7 @@ async function alignRefinerySubmodulesAfterMerge(repoRoot, previousBaseHead, cur
|
|
|
35532
36091
|
changedGitlinkPaths,
|
|
35533
36092
|
outOfSyncPaths,
|
|
35534
36093
|
updatedPaths: updatePaths,
|
|
35535
|
-
verifiedPaths: updatePaths.filter((
|
|
36094
|
+
verifiedPaths: updatePaths.filter((path40) => !remaining.some((submodule) => submodule.path === path40)),
|
|
35536
36095
|
durationMs: Date.now() - startedAt,
|
|
35537
36096
|
command: `git ${commandArgs.join(" ")}`,
|
|
35538
36097
|
stdout: truncateValidationOutput(result.stdout),
|
|
@@ -35587,7 +36146,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
35587
36146
|
return { stdout: String(stdout || ""), stderr: String(stderr || ""), refspec };
|
|
35588
36147
|
};
|
|
35589
36148
|
const importCommitFromWorktreeSubmodule = async (submodulePath, worktreeSubmodulePath, commit) => {
|
|
35590
|
-
if (!
|
|
36149
|
+
if (!fs22.existsSync(worktreeSubmodulePath)) return false;
|
|
35591
36150
|
try {
|
|
35592
36151
|
await runGit3(worktreeSubmodulePath, ["cat-file", "-e", `${commit}^{commit}`]);
|
|
35593
36152
|
} catch {
|
|
@@ -35610,7 +36169,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
35610
36169
|
reachable: false
|
|
35611
36170
|
};
|
|
35612
36171
|
try {
|
|
35613
|
-
if (!
|
|
36172
|
+
if (!fs22.existsSync(submodulePath)) {
|
|
35614
36173
|
entry.error = `Submodule checkout missing at ${gitlink.path}`;
|
|
35615
36174
|
entry.publishRequired = true;
|
|
35616
36175
|
if (options.allowAutoPublishSubmoduleMainCommits === true) {
|
|
@@ -35802,9 +36361,9 @@ async function runMeshRefineValidationGate(mesh, workspace) {
|
|
|
35802
36361
|
return ["npm", "pnpm", "yarn", "bun"].includes(command) && candidate.args.some((arg) => arg === "run" || arg === "test" || arg === "exec");
|
|
35803
36362
|
};
|
|
35804
36363
|
const dependenciesLikelyMissing = (cwd) => {
|
|
35805
|
-
if (!
|
|
35806
|
-
if (
|
|
35807
|
-
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) =>
|
|
36364
|
+
if (!fs22.existsSync(pathJoin(cwd, "package.json"))) return false;
|
|
36365
|
+
if (fs22.existsSync(pathJoin(cwd, "node_modules"))) return false;
|
|
36366
|
+
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) => fs22.existsSync(pathJoin(cwd, lock)));
|
|
35808
36367
|
};
|
|
35809
36368
|
for (const candidate of selection.bootstrapCommands) {
|
|
35810
36369
|
const startedAt = Date.now();
|
|
@@ -35896,14 +36455,14 @@ function serializeMeshCoordinatorMcpConfig(config, format) {
|
|
|
35896
36455
|
}
|
|
35897
36456
|
function resolveHermesUserHome() {
|
|
35898
36457
|
const explicitHome = process.env.HERMES_HOME?.trim();
|
|
35899
|
-
return explicitHome || pathJoin(
|
|
36458
|
+
return explicitHome || pathJoin(homedir25(), ".hermes");
|
|
35900
36459
|
}
|
|
35901
36460
|
function loadHermesCoordinatorBaseConfig(targetConfigPath) {
|
|
35902
36461
|
const sourceHome = resolveHermesUserHome();
|
|
35903
36462
|
const sourceConfigPath = pathJoin(sourceHome, "config.yaml");
|
|
35904
|
-
if (!
|
|
36463
|
+
if (!fs22.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
35905
36464
|
if (pathResolve2(sourceConfigPath) === pathResolve2(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
35906
|
-
const parsed = parseMeshCoordinatorMcpConfig(
|
|
36465
|
+
const parsed = parseMeshCoordinatorMcpConfig(fs22.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
|
|
35907
36466
|
const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
|
|
35908
36467
|
return { config: baseConfig, sourceHome, sourceConfigPath };
|
|
35909
36468
|
}
|
|
@@ -35940,9 +36499,9 @@ function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
|
|
|
35940
36499
|
for (const fileName of [".env", "auth.json"]) {
|
|
35941
36500
|
const sourcePath = pathJoin(sourceHome, fileName);
|
|
35942
36501
|
const targetPath = pathJoin(targetHome, fileName);
|
|
35943
|
-
if (!
|
|
36502
|
+
if (!fs22.existsSync(sourcePath)) continue;
|
|
35944
36503
|
try {
|
|
35945
|
-
|
|
36504
|
+
fs22.copyFileSync(sourcePath, targetPath);
|
|
35946
36505
|
} catch (error) {
|
|
35947
36506
|
LOG.warn("MeshCoordinator", `Could not copy Hermes ${fileName} into isolated coordinator home: ${error?.message || error}`);
|
|
35948
36507
|
}
|
|
@@ -36297,13 +36856,13 @@ var DaemonCommandRouter = class {
|
|
|
36297
36856
|
recoveryHint: "Inspect the mesh node record before removing it, or remove stale metadata manually only after confirming no managed worktree remains."
|
|
36298
36857
|
};
|
|
36299
36858
|
}
|
|
36300
|
-
const worktreeExists =
|
|
36859
|
+
const worktreeExists = fs22.existsSync(workspace);
|
|
36301
36860
|
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);
|
|
36302
36861
|
const repoRoot = typeof sourceNode?.repoRoot === "string" && sourceNode.repoRoot.trim() ? sourceNode.repoRoot.trim() : typeof sourceNode?.workspace === "string" && sourceNode.workspace.trim() ? sourceNode.workspace.trim() : "";
|
|
36303
36862
|
if (!worktreeExists) {
|
|
36304
36863
|
return { success: true, skipped: true, removedPath: workspace, repoRoot: repoRoot || void 0, reason: "worktree_path_missing" };
|
|
36305
36864
|
}
|
|
36306
|
-
if (!repoRoot || !
|
|
36865
|
+
if (!repoRoot || !fs22.existsSync(repoRoot)) {
|
|
36307
36866
|
return {
|
|
36308
36867
|
success: false,
|
|
36309
36868
|
code: "mesh_worktree_cleanup_missing_source_repo",
|
|
@@ -36323,7 +36882,7 @@ var DaemonCommandRouter = class {
|
|
|
36323
36882
|
const normalizePath = (value) => {
|
|
36324
36883
|
const resolved = pathResolve2(value);
|
|
36325
36884
|
try {
|
|
36326
|
-
return
|
|
36885
|
+
return fs22.realpathSync(resolved);
|
|
36327
36886
|
} catch {
|
|
36328
36887
|
return resolved;
|
|
36329
36888
|
}
|
|
@@ -37262,8 +37821,8 @@ var DaemonCommandRouter = class {
|
|
|
37262
37821
|
if (sinceTs > 0) {
|
|
37263
37822
|
return { success: true, logs: [], totalBuffered: 0 };
|
|
37264
37823
|
}
|
|
37265
|
-
if (
|
|
37266
|
-
const content =
|
|
37824
|
+
if (fs22.existsSync(LOG_PATH)) {
|
|
37825
|
+
const content = fs22.readFileSync(LOG_PATH, "utf-8");
|
|
37267
37826
|
const allLines = content.split("\n");
|
|
37268
37827
|
const recent = allLines.slice(-count).join("\n");
|
|
37269
37828
|
return { success: true, logs: recent, totalLines: allLines.length };
|
|
@@ -37653,24 +38212,24 @@ var DaemonCommandRouter = class {
|
|
|
37653
38212
|
// Settings page in the dashboard reads/writes via these two
|
|
37654
38213
|
// commands instead of going through fs from the browser.
|
|
37655
38214
|
case "list_coordinator_prompts": {
|
|
37656
|
-
const
|
|
37657
|
-
const
|
|
37658
|
-
const
|
|
37659
|
-
const dir =
|
|
38215
|
+
const fs28 = await import("fs");
|
|
38216
|
+
const path40 = await import("path");
|
|
38217
|
+
const os29 = await import("os");
|
|
38218
|
+
const dir = path40.join(os29.homedir(), ".adhdev", "coordinator-prompts");
|
|
37660
38219
|
const entries = {};
|
|
37661
38220
|
try {
|
|
37662
|
-
if (
|
|
37663
|
-
for (const name of
|
|
38221
|
+
if (fs28.existsSync(dir)) {
|
|
38222
|
+
for (const name of fs28.readdirSync(dir)) {
|
|
37664
38223
|
const matchOverride = name.match(/^([a-zA-Z0-9_.-]+)\.md$/);
|
|
37665
38224
|
const matchAppend = name.match(/^([a-zA-Z0-9_.-]+)\.append\.md$/);
|
|
37666
38225
|
const m = matchAppend || matchOverride;
|
|
37667
38226
|
if (!m) continue;
|
|
37668
38227
|
const isAppend = !!matchAppend;
|
|
37669
38228
|
const key = m[1];
|
|
37670
|
-
const full =
|
|
38229
|
+
const full = path40.join(dir, name);
|
|
37671
38230
|
let content = "";
|
|
37672
38231
|
try {
|
|
37673
|
-
content =
|
|
38232
|
+
content = fs28.readFileSync(full, "utf8");
|
|
37674
38233
|
} catch {
|
|
37675
38234
|
}
|
|
37676
38235
|
if (!entries[key]) entries[key] = { override: "", append: "" };
|
|
@@ -37684,24 +38243,24 @@ var DaemonCommandRouter = class {
|
|
|
37684
38243
|
return { success: true, dir, entries };
|
|
37685
38244
|
}
|
|
37686
38245
|
case "write_coordinator_prompt": {
|
|
37687
|
-
const
|
|
37688
|
-
const
|
|
37689
|
-
const
|
|
38246
|
+
const fs28 = await import("fs");
|
|
38247
|
+
const path40 = await import("path");
|
|
38248
|
+
const os29 = await import("os");
|
|
37690
38249
|
const key = typeof args?.key === "string" ? args.key.trim() : "";
|
|
37691
38250
|
const kind = args?.kind === "append" ? "append" : "override";
|
|
37692
38251
|
const content = typeof args?.content === "string" ? args.content : "";
|
|
37693
38252
|
if (!key || !/^[a-zA-Z0-9_.-]+$/.test(key)) {
|
|
37694
38253
|
return { success: false, error: "key must match [a-zA-Z0-9_.-]+" };
|
|
37695
38254
|
}
|
|
37696
|
-
const dir =
|
|
38255
|
+
const dir = path40.join(os29.homedir(), ".adhdev", "coordinator-prompts");
|
|
37697
38256
|
const filename = kind === "append" ? `${key}.append.md` : `${key}.md`;
|
|
37698
|
-
const full =
|
|
38257
|
+
const full = path40.join(dir, filename);
|
|
37699
38258
|
try {
|
|
37700
|
-
|
|
38259
|
+
fs28.mkdirSync(dir, { recursive: true });
|
|
37701
38260
|
if (content.trim()) {
|
|
37702
|
-
|
|
37703
|
-
} else if (
|
|
37704
|
-
|
|
38261
|
+
fs28.writeFileSync(full, content, { encoding: "utf8", mode: 384 });
|
|
38262
|
+
} else if (fs28.existsSync(full)) {
|
|
38263
|
+
fs28.unlinkSync(full);
|
|
37705
38264
|
}
|
|
37706
38265
|
return { success: true, path: full, kind, key };
|
|
37707
38266
|
} catch (error) {
|
|
@@ -38910,7 +39469,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
38910
39469
|
workspace
|
|
38911
39470
|
};
|
|
38912
39471
|
}
|
|
38913
|
-
const { existsSync:
|
|
39472
|
+
const { existsSync: existsSync39, readFileSync: readFileSync33, writeFileSync: writeFileSync20, copyFileSync: copyFileSync4, mkdirSync: mkdirSync19 } = await import("fs");
|
|
38914
39473
|
const { dirname: dirname11 } = await import("path");
|
|
38915
39474
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
38916
39475
|
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
@@ -38946,21 +39505,21 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
38946
39505
|
};
|
|
38947
39506
|
}
|
|
38948
39507
|
try {
|
|
38949
|
-
|
|
39508
|
+
mkdirSync19(dirname11(mcpConfigPath), { recursive: true });
|
|
38950
39509
|
} catch (error) {
|
|
38951
39510
|
const message = `Could not prepare MCP config path for automatic setup: ${error?.message || error}`;
|
|
38952
39511
|
LOG.error("MeshCoordinator", message);
|
|
38953
39512
|
if (hermesManualFallback) return returnManualFallback(message);
|
|
38954
39513
|
return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
|
|
38955
39514
|
}
|
|
38956
|
-
const hadExistingMcpConfig =
|
|
39515
|
+
const hadExistingMcpConfig = existsSync39(mcpConfigPath);
|
|
38957
39516
|
let existingMcpConfig = hermesBaseConfig?.config || {};
|
|
38958
39517
|
if (hermesBaseConfig) {
|
|
38959
39518
|
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname11(mcpConfigPath));
|
|
38960
39519
|
}
|
|
38961
39520
|
if (hadExistingMcpConfig) {
|
|
38962
39521
|
try {
|
|
38963
|
-
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(
|
|
39522
|
+
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync33(mcpConfigPath, "utf-8"), configFormat);
|
|
38964
39523
|
const existingCoordinatorConfig = hermesManualFallback ? stripHermesCoordinatorTempModelProviderOverrides(parsedExistingMcpConfig) : parsedExistingMcpConfig;
|
|
38965
39524
|
existingMcpConfig = { ...existingMcpConfig, ...existingCoordinatorConfig };
|
|
38966
39525
|
copyFileSync4(mcpConfigPath, mcpConfigPath + ".backup");
|
|
@@ -38983,7 +39542,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
38983
39542
|
}
|
|
38984
39543
|
};
|
|
38985
39544
|
try {
|
|
38986
|
-
|
|
39545
|
+
writeFileSync20(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
|
|
38987
39546
|
} catch (error) {
|
|
38988
39547
|
const message = `Could not write MCP config for automatic setup: ${error?.message || error}`;
|
|
38989
39548
|
LOG.error("MeshCoordinator", message);
|
|
@@ -39262,7 +39821,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
39262
39821
|
}
|
|
39263
39822
|
}
|
|
39264
39823
|
if (workspace) {
|
|
39265
|
-
if (!
|
|
39824
|
+
if (!fs22.existsSync(workspace)) {
|
|
39266
39825
|
const inlineTransitGit = buildInlineMeshTransitGitStatus(node);
|
|
39267
39826
|
let remoteProbeApplied = false;
|
|
39268
39827
|
if (inlineTransitGit) {
|
|
@@ -39375,7 +39934,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
39375
39934
|
const callerCoordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : this.deps.statusInstanceId || void 0;
|
|
39376
39935
|
const pendingCoordinatorEvents = drainPendingMeshCoordinatorEvents(meshId, callerCoordinatorDaemonId);
|
|
39377
39936
|
const previewFreshness = (() => {
|
|
39378
|
-
const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate &&
|
|
39937
|
+
const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate && fs22.existsSync(candidate));
|
|
39379
39938
|
return localRepoRoot ? buildPreviewFreshness(localRepoRoot) : void 0;
|
|
39380
39939
|
})();
|
|
39381
39940
|
const asyncRefineJobs = buildMeshAsyncRefineJobs({
|
|
@@ -41122,12 +41681,12 @@ var ProviderInstanceManager = class {
|
|
|
41122
41681
|
};
|
|
41123
41682
|
|
|
41124
41683
|
// src/providers/version-archive.ts
|
|
41125
|
-
import * as
|
|
41126
|
-
import * as
|
|
41127
|
-
import * as
|
|
41684
|
+
import * as fs23 from "fs";
|
|
41685
|
+
import * as path35 from "path";
|
|
41686
|
+
import * as os27 from "os";
|
|
41128
41687
|
import { platform as platform8 } from "os";
|
|
41129
41688
|
import { exec as exec5 } from "child_process";
|
|
41130
|
-
var ARCHIVE_PATH =
|
|
41689
|
+
var ARCHIVE_PATH = path35.join(os27.homedir(), ".adhdev", "version-history.json");
|
|
41131
41690
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
41132
41691
|
var VersionArchive = class {
|
|
41133
41692
|
history = {};
|
|
@@ -41136,8 +41695,8 @@ var VersionArchive = class {
|
|
|
41136
41695
|
}
|
|
41137
41696
|
load() {
|
|
41138
41697
|
try {
|
|
41139
|
-
if (
|
|
41140
|
-
this.history = JSON.parse(
|
|
41698
|
+
if (fs23.existsSync(ARCHIVE_PATH)) {
|
|
41699
|
+
this.history = JSON.parse(fs23.readFileSync(ARCHIVE_PATH, "utf-8"));
|
|
41141
41700
|
}
|
|
41142
41701
|
} catch {
|
|
41143
41702
|
this.history = {};
|
|
@@ -41174,8 +41733,8 @@ var VersionArchive = class {
|
|
|
41174
41733
|
}
|
|
41175
41734
|
save() {
|
|
41176
41735
|
try {
|
|
41177
|
-
|
|
41178
|
-
|
|
41736
|
+
fs23.mkdirSync(path35.dirname(ARCHIVE_PATH), { recursive: true });
|
|
41737
|
+
fs23.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
41179
41738
|
} catch {
|
|
41180
41739
|
}
|
|
41181
41740
|
}
|
|
@@ -41198,10 +41757,10 @@ function findBinary2(name) {
|
|
|
41198
41757
|
for (const p of paths) {
|
|
41199
41758
|
if (!p) continue;
|
|
41200
41759
|
for (const ext of exes) {
|
|
41201
|
-
const fullPath =
|
|
41760
|
+
const fullPath = path35.join(p, name + ext);
|
|
41202
41761
|
try {
|
|
41203
|
-
if (
|
|
41204
|
-
const stat2 =
|
|
41762
|
+
if (fs23.existsSync(fullPath)) {
|
|
41763
|
+
const stat2 = fs23.statSync(fullPath);
|
|
41205
41764
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
41206
41765
|
return fullPath;
|
|
41207
41766
|
}
|
|
@@ -41246,19 +41805,19 @@ async function getVersion(binary, versionCommand) {
|
|
|
41246
41805
|
function checkPathExists2(paths) {
|
|
41247
41806
|
for (const p of paths) {
|
|
41248
41807
|
if (p.includes("*")) {
|
|
41249
|
-
const home =
|
|
41250
|
-
const resolved = p.replace(/\*/g, home.split(
|
|
41251
|
-
if (
|
|
41808
|
+
const home = os27.homedir();
|
|
41809
|
+
const resolved = p.replace(/\*/g, home.split(path35.sep).pop() || "");
|
|
41810
|
+
if (fs23.existsSync(resolved)) return resolved;
|
|
41252
41811
|
} else {
|
|
41253
|
-
if (
|
|
41812
|
+
if (fs23.existsSync(p)) return p;
|
|
41254
41813
|
}
|
|
41255
41814
|
}
|
|
41256
41815
|
return null;
|
|
41257
41816
|
}
|
|
41258
41817
|
async function getMacAppVersion(appPath) {
|
|
41259
41818
|
if (platform8() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
41260
|
-
const plistPath =
|
|
41261
|
-
if (!
|
|
41819
|
+
const plistPath = path35.join(appPath, "Contents", "Info.plist");
|
|
41820
|
+
if (!fs23.existsSync(plistPath)) return null;
|
|
41262
41821
|
const raw = await runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
41263
41822
|
return raw || null;
|
|
41264
41823
|
}
|
|
@@ -41283,8 +41842,8 @@ async function detectAllVersions(loader, archive) {
|
|
|
41283
41842
|
const cliBin = provider.cli ? findBinary2(provider.cli) : null;
|
|
41284
41843
|
let resolvedBin = cliBin;
|
|
41285
41844
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
41286
|
-
const bundled =
|
|
41287
|
-
if (provider.cli &&
|
|
41845
|
+
const bundled = path35.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
41846
|
+
if (provider.cli && fs23.existsSync(bundled)) resolvedBin = bundled;
|
|
41288
41847
|
}
|
|
41289
41848
|
info.installed = !!(appPath || resolvedBin);
|
|
41290
41849
|
info.path = appPath || null;
|
|
@@ -41323,8 +41882,8 @@ async function detectAllVersions(loader, archive) {
|
|
|
41323
41882
|
|
|
41324
41883
|
// src/daemon/dev-server.ts
|
|
41325
41884
|
import * as http2 from "http";
|
|
41326
|
-
import * as
|
|
41327
|
-
import * as
|
|
41885
|
+
import * as fs27 from "fs";
|
|
41886
|
+
import * as path39 from "path";
|
|
41328
41887
|
init_config();
|
|
41329
41888
|
|
|
41330
41889
|
// src/daemon/scaffold-template.ts
|
|
@@ -41675,8 +42234,8 @@ init_logger();
|
|
|
41675
42234
|
|
|
41676
42235
|
// src/daemon/dev-cdp-handlers.ts
|
|
41677
42236
|
init_logger();
|
|
41678
|
-
import * as
|
|
41679
|
-
import * as
|
|
42237
|
+
import * as fs24 from "fs";
|
|
42238
|
+
import * as path36 from "path";
|
|
41680
42239
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
41681
42240
|
const body = await ctx.readBody(req);
|
|
41682
42241
|
const { expression, timeout, ideType } = body;
|
|
@@ -41854,18 +42413,18 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
41854
42413
|
return;
|
|
41855
42414
|
}
|
|
41856
42415
|
let scriptsPath = "";
|
|
41857
|
-
const directScripts =
|
|
41858
|
-
if (
|
|
42416
|
+
const directScripts = path36.join(dir, "scripts.js");
|
|
42417
|
+
if (fs24.existsSync(directScripts)) {
|
|
41859
42418
|
scriptsPath = directScripts;
|
|
41860
42419
|
} else {
|
|
41861
|
-
const scriptsDir =
|
|
41862
|
-
if (
|
|
41863
|
-
const versions =
|
|
41864
|
-
return
|
|
42420
|
+
const scriptsDir = path36.join(dir, "scripts");
|
|
42421
|
+
if (fs24.existsSync(scriptsDir)) {
|
|
42422
|
+
const versions = fs24.readdirSync(scriptsDir).filter((d) => {
|
|
42423
|
+
return fs24.statSync(path36.join(scriptsDir, d)).isDirectory();
|
|
41865
42424
|
}).sort().reverse();
|
|
41866
42425
|
for (const ver of versions) {
|
|
41867
|
-
const p =
|
|
41868
|
-
if (
|
|
42426
|
+
const p = path36.join(scriptsDir, ver, "scripts.js");
|
|
42427
|
+
if (fs24.existsSync(p)) {
|
|
41869
42428
|
scriptsPath = p;
|
|
41870
42429
|
break;
|
|
41871
42430
|
}
|
|
@@ -41877,7 +42436,7 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
41877
42436
|
return;
|
|
41878
42437
|
}
|
|
41879
42438
|
try {
|
|
41880
|
-
const source =
|
|
42439
|
+
const source = fs24.readFileSync(scriptsPath, "utf-8");
|
|
41881
42440
|
const hints = {};
|
|
41882
42441
|
const funcRegex = /module\.exports\.(\w+)\s*=\s*function\s+\w+\s*\(params\)/g;
|
|
41883
42442
|
let match;
|
|
@@ -42692,8 +43251,8 @@ async function handleDomContext(ctx, type, req, res) {
|
|
|
42692
43251
|
}
|
|
42693
43252
|
|
|
42694
43253
|
// src/daemon/dev-cli-debug.ts
|
|
42695
|
-
import * as
|
|
42696
|
-
import * as
|
|
43254
|
+
import * as fs25 from "fs";
|
|
43255
|
+
import * as path37 from "path";
|
|
42697
43256
|
function slugifyFixtureName(value) {
|
|
42698
43257
|
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
42699
43258
|
return normalized || `fixture-${Date.now()}`;
|
|
@@ -42703,15 +43262,15 @@ function getCliFixtureDir(ctx, type) {
|
|
|
42703
43262
|
if (!providerDir) {
|
|
42704
43263
|
throw new Error(`Provider directory not found for '${type}'`);
|
|
42705
43264
|
}
|
|
42706
|
-
return
|
|
43265
|
+
return path37.join(providerDir, "fixtures");
|
|
42707
43266
|
}
|
|
42708
43267
|
function readCliFixture(ctx, type, name) {
|
|
42709
43268
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
42710
|
-
const filePath =
|
|
42711
|
-
if (!
|
|
43269
|
+
const filePath = path37.join(fixtureDir, `${name}.json`);
|
|
43270
|
+
if (!fs25.existsSync(filePath)) {
|
|
42712
43271
|
throw new Error(`Fixture not found: ${filePath}`);
|
|
42713
43272
|
}
|
|
42714
|
-
return JSON.parse(
|
|
43273
|
+
return JSON.parse(fs25.readFileSync(filePath, "utf-8"));
|
|
42715
43274
|
}
|
|
42716
43275
|
function getExerciseTranscriptText(result) {
|
|
42717
43276
|
const parts = [];
|
|
@@ -43456,7 +44015,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
43456
44015
|
return;
|
|
43457
44016
|
}
|
|
43458
44017
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
43459
|
-
|
|
44018
|
+
fs25.mkdirSync(fixtureDir, { recursive: true });
|
|
43460
44019
|
const name = slugifyFixtureName(String(body?.name || `${type}-${Date.now()}`));
|
|
43461
44020
|
const result = await runCliExerciseInternal(ctx, { ...request, type });
|
|
43462
44021
|
const fixture = {
|
|
@@ -43483,8 +44042,8 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
43483
44042
|
},
|
|
43484
44043
|
notes: typeof body?.notes === "string" ? body.notes : void 0
|
|
43485
44044
|
};
|
|
43486
|
-
const filePath =
|
|
43487
|
-
|
|
44045
|
+
const filePath = path37.join(fixtureDir, `${name}.json`);
|
|
44046
|
+
fs25.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
|
|
43488
44047
|
ctx.json(res, 200, {
|
|
43489
44048
|
saved: true,
|
|
43490
44049
|
name,
|
|
@@ -43502,14 +44061,14 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
43502
44061
|
async function handleCliFixtureList(ctx, type, _req, res) {
|
|
43503
44062
|
try {
|
|
43504
44063
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
43505
|
-
if (!
|
|
44064
|
+
if (!fs25.existsSync(fixtureDir)) {
|
|
43506
44065
|
ctx.json(res, 200, { fixtures: [], count: 0 });
|
|
43507
44066
|
return;
|
|
43508
44067
|
}
|
|
43509
|
-
const fixtures =
|
|
43510
|
-
const fullPath =
|
|
44068
|
+
const fixtures = fs25.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
|
|
44069
|
+
const fullPath = path37.join(fixtureDir, file);
|
|
43511
44070
|
try {
|
|
43512
|
-
const raw = JSON.parse(
|
|
44071
|
+
const raw = JSON.parse(fs25.readFileSync(fullPath, "utf-8"));
|
|
43513
44072
|
return {
|
|
43514
44073
|
name: raw.name || file.replace(/\.json$/i, ""),
|
|
43515
44074
|
path: fullPath,
|
|
@@ -43642,9 +44201,9 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
43642
44201
|
}
|
|
43643
44202
|
|
|
43644
44203
|
// src/daemon/dev-auto-implement.ts
|
|
43645
|
-
import * as
|
|
43646
|
-
import * as
|
|
43647
|
-
import * as
|
|
44204
|
+
import * as fs26 from "fs";
|
|
44205
|
+
import * as path38 from "path";
|
|
44206
|
+
import * as os28 from "os";
|
|
43648
44207
|
function getAutoImplPid(ctx) {
|
|
43649
44208
|
const pid = ctx.autoImplProcess?.pid;
|
|
43650
44209
|
return typeof pid === "number" && pid > 0 ? pid : null;
|
|
@@ -43690,38 +44249,38 @@ function resolveAutoImplReference(ctx, category, requestedReference, targetType)
|
|
|
43690
44249
|
return fallback?.type || null;
|
|
43691
44250
|
}
|
|
43692
44251
|
function getLatestScriptVersionDir(scriptsDir) {
|
|
43693
|
-
if (!
|
|
43694
|
-
const versions =
|
|
44252
|
+
if (!fs26.existsSync(scriptsDir)) return null;
|
|
44253
|
+
const versions = fs26.readdirSync(scriptsDir).filter((d) => {
|
|
43695
44254
|
try {
|
|
43696
|
-
return
|
|
44255
|
+
return fs26.statSync(path38.join(scriptsDir, d)).isDirectory();
|
|
43697
44256
|
} catch {
|
|
43698
44257
|
return false;
|
|
43699
44258
|
}
|
|
43700
44259
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
43701
44260
|
if (versions.length === 0) return null;
|
|
43702
|
-
return
|
|
44261
|
+
return path38.join(scriptsDir, versions[0]);
|
|
43703
44262
|
}
|
|
43704
44263
|
function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
43705
|
-
const canonicalUserDir =
|
|
43706
|
-
const desiredDir = requestedDir ?
|
|
43707
|
-
const upstreamRoot =
|
|
43708
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
44264
|
+
const canonicalUserDir = path38.resolve(ctx.providerLoader.getUserProviderDir(category, type));
|
|
44265
|
+
const desiredDir = requestedDir ? path38.resolve(requestedDir) : canonicalUserDir;
|
|
44266
|
+
const upstreamRoot = path38.resolve(ctx.providerLoader.getUpstreamDir());
|
|
44267
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path38.sep}`)) {
|
|
43709
44268
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
43710
44269
|
}
|
|
43711
|
-
if (
|
|
44270
|
+
if (path38.basename(desiredDir) !== type) {
|
|
43712
44271
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
43713
44272
|
}
|
|
43714
44273
|
const sourceDir = ctx.findProviderDir(type);
|
|
43715
44274
|
if (!sourceDir) {
|
|
43716
44275
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
43717
44276
|
}
|
|
43718
|
-
if (!
|
|
43719
|
-
|
|
43720
|
-
|
|
44277
|
+
if (!fs26.existsSync(desiredDir)) {
|
|
44278
|
+
fs26.mkdirSync(path38.dirname(desiredDir), { recursive: true });
|
|
44279
|
+
fs26.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
43721
44280
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
43722
44281
|
}
|
|
43723
|
-
const providerJson =
|
|
43724
|
-
if (!
|
|
44282
|
+
const providerJson = path38.join(desiredDir, "provider.json");
|
|
44283
|
+
if (!fs26.existsSync(providerJson)) {
|
|
43725
44284
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
43726
44285
|
}
|
|
43727
44286
|
return { dir: desiredDir };
|
|
@@ -43729,15 +44288,15 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
43729
44288
|
function loadAutoImplReferenceScripts(ctx, referenceType) {
|
|
43730
44289
|
if (!referenceType) return {};
|
|
43731
44290
|
const refDir = ctx.findProviderDir(referenceType);
|
|
43732
|
-
if (!refDir || !
|
|
44291
|
+
if (!refDir || !fs26.existsSync(refDir)) return {};
|
|
43733
44292
|
const referenceScripts = {};
|
|
43734
|
-
const scriptsDir =
|
|
44293
|
+
const scriptsDir = path38.join(refDir, "scripts");
|
|
43735
44294
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
43736
44295
|
if (!latestDir) return referenceScripts;
|
|
43737
|
-
for (const file of
|
|
44296
|
+
for (const file of fs26.readdirSync(latestDir)) {
|
|
43738
44297
|
if (!file.endsWith(".js")) continue;
|
|
43739
44298
|
try {
|
|
43740
|
-
referenceScripts[file] =
|
|
44299
|
+
referenceScripts[file] = fs26.readFileSync(path38.join(latestDir, file), "utf-8");
|
|
43741
44300
|
} catch {
|
|
43742
44301
|
}
|
|
43743
44302
|
}
|
|
@@ -43845,16 +44404,16 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
43845
44404
|
});
|
|
43846
44405
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
43847
44406
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
43848
|
-
const tmpDir =
|
|
43849
|
-
if (!
|
|
43850
|
-
const promptFile =
|
|
43851
|
-
|
|
44407
|
+
const tmpDir = path38.join(os28.tmpdir(), "adhdev-autoimpl");
|
|
44408
|
+
if (!fs26.existsSync(tmpDir)) fs26.mkdirSync(tmpDir, { recursive: true });
|
|
44409
|
+
const promptFile = path38.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
44410
|
+
fs26.writeFileSync(promptFile, prompt, "utf-8");
|
|
43852
44411
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
43853
44412
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
43854
44413
|
const spawn4 = agentProvider?.spawn;
|
|
43855
44414
|
if (!spawn4?.command) {
|
|
43856
44415
|
try {
|
|
43857
|
-
|
|
44416
|
+
fs26.unlinkSync(promptFile);
|
|
43858
44417
|
} catch {
|
|
43859
44418
|
}
|
|
43860
44419
|
ctx.json(res, 400, { error: `Agent '${agent}' has no spawn config. Select a CLI provider with a spawn configuration.` });
|
|
@@ -43956,7 +44515,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
43956
44515
|
} catch {
|
|
43957
44516
|
}
|
|
43958
44517
|
try {
|
|
43959
|
-
|
|
44518
|
+
fs26.unlinkSync(promptFile);
|
|
43960
44519
|
} catch {
|
|
43961
44520
|
}
|
|
43962
44521
|
ctx.log(`Auto-implement (ACP) ${success ? "completed" : "failed"}: ${type} (exit: ${code})`);
|
|
@@ -44000,7 +44559,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
44000
44559
|
const interactiveFlags = ["--yolo", "--interactive", "-i"];
|
|
44001
44560
|
const baseArgs = [...spawn4.args || []].filter((a) => !interactiveFlags.includes(a));
|
|
44002
44561
|
let shellCmd;
|
|
44003
|
-
const isWin =
|
|
44562
|
+
const isWin = os28.platform() === "win32";
|
|
44004
44563
|
const escapeArg = (a) => isWin ? `"${a.replace(/"/g, '""')}"` : `'${a.replace(/'/g, "'\\''")}'`;
|
|
44005
44564
|
const promptMode = autoImpl?.promptMode ?? "stdin";
|
|
44006
44565
|
const extraArgs = autoImpl?.extraArgs ?? [];
|
|
@@ -44039,7 +44598,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
44039
44598
|
try {
|
|
44040
44599
|
const pty = __require("node-pty");
|
|
44041
44600
|
ctx.log(`Auto-implement spawn (PTY): ${shellCmd}`);
|
|
44042
|
-
const isWin2 =
|
|
44601
|
+
const isWin2 = os28.platform() === "win32";
|
|
44043
44602
|
child = pty.spawn(isWin2 ? "cmd.exe" : process.env.SHELL || "/bin/zsh", [isWin2 ? "/c" : "-c", shellCmd], {
|
|
44044
44603
|
name: "xterm-256color",
|
|
44045
44604
|
cols: 120,
|
|
@@ -44182,7 +44741,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
44182
44741
|
}
|
|
44183
44742
|
});
|
|
44184
44743
|
try {
|
|
44185
|
-
|
|
44744
|
+
fs26.unlinkSync(promptFile);
|
|
44186
44745
|
} catch {
|
|
44187
44746
|
}
|
|
44188
44747
|
ctx.log(`Auto-implement ${success ? "completed" : "failed"}: ${type} (exit: ${code})${verificationSummary ? ` verify=${verificationSummary.pass ? "pass" : "fail"}` : ""}`);
|
|
@@ -44279,7 +44838,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
44279
44838
|
setMode: "set_mode.js"
|
|
44280
44839
|
};
|
|
44281
44840
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
44282
|
-
const scriptsDir =
|
|
44841
|
+
const scriptsDir = path38.join(providerDir, "scripts");
|
|
44283
44842
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
44284
44843
|
if (latestScriptsDir) {
|
|
44285
44844
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -44287,10 +44846,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
44287
44846
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
44288
44847
|
lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
|
|
44289
44848
|
lines.push("");
|
|
44290
|
-
for (const file of
|
|
44849
|
+
for (const file of fs26.readdirSync(latestScriptsDir)) {
|
|
44291
44850
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
44292
44851
|
try {
|
|
44293
|
-
const content =
|
|
44852
|
+
const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
|
|
44294
44853
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
44295
44854
|
lines.push("```javascript");
|
|
44296
44855
|
lines.push(content);
|
|
@@ -44300,14 +44859,14 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
44300
44859
|
}
|
|
44301
44860
|
}
|
|
44302
44861
|
}
|
|
44303
|
-
const refFiles =
|
|
44862
|
+
const refFiles = fs26.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
44304
44863
|
if (refFiles.length > 0) {
|
|
44305
44864
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
44306
44865
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
44307
44866
|
lines.push("");
|
|
44308
44867
|
for (const file of refFiles) {
|
|
44309
44868
|
try {
|
|
44310
|
-
const content =
|
|
44869
|
+
const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
|
|
44311
44870
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
44312
44871
|
lines.push("```javascript");
|
|
44313
44872
|
lines.push(content);
|
|
@@ -44348,11 +44907,11 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
44348
44907
|
lines.push("");
|
|
44349
44908
|
}
|
|
44350
44909
|
}
|
|
44351
|
-
const docsDir =
|
|
44910
|
+
const docsDir = path38.join(providerDir, "../../docs");
|
|
44352
44911
|
const loadGuide = (name) => {
|
|
44353
44912
|
try {
|
|
44354
|
-
const p =
|
|
44355
|
-
if (
|
|
44913
|
+
const p = path38.join(docsDir, name);
|
|
44914
|
+
if (fs26.existsSync(p)) return fs26.readFileSync(p, "utf-8");
|
|
44356
44915
|
} catch {
|
|
44357
44916
|
}
|
|
44358
44917
|
return null;
|
|
@@ -44588,7 +45147,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
44588
45147
|
parseApproval: "parse_approval.js"
|
|
44589
45148
|
};
|
|
44590
45149
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
44591
|
-
const scriptsDir =
|
|
45150
|
+
const scriptsDir = path38.join(providerDir, "scripts");
|
|
44592
45151
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
44593
45152
|
if (latestScriptsDir) {
|
|
44594
45153
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -44596,11 +45155,11 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
44596
45155
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
44597
45156
|
lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
|
|
44598
45157
|
lines.push("");
|
|
44599
|
-
for (const file of
|
|
45158
|
+
for (const file of fs26.readdirSync(latestScriptsDir)) {
|
|
44600
45159
|
if (!file.endsWith(".js")) continue;
|
|
44601
45160
|
if (!targetFileNames.has(file)) continue;
|
|
44602
45161
|
try {
|
|
44603
|
-
const content =
|
|
45162
|
+
const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
|
|
44604
45163
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
44605
45164
|
lines.push("```javascript");
|
|
44606
45165
|
lines.push(content);
|
|
@@ -44609,14 +45168,14 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
44609
45168
|
} catch {
|
|
44610
45169
|
}
|
|
44611
45170
|
}
|
|
44612
|
-
const refFiles =
|
|
45171
|
+
const refFiles = fs26.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
44613
45172
|
if (refFiles.length > 0) {
|
|
44614
45173
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
44615
45174
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
44616
45175
|
lines.push("");
|
|
44617
45176
|
for (const file of refFiles) {
|
|
44618
45177
|
try {
|
|
44619
|
-
const content =
|
|
45178
|
+
const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
|
|
44620
45179
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
44621
45180
|
lines.push("```javascript");
|
|
44622
45181
|
lines.push(content);
|
|
@@ -44649,11 +45208,11 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
44649
45208
|
lines.push("");
|
|
44650
45209
|
}
|
|
44651
45210
|
}
|
|
44652
|
-
const docsDir =
|
|
45211
|
+
const docsDir = path38.join(providerDir, "../../docs");
|
|
44653
45212
|
const loadGuide = (name) => {
|
|
44654
45213
|
try {
|
|
44655
|
-
const p =
|
|
44656
|
-
if (
|
|
45214
|
+
const p = path38.join(docsDir, name);
|
|
45215
|
+
if (fs26.existsSync(p)) return fs26.readFileSync(p, "utf-8");
|
|
44657
45216
|
} catch {
|
|
44658
45217
|
}
|
|
44659
45218
|
return null;
|
|
@@ -45099,8 +45658,8 @@ var DevServer = class _DevServer {
|
|
|
45099
45658
|
}
|
|
45100
45659
|
getEndpointList() {
|
|
45101
45660
|
return this.routes.map((r) => {
|
|
45102
|
-
const
|
|
45103
|
-
return `${r.method.padEnd(5)} ${
|
|
45661
|
+
const path40 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
|
|
45662
|
+
return `${r.method.padEnd(5)} ${path40}`;
|
|
45104
45663
|
});
|
|
45105
45664
|
}
|
|
45106
45665
|
async start(port = DEV_SERVER_PORT) {
|
|
@@ -45388,12 +45947,12 @@ var DevServer = class _DevServer {
|
|
|
45388
45947
|
// ─── DevConsole SPA ───
|
|
45389
45948
|
getConsoleDistDir() {
|
|
45390
45949
|
const candidates = [
|
|
45391
|
-
|
|
45392
|
-
|
|
45393
|
-
|
|
45950
|
+
path39.resolve(__dirname, "../../web-devconsole/dist"),
|
|
45951
|
+
path39.resolve(__dirname, "../../../web-devconsole/dist"),
|
|
45952
|
+
path39.join(process.cwd(), "packages/web-devconsole/dist")
|
|
45394
45953
|
];
|
|
45395
45954
|
for (const dir of candidates) {
|
|
45396
|
-
if (
|
|
45955
|
+
if (fs27.existsSync(path39.join(dir, "index.html"))) return dir;
|
|
45397
45956
|
}
|
|
45398
45957
|
return null;
|
|
45399
45958
|
}
|
|
@@ -45403,9 +45962,9 @@ var DevServer = class _DevServer {
|
|
|
45403
45962
|
this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
|
|
45404
45963
|
return;
|
|
45405
45964
|
}
|
|
45406
|
-
const htmlPath =
|
|
45965
|
+
const htmlPath = path39.join(distDir, "index.html");
|
|
45407
45966
|
try {
|
|
45408
|
-
const html =
|
|
45967
|
+
const html = fs27.readFileSync(htmlPath, "utf-8");
|
|
45409
45968
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
45410
45969
|
res.end(html);
|
|
45411
45970
|
} catch (e) {
|
|
@@ -45428,15 +45987,15 @@ var DevServer = class _DevServer {
|
|
|
45428
45987
|
this.json(res, 404, { error: "Not found" });
|
|
45429
45988
|
return;
|
|
45430
45989
|
}
|
|
45431
|
-
const safePath =
|
|
45432
|
-
const filePath =
|
|
45990
|
+
const safePath = path39.normalize(pathname).replace(/^\.\.\//, "");
|
|
45991
|
+
const filePath = path39.join(distDir, safePath);
|
|
45433
45992
|
if (!filePath.startsWith(distDir)) {
|
|
45434
45993
|
this.json(res, 403, { error: "Forbidden" });
|
|
45435
45994
|
return;
|
|
45436
45995
|
}
|
|
45437
45996
|
try {
|
|
45438
|
-
const content =
|
|
45439
|
-
const ext =
|
|
45997
|
+
const content = fs27.readFileSync(filePath);
|
|
45998
|
+
const ext = path39.extname(filePath);
|
|
45440
45999
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
45441
46000
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
45442
46001
|
res.end(content);
|
|
@@ -45544,14 +46103,14 @@ var DevServer = class _DevServer {
|
|
|
45544
46103
|
const files = [];
|
|
45545
46104
|
const scan = (d, prefix) => {
|
|
45546
46105
|
try {
|
|
45547
|
-
for (const entry of
|
|
46106
|
+
for (const entry of fs27.readdirSync(d, { withFileTypes: true })) {
|
|
45548
46107
|
if (entry.name.startsWith(".") || entry.name.endsWith(".bak")) continue;
|
|
45549
46108
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
45550
46109
|
if (entry.isDirectory()) {
|
|
45551
46110
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
45552
|
-
scan(
|
|
46111
|
+
scan(path39.join(d, entry.name), rel);
|
|
45553
46112
|
} else {
|
|
45554
|
-
const stat2 =
|
|
46113
|
+
const stat2 = fs27.statSync(path39.join(d, entry.name));
|
|
45555
46114
|
files.push({ path: rel, size: stat2.size, type: "file" });
|
|
45556
46115
|
}
|
|
45557
46116
|
}
|
|
@@ -45574,16 +46133,16 @@ var DevServer = class _DevServer {
|
|
|
45574
46133
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
45575
46134
|
return;
|
|
45576
46135
|
}
|
|
45577
|
-
const fullPath =
|
|
46136
|
+
const fullPath = path39.resolve(dir, path39.normalize(filePath));
|
|
45578
46137
|
if (!fullPath.startsWith(dir)) {
|
|
45579
46138
|
this.json(res, 403, { error: "Forbidden" });
|
|
45580
46139
|
return;
|
|
45581
46140
|
}
|
|
45582
|
-
if (!
|
|
46141
|
+
if (!fs27.existsSync(fullPath) || fs27.statSync(fullPath).isDirectory()) {
|
|
45583
46142
|
this.json(res, 404, { error: `File not found: ${filePath}` });
|
|
45584
46143
|
return;
|
|
45585
46144
|
}
|
|
45586
|
-
const content =
|
|
46145
|
+
const content = fs27.readFileSync(fullPath, "utf-8");
|
|
45587
46146
|
this.json(res, 200, { type, path: filePath, content, lines: content.split("\n").length });
|
|
45588
46147
|
}
|
|
45589
46148
|
/** POST /api/providers/:type/file — write a file { path, content } */
|
|
@@ -45599,15 +46158,15 @@ var DevServer = class _DevServer {
|
|
|
45599
46158
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
45600
46159
|
return;
|
|
45601
46160
|
}
|
|
45602
|
-
const fullPath =
|
|
46161
|
+
const fullPath = path39.resolve(dir, path39.normalize(filePath));
|
|
45603
46162
|
if (!fullPath.startsWith(dir)) {
|
|
45604
46163
|
this.json(res, 403, { error: "Forbidden" });
|
|
45605
46164
|
return;
|
|
45606
46165
|
}
|
|
45607
46166
|
try {
|
|
45608
|
-
if (
|
|
45609
|
-
|
|
45610
|
-
|
|
46167
|
+
if (fs27.existsSync(fullPath)) fs27.copyFileSync(fullPath, fullPath + ".bak");
|
|
46168
|
+
fs27.mkdirSync(path39.dirname(fullPath), { recursive: true });
|
|
46169
|
+
fs27.writeFileSync(fullPath, content, "utf-8");
|
|
45611
46170
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
45612
46171
|
this.providerLoader.reload();
|
|
45613
46172
|
this.json(res, 200, { saved: true, path: filePath, chars: content.length });
|
|
@@ -45623,9 +46182,9 @@ var DevServer = class _DevServer {
|
|
|
45623
46182
|
return;
|
|
45624
46183
|
}
|
|
45625
46184
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
45626
|
-
const p =
|
|
45627
|
-
if (
|
|
45628
|
-
const source =
|
|
46185
|
+
const p = path39.join(dir, name);
|
|
46186
|
+
if (fs27.existsSync(p)) {
|
|
46187
|
+
const source = fs27.readFileSync(p, "utf-8");
|
|
45629
46188
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
45630
46189
|
return;
|
|
45631
46190
|
}
|
|
@@ -45644,11 +46203,11 @@ var DevServer = class _DevServer {
|
|
|
45644
46203
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
45645
46204
|
return;
|
|
45646
46205
|
}
|
|
45647
|
-
const target =
|
|
45648
|
-
const targetPath =
|
|
46206
|
+
const target = fs27.existsSync(path39.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
46207
|
+
const targetPath = path39.join(dir, target);
|
|
45649
46208
|
try {
|
|
45650
|
-
if (
|
|
45651
|
-
|
|
46209
|
+
if (fs27.existsSync(targetPath)) fs27.copyFileSync(targetPath, targetPath + ".bak");
|
|
46210
|
+
fs27.writeFileSync(targetPath, source, "utf-8");
|
|
45652
46211
|
this.log(`Saved provider: ${targetPath} (${source.length} chars)`);
|
|
45653
46212
|
this.providerLoader.reload();
|
|
45654
46213
|
this.json(res, 200, { saved: true, path: targetPath, chars: source.length });
|
|
@@ -45792,21 +46351,21 @@ var DevServer = class _DevServer {
|
|
|
45792
46351
|
}
|
|
45793
46352
|
let targetDir;
|
|
45794
46353
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
45795
|
-
const jsonPath =
|
|
45796
|
-
if (
|
|
46354
|
+
const jsonPath = path39.join(targetDir, "provider.json");
|
|
46355
|
+
if (fs27.existsSync(jsonPath)) {
|
|
45797
46356
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
45798
46357
|
return;
|
|
45799
46358
|
}
|
|
45800
46359
|
try {
|
|
45801
46360
|
const result = generateFiles(type, name, category, { cdpPorts, cli, processName, installPath, binary, extensionId, version, osPaths, processNames });
|
|
45802
|
-
|
|
45803
|
-
|
|
46361
|
+
fs27.mkdirSync(targetDir, { recursive: true });
|
|
46362
|
+
fs27.writeFileSync(jsonPath, result["provider.json"], "utf-8");
|
|
45804
46363
|
const createdFiles = ["provider.json"];
|
|
45805
46364
|
if (result.files) {
|
|
45806
46365
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
45807
|
-
const fullPath =
|
|
45808
|
-
|
|
45809
|
-
|
|
46366
|
+
const fullPath = path39.join(targetDir, relPath);
|
|
46367
|
+
fs27.mkdirSync(path39.dirname(fullPath), { recursive: true });
|
|
46368
|
+
fs27.writeFileSync(fullPath, content, "utf-8");
|
|
45810
46369
|
createdFiles.push(relPath);
|
|
45811
46370
|
}
|
|
45812
46371
|
}
|
|
@@ -45855,38 +46414,38 @@ var DevServer = class _DevServer {
|
|
|
45855
46414
|
}
|
|
45856
46415
|
// ─── Phase 2: Auto-Implement Backend ───
|
|
45857
46416
|
getLatestScriptVersionDir(scriptsDir) {
|
|
45858
|
-
if (!
|
|
45859
|
-
const versions =
|
|
46417
|
+
if (!fs27.existsSync(scriptsDir)) return null;
|
|
46418
|
+
const versions = fs27.readdirSync(scriptsDir).filter((d) => {
|
|
45860
46419
|
try {
|
|
45861
|
-
return
|
|
46420
|
+
return fs27.statSync(path39.join(scriptsDir, d)).isDirectory();
|
|
45862
46421
|
} catch {
|
|
45863
46422
|
return false;
|
|
45864
46423
|
}
|
|
45865
46424
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
45866
46425
|
if (versions.length === 0) return null;
|
|
45867
|
-
return
|
|
46426
|
+
return path39.join(scriptsDir, versions[0]);
|
|
45868
46427
|
}
|
|
45869
46428
|
resolveAutoImplWritableProviderDir(category, type, requestedDir) {
|
|
45870
|
-
const canonicalUserDir =
|
|
45871
|
-
const desiredDir = requestedDir ?
|
|
45872
|
-
const upstreamRoot =
|
|
45873
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
46429
|
+
const canonicalUserDir = path39.resolve(this.providerLoader.getUserProviderDir(category, type));
|
|
46430
|
+
const desiredDir = requestedDir ? path39.resolve(requestedDir) : canonicalUserDir;
|
|
46431
|
+
const upstreamRoot = path39.resolve(this.providerLoader.getUpstreamDir());
|
|
46432
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path39.sep}`)) {
|
|
45874
46433
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
45875
46434
|
}
|
|
45876
|
-
if (
|
|
46435
|
+
if (path39.basename(desiredDir) !== type) {
|
|
45877
46436
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
45878
46437
|
}
|
|
45879
46438
|
const sourceDir = this.findProviderDir(type);
|
|
45880
46439
|
if (!sourceDir) {
|
|
45881
46440
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
45882
46441
|
}
|
|
45883
|
-
if (!
|
|
45884
|
-
|
|
45885
|
-
|
|
46442
|
+
if (!fs27.existsSync(desiredDir)) {
|
|
46443
|
+
fs27.mkdirSync(path39.dirname(desiredDir), { recursive: true });
|
|
46444
|
+
fs27.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
45886
46445
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
45887
46446
|
}
|
|
45888
|
-
const providerJson =
|
|
45889
|
-
if (!
|
|
46447
|
+
const providerJson = path39.join(desiredDir, "provider.json");
|
|
46448
|
+
if (!fs27.existsSync(providerJson)) {
|
|
45890
46449
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
45891
46450
|
}
|
|
45892
46451
|
return { dir: desiredDir };
|
|
@@ -45921,7 +46480,7 @@ var DevServer = class _DevServer {
|
|
|
45921
46480
|
setMode: "set_mode.js"
|
|
45922
46481
|
};
|
|
45923
46482
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
45924
|
-
const scriptsDir =
|
|
46483
|
+
const scriptsDir = path39.join(providerDir, "scripts");
|
|
45925
46484
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
45926
46485
|
if (latestScriptsDir) {
|
|
45927
46486
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -45929,10 +46488,10 @@ var DevServer = class _DevServer {
|
|
|
45929
46488
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
45930
46489
|
lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
|
|
45931
46490
|
lines.push("");
|
|
45932
|
-
for (const file of
|
|
46491
|
+
for (const file of fs27.readdirSync(latestScriptsDir)) {
|
|
45933
46492
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
45934
46493
|
try {
|
|
45935
|
-
const content =
|
|
46494
|
+
const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
45936
46495
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
45937
46496
|
lines.push("```javascript");
|
|
45938
46497
|
lines.push(content);
|
|
@@ -45942,14 +46501,14 @@ var DevServer = class _DevServer {
|
|
|
45942
46501
|
}
|
|
45943
46502
|
}
|
|
45944
46503
|
}
|
|
45945
|
-
const refFiles =
|
|
46504
|
+
const refFiles = fs27.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
45946
46505
|
if (refFiles.length > 0) {
|
|
45947
46506
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
45948
46507
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
45949
46508
|
lines.push("");
|
|
45950
46509
|
for (const file of refFiles) {
|
|
45951
46510
|
try {
|
|
45952
|
-
const content =
|
|
46511
|
+
const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
45953
46512
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
45954
46513
|
lines.push("```javascript");
|
|
45955
46514
|
lines.push(content);
|
|
@@ -45990,11 +46549,11 @@ var DevServer = class _DevServer {
|
|
|
45990
46549
|
lines.push("");
|
|
45991
46550
|
}
|
|
45992
46551
|
}
|
|
45993
|
-
const docsDir =
|
|
46552
|
+
const docsDir = path39.join(providerDir, "../../docs");
|
|
45994
46553
|
const loadGuide = (name) => {
|
|
45995
46554
|
try {
|
|
45996
|
-
const p =
|
|
45997
|
-
if (
|
|
46555
|
+
const p = path39.join(docsDir, name);
|
|
46556
|
+
if (fs27.existsSync(p)) return fs27.readFileSync(p, "utf-8");
|
|
45998
46557
|
} catch {
|
|
45999
46558
|
}
|
|
46000
46559
|
return null;
|
|
@@ -46167,7 +46726,7 @@ var DevServer = class _DevServer {
|
|
|
46167
46726
|
parseApproval: "parse_approval.js"
|
|
46168
46727
|
};
|
|
46169
46728
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
46170
|
-
const scriptsDir =
|
|
46729
|
+
const scriptsDir = path39.join(providerDir, "scripts");
|
|
46171
46730
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
46172
46731
|
if (latestScriptsDir) {
|
|
46173
46732
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -46175,11 +46734,11 @@ var DevServer = class _DevServer {
|
|
|
46175
46734
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
46176
46735
|
lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
|
|
46177
46736
|
lines.push("");
|
|
46178
|
-
for (const file of
|
|
46737
|
+
for (const file of fs27.readdirSync(latestScriptsDir)) {
|
|
46179
46738
|
if (!file.endsWith(".js")) continue;
|
|
46180
46739
|
if (!targetFileNames.has(file)) continue;
|
|
46181
46740
|
try {
|
|
46182
|
-
const content =
|
|
46741
|
+
const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
46183
46742
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
46184
46743
|
lines.push("```javascript");
|
|
46185
46744
|
lines.push(content);
|
|
@@ -46188,14 +46747,14 @@ var DevServer = class _DevServer {
|
|
|
46188
46747
|
} catch {
|
|
46189
46748
|
}
|
|
46190
46749
|
}
|
|
46191
|
-
const refFiles =
|
|
46750
|
+
const refFiles = fs27.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
46192
46751
|
if (refFiles.length > 0) {
|
|
46193
46752
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
46194
46753
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
46195
46754
|
lines.push("");
|
|
46196
46755
|
for (const file of refFiles) {
|
|
46197
46756
|
try {
|
|
46198
|
-
const content =
|
|
46757
|
+
const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
46199
46758
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
46200
46759
|
lines.push("```javascript");
|
|
46201
46760
|
lines.push(content);
|
|
@@ -46228,11 +46787,11 @@ var DevServer = class _DevServer {
|
|
|
46228
46787
|
lines.push("");
|
|
46229
46788
|
}
|
|
46230
46789
|
}
|
|
46231
|
-
const docsDir =
|
|
46790
|
+
const docsDir = path39.join(providerDir, "../../docs");
|
|
46232
46791
|
const loadGuide = (name) => {
|
|
46233
46792
|
try {
|
|
46234
|
-
const p =
|
|
46235
|
-
if (
|
|
46793
|
+
const p = path39.join(docsDir, name);
|
|
46794
|
+
if (fs27.existsSync(p)) return fs27.readFileSync(p, "utf-8");
|
|
46236
46795
|
} catch {
|
|
46237
46796
|
}
|
|
46238
46797
|
return null;
|
|
@@ -47142,8 +47701,8 @@ async function installExtension(ide, extension) {
|
|
|
47142
47701
|
const res = await fetch(extension.vsixUrl);
|
|
47143
47702
|
if (res.ok) {
|
|
47144
47703
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
47145
|
-
const
|
|
47146
|
-
|
|
47704
|
+
const fs28 = await import("fs");
|
|
47705
|
+
fs28.writeFileSync(vsixPath, buffer);
|
|
47147
47706
|
return new Promise((resolve23) => {
|
|
47148
47707
|
const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
|
|
47149
47708
|
exec6(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
|
|
@@ -47714,12 +48273,12 @@ init_parse_session();
|
|
|
47714
48273
|
|
|
47715
48274
|
// src/providers/sdk/v1/fixture-tooling/replay.ts
|
|
47716
48275
|
init_provider_cli_shared();
|
|
47717
|
-
import { readFileSync as
|
|
48276
|
+
import { readFileSync as readFileSync31 } from "fs";
|
|
47718
48277
|
import { dirname as dirname9, resolve as resolve21 } from "path";
|
|
47719
48278
|
|
|
47720
48279
|
// src/providers/sdk/v1/validators/taint.ts
|
|
47721
|
-
import { readFileSync as
|
|
47722
|
-
import { resolve as resolve22, dirname as dirname10, join as
|
|
48280
|
+
import { readFileSync as readFileSync32, existsSync as existsSync38 } from "fs";
|
|
48281
|
+
import { resolve as resolve22, dirname as dirname10, join as join43 } from "path";
|
|
47723
48282
|
|
|
47724
48283
|
// src/providers/sdk/v1/validators/index.ts
|
|
47725
48284
|
init_manifest();
|