@adhdev/daemon-core 0.9.82-rc.165 → 0.9.82-rc.166
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 +1298 -752
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1296 -750
- 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/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/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/index.ts +1 -1
- package/src/providers/sdk/v1/sandbox/require-whitelist.ts +1 -1
- package/src/providers/sdk/v1/validators/manifest.ts +1 -1
- package/src/providers/sdk/v1/validators/taint.ts +1 -1
- package/src/shared-types.ts +33 -1
- package/src/status/snapshot.ts +49 -14
package/dist/index.js
CHANGED
|
@@ -106,8 +106,8 @@ function normalizeGitOutput(value) {
|
|
|
106
106
|
return String(value).replace(/\r\n/g, "\n");
|
|
107
107
|
}
|
|
108
108
|
function isPathInside(parent, child) {
|
|
109
|
-
const
|
|
110
|
-
return
|
|
109
|
+
const relative5 = path.relative(path.resolve(parent), path.resolve(child));
|
|
110
|
+
return relative5 === "" || !relative5.startsWith("..") && !path.isAbsolute(relative5);
|
|
111
111
|
}
|
|
112
112
|
async function validateWorkspace(workspace) {
|
|
113
113
|
if (typeof workspace !== "string" || workspace.length === 0 || workspace.includes("\0")) {
|
|
@@ -770,10 +770,10 @@ function getMeshConfigPath() {
|
|
|
770
770
|
return (0, import_path2.join)(getConfigDir(), "meshes.json");
|
|
771
771
|
}
|
|
772
772
|
function loadMeshConfig() {
|
|
773
|
-
const
|
|
774
|
-
if (!(0, import_fs2.existsSync)(
|
|
773
|
+
const path40 = getMeshConfigPath();
|
|
774
|
+
if (!(0, import_fs2.existsSync)(path40)) return { meshes: [] };
|
|
775
775
|
try {
|
|
776
|
-
const raw = JSON.parse((0, import_fs2.readFileSync)(
|
|
776
|
+
const raw = JSON.parse((0, import_fs2.readFileSync)(path40, "utf-8"));
|
|
777
777
|
if (!raw || !Array.isArray(raw.meshes)) return { meshes: [] };
|
|
778
778
|
return raw;
|
|
779
779
|
} catch {
|
|
@@ -781,16 +781,16 @@ function loadMeshConfig() {
|
|
|
781
781
|
}
|
|
782
782
|
}
|
|
783
783
|
function saveMeshConfig(config) {
|
|
784
|
-
const
|
|
785
|
-
(0, import_fs2.writeFileSync)(
|
|
784
|
+
const path40 = getMeshConfigPath();
|
|
785
|
+
(0, import_fs2.writeFileSync)(path40, JSON.stringify(config, null, 2), { encoding: "utf-8", mode: 384 });
|
|
786
786
|
}
|
|
787
787
|
function normalizeRepoIdentity(remoteUrl) {
|
|
788
788
|
let identity = remoteUrl.trim();
|
|
789
789
|
if (identity.startsWith("http://") || identity.startsWith("https://")) {
|
|
790
790
|
try {
|
|
791
791
|
const url = new URL(identity);
|
|
792
|
-
const
|
|
793
|
-
return `${url.hostname}/${
|
|
792
|
+
const path40 = url.pathname.replace(/^\//, "").replace(/\.git$/, "");
|
|
793
|
+
return `${url.hostname}/${path40}`;
|
|
794
794
|
} catch {
|
|
795
795
|
}
|
|
796
796
|
}
|
|
@@ -1718,8 +1718,8 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
1718
1718
|
}
|
|
1719
1719
|
const serverName = mcpConfig.serverName?.trim() || DEFAULT_SERVER_NAME;
|
|
1720
1720
|
if (mcpConfig.mode === "auto_import") {
|
|
1721
|
-
const
|
|
1722
|
-
if (!
|
|
1721
|
+
const path40 = mcpConfig.path?.trim();
|
|
1722
|
+
if (!path40) {
|
|
1723
1723
|
return { kind: "unsupported", reason: "Provider auto-import MCP config is missing a config path" };
|
|
1724
1724
|
}
|
|
1725
1725
|
const mcpServer = resolveAdhdevMcpServerLaunch({
|
|
@@ -1737,7 +1737,7 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
1737
1737
|
return {
|
|
1738
1738
|
kind: "auto_import",
|
|
1739
1739
|
serverName,
|
|
1740
|
-
configPath: resolveMcpConfigPath(
|
|
1740
|
+
configPath: resolveMcpConfigPath(path40, workspace),
|
|
1741
1741
|
configFormat: mcpConfig.format,
|
|
1742
1742
|
mcpServer
|
|
1743
1743
|
};
|
|
@@ -1894,8 +1894,8 @@ function stripCoordinatorWrapperFile(filePath) {
|
|
|
1894
1894
|
const remaining = (existing.slice(0, openIdx) + existing.slice(closeIdx + CLOSE.length)).replace(/^\s*\n+/, "").replace(/\n+\s*$/, "");
|
|
1895
1895
|
if (!remaining.trim()) {
|
|
1896
1896
|
try {
|
|
1897
|
-
const
|
|
1898
|
-
|
|
1897
|
+
const fs28 = require("fs");
|
|
1898
|
+
fs28.unlinkSync(filePath);
|
|
1899
1899
|
} catch {
|
|
1900
1900
|
}
|
|
1901
1901
|
} else {
|
|
@@ -2033,10 +2033,10 @@ function rotateArchiveFile(meshId, archivePath) {
|
|
|
2033
2033
|
}
|
|
2034
2034
|
}
|
|
2035
2035
|
function readArchivedCounts(meshId) {
|
|
2036
|
-
const
|
|
2037
|
-
if (!(0, import_fs6.existsSync)(
|
|
2036
|
+
const path40 = getArchivedCountsPath(meshId);
|
|
2037
|
+
if (!(0, import_fs6.existsSync)(path40)) return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
|
|
2038
2038
|
try {
|
|
2039
|
-
return JSON.parse((0, import_fs6.readFileSync)(
|
|
2039
|
+
return JSON.parse((0, import_fs6.readFileSync)(path40, "utf-8"));
|
|
2040
2040
|
} catch {
|
|
2041
2041
|
return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
|
|
2042
2042
|
}
|
|
@@ -2691,10 +2691,10 @@ var init_beads_db = __esm({
|
|
|
2691
2691
|
this.migratedMeshIds.add(meshId);
|
|
2692
2692
|
const count = this.db.prepare("SELECT COUNT(*) AS count FROM mesh_queue WHERE mesh_id = ?").get(meshId);
|
|
2693
2693
|
if (count.count > 0) return;
|
|
2694
|
-
const
|
|
2695
|
-
if (!(0, import_fs7.existsSync)(
|
|
2694
|
+
const path40 = legacyQueuePath(meshId);
|
|
2695
|
+
if (!(0, import_fs7.existsSync)(path40)) return;
|
|
2696
2696
|
try {
|
|
2697
|
-
const entries = JSON.parse((0, import_fs7.readFileSync)(
|
|
2697
|
+
const entries = JSON.parse((0, import_fs7.readFileSync)(path40, "utf-8"));
|
|
2698
2698
|
if (!Array.isArray(entries)) return;
|
|
2699
2699
|
const insert = this.db.prepare(`
|
|
2700
2700
|
INSERT OR REPLACE INTO mesh_queue (
|
|
@@ -3404,10 +3404,10 @@ function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
|
|
|
3404
3404
|
if (!meshId) return [];
|
|
3405
3405
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
3406
3406
|
const events = [];
|
|
3407
|
-
for (const
|
|
3408
|
-
if (!(0, import_fs9.existsSync)(
|
|
3407
|
+
for (const path40 of paths) {
|
|
3408
|
+
if (!(0, import_fs9.existsSync)(path40)) continue;
|
|
3409
3409
|
try {
|
|
3410
|
-
const raw = (0, import_fs9.readFileSync)(
|
|
3410
|
+
const raw = (0, import_fs9.readFileSync)(path40, "utf-8");
|
|
3411
3411
|
const parsed = raw.split("\n").filter(Boolean).flatMap((line) => {
|
|
3412
3412
|
try {
|
|
3413
3413
|
return [JSON.parse(line)];
|
|
@@ -3415,7 +3415,7 @@ function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
|
|
|
3415
3415
|
return [];
|
|
3416
3416
|
}
|
|
3417
3417
|
});
|
|
3418
|
-
const filtered = coordinatorDaemonId &&
|
|
3418
|
+
const filtered = coordinatorDaemonId && path40 === getPendingEventsPath(meshId) ? parsed.filter((e) => !e.targetCoordinatorDaemonId || e.targetCoordinatorDaemonId === coordinatorDaemonId) : parsed;
|
|
3419
3419
|
events.push(...filtered);
|
|
3420
3420
|
} catch {
|
|
3421
3421
|
}
|
|
@@ -3484,13 +3484,13 @@ function reconcilePendingMeshCoordinatorEvents(meshId, events) {
|
|
|
3484
3484
|
...backfilled
|
|
3485
3485
|
];
|
|
3486
3486
|
}
|
|
3487
|
-
function trimPendingEventsIfNeeded(
|
|
3487
|
+
function trimPendingEventsIfNeeded(path40) {
|
|
3488
3488
|
try {
|
|
3489
|
-
if (!(0, import_fs9.existsSync)(
|
|
3490
|
-
if ((0, import_fs9.statSync)(
|
|
3491
|
-
const lines = (0, import_fs9.readFileSync)(
|
|
3489
|
+
if (!(0, import_fs9.existsSync)(path40)) return;
|
|
3490
|
+
if ((0, import_fs9.statSync)(path40).size <= MAX_PENDING_EVENTS_BYTES) return;
|
|
3491
|
+
const lines = (0, import_fs9.readFileSync)(path40, "utf-8").split("\n").filter(Boolean);
|
|
3492
3492
|
if (lines.length <= MAX_PENDING_EVENTS_KEEP) return;
|
|
3493
|
-
(0, import_fs9.writeFileSync)(
|
|
3493
|
+
(0, import_fs9.writeFileSync)(path40, lines.slice(-MAX_PENDING_EVENTS_KEEP).join("\n") + "\n", "utf-8");
|
|
3494
3494
|
} catch {
|
|
3495
3495
|
}
|
|
3496
3496
|
}
|
|
@@ -3504,19 +3504,19 @@ function queuePendingMeshCoordinatorEvent(event) {
|
|
|
3504
3504
|
LOG.info("MeshEvents", `Suppressed duplicate pending ${event.event} for mesh ${event.meshId}`);
|
|
3505
3505
|
return true;
|
|
3506
3506
|
}
|
|
3507
|
-
const
|
|
3508
|
-
trimPendingEventsIfNeeded(
|
|
3509
|
-
(0, import_fs9.appendFileSync)(
|
|
3507
|
+
const path40 = getPendingEventsPath(event.meshId, event.targetCoordinatorDaemonId);
|
|
3508
|
+
trimPendingEventsIfNeeded(path40);
|
|
3509
|
+
(0, import_fs9.appendFileSync)(path40, JSON.stringify(event) + "\n", "utf-8");
|
|
3510
3510
|
return true;
|
|
3511
3511
|
} catch (e) {
|
|
3512
3512
|
LOG.warn("MeshEvents", `Failed to persist pending coordinator event: ${e?.message || e}`);
|
|
3513
3513
|
return false;
|
|
3514
3514
|
}
|
|
3515
3515
|
}
|
|
3516
|
-
function atomicDrainFile(
|
|
3517
|
-
const tmpPath = `${
|
|
3516
|
+
function atomicDrainFile(path40) {
|
|
3517
|
+
const tmpPath = `${path40}.draining`;
|
|
3518
3518
|
try {
|
|
3519
|
-
(0, import_fs9.renameSync)(
|
|
3519
|
+
(0, import_fs9.renameSync)(path40, tmpPath);
|
|
3520
3520
|
} catch {
|
|
3521
3521
|
return null;
|
|
3522
3522
|
}
|
|
@@ -3539,8 +3539,8 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
3539
3539
|
if (!meshId) return [];
|
|
3540
3540
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
3541
3541
|
const all = [];
|
|
3542
|
-
for (const
|
|
3543
|
-
const content = atomicDrainFile(
|
|
3542
|
+
for (const path40 of paths) {
|
|
3543
|
+
const content = atomicDrainFile(path40);
|
|
3544
3544
|
if (!content) continue;
|
|
3545
3545
|
const parsed = content.split("\n").filter(Boolean).flatMap((line) => {
|
|
3546
3546
|
try {
|
|
@@ -3549,7 +3549,7 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
3549
3549
|
return [];
|
|
3550
3550
|
}
|
|
3551
3551
|
});
|
|
3552
|
-
const filtered = coordinatorDaemonId &&
|
|
3552
|
+
const filtered = coordinatorDaemonId && path40 === getPendingEventsPath(meshId) ? parsed.filter((e) => !e.targetCoordinatorDaemonId || e.targetCoordinatorDaemonId === coordinatorDaemonId) : parsed;
|
|
3553
3553
|
all.push(...filtered);
|
|
3554
3554
|
}
|
|
3555
3555
|
if (all.length === 0) return [];
|
|
@@ -3562,9 +3562,9 @@ function getPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
3562
3562
|
function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
3563
3563
|
if (!meshId) return;
|
|
3564
3564
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
3565
|
-
for (const
|
|
3566
|
-
if ((0, import_fs9.existsSync)(
|
|
3567
|
-
(0, import_fs9.unlinkSync)(
|
|
3565
|
+
for (const path40 of paths) {
|
|
3566
|
+
if ((0, import_fs9.existsSync)(path40)) try {
|
|
3567
|
+
(0, import_fs9.unlinkSync)(path40);
|
|
3568
3568
|
} catch {
|
|
3569
3569
|
}
|
|
3570
3570
|
}
|
|
@@ -4690,6 +4690,56 @@ var init_debug_config = __esm({
|
|
|
4690
4690
|
}
|
|
4691
4691
|
});
|
|
4692
4692
|
|
|
4693
|
+
// src/providers/provider-trust.ts
|
|
4694
|
+
var provider_trust_exports = {};
|
|
4695
|
+
__export(provider_trust_exports, {
|
|
4696
|
+
classifyTrust: () => classifyTrust,
|
|
4697
|
+
describeTrust: () => describeTrust,
|
|
4698
|
+
inspectManifestShape: () => inspectManifestShape,
|
|
4699
|
+
requiresConfirmation: () => requiresConfirmation
|
|
4700
|
+
});
|
|
4701
|
+
function inspectManifestShape(manifest) {
|
|
4702
|
+
const hasTui = !!manifest.tui && typeof manifest.tui === "object" && Object.keys(manifest.tui).length > 0;
|
|
4703
|
+
const hasOverrides = !!manifest.overrides && typeof manifest.overrides === "object" && !Array.isArray(manifest.overrides) && Object.keys(manifest.overrides).length > 0;
|
|
4704
|
+
const compat = Array.isArray(manifest.compatibility) ? manifest.compatibility : [];
|
|
4705
|
+
const compatHasScriptDir = compat.some((entry) => typeof entry?.scriptDir === "string");
|
|
4706
|
+
const hasScriptDir = compatHasScriptDir || typeof manifest.defaultScriptDir === "string";
|
|
4707
|
+
return { hasTui, hasOverrides, hasScriptDir };
|
|
4708
|
+
}
|
|
4709
|
+
function classifyTrust(layer, shape) {
|
|
4710
|
+
const isSpecOnly = !shape.hasTui && !shape.hasOverrides && !shape.hasScriptDir;
|
|
4711
|
+
switch (layer) {
|
|
4712
|
+
case "user":
|
|
4713
|
+
return "user-custom";
|
|
4714
|
+
case "upstream":
|
|
4715
|
+
return isSpecOnly ? "trusted" : "trusted-with-scripts";
|
|
4716
|
+
case "external":
|
|
4717
|
+
return isSpecOnly ? "external-safe" : "external-untrusted";
|
|
4718
|
+
}
|
|
4719
|
+
}
|
|
4720
|
+
function requiresConfirmation(trust) {
|
|
4721
|
+
return trust === "external-untrusted";
|
|
4722
|
+
}
|
|
4723
|
+
function describeTrust(trust) {
|
|
4724
|
+
switch (trust) {
|
|
4725
|
+
case "user-custom":
|
|
4726
|
+
return "Hand-authored in ~/.adhdev/providers/. Runs your own code.";
|
|
4727
|
+
case "trusted":
|
|
4728
|
+
return "Official, declarative-only manifest from the ADHDev registry.";
|
|
4729
|
+
case "trusted-with-scripts":
|
|
4730
|
+
return "Official manifest from the ADHDev registry. Ships JavaScript hooks executed by the daemon.";
|
|
4731
|
+
case "external-safe":
|
|
4732
|
+
return "Manifest from a 3rd-party git source you added. Declarative-only \u2014 the daemon never runs JS from this source.";
|
|
4733
|
+
case "external-untrusted":
|
|
4734
|
+
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.";
|
|
4735
|
+
}
|
|
4736
|
+
}
|
|
4737
|
+
var init_provider_trust = __esm({
|
|
4738
|
+
"src/providers/provider-trust.ts"() {
|
|
4739
|
+
"use strict";
|
|
4740
|
+
}
|
|
4741
|
+
});
|
|
4742
|
+
|
|
4693
4743
|
// src/providers/sdk/v1/schemas/cli/provider.schema.json
|
|
4694
4744
|
var provider_schema_default;
|
|
4695
4745
|
var init_provider_schema = __esm({
|
|
@@ -5193,7 +5243,7 @@ function getCliValidator() {
|
|
|
5193
5243
|
return _cliValidator;
|
|
5194
5244
|
}
|
|
5195
5245
|
function formatIssue(err) {
|
|
5196
|
-
const
|
|
5246
|
+
const path40 = err.instancePath || "";
|
|
5197
5247
|
const params = err.params;
|
|
5198
5248
|
let message = err.message || "validation failed";
|
|
5199
5249
|
let allowed;
|
|
@@ -5211,7 +5261,7 @@ function formatIssue(err) {
|
|
|
5211
5261
|
} else if (err.keyword === "type") {
|
|
5212
5262
|
message = `must be ${params.type}`;
|
|
5213
5263
|
}
|
|
5214
|
-
return { path:
|
|
5264
|
+
return { path: path40, keyword: err.keyword, message, ...allowed !== void 0 ? { allowed } : {} };
|
|
5215
5265
|
}
|
|
5216
5266
|
function validateCliProviderManifest(manifest) {
|
|
5217
5267
|
const validator = getCliValidator();
|
|
@@ -5238,6 +5288,156 @@ var init_manifest = __esm({
|
|
|
5238
5288
|
}
|
|
5239
5289
|
});
|
|
5240
5290
|
|
|
5291
|
+
// src/providers/external-sources.ts
|
|
5292
|
+
var external_sources_exports = {};
|
|
5293
|
+
__export(external_sources_exports, {
|
|
5294
|
+
activeFilePath: () => activeFilePath,
|
|
5295
|
+
deriveSourceName: () => deriveSourceName,
|
|
5296
|
+
externalRoot: () => externalRoot,
|
|
5297
|
+
inventoryExternalSources: () => inventoryExternalSources,
|
|
5298
|
+
loadExternalSources: () => loadExternalSources,
|
|
5299
|
+
loadProvidersActive: () => loadProvidersActive,
|
|
5300
|
+
resolveActiveSource: () => resolveActiveSource,
|
|
5301
|
+
saveExternalSources: () => saveExternalSources,
|
|
5302
|
+
saveProvidersActive: () => saveProvidersActive,
|
|
5303
|
+
sourcesFilePath: () => sourcesFilePath,
|
|
5304
|
+
sourcesProviding: () => sourcesProviding
|
|
5305
|
+
});
|
|
5306
|
+
function adhdevDir() {
|
|
5307
|
+
return path15.join(os10.homedir(), ".adhdev");
|
|
5308
|
+
}
|
|
5309
|
+
function externalRoot() {
|
|
5310
|
+
return path15.join(adhdevDir(), "external");
|
|
5311
|
+
}
|
|
5312
|
+
function sourcesFilePath() {
|
|
5313
|
+
return path15.join(adhdevDir(), SOURCES_FILENAME);
|
|
5314
|
+
}
|
|
5315
|
+
function activeFilePath() {
|
|
5316
|
+
return path15.join(adhdevDir(), ACTIVE_FILENAME);
|
|
5317
|
+
}
|
|
5318
|
+
function ensureAdhdevDir() {
|
|
5319
|
+
const d = adhdevDir();
|
|
5320
|
+
if (!fs8.existsSync(d)) fs8.mkdirSync(d, { recursive: true });
|
|
5321
|
+
}
|
|
5322
|
+
function loadExternalSources() {
|
|
5323
|
+
const p = sourcesFilePath();
|
|
5324
|
+
if (!fs8.existsSync(p)) return { schema: 1, sources: [] };
|
|
5325
|
+
try {
|
|
5326
|
+
const raw = JSON.parse(fs8.readFileSync(p, "utf-8"));
|
|
5327
|
+
if (!raw || typeof raw !== "object") return { schema: 1, sources: [] };
|
|
5328
|
+
const sources = Array.isArray(raw.sources) ? raw.sources.filter(isValidSource) : [];
|
|
5329
|
+
return { schema: 1, sources };
|
|
5330
|
+
} catch {
|
|
5331
|
+
return { schema: 1, sources: [] };
|
|
5332
|
+
}
|
|
5333
|
+
}
|
|
5334
|
+
function saveExternalSources(file) {
|
|
5335
|
+
ensureAdhdevDir();
|
|
5336
|
+
const tmp = sourcesFilePath() + ".tmp";
|
|
5337
|
+
fs8.writeFileSync(tmp, JSON.stringify(file, null, 2) + "\n", "utf-8");
|
|
5338
|
+
fs8.renameSync(tmp, sourcesFilePath());
|
|
5339
|
+
}
|
|
5340
|
+
function loadProvidersActive() {
|
|
5341
|
+
const p = activeFilePath();
|
|
5342
|
+
if (!fs8.existsSync(p)) return { schema: 1, active: {} };
|
|
5343
|
+
try {
|
|
5344
|
+
const raw = JSON.parse(fs8.readFileSync(p, "utf-8"));
|
|
5345
|
+
if (!raw || typeof raw !== "object") return { schema: 1, active: {} };
|
|
5346
|
+
const active = raw.active && typeof raw.active === "object" ? raw.active : {};
|
|
5347
|
+
return { schema: 1, active };
|
|
5348
|
+
} catch {
|
|
5349
|
+
return { schema: 1, active: {} };
|
|
5350
|
+
}
|
|
5351
|
+
}
|
|
5352
|
+
function saveProvidersActive(file) {
|
|
5353
|
+
ensureAdhdevDir();
|
|
5354
|
+
const tmp = activeFilePath() + ".tmp";
|
|
5355
|
+
fs8.writeFileSync(tmp, JSON.stringify(file, null, 2) + "\n", "utf-8");
|
|
5356
|
+
fs8.renameSync(tmp, activeFilePath());
|
|
5357
|
+
}
|
|
5358
|
+
function isValidSource(x) {
|
|
5359
|
+
if (!x || typeof x !== "object") return false;
|
|
5360
|
+
const s = x;
|
|
5361
|
+
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";
|
|
5362
|
+
}
|
|
5363
|
+
function deriveSourceName(url) {
|
|
5364
|
+
const m = url.match(/[/:]([^/:]+)\/([^/]+?)(?:\.git)?$/);
|
|
5365
|
+
if (!m) return "@source";
|
|
5366
|
+
const owner = m[1].toLowerCase().replace(/[^a-z0-9_-]/g, "-");
|
|
5367
|
+
const repo = m[2].toLowerCase().replace(/[^a-z0-9_-]/g, "-");
|
|
5368
|
+
return `@${owner}-${repo}`;
|
|
5369
|
+
}
|
|
5370
|
+
function inventoryExternalSources() {
|
|
5371
|
+
const root = externalRoot();
|
|
5372
|
+
if (!fs8.existsSync(root)) return [];
|
|
5373
|
+
const out = [];
|
|
5374
|
+
let entries;
|
|
5375
|
+
try {
|
|
5376
|
+
entries = fs8.readdirSync(root, { withFileTypes: true });
|
|
5377
|
+
} catch {
|
|
5378
|
+
return [];
|
|
5379
|
+
}
|
|
5380
|
+
for (const sourceEntry of entries) {
|
|
5381
|
+
if (!sourceEntry.isDirectory()) continue;
|
|
5382
|
+
const sourceName = sourceEntry.name;
|
|
5383
|
+
const sourceDir = path15.join(root, sourceName);
|
|
5384
|
+
const providers = {};
|
|
5385
|
+
let categoryEntries;
|
|
5386
|
+
try {
|
|
5387
|
+
categoryEntries = fs8.readdirSync(sourceDir, { withFileTypes: true });
|
|
5388
|
+
} catch {
|
|
5389
|
+
continue;
|
|
5390
|
+
}
|
|
5391
|
+
for (const categoryEntry of categoryEntries) {
|
|
5392
|
+
if (!categoryEntry.isDirectory()) continue;
|
|
5393
|
+
const category = categoryEntry.name;
|
|
5394
|
+
const categoryDir = path15.join(sourceDir, category);
|
|
5395
|
+
let typeEntries;
|
|
5396
|
+
try {
|
|
5397
|
+
typeEntries = fs8.readdirSync(categoryDir, { withFileTypes: true });
|
|
5398
|
+
} catch {
|
|
5399
|
+
continue;
|
|
5400
|
+
}
|
|
5401
|
+
const types = [];
|
|
5402
|
+
for (const typeEntry of typeEntries) {
|
|
5403
|
+
if (!typeEntry.isDirectory()) continue;
|
|
5404
|
+
const typeDir = path15.join(categoryDir, typeEntry.name);
|
|
5405
|
+
const hasV1 = fs8.existsSync(path15.join(typeDir, "provider.v1.json"));
|
|
5406
|
+
const hasV0 = fs8.existsSync(path15.join(typeDir, "provider.json"));
|
|
5407
|
+
if (hasV1 || hasV0) types.push(typeEntry.name);
|
|
5408
|
+
}
|
|
5409
|
+
if (types.length > 0) providers[category] = types;
|
|
5410
|
+
}
|
|
5411
|
+
out.push({ sourceName, providers });
|
|
5412
|
+
}
|
|
5413
|
+
return out;
|
|
5414
|
+
}
|
|
5415
|
+
function sourcesProviding(category, type) {
|
|
5416
|
+
const inventory = inventoryExternalSources();
|
|
5417
|
+
return inventory.filter((s) => (s.providers[category] || []).includes(type)).map((s) => s.sourceName);
|
|
5418
|
+
}
|
|
5419
|
+
function resolveActiveSource(category, type, activeFile) {
|
|
5420
|
+
const candidates = sourcesProviding(category, type);
|
|
5421
|
+
if (candidates.length === 0) return { source: null, ambiguous: false, candidates };
|
|
5422
|
+
if (candidates.length === 1) return { source: candidates[0], ambiguous: false, candidates };
|
|
5423
|
+
const explicit = (activeFile ?? loadProvidersActive()).active[type];
|
|
5424
|
+
if (explicit && candidates.includes(explicit)) {
|
|
5425
|
+
return { source: explicit, ambiguous: false, candidates };
|
|
5426
|
+
}
|
|
5427
|
+
return { source: candidates[0], ambiguous: true, candidates };
|
|
5428
|
+
}
|
|
5429
|
+
var fs8, os10, path15, SOURCES_FILENAME, ACTIVE_FILENAME;
|
|
5430
|
+
var init_external_sources = __esm({
|
|
5431
|
+
"src/providers/external-sources.ts"() {
|
|
5432
|
+
"use strict";
|
|
5433
|
+
fs8 = __toESM(require("fs"));
|
|
5434
|
+
os10 = __toESM(require("os"));
|
|
5435
|
+
path15 = __toESM(require("path"));
|
|
5436
|
+
SOURCES_FILENAME = "providers-sources.json";
|
|
5437
|
+
ACTIVE_FILENAME = "providers-active.json";
|
|
5438
|
+
}
|
|
5439
|
+
});
|
|
5440
|
+
|
|
5241
5441
|
// src/cli-adapters/terminal-backends/ghostty-vt-backend.ts
|
|
5242
5442
|
function isModuleNotFoundError(error, ref) {
|
|
5243
5443
|
if (!(error instanceof Error)) return false;
|
|
@@ -5533,11 +5733,11 @@ function loadNodePty() {
|
|
|
5533
5733
|
}
|
|
5534
5734
|
return cachedPty;
|
|
5535
5735
|
}
|
|
5536
|
-
var
|
|
5736
|
+
var os11, cachedPty, NodePtyRuntimeTransport, NodePtyTransportFactory;
|
|
5537
5737
|
var init_pty_transport = __esm({
|
|
5538
5738
|
"src/cli-adapters/pty-transport.ts"() {
|
|
5539
5739
|
"use strict";
|
|
5540
|
-
|
|
5740
|
+
os11 = __toESM(require("os"));
|
|
5541
5741
|
init_spawn_env();
|
|
5542
5742
|
NodePtyRuntimeTransport = class {
|
|
5543
5743
|
constructor(handle) {
|
|
@@ -5574,11 +5774,11 @@ var init_pty_transport = __esm({
|
|
|
5574
5774
|
let cwd = options.cwd;
|
|
5575
5775
|
if (cwd) {
|
|
5576
5776
|
try {
|
|
5577
|
-
const
|
|
5578
|
-
const stat2 =
|
|
5579
|
-
if (!stat2.isDirectory()) cwd =
|
|
5777
|
+
const fs28 = require("fs");
|
|
5778
|
+
const stat2 = fs28.statSync(cwd);
|
|
5779
|
+
if (!stat2.isDirectory()) cwd = os11.homedir();
|
|
5580
5780
|
} catch {
|
|
5581
|
-
cwd =
|
|
5781
|
+
cwd = os11.homedir();
|
|
5582
5782
|
}
|
|
5583
5783
|
}
|
|
5584
5784
|
const handle = pty.spawn(command, args, {
|
|
@@ -5670,21 +5870,21 @@ function buildCliScreenSnapshot(text) {
|
|
|
5670
5870
|
function findBinary(name) {
|
|
5671
5871
|
const trimmed = String(name || "").trim();
|
|
5672
5872
|
if (!trimmed) return trimmed;
|
|
5673
|
-
const expanded = trimmed.startsWith("~") ?
|
|
5674
|
-
if (
|
|
5675
|
-
return
|
|
5873
|
+
const expanded = trimmed.startsWith("~") ? path16.join(os12.homedir(), trimmed.slice(1)) : trimmed;
|
|
5874
|
+
if (path16.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
|
|
5875
|
+
return path16.isAbsolute(expanded) ? expanded : path16.resolve(expanded);
|
|
5676
5876
|
}
|
|
5677
|
-
const isWin =
|
|
5678
|
-
const paths = (process.env.PATH || "").split(
|
|
5877
|
+
const isWin = os12.platform() === "win32";
|
|
5878
|
+
const paths = (process.env.PATH || "").split(path16.delimiter);
|
|
5679
5879
|
const exes = isWin ? [".exe", ".cmd", ".bat", ""] : [""];
|
|
5680
5880
|
for (const p of paths) {
|
|
5681
5881
|
if (!p) continue;
|
|
5682
5882
|
for (const ext of exes) {
|
|
5683
|
-
const fullPath =
|
|
5883
|
+
const fullPath = path16.join(p, trimmed + ext);
|
|
5684
5884
|
try {
|
|
5685
|
-
const
|
|
5686
|
-
if (
|
|
5687
|
-
const stat2 =
|
|
5885
|
+
const fs28 = require("fs");
|
|
5886
|
+
if (fs28.existsSync(fullPath)) {
|
|
5887
|
+
const stat2 = fs28.statSync(fullPath);
|
|
5688
5888
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
5689
5889
|
return fullPath;
|
|
5690
5890
|
}
|
|
@@ -5696,14 +5896,14 @@ function findBinary(name) {
|
|
|
5696
5896
|
return isWin ? `${trimmed}.cmd` : trimmed;
|
|
5697
5897
|
}
|
|
5698
5898
|
function isScriptBinary(binaryPath) {
|
|
5699
|
-
if (!
|
|
5899
|
+
if (!path16.isAbsolute(binaryPath)) return false;
|
|
5700
5900
|
try {
|
|
5701
|
-
const
|
|
5702
|
-
const resolved =
|
|
5901
|
+
const fs28 = require("fs");
|
|
5902
|
+
const resolved = fs28.realpathSync(binaryPath);
|
|
5703
5903
|
const head = Buffer.alloc(8);
|
|
5704
|
-
const fd =
|
|
5705
|
-
|
|
5706
|
-
|
|
5904
|
+
const fd = fs28.openSync(resolved, "r");
|
|
5905
|
+
fs28.readSync(fd, head, 0, 8, 0);
|
|
5906
|
+
fs28.closeSync(fd);
|
|
5707
5907
|
let i = 0;
|
|
5708
5908
|
if (head[0] === 239 && head[1] === 187 && head[2] === 191) i = 3;
|
|
5709
5909
|
return head[i] === 35 && head[i + 1] === 33;
|
|
@@ -5712,14 +5912,14 @@ function isScriptBinary(binaryPath) {
|
|
|
5712
5912
|
}
|
|
5713
5913
|
}
|
|
5714
5914
|
function looksLikeMachOOrElf(filePath) {
|
|
5715
|
-
if (!
|
|
5915
|
+
if (!path16.isAbsolute(filePath)) return false;
|
|
5716
5916
|
try {
|
|
5717
|
-
const
|
|
5718
|
-
const resolved =
|
|
5917
|
+
const fs28 = require("fs");
|
|
5918
|
+
const resolved = fs28.realpathSync(filePath);
|
|
5719
5919
|
const buf = Buffer.alloc(8);
|
|
5720
|
-
const fd =
|
|
5721
|
-
|
|
5722
|
-
|
|
5920
|
+
const fd = fs28.openSync(resolved, "r");
|
|
5921
|
+
fs28.readSync(fd, buf, 0, 8, 0);
|
|
5922
|
+
fs28.closeSync(fd);
|
|
5723
5923
|
let i = 0;
|
|
5724
5924
|
if (buf[0] === 239 && buf[1] === 187 && buf[2] === 191) i = 3;
|
|
5725
5925
|
const b = buf.subarray(i);
|
|
@@ -5735,7 +5935,7 @@ function looksLikeMachOOrElf(filePath) {
|
|
|
5735
5935
|
}
|
|
5736
5936
|
function shSingleQuote(arg) {
|
|
5737
5937
|
if (/^[a-zA-Z0-9@%_+=:,./-]+$/.test(arg)) return arg;
|
|
5738
|
-
if (
|
|
5938
|
+
if (os12.platform() === "win32") {
|
|
5739
5939
|
return `"${arg.replace(/"/g, '""')}"`;
|
|
5740
5940
|
}
|
|
5741
5941
|
return `'${arg.replace(/'/g, `'\\''`)}'`;
|
|
@@ -5801,12 +6001,12 @@ function normalizeCliProviderForRuntime(raw) {
|
|
|
5801
6001
|
}
|
|
5802
6002
|
};
|
|
5803
6003
|
}
|
|
5804
|
-
var
|
|
6004
|
+
var os12, path16, TerminalTranscriptAccumulator, buildCliSpawnEnv;
|
|
5805
6005
|
var init_provider_cli_shared = __esm({
|
|
5806
6006
|
"src/cli-adapters/provider-cli-shared.ts"() {
|
|
5807
6007
|
"use strict";
|
|
5808
|
-
|
|
5809
|
-
|
|
6008
|
+
os12 = __toESM(require("os"));
|
|
6009
|
+
path16 = __toESM(require("path"));
|
|
5810
6010
|
init_spawn_env();
|
|
5811
6011
|
TerminalTranscriptAccumulator = class {
|
|
5812
6012
|
lines = [[]];
|
|
@@ -7695,15 +7895,15 @@ function resolveCliSpawnPlan(options) {
|
|
|
7695
7895
|
const { spawn: spawnConfig } = provider;
|
|
7696
7896
|
const configuredCommand = typeof runtimeSettings.executablePath === "string" && runtimeSettings.executablePath.trim() ? runtimeSettings.executablePath.trim() : spawnConfig.command;
|
|
7697
7897
|
const binaryPath = findBinary(configuredCommand);
|
|
7698
|
-
const isWin =
|
|
7898
|
+
const isWin = os13.platform() === "win32";
|
|
7699
7899
|
const allArgs = [...spawnConfig.args, ...extraArgs].map(
|
|
7700
7900
|
(arg) => typeof arg === "string" ? arg.replace(/\{\{workingDir\}\}/g, workingDir) : arg
|
|
7701
7901
|
);
|
|
7702
7902
|
let shellCmd;
|
|
7703
7903
|
let shellArgs;
|
|
7704
|
-
const useShellUnix = !isWin && (!!spawnConfig.shell || !
|
|
7904
|
+
const useShellUnix = !isWin && (!!spawnConfig.shell || !path17.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
|
|
7705
7905
|
const isCmdShim = isWin && /\.(cmd|bat)$/i.test(binaryPath);
|
|
7706
|
-
const useShellWin = !!spawnConfig.shell || isCmdShim || !
|
|
7906
|
+
const useShellWin = !!spawnConfig.shell || isCmdShim || !path17.isAbsolute(binaryPath) || isScriptBinary(binaryPath);
|
|
7707
7907
|
const useShell = isWin ? useShellWin : useShellUnix;
|
|
7708
7908
|
if (useShell) {
|
|
7709
7909
|
shellCmd = isWin ? "cmd.exe" : process.env.SHELL || "/bin/zsh";
|
|
@@ -7779,12 +7979,12 @@ function respondToCliTerminalQueries(options) {
|
|
|
7779
7979
|
}
|
|
7780
7980
|
return "";
|
|
7781
7981
|
}
|
|
7782
|
-
var
|
|
7982
|
+
var os13, path17, import_session_host_core2;
|
|
7783
7983
|
var init_provider_cli_runtime = __esm({
|
|
7784
7984
|
"src/cli-adapters/provider-cli-runtime.ts"() {
|
|
7785
7985
|
"use strict";
|
|
7786
|
-
|
|
7787
|
-
|
|
7986
|
+
os13 = __toESM(require("os"));
|
|
7987
|
+
path17 = __toESM(require("path"));
|
|
7788
7988
|
import_session_host_core2 = require("@adhdev/session-host-core");
|
|
7789
7989
|
init_provider_cli_shared();
|
|
7790
7990
|
}
|
|
@@ -7805,11 +8005,11 @@ function appendBoundedText(current, chunk, maxChars) {
|
|
|
7805
8005
|
if (current.length <= keepFromCurrent) return current + chunk;
|
|
7806
8006
|
return current.slice(-keepFromCurrent) + chunk;
|
|
7807
8007
|
}
|
|
7808
|
-
var
|
|
8008
|
+
var os14, ProviderCliAdapter;
|
|
7809
8009
|
var init_provider_cli_adapter = __esm({
|
|
7810
8010
|
"src/cli-adapters/provider-cli-adapter.ts"() {
|
|
7811
8011
|
"use strict";
|
|
7812
|
-
|
|
8012
|
+
os14 = __toESM(require("os"));
|
|
7813
8013
|
init_logger();
|
|
7814
8014
|
init_debug_config();
|
|
7815
8015
|
init_terminal_screen();
|
|
@@ -7830,7 +8030,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
7830
8030
|
this.transportFactory = transportFactory;
|
|
7831
8031
|
this.cliType = provider.type;
|
|
7832
8032
|
this.cliName = provider.name;
|
|
7833
|
-
this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/,
|
|
8033
|
+
this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/, os14.homedir()) : workingDir;
|
|
7834
8034
|
const resolvedConfig = resolveCliAdapterConfig(provider);
|
|
7835
8035
|
this.timeouts = resolvedConfig.timeouts;
|
|
7836
8036
|
this.approvalKeys = resolvedConfig.approvalKeys;
|
|
@@ -9977,7 +10177,7 @@ __export(loader_exports, {
|
|
|
9977
10177
|
function loadSpec(sourcePath) {
|
|
9978
10178
|
let raw;
|
|
9979
10179
|
try {
|
|
9980
|
-
const text =
|
|
10180
|
+
const text = fs9.readFileSync(sourcePath, "utf8");
|
|
9981
10181
|
raw = JSON.parse(text);
|
|
9982
10182
|
} catch (err) {
|
|
9983
10183
|
return { ok: false, errors: [`Failed to read spec: ${err.message}`], sourcePath };
|
|
@@ -10053,14 +10253,14 @@ function compileRegex2(source, flags, where, errs) {
|
|
|
10053
10253
|
}
|
|
10054
10254
|
}
|
|
10055
10255
|
function resolveSpecPath(providerDir) {
|
|
10056
|
-
return
|
|
10256
|
+
return path18.join(providerDir, "spec.json");
|
|
10057
10257
|
}
|
|
10058
|
-
var
|
|
10258
|
+
var fs9, path18, import_ajv, ajv, validate;
|
|
10059
10259
|
var init_loader = __esm({
|
|
10060
10260
|
"src/providers/spec/loader.ts"() {
|
|
10061
10261
|
"use strict";
|
|
10062
|
-
|
|
10063
|
-
|
|
10262
|
+
fs9 = __toESM(require("fs"));
|
|
10263
|
+
path18 = __toESM(require("path"));
|
|
10064
10264
|
import_ajv = __toESM(require("ajv"));
|
|
10065
10265
|
init_schema_gen();
|
|
10066
10266
|
ajv = new import_ajv.default({ allErrors: true, strict: false });
|
|
@@ -10216,7 +10416,7 @@ function _getRegisteredRoots() {
|
|
|
10216
10416
|
}
|
|
10217
10417
|
function canonicalize(p) {
|
|
10218
10418
|
try {
|
|
10219
|
-
const resolved =
|
|
10419
|
+
const resolved = path24.resolve(p);
|
|
10220
10420
|
try {
|
|
10221
10421
|
return nodeFs.realpathSync.native ? nodeFs.realpathSync.native(resolved) : nodeFs.realpathSync(resolved);
|
|
10222
10422
|
} catch {
|
|
@@ -10236,7 +10436,7 @@ function isCallerInsideGatedRoot(callerFilename) {
|
|
|
10236
10436
|
}
|
|
10237
10437
|
for (const root of _gatedRoots) {
|
|
10238
10438
|
if (normalized === root.rootPath) return root;
|
|
10239
|
-
if (normalized.startsWith(root.rootPath +
|
|
10439
|
+
if (normalized.startsWith(root.rootPath + path24.sep)) return root;
|
|
10240
10440
|
}
|
|
10241
10441
|
return null;
|
|
10242
10442
|
}
|
|
@@ -10255,16 +10455,16 @@ function ensureInstalled() {
|
|
|
10255
10455
|
};
|
|
10256
10456
|
}
|
|
10257
10457
|
function gatedRequire(request, parent, isMain, gated, originalLoad) {
|
|
10258
|
-
if (request.startsWith("./") || request.startsWith("../") ||
|
|
10458
|
+
if (request.startsWith("./") || request.startsWith("../") || path24.isAbsolute(request)) {
|
|
10259
10459
|
let resolved;
|
|
10260
10460
|
try {
|
|
10261
|
-
const callerRequire = parent?.filename ? (0, import_node_module2.createRequire)(parent.filename) : (0, import_node_module2.createRequire)(
|
|
10461
|
+
const callerRequire = parent?.filename ? (0, import_node_module2.createRequire)(parent.filename) : (0, import_node_module2.createRequire)(path24.join(gated.rootPath, "__entry__.js"));
|
|
10262
10462
|
resolved = callerRequire.resolve(request);
|
|
10263
10463
|
} catch {
|
|
10264
10464
|
return originalLoad.call(this, request, parent, isMain);
|
|
10265
10465
|
}
|
|
10266
10466
|
const resolvedCanon = canonicalize(resolved) || resolved;
|
|
10267
|
-
if (!(resolvedCanon === gated.rootPath || resolvedCanon.startsWith(gated.rootPath +
|
|
10467
|
+
if (!(resolvedCanon === gated.rootPath || resolvedCanon.startsWith(gated.rootPath + path24.sep))) {
|
|
10268
10468
|
denyRequire(request, parent, `relative path escapes provider root (resolved to ${resolvedCanon})`);
|
|
10269
10469
|
}
|
|
10270
10470
|
return originalLoad.call(this, request, parent, isMain);
|
|
@@ -10288,11 +10488,11 @@ function denyRequire(request, parent, reason) {
|
|
|
10288
10488
|
err.callerFilename = caller;
|
|
10289
10489
|
throw err;
|
|
10290
10490
|
}
|
|
10291
|
-
var
|
|
10491
|
+
var path24, import_node_module2, nodeFs, nodeChildProcess, SAFE_STDLIB, SHIMMED_STDLIB, ALL_GATED_STDLIB, FS_READ_ONLY_MEMBERS, FS_PROMISES_READ_ONLY_MEMBERS, FS_SHIM, CHILD_PROCESS_SHIM, DANGEROUS_PROCESS_METHODS, _processGloballyHardened, _originalProcessMethods, PROCESS_SHIM, _gatedRoots, _installed, PROVIDER_REQUIRE_POLICY;
|
|
10292
10492
|
var init_require_whitelist = __esm({
|
|
10293
10493
|
"src/providers/sdk/v1/sandbox/require-whitelist.ts"() {
|
|
10294
10494
|
"use strict";
|
|
10295
|
-
|
|
10495
|
+
path24 = __toESM(require("path"));
|
|
10296
10496
|
import_node_module2 = require("module");
|
|
10297
10497
|
nodeFs = __toESM(require("fs"));
|
|
10298
10498
|
nodeChildProcess = __toESM(require("child_process"));
|
|
@@ -10402,7 +10602,7 @@ function executeJsonl(src, input) {
|
|
|
10402
10602
|
} else {
|
|
10403
10603
|
let stat2 = null;
|
|
10404
10604
|
try {
|
|
10405
|
-
stat2 =
|
|
10605
|
+
stat2 = fs13.statSync(resolved);
|
|
10406
10606
|
} catch {
|
|
10407
10607
|
return null;
|
|
10408
10608
|
}
|
|
@@ -10421,7 +10621,7 @@ function executeJsonl(src, input) {
|
|
|
10421
10621
|
const v = jsonPathGet(lines[0], src.session_id_path);
|
|
10422
10622
|
if (typeof v === "string" && v) providerSessionId = v;
|
|
10423
10623
|
} else if (src.session_id_from === "filename_uuid" || !src.session_id_from) {
|
|
10424
|
-
const m =
|
|
10624
|
+
const m = path25.basename(sourcePath).match(UUID_RE);
|
|
10425
10625
|
if (m) providerSessionId = m[1];
|
|
10426
10626
|
}
|
|
10427
10627
|
const requested = input.providerSessionId || "";
|
|
@@ -10446,7 +10646,7 @@ function executeJsonl(src, input) {
|
|
|
10446
10646
|
function readJsonlLines(p) {
|
|
10447
10647
|
let text;
|
|
10448
10648
|
try {
|
|
10449
|
-
text =
|
|
10649
|
+
text = fs13.readFileSync(p, "utf8");
|
|
10450
10650
|
} catch {
|
|
10451
10651
|
return [];
|
|
10452
10652
|
}
|
|
@@ -10463,7 +10663,7 @@ function readJsonlLines(p) {
|
|
|
10463
10663
|
}
|
|
10464
10664
|
function executeSqlite(src, input) {
|
|
10465
10665
|
const resolved = expandPath2(src.path, input);
|
|
10466
|
-
if (!resolved || !
|
|
10666
|
+
if (!resolved || !fs13.existsSync(resolved)) return null;
|
|
10467
10667
|
let Database;
|
|
10468
10668
|
try {
|
|
10469
10669
|
Database = require("better-sqlite3");
|
|
@@ -10522,19 +10722,19 @@ function expandPath2(template, input) {
|
|
|
10522
10722
|
if (!template) return null;
|
|
10523
10723
|
let out = template;
|
|
10524
10724
|
if (out.startsWith("~/") || out === "~") {
|
|
10525
|
-
out =
|
|
10725
|
+
out = path25.join(os18.homedir(), out.slice(2));
|
|
10526
10726
|
}
|
|
10527
10727
|
out = out.replace(/\$\{([A-Z_][A-Z0-9_]*)(?::-(.*?))?\}/g, (_m, name, fallback) => {
|
|
10528
10728
|
const v = input.envOverrides?.[name] ?? process.env[name];
|
|
10529
10729
|
return v != null && v !== "" ? v : fallback ?? "";
|
|
10530
10730
|
});
|
|
10531
|
-
if (out.startsWith("~/")) out =
|
|
10731
|
+
if (out.startsWith("~/")) out = path25.join(os18.homedir(), out.slice(2));
|
|
10532
10732
|
const now = /* @__PURE__ */ new Date();
|
|
10533
10733
|
const workspaceRaw = input.workspace ?? "";
|
|
10534
10734
|
let workspaceResolved = workspaceRaw;
|
|
10535
10735
|
if (workspaceRaw) {
|
|
10536
10736
|
try {
|
|
10537
|
-
workspaceResolved =
|
|
10737
|
+
workspaceResolved = fs13.realpathSync(workspaceRaw);
|
|
10538
10738
|
} catch {
|
|
10539
10739
|
}
|
|
10540
10740
|
}
|
|
@@ -10576,20 +10776,20 @@ function expandDirGlob(template) {
|
|
|
10576
10776
|
for (const d of dirs) {
|
|
10577
10777
|
let entries;
|
|
10578
10778
|
try {
|
|
10579
|
-
entries =
|
|
10779
|
+
entries = fs13.readdirSync(d, { withFileTypes: true });
|
|
10580
10780
|
} catch {
|
|
10581
10781
|
continue;
|
|
10582
10782
|
}
|
|
10583
10783
|
for (const e of entries) {
|
|
10584
|
-
if (e.isDirectory() && re.test(e.name)) next.push(
|
|
10784
|
+
if (e.isDirectory() && re.test(e.name)) next.push(path25.join(d, e.name));
|
|
10585
10785
|
}
|
|
10586
10786
|
}
|
|
10587
10787
|
} else {
|
|
10588
10788
|
for (const d of dirs) {
|
|
10589
|
-
const candidate =
|
|
10789
|
+
const candidate = path25.join(d, seg);
|
|
10590
10790
|
let stat2 = null;
|
|
10591
10791
|
try {
|
|
10592
|
-
stat2 =
|
|
10792
|
+
stat2 = fs13.statSync(candidate);
|
|
10593
10793
|
} catch {
|
|
10594
10794
|
continue;
|
|
10595
10795
|
}
|
|
@@ -10603,13 +10803,13 @@ function expandDirGlob(template) {
|
|
|
10603
10803
|
function walkAllDirs(root, out) {
|
|
10604
10804
|
let entries;
|
|
10605
10805
|
try {
|
|
10606
|
-
entries =
|
|
10806
|
+
entries = fs13.readdirSync(root, { withFileTypes: true });
|
|
10607
10807
|
} catch {
|
|
10608
10808
|
return;
|
|
10609
10809
|
}
|
|
10610
10810
|
out.push(root);
|
|
10611
10811
|
for (const e of entries) {
|
|
10612
|
-
if (e.isDirectory()) walkAllDirs(
|
|
10812
|
+
if (e.isDirectory()) walkAllDirs(path25.join(root, e.name), out);
|
|
10613
10813
|
}
|
|
10614
10814
|
}
|
|
10615
10815
|
function newestRecentFileAcrossGlob(template, pattern, windowMs, sessionFloorMs = 0) {
|
|
@@ -10619,13 +10819,13 @@ function newestRecentFileAcrossGlob(template, pattern, windowMs, sessionFloorMs
|
|
|
10619
10819
|
for (const d of dirs) {
|
|
10620
10820
|
let entries;
|
|
10621
10821
|
try {
|
|
10622
|
-
entries =
|
|
10822
|
+
entries = fs13.readdirSync(d, { withFileTypes: true });
|
|
10623
10823
|
} catch {
|
|
10624
10824
|
continue;
|
|
10625
10825
|
}
|
|
10626
10826
|
for (const e of entries) {
|
|
10627
10827
|
if (!e.isFile() || !pattern.test(e.name)) continue;
|
|
10628
|
-
const p =
|
|
10828
|
+
const p = path25.join(d, e.name);
|
|
10629
10829
|
const mtime = safeMtimeMs(p);
|
|
10630
10830
|
if (mtime < cutoff) continue;
|
|
10631
10831
|
if (!best || mtime > best.mtime) best = { p, mtime };
|
|
@@ -10636,7 +10836,7 @@ function newestRecentFileAcrossGlob(template, pattern, windowMs, sessionFloorMs
|
|
|
10636
10836
|
function newestRecentFile(dir, pattern, windowMs, sessionFloorMs = 0) {
|
|
10637
10837
|
let entries;
|
|
10638
10838
|
try {
|
|
10639
|
-
entries =
|
|
10839
|
+
entries = fs13.readdirSync(dir, { withFileTypes: true });
|
|
10640
10840
|
} catch {
|
|
10641
10841
|
return null;
|
|
10642
10842
|
}
|
|
@@ -10644,7 +10844,7 @@ function newestRecentFile(dir, pattern, windowMs, sessionFloorMs = 0) {
|
|
|
10644
10844
|
let best = null;
|
|
10645
10845
|
for (const e of entries) {
|
|
10646
10846
|
if (!e.isFile() || !pattern.test(e.name)) continue;
|
|
10647
|
-
const p =
|
|
10847
|
+
const p = path25.join(dir, e.name);
|
|
10648
10848
|
const mtime = safeMtimeMs(p);
|
|
10649
10849
|
if (mtime < cutoff) continue;
|
|
10650
10850
|
if (!best || mtime > best.mtime) best = { p, mtime };
|
|
@@ -10653,7 +10853,7 @@ function newestRecentFile(dir, pattern, windowMs, sessionFloorMs = 0) {
|
|
|
10653
10853
|
}
|
|
10654
10854
|
function safeMtimeMs(p) {
|
|
10655
10855
|
try {
|
|
10656
|
-
return Math.floor(
|
|
10856
|
+
return Math.floor(fs13.statSync(p).mtimeMs);
|
|
10657
10857
|
} catch {
|
|
10658
10858
|
return 0;
|
|
10659
10859
|
}
|
|
@@ -10857,13 +11057,13 @@ function evalTerm(t, record) {
|
|
|
10857
11057
|
}
|
|
10858
11058
|
return t.negate ? !result : result;
|
|
10859
11059
|
}
|
|
10860
|
-
var
|
|
11060
|
+
var fs13, os18, path25, UUID_RE;
|
|
10861
11061
|
var init_native_history_executor = __esm({
|
|
10862
11062
|
"src/providers/spec/native-history-executor.ts"() {
|
|
10863
11063
|
"use strict";
|
|
10864
|
-
|
|
10865
|
-
|
|
10866
|
-
|
|
11064
|
+
fs13 = __toESM(require("fs"));
|
|
11065
|
+
os18 = __toESM(require("os"));
|
|
11066
|
+
path25 = __toESM(require("path"));
|
|
10867
11067
|
UUID_RE = /([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i;
|
|
10868
11068
|
}
|
|
10869
11069
|
});
|
|
@@ -10881,7 +11081,7 @@ function extractTimestampValue(value) {
|
|
|
10881
11081
|
}
|
|
10882
11082
|
function statMtimeMs(filePath) {
|
|
10883
11083
|
try {
|
|
10884
|
-
return
|
|
11084
|
+
return fs14.statSync(filePath).mtimeMs;
|
|
10885
11085
|
} catch {
|
|
10886
11086
|
return 0;
|
|
10887
11087
|
}
|
|
@@ -10951,7 +11151,7 @@ function extractUserContentParts(content) {
|
|
|
10951
11151
|
function parseTranscriptFile(filePath, sessionId, workspaceFallback) {
|
|
10952
11152
|
let raw;
|
|
10953
11153
|
try {
|
|
10954
|
-
raw =
|
|
11154
|
+
raw = fs14.readFileSync(filePath, "utf-8");
|
|
10955
11155
|
} catch {
|
|
10956
11156
|
return [];
|
|
10957
11157
|
}
|
|
@@ -11024,10 +11224,10 @@ function parseTranscriptFile(filePath, sessionId, workspaceFallback) {
|
|
|
11024
11224
|
return records;
|
|
11025
11225
|
}
|
|
11026
11226
|
function readSession(sessionPath) {
|
|
11027
|
-
if (!sessionPath || !
|
|
11028
|
-
const basename12 =
|
|
11227
|
+
if (!sessionPath || !path26.isAbsolute(sessionPath)) return null;
|
|
11228
|
+
const basename12 = path26.basename(sessionPath, ".jsonl");
|
|
11029
11229
|
if (!isSafeSessionId(basename12)) return null;
|
|
11030
|
-
if (!
|
|
11230
|
+
if (!fs14.existsSync(sessionPath)) return null;
|
|
11031
11231
|
const sourceMtimeMs = statMtimeMs(sessionPath);
|
|
11032
11232
|
const messages = parseTranscriptFile(sessionPath, basename12);
|
|
11033
11233
|
if (messages.length === 0) return null;
|
|
@@ -11043,12 +11243,12 @@ function readSession(sessionPath) {
|
|
|
11043
11243
|
workspace
|
|
11044
11244
|
};
|
|
11045
11245
|
}
|
|
11046
|
-
var
|
|
11246
|
+
var fs14, path26;
|
|
11047
11247
|
var init_claude_cli_transcript = __esm({
|
|
11048
11248
|
"src/providers/native-history/claude-cli-transcript.ts"() {
|
|
11049
11249
|
"use strict";
|
|
11050
|
-
|
|
11051
|
-
|
|
11250
|
+
fs14 = __toESM(require("fs"));
|
|
11251
|
+
path26 = __toESM(require("path"));
|
|
11052
11252
|
}
|
|
11053
11253
|
});
|
|
11054
11254
|
|
|
@@ -11065,7 +11265,7 @@ function extractTimestampValue2(value) {
|
|
|
11065
11265
|
}
|
|
11066
11266
|
function statMtimeMs2(filePath) {
|
|
11067
11267
|
try {
|
|
11068
|
-
return
|
|
11268
|
+
return fs15.statSync(filePath).mtimeMs;
|
|
11069
11269
|
} catch {
|
|
11070
11270
|
return 0;
|
|
11071
11271
|
}
|
|
@@ -11133,7 +11333,7 @@ function extractToolOutputContent(payload) {
|
|
|
11133
11333
|
}
|
|
11134
11334
|
function readSessionMeta(filePath) {
|
|
11135
11335
|
try {
|
|
11136
|
-
const firstLine =
|
|
11336
|
+
const firstLine = fs15.readFileSync(filePath, "utf-8").split("\n").find(Boolean);
|
|
11137
11337
|
if (!firstLine) return null;
|
|
11138
11338
|
const parsed = JSON.parse(firstLine);
|
|
11139
11339
|
if (String(parsed.type ?? "") !== "session_meta") return null;
|
|
@@ -11145,7 +11345,7 @@ function readSessionMeta(filePath) {
|
|
|
11145
11345
|
function parseSessionFile(filePath, sessionId, workspaceFallback) {
|
|
11146
11346
|
let raw;
|
|
11147
11347
|
try {
|
|
11148
|
-
raw =
|
|
11348
|
+
raw = fs15.readFileSync(filePath, "utf-8");
|
|
11149
11349
|
} catch {
|
|
11150
11350
|
return [];
|
|
11151
11351
|
}
|
|
@@ -11239,11 +11439,11 @@ function parseSessionFile(filePath, sessionId, workspaceFallback) {
|
|
|
11239
11439
|
return records;
|
|
11240
11440
|
}
|
|
11241
11441
|
function readSession2(sessionPath) {
|
|
11242
|
-
if (!sessionPath || !
|
|
11243
|
-
if (!
|
|
11442
|
+
if (!sessionPath || !path27.isAbsolute(sessionPath)) return null;
|
|
11443
|
+
if (!fs15.existsSync(sessionPath)) return null;
|
|
11244
11444
|
const meta = readSessionMeta(sessionPath);
|
|
11245
11445
|
const metaId = String(meta?.id ?? "").trim();
|
|
11246
|
-
const basename12 =
|
|
11446
|
+
const basename12 = path27.basename(sessionPath, ".jsonl");
|
|
11247
11447
|
const uuidMatch = basename12.match(/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i);
|
|
11248
11448
|
const filenameUuid = uuidMatch ? uuidMatch[1] : "";
|
|
11249
11449
|
if (metaId && filenameUuid && metaId !== filenameUuid) return null;
|
|
@@ -11265,12 +11465,12 @@ function readSession2(sessionPath) {
|
|
|
11265
11465
|
workspace
|
|
11266
11466
|
};
|
|
11267
11467
|
}
|
|
11268
|
-
var
|
|
11468
|
+
var fs15, path27;
|
|
11269
11469
|
var init_codex_cli_transcript = __esm({
|
|
11270
11470
|
"src/providers/native-history/codex-cli-transcript.ts"() {
|
|
11271
11471
|
"use strict";
|
|
11272
|
-
|
|
11273
|
-
|
|
11472
|
+
fs15 = __toESM(require("fs"));
|
|
11473
|
+
path27 = __toESM(require("path"));
|
|
11274
11474
|
}
|
|
11275
11475
|
});
|
|
11276
11476
|
|
|
@@ -11287,7 +11487,7 @@ function extractTimestampValue3(value) {
|
|
|
11287
11487
|
}
|
|
11288
11488
|
function statMtimeMs3(filePath) {
|
|
11289
11489
|
try {
|
|
11290
|
-
return
|
|
11490
|
+
return fs16.statSync(filePath).mtimeMs;
|
|
11291
11491
|
} catch {
|
|
11292
11492
|
return 0;
|
|
11293
11493
|
}
|
|
@@ -11296,13 +11496,13 @@ function isUuidLike(value) {
|
|
|
11296
11496
|
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
|
|
11297
11497
|
}
|
|
11298
11498
|
function antigravityRoot() {
|
|
11299
|
-
return
|
|
11499
|
+
return path28.join(os19.homedir(), ".gemini", "antigravity-cli");
|
|
11300
11500
|
}
|
|
11301
11501
|
function historyJsonlPath() {
|
|
11302
|
-
return
|
|
11502
|
+
return path28.join(antigravityRoot(), "history.jsonl");
|
|
11303
11503
|
}
|
|
11304
11504
|
function brainRoot() {
|
|
11305
|
-
return
|
|
11505
|
+
return path28.join(antigravityRoot(), "brain");
|
|
11306
11506
|
}
|
|
11307
11507
|
function extractUserRequestContent(content) {
|
|
11308
11508
|
const raw = content.trim();
|
|
@@ -11318,7 +11518,7 @@ function antigravityRowKind(rowType) {
|
|
|
11318
11518
|
function parseBrainTranscript(filePath, sessionId, workspace) {
|
|
11319
11519
|
let raw;
|
|
11320
11520
|
try {
|
|
11321
|
-
raw =
|
|
11521
|
+
raw = fs16.readFileSync(filePath, "utf-8");
|
|
11322
11522
|
} catch {
|
|
11323
11523
|
return null;
|
|
11324
11524
|
}
|
|
@@ -11378,7 +11578,7 @@ function readHistoryRows() {
|
|
|
11378
11578
|
const sourcePath = historyJsonlPath();
|
|
11379
11579
|
let lines = [];
|
|
11380
11580
|
try {
|
|
11381
|
-
lines =
|
|
11581
|
+
lines = fs16.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
|
|
11382
11582
|
} catch {
|
|
11383
11583
|
return [];
|
|
11384
11584
|
}
|
|
@@ -11425,7 +11625,7 @@ function extractStringsFromBuffer(buf) {
|
|
|
11425
11625
|
function parsePbFile(filePath, sessionId) {
|
|
11426
11626
|
let buf;
|
|
11427
11627
|
try {
|
|
11428
|
-
buf =
|
|
11628
|
+
buf = fs16.readFileSync(filePath);
|
|
11429
11629
|
} catch {
|
|
11430
11630
|
return null;
|
|
11431
11631
|
}
|
|
@@ -11448,13 +11648,13 @@ function parsePbFile(filePath, sessionId) {
|
|
|
11448
11648
|
];
|
|
11449
11649
|
}
|
|
11450
11650
|
function readSession3(sessionPath, sessionId, workspace) {
|
|
11451
|
-
if (!sessionPath || !
|
|
11452
|
-
if (!
|
|
11651
|
+
if (!sessionPath || !path28.isAbsolute(sessionPath)) return null;
|
|
11652
|
+
if (!fs16.existsSync(sessionPath)) return null;
|
|
11453
11653
|
const sourceMtimeMs = statMtimeMs3(sessionPath);
|
|
11454
11654
|
const brainRootPath = brainRoot();
|
|
11455
|
-
if (sessionPath.startsWith(brainRootPath +
|
|
11456
|
-
const
|
|
11457
|
-
const uuidFromPath =
|
|
11655
|
+
if (sessionPath.startsWith(brainRootPath + path28.sep) && sessionPath.endsWith(".jsonl")) {
|
|
11656
|
+
const relative5 = sessionPath.slice(brainRootPath.length + 1);
|
|
11657
|
+
const uuidFromPath = relative5.split(path28.sep)[0];
|
|
11458
11658
|
const resolvedSessionId = sessionId || (isUuidLike(uuidFromPath) ? uuidFromPath : "");
|
|
11459
11659
|
if (!resolvedSessionId) return null;
|
|
11460
11660
|
const messages = parseBrainTranscript(sessionPath, resolvedSessionId, workspace);
|
|
@@ -11470,7 +11670,7 @@ function readSession3(sessionPath, sessionId, workspace) {
|
|
|
11470
11670
|
};
|
|
11471
11671
|
}
|
|
11472
11672
|
if (sessionPath.endsWith(".pb")) {
|
|
11473
|
-
const pbSessionId = sessionId ||
|
|
11673
|
+
const pbSessionId = sessionId || path28.basename(sessionPath, ".pb");
|
|
11474
11674
|
if (!isUuidLike(pbSessionId)) return null;
|
|
11475
11675
|
const messages = parsePbFile(sessionPath, pbSessionId);
|
|
11476
11676
|
if (!messages || messages.length === 0) return null;
|
|
@@ -11484,7 +11684,7 @@ function readSession3(sessionPath, sessionId, workspace) {
|
|
|
11484
11684
|
partialReason: "antigravity_cli_pb_raw_text_extraction"
|
|
11485
11685
|
};
|
|
11486
11686
|
}
|
|
11487
|
-
if (
|
|
11687
|
+
if (path28.basename(sessionPath) === "history.jsonl") {
|
|
11488
11688
|
const resolvedSessionId = sessionId || "";
|
|
11489
11689
|
if (!resolvedSessionId || !isUuidLike(resolvedSessionId)) return null;
|
|
11490
11690
|
const rows = readHistoryRows().filter((r) => r.conversationId === resolvedSessionId);
|
|
@@ -11529,13 +11729,13 @@ function readSession3(sessionPath, sessionId, workspace) {
|
|
|
11529
11729
|
}
|
|
11530
11730
|
return null;
|
|
11531
11731
|
}
|
|
11532
|
-
var
|
|
11732
|
+
var fs16, path28, os19, MIN_PRINTABLE_RUN;
|
|
11533
11733
|
var init_antigravity_cli_transcript = __esm({
|
|
11534
11734
|
"src/providers/native-history/antigravity-cli-transcript.ts"() {
|
|
11535
11735
|
"use strict";
|
|
11536
|
-
|
|
11537
|
-
|
|
11538
|
-
|
|
11736
|
+
fs16 = __toESM(require("fs"));
|
|
11737
|
+
path28 = __toESM(require("path"));
|
|
11738
|
+
os19 = __toESM(require("os"));
|
|
11539
11739
|
MIN_PRINTABLE_RUN = 8;
|
|
11540
11740
|
}
|
|
11541
11741
|
});
|
|
@@ -11543,13 +11743,13 @@ var init_antigravity_cli_transcript = __esm({
|
|
|
11543
11743
|
// src/providers/native-history/hermes-cli-transcript.ts
|
|
11544
11744
|
function statMtimeMs4(p) {
|
|
11545
11745
|
try {
|
|
11546
|
-
return Math.floor(
|
|
11746
|
+
return Math.floor(fs17.statSync(p).mtimeMs);
|
|
11547
11747
|
} catch {
|
|
11548
11748
|
return 0;
|
|
11549
11749
|
}
|
|
11550
11750
|
}
|
|
11551
11751
|
function openDb() {
|
|
11552
|
-
if (!
|
|
11752
|
+
if (!fs17.existsSync(HERMES_STATE_DB)) return null;
|
|
11553
11753
|
try {
|
|
11554
11754
|
const Database = require("better-sqlite3");
|
|
11555
11755
|
return new Database(HERMES_STATE_DB, { readonly: true, fileMustExist: true });
|
|
@@ -11606,10 +11806,10 @@ function readSession4(sessionPath) {
|
|
|
11606
11806
|
}
|
|
11607
11807
|
}
|
|
11608
11808
|
}
|
|
11609
|
-
if (!
|
|
11809
|
+
if (!path29.isAbsolute(sessionPath) || !fs17.existsSync(sessionPath)) return null;
|
|
11610
11810
|
let raw;
|
|
11611
11811
|
try {
|
|
11612
|
-
raw = JSON.parse(
|
|
11812
|
+
raw = JSON.parse(fs17.readFileSync(sessionPath, "utf8"));
|
|
11613
11813
|
} catch {
|
|
11614
11814
|
return null;
|
|
11615
11815
|
}
|
|
@@ -11632,7 +11832,7 @@ function readSession4(sessionPath) {
|
|
|
11632
11832
|
});
|
|
11633
11833
|
}
|
|
11634
11834
|
if (messages.length === 0) return null;
|
|
11635
|
-
const sessionId = typeof raw.session_id === "string" && raw.session_id ? raw.session_id :
|
|
11835
|
+
const sessionId = typeof raw.session_id === "string" && raw.session_id ? raw.session_id : path29.basename(sessionPath, ".json").replace(/^session_/, "");
|
|
11636
11836
|
return {
|
|
11637
11837
|
messages,
|
|
11638
11838
|
providerSessionId: sessionId,
|
|
@@ -11649,15 +11849,15 @@ function normalizeHermesRole(r) {
|
|
|
11649
11849
|
if (s === "tool" || s === "tool_result" || s === "function") return "assistant";
|
|
11650
11850
|
return "system";
|
|
11651
11851
|
}
|
|
11652
|
-
var
|
|
11852
|
+
var fs17, path29, os20, HERMES_STATE_DB, HERMES_LEGACY_SESSIONS_DIR;
|
|
11653
11853
|
var init_hermes_cli_transcript = __esm({
|
|
11654
11854
|
"src/providers/native-history/hermes-cli-transcript.ts"() {
|
|
11655
11855
|
"use strict";
|
|
11656
|
-
|
|
11657
|
-
|
|
11658
|
-
|
|
11659
|
-
HERMES_STATE_DB =
|
|
11660
|
-
HERMES_LEGACY_SESSIONS_DIR =
|
|
11856
|
+
fs17 = __toESM(require("fs"));
|
|
11857
|
+
path29 = __toESM(require("path"));
|
|
11858
|
+
os20 = __toESM(require("os"));
|
|
11859
|
+
HERMES_STATE_DB = path29.join(os20.homedir(), ".hermes", "state.db");
|
|
11860
|
+
HERMES_LEGACY_SESSIONS_DIR = path29.join(os20.homedir(), ".hermes", "sessions");
|
|
11661
11861
|
}
|
|
11662
11862
|
});
|
|
11663
11863
|
|
|
@@ -11705,26 +11905,26 @@ function resolveSourcePath(reader, workspace, sessionId) {
|
|
|
11705
11905
|
}
|
|
11706
11906
|
}
|
|
11707
11907
|
function resolveClaudePath(workspace, sessionId) {
|
|
11708
|
-
const dir =
|
|
11709
|
-
if (!
|
|
11908
|
+
const dir = path30.join(os21.homedir(), ".claude", "projects", cwdAsDashes(workspace));
|
|
11909
|
+
if (!fs18.existsSync(dir)) return null;
|
|
11710
11910
|
if (sessionId) {
|
|
11711
|
-
const candidate =
|
|
11712
|
-
if (
|
|
11911
|
+
const candidate = path30.join(dir, `${sessionId}.jsonl`);
|
|
11912
|
+
if (fs18.existsSync(candidate)) return candidate;
|
|
11713
11913
|
}
|
|
11714
11914
|
return null;
|
|
11715
11915
|
}
|
|
11716
11916
|
function resolveCodexPath(workspace) {
|
|
11717
11917
|
void workspace;
|
|
11718
11918
|
const now = /* @__PURE__ */ new Date();
|
|
11719
|
-
const dir =
|
|
11720
|
-
|
|
11919
|
+
const dir = path30.join(
|
|
11920
|
+
os21.homedir(),
|
|
11721
11921
|
".codex",
|
|
11722
11922
|
"sessions",
|
|
11723
11923
|
String(now.getUTCFullYear()),
|
|
11724
11924
|
String(now.getUTCMonth() + 1).padStart(2, "0"),
|
|
11725
11925
|
String(now.getUTCDate()).padStart(2, "0")
|
|
11726
11926
|
);
|
|
11727
|
-
if (
|
|
11927
|
+
if (fs18.existsSync(dir)) {
|
|
11728
11928
|
const f = newestRecentFile2(dir, /\.jsonl$/);
|
|
11729
11929
|
if (f) return f;
|
|
11730
11930
|
}
|
|
@@ -11732,23 +11932,23 @@ function resolveCodexPath(workspace) {
|
|
|
11732
11932
|
}
|
|
11733
11933
|
function resolveAntigravityPath(workspace) {
|
|
11734
11934
|
void workspace;
|
|
11735
|
-
const brainRoot2 =
|
|
11736
|
-
if (!
|
|
11935
|
+
const brainRoot2 = path30.join(os21.homedir(), ".gemini", "antigravity-cli", "brain");
|
|
11936
|
+
if (!fs18.existsSync(brainRoot2)) return null;
|
|
11737
11937
|
const cutoff = Date.now() - RECENT_WINDOW_MS;
|
|
11738
|
-
const entries =
|
|
11938
|
+
const entries = fs18.readdirSync(brainRoot2, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => ({ p: path30.join(brainRoot2, e.name), mtime: safeMtime(path30.join(brainRoot2, e.name)) })).filter((e) => e.mtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
11739
11939
|
for (const e of entries) {
|
|
11740
|
-
const t =
|
|
11741
|
-
if (
|
|
11940
|
+
const t = path30.join(e.p, ".system_generated", "logs", "transcript.jsonl");
|
|
11941
|
+
if (fs18.existsSync(t)) return t;
|
|
11742
11942
|
}
|
|
11743
11943
|
return null;
|
|
11744
11944
|
}
|
|
11745
11945
|
function resolveHermesPath(workspace, sessionId) {
|
|
11746
11946
|
void workspace;
|
|
11747
11947
|
void sessionId;
|
|
11748
|
-
const dbPath =
|
|
11749
|
-
if (
|
|
11750
|
-
const dir =
|
|
11751
|
-
if (!
|
|
11948
|
+
const dbPath = path30.join(os21.homedir(), ".hermes", "state.db");
|
|
11949
|
+
if (fs18.existsSync(dbPath)) return dbPath;
|
|
11950
|
+
const dir = path30.join(os21.homedir(), ".hermes", "sessions");
|
|
11951
|
+
if (!fs18.existsSync(dir)) return null;
|
|
11752
11952
|
return newestRecentFile2(dir, /^session_.*\.json$/);
|
|
11753
11953
|
}
|
|
11754
11954
|
function readByReader(reader, sourcePath, sessionId, workspace) {
|
|
@@ -11770,7 +11970,7 @@ function cwdAsDashes(cwd) {
|
|
|
11770
11970
|
function newestRecentFile2(dir, pattern) {
|
|
11771
11971
|
try {
|
|
11772
11972
|
const cutoff = Date.now() - RECENT_WINDOW_MS;
|
|
11773
|
-
const entries =
|
|
11973
|
+
const entries = fs18.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && pattern.test(e.name)).map((e) => ({ p: path30.join(dir, e.name), mtime: safeMtime(path30.join(dir, e.name)) })).filter((e) => e.mtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
|
|
11774
11974
|
return entries[0]?.p ?? null;
|
|
11775
11975
|
} catch {
|
|
11776
11976
|
return null;
|
|
@@ -11778,7 +11978,7 @@ function newestRecentFile2(dir, pattern) {
|
|
|
11778
11978
|
}
|
|
11779
11979
|
function safeMtime(p) {
|
|
11780
11980
|
try {
|
|
11781
|
-
return Math.floor(
|
|
11981
|
+
return Math.floor(fs18.statSync(p).mtimeMs);
|
|
11782
11982
|
} catch {
|
|
11783
11983
|
return 0;
|
|
11784
11984
|
}
|
|
@@ -11790,13 +11990,13 @@ function normalizeRole2(r) {
|
|
|
11790
11990
|
if (s === "tool" || s === "tool_result" || s === "function") return "assistant";
|
|
11791
11991
|
return "system";
|
|
11792
11992
|
}
|
|
11793
|
-
var
|
|
11993
|
+
var fs18, os21, path30, RECENT_WINDOW_MS;
|
|
11794
11994
|
var init_dispatcher = __esm({
|
|
11795
11995
|
"src/providers/native-history/dispatcher.ts"() {
|
|
11796
11996
|
"use strict";
|
|
11797
|
-
|
|
11798
|
-
|
|
11799
|
-
|
|
11997
|
+
fs18 = __toESM(require("fs"));
|
|
11998
|
+
os21 = __toESM(require("os"));
|
|
11999
|
+
path30 = __toESM(require("path"));
|
|
11800
12000
|
init_claude_cli_transcript();
|
|
11801
12001
|
init_codex_cli_transcript();
|
|
11802
12002
|
init_antigravity_cli_transcript();
|
|
@@ -12339,12 +12539,12 @@ function parseSubmoduleStatusOutput(output, repoRoot, ignorePaths) {
|
|
|
12339
12539
|
if (!match) continue;
|
|
12340
12540
|
const prefix = match[1];
|
|
12341
12541
|
const commit = match[2];
|
|
12342
|
-
const
|
|
12343
|
-
if (ignoreSet.has(
|
|
12542
|
+
const path40 = match[3];
|
|
12543
|
+
if (ignoreSet.has(path40)) continue;
|
|
12344
12544
|
submodules.push({
|
|
12345
|
-
path:
|
|
12545
|
+
path: path40,
|
|
12346
12546
|
commit,
|
|
12347
|
-
repoPath: repoRoot + "/" +
|
|
12547
|
+
repoPath: repoRoot + "/" + path40,
|
|
12348
12548
|
dirty: prefix === "+",
|
|
12349
12549
|
outOfSync: prefix === "-",
|
|
12350
12550
|
lastCheckedAt: Date.now()
|
|
@@ -13848,10 +14048,10 @@ function getRegistryPath() {
|
|
|
13848
14048
|
return (0, import_path3.join)(getDaemonDataDir(), "mesh-coordinators.json");
|
|
13849
14049
|
}
|
|
13850
14050
|
function loadMeshCoordinatorRegistry() {
|
|
13851
|
-
const
|
|
13852
|
-
if (!(0, import_fs3.existsSync)(
|
|
14051
|
+
const path40 = getRegistryPath();
|
|
14052
|
+
if (!(0, import_fs3.existsSync)(path40)) return;
|
|
13853
14053
|
try {
|
|
13854
|
-
const raw = JSON.parse((0, import_fs3.readFileSync)(
|
|
14054
|
+
const raw = JSON.parse((0, import_fs3.readFileSync)(path40, "utf-8"));
|
|
13855
14055
|
if (!Array.isArray(raw)) return;
|
|
13856
14056
|
_registry.clear();
|
|
13857
14057
|
for (const entry of raw) {
|
|
@@ -14070,8 +14270,8 @@ function validateMeshRefineConfig(config, source = "inline") {
|
|
|
14070
14270
|
if (rejectedCommands.length) errors.push("one or more validation commands are invalid");
|
|
14071
14271
|
return { valid: errors.length === 0, errors, bootstrapCommands, commands, rejectedCommands };
|
|
14072
14272
|
}
|
|
14073
|
-
function parseConfigText(
|
|
14074
|
-
if (/\.json$/i.test(
|
|
14273
|
+
function parseConfigText(path40, text) {
|
|
14274
|
+
if (/\.json$/i.test(path40)) return JSON.parse(text);
|
|
14075
14275
|
return yaml.load(text);
|
|
14076
14276
|
}
|
|
14077
14277
|
function loadMeshRefineConfig(mesh, workspace) {
|
|
@@ -14082,16 +14282,16 @@ function loadMeshRefineConfig(mesh, workspace) {
|
|
|
14082
14282
|
if (!validation.valid) return { source: "mesh.policy.refineConfig", sourceType: "invalid", error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
14083
14283
|
return { config: inline, source: "mesh.policy.refineConfig", sourceType: "mesh_policy" };
|
|
14084
14284
|
}
|
|
14085
|
-
for (const
|
|
14086
|
-
const configPath = (0, import_path4.join)(workspace,
|
|
14285
|
+
for (const relative5 of MESH_REFINE_CONFIG_LOCATIONS) {
|
|
14286
|
+
const configPath = (0, import_path4.join)(workspace, relative5);
|
|
14087
14287
|
if (!(0, import_fs4.existsSync)(configPath)) continue;
|
|
14088
14288
|
try {
|
|
14089
14289
|
const parsed = parseConfigText(configPath, (0, import_fs4.readFileSync)(configPath, "utf-8"));
|
|
14090
|
-
const validation = validateMeshRefineConfig(parsed,
|
|
14091
|
-
if (!validation.valid) return { source:
|
|
14092
|
-
return { config: parsed, source:
|
|
14290
|
+
const validation = validateMeshRefineConfig(parsed, relative5);
|
|
14291
|
+
if (!validation.valid) return { source: relative5, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
14292
|
+
return { config: parsed, source: relative5, sourceType: "repo_file", path: configPath };
|
|
14093
14293
|
} catch (error) {
|
|
14094
|
-
return { source:
|
|
14294
|
+
return { source: relative5, sourceType: "invalid", path: configPath, error: error?.message || String(error) };
|
|
14095
14295
|
}
|
|
14096
14296
|
}
|
|
14097
14297
|
return {
|
|
@@ -14224,8 +14424,8 @@ var MESH_WORKTREE_BOOTSTRAP_CONFIG_SCHEMA = {
|
|
|
14224
14424
|
var DEFAULT_TIMEOUT_MS2 = 12e4;
|
|
14225
14425
|
var DEFAULT_OUTPUT_LIMIT_BYTES = 128 * 1024;
|
|
14226
14426
|
var OUTPUT_SUMMARY_CHARS = 2e3;
|
|
14227
|
-
function parseConfigText2(
|
|
14228
|
-
if (/\.json$/i.test(
|
|
14427
|
+
function parseConfigText2(path40, text) {
|
|
14428
|
+
if (/\.json$/i.test(path40)) return JSON.parse(text);
|
|
14229
14429
|
return yaml2.load(text);
|
|
14230
14430
|
}
|
|
14231
14431
|
function truncateOutput(value) {
|
|
@@ -14265,16 +14465,16 @@ function loadMeshWorktreeBootstrapConfig(mesh, workspace) {
|
|
|
14265
14465
|
if (!validation.valid) return { source: "mesh.policy.worktreeBootstrapConfig", sourceType: "invalid", error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
14266
14466
|
return { config: inline, source: "mesh.policy.worktreeBootstrapConfig", sourceType: "mesh_policy" };
|
|
14267
14467
|
}
|
|
14268
|
-
for (const
|
|
14269
|
-
const configPath = (0, import_path5.join)(workspace,
|
|
14468
|
+
for (const relative5 of MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS) {
|
|
14469
|
+
const configPath = (0, import_path5.join)(workspace, relative5);
|
|
14270
14470
|
if (!(0, import_fs5.existsSync)(configPath)) continue;
|
|
14271
14471
|
try {
|
|
14272
14472
|
const parsed = parseConfigText2(configPath, (0, import_fs5.readFileSync)(configPath, "utf-8"));
|
|
14273
|
-
const validation = validateMeshWorktreeBootstrapConfig(parsed,
|
|
14274
|
-
if (!validation.valid) return { source:
|
|
14275
|
-
return { config: parsed, source:
|
|
14473
|
+
const validation = validateMeshWorktreeBootstrapConfig(parsed, relative5);
|
|
14474
|
+
if (!validation.valid) return { source: relative5, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
14475
|
+
return { config: parsed, source: relative5, sourceType: "repo_file", path: configPath };
|
|
14276
14476
|
} catch (error) {
|
|
14277
|
-
return { source:
|
|
14477
|
+
return { source: relative5, sourceType: "invalid", path: configPath, error: error?.message || String(error) };
|
|
14278
14478
|
}
|
|
14279
14479
|
}
|
|
14280
14480
|
return { source: "unavailable", sourceType: "unavailable", error: `No worktree bootstrap config found. Checked: ${MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS.join(", ")}` };
|
|
@@ -15515,17 +15715,17 @@ function checkPathExists(paths) {
|
|
|
15515
15715
|
return null;
|
|
15516
15716
|
}
|
|
15517
15717
|
async function detectIDEs(providerLoader) {
|
|
15518
|
-
const
|
|
15718
|
+
const os29 = (0, import_os2.platform)();
|
|
15519
15719
|
const results = [];
|
|
15520
15720
|
for (const def of getMergedDefinitions()) {
|
|
15521
15721
|
const cliPath = findCliCommand(providerLoader?.getIdeCliCommand(def.id, def.cli) || def.cli);
|
|
15522
|
-
const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[
|
|
15722
|
+
const appPath = checkPathExists(providerLoader?.getIdePathCandidates(def.id, def.paths[os29] || []) || []);
|
|
15523
15723
|
let resolvedCli = cliPath;
|
|
15524
|
-
if (!resolvedCli && appPath &&
|
|
15724
|
+
if (!resolvedCli && appPath && os29 === "darwin") {
|
|
15525
15725
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
15526
15726
|
if ((0, import_fs11.existsSync)(bundledCli)) resolvedCli = bundledCli;
|
|
15527
15727
|
}
|
|
15528
|
-
if (!resolvedCli && appPath &&
|
|
15728
|
+
if (!resolvedCli && appPath && os29 === "win32") {
|
|
15529
15729
|
const { dirname: dirname11 } = await import("path");
|
|
15530
15730
|
const appDir = dirname11(appPath);
|
|
15531
15731
|
const candidates = [
|
|
@@ -15542,7 +15742,7 @@ async function detectIDEs(providerLoader) {
|
|
|
15542
15742
|
}
|
|
15543
15743
|
}
|
|
15544
15744
|
}
|
|
15545
|
-
const installed =
|
|
15745
|
+
const installed = os29 === "darwin" ? !!(resolvedCli || appPath) : !!resolvedCli;
|
|
15546
15746
|
const version = resolvedCli ? await getIdeVersion(resolvedCli) : null;
|
|
15547
15747
|
results.push({
|
|
15548
15748
|
id: def.id,
|
|
@@ -25924,6 +26124,14 @@ var DaemonCommandHandler = class {
|
|
|
25924
26124
|
return this.handleCheckProviderUpdates(args);
|
|
25925
26125
|
case "list_installed_providers":
|
|
25926
26126
|
return this.handleListInstalledProviders(args);
|
|
26127
|
+
case "add_provider_source":
|
|
26128
|
+
return this.handleAddProviderSource(args);
|
|
26129
|
+
case "remove_provider_source":
|
|
26130
|
+
return this.handleRemoveProviderSource(args);
|
|
26131
|
+
case "list_provider_sources":
|
|
26132
|
+
return this.handleListProviderSources(args);
|
|
26133
|
+
case "set_active_provider_source":
|
|
26134
|
+
return this.handleSetActiveProviderSource(args);
|
|
25927
26135
|
// ─── Stream commands (stream-commands.ts) ───────────
|
|
25928
26136
|
case "select_session":
|
|
25929
26137
|
return handleSelectSession(this, args);
|
|
@@ -25987,49 +26195,62 @@ var DaemonCommandHandler = class {
|
|
|
25987
26195
|
return { success: false, error: "ProviderLoader not initialized" };
|
|
25988
26196
|
}
|
|
25989
26197
|
/**
|
|
25990
|
-
* Return per-provider availability so
|
|
25991
|
-
* "Installed" badges. Reuses the existing detection state from
|
|
26198
|
+
* Return per-provider availability so the dashboard's provider catalog
|
|
26199
|
+
* can show "Installed" badges. Reuses the existing detection state from
|
|
25992
26200
|
* ProviderLoader.getMachineProviderStatus() — no probing is triggered.
|
|
25993
26201
|
*/
|
|
25994
26202
|
handleListProviderAvailability(_args) {
|
|
25995
26203
|
if (!this._ctx.providerLoader) {
|
|
25996
26204
|
return { success: false, error: "ProviderLoader not initialized" };
|
|
25997
26205
|
}
|
|
26206
|
+
const { describeTrust: describeTrust2, requiresConfirmation: requiresConfirmation2 } = (init_provider_trust(), __toCommonJS(provider_trust_exports));
|
|
25998
26207
|
const loader = this._ctx.providerLoader;
|
|
25999
26208
|
const items = loader.getAll().map((provider) => {
|
|
26000
26209
|
const machineConfig = loader.getMachineProviderConfig(provider.type);
|
|
26001
26210
|
const lastDetection = machineConfig.lastDetection;
|
|
26211
|
+
const trust = provider._sourceTrust ?? "trusted";
|
|
26212
|
+
const layer = provider._sourceLayer ?? "upstream";
|
|
26213
|
+
const sourceName = provider._sourceName ?? null;
|
|
26002
26214
|
return {
|
|
26003
26215
|
type: provider.type,
|
|
26004
26216
|
category: provider.category,
|
|
26005
26217
|
status: loader.getMachineProviderStatus(provider.type),
|
|
26006
26218
|
installed: lastDetection?.ok === true,
|
|
26007
26219
|
detectedPath: lastDetection?.path ?? null,
|
|
26008
|
-
checkedAt: lastDetection?.checkedAt ?? null
|
|
26220
|
+
checkedAt: lastDetection?.checkedAt ?? null,
|
|
26221
|
+
trust,
|
|
26222
|
+
trustDescription: describeTrust2(trust),
|
|
26223
|
+
requiresConfirmation: requiresConfirmation2(trust),
|
|
26224
|
+
sourceLayer: layer,
|
|
26225
|
+
sourceName
|
|
26009
26226
|
};
|
|
26010
26227
|
});
|
|
26011
26228
|
return { success: true, providers: items };
|
|
26012
26229
|
}
|
|
26013
26230
|
/**
|
|
26014
|
-
* Compute the *
|
|
26015
|
-
*
|
|
26016
|
-
*
|
|
26017
|
-
*
|
|
26018
|
-
*
|
|
26019
|
-
*
|
|
26231
|
+
* Compute the *upstream cache root*. install_provider_manifest writes
|
|
26232
|
+
* official-registry manifests here so the daemon's standard upstream
|
|
26233
|
+
* layer picks them up — no special handling needed at load time, and
|
|
26234
|
+
* the manifests inherit the official-trust badge instead of the
|
|
26235
|
+
* untrusted-external one.
|
|
26236
|
+
*
|
|
26237
|
+
* Path matches ProviderLoader.upstreamDir but we recompute it from
|
|
26238
|
+
* homedir() so this method stays usable in dev where userDir can
|
|
26239
|
+
* point at a sibling git checkout.
|
|
26020
26240
|
*/
|
|
26021
|
-
|
|
26022
|
-
const
|
|
26023
|
-
const
|
|
26024
|
-
return
|
|
26241
|
+
getUpstreamInstallRoot() {
|
|
26242
|
+
const os29 = require("os");
|
|
26243
|
+
const path40 = require("path");
|
|
26244
|
+
return path40.join(os29.homedir(), ".adhdev", "providers", ".upstream");
|
|
26025
26245
|
}
|
|
26026
26246
|
/**
|
|
26027
26247
|
* Download a single provider manifest from the registry and write it to
|
|
26028
|
-
* ~/.adhdev/
|
|
26248
|
+
* ~/.adhdev/providers/.upstream/{category}/{type}/provider.json.
|
|
26029
26249
|
*
|
|
26030
|
-
* Used by
|
|
26031
|
-
*
|
|
26032
|
-
* the
|
|
26250
|
+
* Used by standalone onboarding to seed the upstream cache with the
|
|
26251
|
+
* default provider set on first launch. Verifies SHA-256 checksum
|
|
26252
|
+
* against the registry meta before persisting. Refuses to write
|
|
26253
|
+
* outside the upstream root.
|
|
26033
26254
|
*
|
|
26034
26255
|
* Args: { type: string, category?: string, version?: string }
|
|
26035
26256
|
* If category/version are omitted, looks up the latest from the registry.
|
|
@@ -26044,8 +26265,8 @@ var DaemonCommandHandler = class {
|
|
|
26044
26265
|
return { success: false, error: "invalid type" };
|
|
26045
26266
|
}
|
|
26046
26267
|
const https = require("https");
|
|
26047
|
-
const
|
|
26048
|
-
const
|
|
26268
|
+
const fs28 = require("fs");
|
|
26269
|
+
const path40 = require("path");
|
|
26049
26270
|
const crypto6 = require("crypto");
|
|
26050
26271
|
const REGISTRY = "https://api.adhf.dev/api/v1/registry";
|
|
26051
26272
|
function fetchText(url, timeoutMs) {
|
|
@@ -26082,13 +26303,13 @@ var DaemonCommandHandler = class {
|
|
|
26082
26303
|
if (actualChecksum !== meta.checksum) {
|
|
26083
26304
|
return { success: false, error: `checksum mismatch: expected ${meta.checksum}, got ${actualChecksum}` };
|
|
26084
26305
|
}
|
|
26085
|
-
const installRoot = this.
|
|
26086
|
-
const installRootResolved =
|
|
26087
|
-
const targetDir =
|
|
26088
|
-
if (!targetDir.startsWith(installRootResolved +
|
|
26089
|
-
return { success: false, error: "install path escaped
|
|
26306
|
+
const installRoot = this.getUpstreamInstallRoot();
|
|
26307
|
+
const installRootResolved = path40.resolve(installRoot);
|
|
26308
|
+
const targetDir = path40.resolve(path40.join(installRoot, category, type));
|
|
26309
|
+
if (!targetDir.startsWith(installRootResolved + path40.sep)) {
|
|
26310
|
+
return { success: false, error: "install path escaped upstream root" };
|
|
26090
26311
|
}
|
|
26091
|
-
|
|
26312
|
+
fs28.mkdirSync(targetDir, { recursive: true });
|
|
26092
26313
|
let manifestProbe = {};
|
|
26093
26314
|
try {
|
|
26094
26315
|
manifestProbe = JSON.parse(manifestBody);
|
|
@@ -26112,8 +26333,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26112
26333
|
}
|
|
26113
26334
|
}
|
|
26114
26335
|
const targetFile = isV1 ? "provider.v1.json" : "provider.json";
|
|
26115
|
-
const targetPath =
|
|
26116
|
-
|
|
26336
|
+
const targetPath = path40.join(targetDir, targetFile);
|
|
26337
|
+
fs28.writeFileSync(targetPath, manifestBody, "utf-8");
|
|
26117
26338
|
const manifestJson = JSON.parse(manifestBody);
|
|
26118
26339
|
const scriptFetch = await this.fetchProviderSources(
|
|
26119
26340
|
manifestJson,
|
|
@@ -26161,6 +26382,10 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26161
26382
|
if (Array.isArray(manifest.compatibility)) {
|
|
26162
26383
|
for (const c of manifest.compatibility) {
|
|
26163
26384
|
if (typeof c?.scriptDir === "string") scriptDirs.add(c.scriptDir);
|
|
26385
|
+
if (typeof c?.spec === "string" && c.spec.includes("/")) {
|
|
26386
|
+
const dir = c.spec.substring(0, c.spec.lastIndexOf("/"));
|
|
26387
|
+
if (dir) scriptDirs.add(dir);
|
|
26388
|
+
}
|
|
26164
26389
|
}
|
|
26165
26390
|
}
|
|
26166
26391
|
if (manifest.overrides && typeof manifest.overrides === "object" && !Array.isArray(manifest.overrides)) {
|
|
@@ -26179,8 +26404,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26179
26404
|
const repo = source.repo;
|
|
26180
26405
|
const ref = source.ref;
|
|
26181
26406
|
const https = require("https");
|
|
26182
|
-
const
|
|
26183
|
-
const
|
|
26407
|
+
const fs28 = require("fs");
|
|
26408
|
+
const path40 = require("path");
|
|
26184
26409
|
function fetchJson(url, timeoutMs) {
|
|
26185
26410
|
return new Promise((resolve23, reject) => {
|
|
26186
26411
|
const req = https.get(url, {
|
|
@@ -26236,9 +26461,9 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26236
26461
|
}
|
|
26237
26462
|
let fetchedCount = 0;
|
|
26238
26463
|
const sharedDirRel = `${category}/_shared`;
|
|
26239
|
-
const sharedTargetDir =
|
|
26240
|
-
const installRootResolved =
|
|
26241
|
-
if (sharedTargetDir.startsWith(installRootResolved +
|
|
26464
|
+
const sharedTargetDir = path40.resolve(path40.join(targetDir, "../_shared"));
|
|
26465
|
+
const installRootResolved = path40.resolve(path40.join(targetDir, "../.."));
|
|
26466
|
+
if (sharedTargetDir.startsWith(installRootResolved + path40.sep)) {
|
|
26242
26467
|
const sharedStack = [sharedDirRel];
|
|
26243
26468
|
while (sharedStack.length) {
|
|
26244
26469
|
const relDir = sharedStack.pop();
|
|
@@ -26261,10 +26486,10 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26261
26486
|
try {
|
|
26262
26487
|
const body = await fetchBinary(entry.download_url, 3e4);
|
|
26263
26488
|
const relInside = entry.path.startsWith(sharedDirRel + "/") ? entry.path.slice(sharedDirRel.length + 1) : entry.path;
|
|
26264
|
-
const outPath =
|
|
26265
|
-
if (!outPath.startsWith(
|
|
26266
|
-
|
|
26267
|
-
|
|
26489
|
+
const outPath = path40.resolve(path40.join(sharedTargetDir, relInside));
|
|
26490
|
+
if (!outPath.startsWith(path40.resolve(sharedTargetDir) + path40.sep)) continue;
|
|
26491
|
+
fs28.mkdirSync(path40.dirname(outPath), { recursive: true });
|
|
26492
|
+
fs28.writeFileSync(outPath, body);
|
|
26268
26493
|
fetchedCount++;
|
|
26269
26494
|
} catch (e) {
|
|
26270
26495
|
errors.push(`fetch shared ${entry.path}: ${e?.message ?? e}`);
|
|
@@ -26297,13 +26522,13 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26297
26522
|
try {
|
|
26298
26523
|
const body = await fetchBinary(entry.download_url, 3e4);
|
|
26299
26524
|
const relInsideProvider = entry.path.startsWith(subdir + "/") ? entry.path.slice(subdir.length + 1) : entry.path;
|
|
26300
|
-
const outPath =
|
|
26301
|
-
if (!outPath.startsWith(
|
|
26525
|
+
const outPath = path40.resolve(path40.join(targetDir, relInsideProvider));
|
|
26526
|
+
if (!outPath.startsWith(path40.resolve(targetDir) + path40.sep)) {
|
|
26302
26527
|
errors.push(`refusing to write outside targetDir: ${entry.path}`);
|
|
26303
26528
|
continue;
|
|
26304
26529
|
}
|
|
26305
|
-
|
|
26306
|
-
|
|
26530
|
+
fs28.mkdirSync(path40.dirname(outPath), { recursive: true });
|
|
26531
|
+
fs28.writeFileSync(outPath, body);
|
|
26307
26532
|
fetchedCount++;
|
|
26308
26533
|
} catch (e) {
|
|
26309
26534
|
errors.push(`fetch ${entry.path}: ${e?.message ?? e}`);
|
|
@@ -26314,9 +26539,12 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26314
26539
|
return { fetchedCount, source: `${repo}@${ref}`, errors };
|
|
26315
26540
|
}
|
|
26316
26541
|
/**
|
|
26317
|
-
* Remove a provider manifest from the
|
|
26318
|
-
* (~/.adhdev/
|
|
26319
|
-
* outside that root.
|
|
26542
|
+
* Remove a provider manifest from the upstream cache root
|
|
26543
|
+
* (~/.adhdev/providers/.upstream/{category}/{type}/). Refuses to touch
|
|
26544
|
+
* anything outside that root. Used by onboarding to opt out of a
|
|
26545
|
+
* provider the user doesn't want; the dashboard no longer exposes a
|
|
26546
|
+
* per-provider uninstall button (external sources are removed as a
|
|
26547
|
+
* whole via remove_provider_source).
|
|
26320
26548
|
*/
|
|
26321
26549
|
async handleUninstallProviderManifest(args) {
|
|
26322
26550
|
const type = typeof args?.type === "string" ? args.type : "";
|
|
@@ -26328,19 +26556,19 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26328
26556
|
if (!["cli", "ide", "extension", "acp"].includes(category)) {
|
|
26329
26557
|
return { success: false, error: `unknown category: ${category}` };
|
|
26330
26558
|
}
|
|
26331
|
-
const
|
|
26332
|
-
const
|
|
26559
|
+
const fs28 = require("fs");
|
|
26560
|
+
const path40 = require("path");
|
|
26333
26561
|
try {
|
|
26334
|
-
const installRoot = this.
|
|
26335
|
-
const installRootResolved =
|
|
26336
|
-
const targetDir =
|
|
26337
|
-
if (!targetDir.startsWith(installRootResolved +
|
|
26338
|
-
return { success: false, error: "refusing to delete outside
|
|
26562
|
+
const installRoot = this.getUpstreamInstallRoot();
|
|
26563
|
+
const installRootResolved = path40.resolve(installRoot);
|
|
26564
|
+
const targetDir = path40.resolve(path40.join(installRoot, category, type));
|
|
26565
|
+
if (!targetDir.startsWith(installRootResolved + path40.sep)) {
|
|
26566
|
+
return { success: false, error: "refusing to delete outside upstream root" };
|
|
26339
26567
|
}
|
|
26340
|
-
if (!
|
|
26568
|
+
if (!fs28.existsSync(targetDir)) {
|
|
26341
26569
|
return { success: false, error: "not installed" };
|
|
26342
26570
|
}
|
|
26343
|
-
|
|
26571
|
+
fs28.rmSync(targetDir, { recursive: true, force: true });
|
|
26344
26572
|
if (this._ctx.providerLoader) {
|
|
26345
26573
|
this._ctx.providerLoader.reload();
|
|
26346
26574
|
this._ctx.providerLoader.registerToDetector();
|
|
@@ -26351,33 +26579,33 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26351
26579
|
}
|
|
26352
26580
|
}
|
|
26353
26581
|
/**
|
|
26354
|
-
* Return everything currently installed in
|
|
26582
|
+
* Return everything currently installed in the upstream cache with its
|
|
26355
26583
|
* version. This is the "what does this daemon have" answer used both by
|
|
26356
26584
|
* the UI and by the update checker.
|
|
26357
26585
|
*/
|
|
26358
26586
|
handleListInstalledProviders(_args) {
|
|
26359
|
-
const
|
|
26360
|
-
const
|
|
26361
|
-
const installRoot = this.
|
|
26362
|
-
if (!
|
|
26587
|
+
const fs28 = require("fs");
|
|
26588
|
+
const path40 = require("path");
|
|
26589
|
+
const installRoot = this.getUpstreamInstallRoot();
|
|
26590
|
+
if (!fs28.existsSync(installRoot)) return { success: true, providers: [] };
|
|
26363
26591
|
const CATEGORIES = ["cli", "ide", "extension", "acp"];
|
|
26364
26592
|
const items = [];
|
|
26365
26593
|
for (const category of CATEGORIES) {
|
|
26366
|
-
const categoryDir =
|
|
26367
|
-
if (!
|
|
26594
|
+
const categoryDir = path40.join(installRoot, category);
|
|
26595
|
+
if (!fs28.existsSync(categoryDir)) continue;
|
|
26368
26596
|
let entries;
|
|
26369
26597
|
try {
|
|
26370
|
-
entries =
|
|
26598
|
+
entries = fs28.readdirSync(categoryDir);
|
|
26371
26599
|
} catch {
|
|
26372
26600
|
continue;
|
|
26373
26601
|
}
|
|
26374
26602
|
for (const type of entries) {
|
|
26375
|
-
const v1Path =
|
|
26376
|
-
const v0Path =
|
|
26377
|
-
const manifestPath =
|
|
26603
|
+
const v1Path = path40.join(categoryDir, type, "provider.v1.json");
|
|
26604
|
+
const v0Path = path40.join(categoryDir, type, "provider.json");
|
|
26605
|
+
const manifestPath = fs28.existsSync(v1Path) ? v1Path : fs28.existsSync(v0Path) ? v0Path : null;
|
|
26378
26606
|
if (!manifestPath) continue;
|
|
26379
26607
|
try {
|
|
26380
|
-
const m = JSON.parse(
|
|
26608
|
+
const m = JSON.parse(fs28.readFileSync(manifestPath, "utf-8"));
|
|
26381
26609
|
items.push({
|
|
26382
26610
|
type,
|
|
26383
26611
|
category,
|
|
@@ -26454,6 +26682,196 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26454
26682
|
);
|
|
26455
26683
|
return { success: true, providers: checks };
|
|
26456
26684
|
}
|
|
26685
|
+
// ─── External provider sources (3rd-party git URLs) ──────────────
|
|
26686
|
+
/**
|
|
26687
|
+
* Register a new external provider source. The daemon clones the repo
|
|
26688
|
+
* to ~/.adhdev/external/<name>/, walks it once to detect provided
|
|
26689
|
+
* types, and surfaces any conflicts with already-installed types so
|
|
26690
|
+
* the dashboard can ask the user how to resolve them.
|
|
26691
|
+
*
|
|
26692
|
+
* Args: { url: string, ref?: string, name?: string }
|
|
26693
|
+
* - url: https://, git@, or any git-cloneable URL
|
|
26694
|
+
* - ref: branch/tag/commit (default "main")
|
|
26695
|
+
* - name: short identifier (default derived from URL)
|
|
26696
|
+
*
|
|
26697
|
+
* Returns: { source, providers, conflicts }
|
|
26698
|
+
* - conflicts: list of types this new source provides that another
|
|
26699
|
+
* source already exposes. UI uses this to prompt for active-source
|
|
26700
|
+
* selection before the load takes effect.
|
|
26701
|
+
*/
|
|
26702
|
+
async handleAddProviderSource(args) {
|
|
26703
|
+
const url = typeof args?.url === "string" ? args.url.trim() : "";
|
|
26704
|
+
if (!url) return { success: false, error: "url is required" };
|
|
26705
|
+
const ref = typeof args?.ref === "string" && args.ref.trim() ? args.ref.trim() : "main";
|
|
26706
|
+
if (url.startsWith("-")) return { success: false, error: 'url must not start with "-"' };
|
|
26707
|
+
if (ref.startsWith("-")) return { success: false, error: 'ref must not start with "-"' };
|
|
26708
|
+
if (!/^(https?:\/\/|git@[a-z0-9._-]+:)[a-z0-9._@:/~\-]+$/i.test(url)) {
|
|
26709
|
+
return { success: false, error: "url must be https://\u2026 or git@host:\u2026 and contain only URL-safe characters" };
|
|
26710
|
+
}
|
|
26711
|
+
if (!/^[A-Za-z0-9._/-]+$/.test(ref)) {
|
|
26712
|
+
return { success: false, error: "ref must contain only [A-Za-z0-9._/-]" };
|
|
26713
|
+
}
|
|
26714
|
+
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
26715
|
+
const requestedName = typeof args?.name === "string" && args.name.trim() ? args.name.trim() : ext.deriveSourceName(url);
|
|
26716
|
+
if (!/^@[a-z0-9_-]+$/i.test(requestedName)) {
|
|
26717
|
+
return { success: false, error: "name must match @[a-z0-9_-]+" };
|
|
26718
|
+
}
|
|
26719
|
+
const fs28 = require("fs");
|
|
26720
|
+
const path40 = require("path");
|
|
26721
|
+
const { spawnSync: spawnSync2 } = require("child_process");
|
|
26722
|
+
const file = ext.loadExternalSources();
|
|
26723
|
+
if (file.sources.some((s) => s.name === requestedName)) {
|
|
26724
|
+
return { success: false, error: `source name "${requestedName}" is already registered` };
|
|
26725
|
+
}
|
|
26726
|
+
if (file.sources.some((s) => s.url === url && s.ref === ref)) {
|
|
26727
|
+
return { success: false, error: `source url+ref already registered (use a different name to track another ref)` };
|
|
26728
|
+
}
|
|
26729
|
+
const sourceDir = path40.join(ext.externalRoot(), requestedName);
|
|
26730
|
+
if (!fs28.existsSync(ext.externalRoot())) fs28.mkdirSync(ext.externalRoot(), { recursive: true });
|
|
26731
|
+
if (fs28.existsSync(sourceDir)) {
|
|
26732
|
+
return { success: false, error: `directory already exists: ${sourceDir} (rename or remove first)` };
|
|
26733
|
+
}
|
|
26734
|
+
const clone = spawnSync2("git", ["clone", "--depth=1", "--branch", ref, "--", url, sourceDir], {
|
|
26735
|
+
encoding: "utf-8",
|
|
26736
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
26737
|
+
timeout: 6e4
|
|
26738
|
+
});
|
|
26739
|
+
if (clone.status !== 0) {
|
|
26740
|
+
try {
|
|
26741
|
+
fs28.rmSync(sourceDir, { recursive: true, force: true });
|
|
26742
|
+
} catch {
|
|
26743
|
+
}
|
|
26744
|
+
return { success: false, error: `git clone failed: ${(clone.stderr || clone.stdout || "").trim() || "unknown error"}` };
|
|
26745
|
+
}
|
|
26746
|
+
const source = {
|
|
26747
|
+
name: requestedName,
|
|
26748
|
+
url,
|
|
26749
|
+
ref,
|
|
26750
|
+
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
26751
|
+
};
|
|
26752
|
+
ext.saveExternalSources({ schema: 1, sources: [...file.sources, source] });
|
|
26753
|
+
const inventory = ext.inventoryExternalSources();
|
|
26754
|
+
const conflicts = [];
|
|
26755
|
+
const newEntry = inventory.find((e) => e.sourceName === requestedName);
|
|
26756
|
+
if (newEntry) {
|
|
26757
|
+
for (const [category, types] of Object.entries(newEntry.providers)) {
|
|
26758
|
+
for (const type of types) {
|
|
26759
|
+
const sources = ext.sourcesProviding(category, type);
|
|
26760
|
+
if (sources.length > 1) conflicts.push({ category, type, sources });
|
|
26761
|
+
}
|
|
26762
|
+
}
|
|
26763
|
+
}
|
|
26764
|
+
if (this._ctx.providerLoader) {
|
|
26765
|
+
this._ctx.providerLoader.reload();
|
|
26766
|
+
this._ctx.providerLoader.registerToDetector();
|
|
26767
|
+
}
|
|
26768
|
+
return {
|
|
26769
|
+
success: true,
|
|
26770
|
+
source,
|
|
26771
|
+
providers: newEntry?.providers ?? {},
|
|
26772
|
+
conflicts
|
|
26773
|
+
};
|
|
26774
|
+
}
|
|
26775
|
+
/**
|
|
26776
|
+
* Remove a registered external source. Deletes the clone directory and
|
|
26777
|
+
* any active-source entry pointing to it.
|
|
26778
|
+
*
|
|
26779
|
+
* Args: { name: string }
|
|
26780
|
+
*/
|
|
26781
|
+
async handleRemoveProviderSource(args) {
|
|
26782
|
+
const name = typeof args?.name === "string" ? args.name.trim() : "";
|
|
26783
|
+
if (!name) return { success: false, error: "name is required" };
|
|
26784
|
+
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
26785
|
+
const fs28 = require("fs");
|
|
26786
|
+
const path40 = require("path");
|
|
26787
|
+
const file = ext.loadExternalSources();
|
|
26788
|
+
const match = file.sources.find((s) => s.name === name);
|
|
26789
|
+
if (!match) return { success: false, error: `source "${name}" not registered` };
|
|
26790
|
+
const sourceDir = path40.join(ext.externalRoot(), name);
|
|
26791
|
+
if (fs28.existsSync(sourceDir)) {
|
|
26792
|
+
try {
|
|
26793
|
+
fs28.rmSync(sourceDir, { recursive: true, force: true });
|
|
26794
|
+
} catch (e) {
|
|
26795
|
+
return { success: false, error: `failed to delete ${sourceDir}: ${e?.message || e}` };
|
|
26796
|
+
}
|
|
26797
|
+
}
|
|
26798
|
+
ext.saveExternalSources({
|
|
26799
|
+
schema: 1,
|
|
26800
|
+
sources: file.sources.filter((s) => s.name !== name)
|
|
26801
|
+
});
|
|
26802
|
+
const active = ext.loadProvidersActive();
|
|
26803
|
+
const filteredActive = {};
|
|
26804
|
+
for (const [type, src] of Object.entries(active.active)) {
|
|
26805
|
+
if (src !== name) filteredActive[type] = src;
|
|
26806
|
+
}
|
|
26807
|
+
ext.saveProvidersActive({ schema: 1, active: filteredActive });
|
|
26808
|
+
if (this._ctx.providerLoader) {
|
|
26809
|
+
this._ctx.providerLoader.reload();
|
|
26810
|
+
this._ctx.providerLoader.registerToDetector();
|
|
26811
|
+
}
|
|
26812
|
+
return { success: true, removed: { name } };
|
|
26813
|
+
}
|
|
26814
|
+
/**
|
|
26815
|
+
* List registered external sources + each source's currently installed
|
|
26816
|
+
* providers + the active selection for any conflicting types. Used by
|
|
26817
|
+
* the dashboard's "Sources" tab.
|
|
26818
|
+
*/
|
|
26819
|
+
handleListProviderSources(_args) {
|
|
26820
|
+
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
26821
|
+
const file = ext.loadExternalSources();
|
|
26822
|
+
const inventory = ext.inventoryExternalSources();
|
|
26823
|
+
const active = ext.loadProvidersActive();
|
|
26824
|
+
const sources = file.sources.map((s) => {
|
|
26825
|
+
const inv = inventory.find((e) => e.sourceName === s.name);
|
|
26826
|
+
return {
|
|
26827
|
+
...s,
|
|
26828
|
+
providers: inv?.providers ?? {}
|
|
26829
|
+
};
|
|
26830
|
+
});
|
|
26831
|
+
const conflictMap = /* @__PURE__ */ new Map();
|
|
26832
|
+
for (const inv of inventory) {
|
|
26833
|
+
for (const [category, types] of Object.entries(inv.providers)) {
|
|
26834
|
+
for (const type of types) {
|
|
26835
|
+
const candidates = ext.sourcesProviding(category, type);
|
|
26836
|
+
if (candidates.length > 1 && !conflictMap.has(type)) {
|
|
26837
|
+
conflictMap.set(type, { category, sources: candidates });
|
|
26838
|
+
}
|
|
26839
|
+
}
|
|
26840
|
+
}
|
|
26841
|
+
}
|
|
26842
|
+
const conflicts = [...conflictMap.entries()].map(([type, info]) => ({
|
|
26843
|
+
type,
|
|
26844
|
+
category: info.category,
|
|
26845
|
+
candidates: info.sources,
|
|
26846
|
+
active: active.active[type] ?? null
|
|
26847
|
+
}));
|
|
26848
|
+
return { success: true, sources, conflicts };
|
|
26849
|
+
}
|
|
26850
|
+
/**
|
|
26851
|
+
* Pick which source's copy of a conflicting provider type is active.
|
|
26852
|
+
* Other sources' copies stay on disk but the loader ignores them.
|
|
26853
|
+
*
|
|
26854
|
+
* Args: { type: string, sourceName: string }
|
|
26855
|
+
*/
|
|
26856
|
+
handleSetActiveProviderSource(args) {
|
|
26857
|
+
const type = typeof args?.type === "string" ? args.type.trim() : "";
|
|
26858
|
+
const sourceName = typeof args?.sourceName === "string" ? args.sourceName.trim() : "";
|
|
26859
|
+
if (!type || !sourceName) return { success: false, error: "type and sourceName are required" };
|
|
26860
|
+
const ext = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
26861
|
+
const inventory = ext.inventoryExternalSources();
|
|
26862
|
+
const entry = inventory.find((e) => e.sourceName === sourceName);
|
|
26863
|
+
if (!entry) return { success: false, error: `source "${sourceName}" not found` };
|
|
26864
|
+
const provided = Object.values(entry.providers).some((types) => types.includes(type));
|
|
26865
|
+
if (!provided) return { success: false, error: `source "${sourceName}" does not provide type "${type}"` };
|
|
26866
|
+
const active = ext.loadProvidersActive();
|
|
26867
|
+
active.active[type] = sourceName;
|
|
26868
|
+
ext.saveProvidersActive(active);
|
|
26869
|
+
if (this._ctx.providerLoader) {
|
|
26870
|
+
this._ctx.providerLoader.reload();
|
|
26871
|
+
this._ctx.providerLoader.registerToDetector();
|
|
26872
|
+
}
|
|
26873
|
+
return { success: true, type, sourceName };
|
|
26874
|
+
}
|
|
26457
26875
|
// ─── DevServer HTTP proxy helpers ─────────────────
|
|
26458
26876
|
// These bridge WS commands to the DevServer REST API (localhost:19280)
|
|
26459
26877
|
async proxyDevServerPost(args, endpoint) {
|
|
@@ -26546,8 +26964,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
26546
26964
|
};
|
|
26547
26965
|
|
|
26548
26966
|
// src/commands/cli-manager.ts
|
|
26549
|
-
var
|
|
26550
|
-
var
|
|
26967
|
+
var os17 = __toESM(require("os"));
|
|
26968
|
+
var path23 = __toESM(require("path"));
|
|
26551
26969
|
var crypto5 = __toESM(require("crypto"));
|
|
26552
26970
|
var import_fs12 = require("fs");
|
|
26553
26971
|
var import_child_process5 = require("child_process");
|
|
@@ -26557,21 +26975,21 @@ init_cli_detector();
|
|
|
26557
26975
|
init_config();
|
|
26558
26976
|
|
|
26559
26977
|
// src/providers/cli-provider-instance.ts
|
|
26560
|
-
var
|
|
26561
|
-
var
|
|
26978
|
+
var os16 = __toESM(require("os"));
|
|
26979
|
+
var path21 = __toESM(require("path"));
|
|
26562
26980
|
var crypto4 = __toESM(require("crypto"));
|
|
26563
|
-
var
|
|
26981
|
+
var fs12 = __toESM(require("fs"));
|
|
26564
26982
|
var import_node_module = require("module");
|
|
26565
26983
|
|
|
26566
26984
|
// src/providers/spec/route.ts
|
|
26567
|
-
var
|
|
26568
|
-
var
|
|
26985
|
+
var fs11 = __toESM(require("fs"));
|
|
26986
|
+
var path20 = __toESM(require("path"));
|
|
26569
26987
|
init_provider_cli_adapter();
|
|
26570
26988
|
|
|
26571
26989
|
// src/providers/spec/driver.ts
|
|
26572
|
-
var
|
|
26573
|
-
var
|
|
26574
|
-
var
|
|
26990
|
+
var fs10 = __toESM(require("fs"));
|
|
26991
|
+
var os15 = __toESM(require("os"));
|
|
26992
|
+
var path19 = __toESM(require("path"));
|
|
26575
26993
|
|
|
26576
26994
|
// src/providers/spec/adapter.ts
|
|
26577
26995
|
var xtermHeadlessNs = __toESM(require("@xterm/headless"));
|
|
@@ -26948,7 +27366,7 @@ var SpecDriver = class {
|
|
|
26948
27366
|
}
|
|
26949
27367
|
armSpecWatcher() {
|
|
26950
27368
|
try {
|
|
26951
|
-
this.specWatcher =
|
|
27369
|
+
this.specWatcher = fs10.watch(this.opts.specPath, { persistent: false }, () => {
|
|
26952
27370
|
const res = loadSpec(this.opts.specPath);
|
|
26953
27371
|
if (!res.ok) {
|
|
26954
27372
|
this.emit({ kind: "spec_error", errors: res.errors });
|
|
@@ -27041,7 +27459,7 @@ var SpecDriver = class {
|
|
|
27041
27459
|
}
|
|
27042
27460
|
fireDelegate(d) {
|
|
27043
27461
|
const ev = this.currentEval;
|
|
27044
|
-
const task = d.task_template.replace(/\{node\}/g,
|
|
27462
|
+
const task = d.task_template.replace(/\{node\}/g, os15.hostname()).replace(/\{state\.label\}/g, ev?.state.label ?? "").replace(/\{state\.title\}/g, ev?.state.title ?? "").replace(/\{duration_ms\}/g, String(d.after_duration_ms ?? 0));
|
|
27045
27463
|
this.emit({ kind: "delegate", id: d.id, task });
|
|
27046
27464
|
}
|
|
27047
27465
|
// ────────────────────────────────────────────────────────────────────
|
|
@@ -27110,9 +27528,9 @@ var SpecDriver = class {
|
|
|
27110
27528
|
const ctl = (this.spec.control_bar ?? []).find((c) => c.action.type === "attach_image");
|
|
27111
27529
|
if (!ctl || ctl.action.type !== "attach_image") return;
|
|
27112
27530
|
const ext = guessExt(mime);
|
|
27113
|
-
const tmp =
|
|
27531
|
+
const tmp = path19.join(os15.tmpdir(), `adhdev-attach-${Date.now()}${ext}`);
|
|
27114
27532
|
try {
|
|
27115
|
-
|
|
27533
|
+
fs10.writeFileSync(tmp, Buffer.from(blob, "base64"));
|
|
27116
27534
|
} catch {
|
|
27117
27535
|
return;
|
|
27118
27536
|
}
|
|
@@ -27440,14 +27858,14 @@ init_logger();
|
|
|
27440
27858
|
function createCliAdapter(provider, workingDir, cliArgs, extraEnv, transportFactory) {
|
|
27441
27859
|
const resolvedSpecPath = provider._resolvedSpecPath;
|
|
27442
27860
|
const dir = provider._resolvedProviderDir;
|
|
27443
|
-
let specPath = resolvedSpecPath &&
|
|
27861
|
+
let specPath = resolvedSpecPath && fs11.existsSync(resolvedSpecPath) ? resolvedSpecPath : void 0;
|
|
27444
27862
|
if (!specPath && dir) {
|
|
27445
|
-
const legacy =
|
|
27446
|
-
if (
|
|
27863
|
+
const legacy = path20.join(dir, "spec.json");
|
|
27864
|
+
if (fs11.existsSync(legacy)) specPath = legacy;
|
|
27447
27865
|
}
|
|
27448
27866
|
if (specPath) {
|
|
27449
27867
|
try {
|
|
27450
|
-
LOG.info("spec-route", `[${provider.type}] routing through SpecCliAdapter (${
|
|
27868
|
+
LOG.info("spec-route", `[${provider.type}] routing through SpecCliAdapter (${path20.relative(dir || "", specPath) || specPath})`);
|
|
27451
27869
|
return new SpecCliAdapter(specPath, workingDir, cliArgs, extraEnv, transportFactory);
|
|
27452
27870
|
} catch (err) {
|
|
27453
27871
|
LOG.warn("spec-route", `[${provider.type}] spec invalid, falling back to ProviderCliAdapter: ${err.message}`);
|
|
@@ -27508,7 +27926,7 @@ function filePathFromUri(uri) {
|
|
|
27508
27926
|
return uri.slice("file://".length);
|
|
27509
27927
|
}
|
|
27510
27928
|
}
|
|
27511
|
-
if (
|
|
27929
|
+
if (path21.isAbsolute(uri)) return uri;
|
|
27512
27930
|
return null;
|
|
27513
27931
|
}
|
|
27514
27932
|
function extensionForImageMime(mimeType) {
|
|
@@ -27523,9 +27941,9 @@ function materializeImageDataPart(part, index, dir) {
|
|
|
27523
27941
|
if (!part.data) return null;
|
|
27524
27942
|
const rawData = part.data.includes(",") ? part.data.split(",").pop() || "" : part.data;
|
|
27525
27943
|
if (!rawData) return null;
|
|
27526
|
-
|
|
27527
|
-
const filePath =
|
|
27528
|
-
|
|
27944
|
+
fs12.mkdirSync(dir, { recursive: true });
|
|
27945
|
+
const filePath = path21.join(dir, safeInputImageBasename(index, part.mimeType));
|
|
27946
|
+
fs12.writeFileSync(filePath, Buffer.from(rawData, "base64"));
|
|
27529
27947
|
cleanupStaleMaterializedImages(dir);
|
|
27530
27948
|
return filePath;
|
|
27531
27949
|
}
|
|
@@ -27537,14 +27955,14 @@ function cleanupStaleMaterializedImages(dir) {
|
|
|
27537
27955
|
if (now - lastMaterializedImageCleanupAt < MATERIALIZED_IMAGE_CLEANUP_INTERVAL_MS) return;
|
|
27538
27956
|
lastMaterializedImageCleanupAt = now;
|
|
27539
27957
|
try {
|
|
27540
|
-
const entries =
|
|
27958
|
+
const entries = fs12.readdirSync(dir);
|
|
27541
27959
|
for (const entry of entries) {
|
|
27542
27960
|
if (!entry.startsWith("adhdev-input-image-")) continue;
|
|
27543
|
-
const fullPath =
|
|
27961
|
+
const fullPath = path21.join(dir, entry);
|
|
27544
27962
|
try {
|
|
27545
|
-
const stat2 =
|
|
27963
|
+
const stat2 = fs12.statSync(fullPath);
|
|
27546
27964
|
if (now - stat2.mtimeMs > MATERIALIZED_IMAGE_MAX_AGE_MS) {
|
|
27547
|
-
|
|
27965
|
+
fs12.unlinkSync(fullPath);
|
|
27548
27966
|
}
|
|
27549
27967
|
} catch {
|
|
27550
27968
|
}
|
|
@@ -27563,7 +27981,7 @@ function buildCliStructuredInputPrompt(input, options = {}) {
|
|
|
27563
27981
|
const promptParts = [];
|
|
27564
27982
|
const imageRefs = [];
|
|
27565
27983
|
const resourceRefs = [];
|
|
27566
|
-
const materializeDir = options.materializeDir ||
|
|
27984
|
+
const materializeDir = options.materializeDir || path21.join(os16.tmpdir(), "adhdev-input-media");
|
|
27567
27985
|
input.parts.forEach((part, index) => {
|
|
27568
27986
|
if (part.type === "text" && part.text.trim()) {
|
|
27569
27987
|
promptParts.push(part.text.trim());
|
|
@@ -27630,7 +28048,7 @@ function buildIncrementalHistoryAppendMessages(previousMessages, currentMessages
|
|
|
27630
28048
|
var CachedDatabaseSync = null;
|
|
27631
28049
|
function getDatabaseSync() {
|
|
27632
28050
|
if (CachedDatabaseSync) return CachedDatabaseSync;
|
|
27633
|
-
const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(
|
|
28051
|
+
const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(path21.join(process.cwd(), "__adhdev_sqlite_loader__.js"));
|
|
27634
28052
|
const sqliteModule = requireFn(`node:${"sqlite"}`);
|
|
27635
28053
|
CachedDatabaseSync = sqliteModule.DatabaseSync;
|
|
27636
28054
|
if (!CachedDatabaseSync) {
|
|
@@ -27784,10 +28202,10 @@ var CliProviderInstance = class {
|
|
|
27784
28202
|
* Replaces the previously duplicated probeOpenCode/Codex/Goose functions.
|
|
27785
28203
|
*/
|
|
27786
28204
|
probeSessionIdFromConfig(probe) {
|
|
27787
|
-
const resolvedDbPath = probe.dbPath.replace(/^~/,
|
|
28205
|
+
const resolvedDbPath = probe.dbPath.replace(/^~/, os16.homedir());
|
|
27788
28206
|
const now = Date.now();
|
|
27789
28207
|
if (this.cachedSqliteDbMissingUntil > now) return null;
|
|
27790
|
-
if (!
|
|
28208
|
+
if (!fs12.existsSync(resolvedDbPath)) {
|
|
27791
28209
|
this.cachedSqliteDbMissingUntil = now + 1e4;
|
|
27792
28210
|
return null;
|
|
27793
28211
|
}
|
|
@@ -28889,7 +29307,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
28889
29307
|
};
|
|
28890
29308
|
addDir(this.workingDir);
|
|
28891
29309
|
try {
|
|
28892
|
-
addDir(
|
|
29310
|
+
addDir(fs12.realpathSync.native(this.workingDir));
|
|
28893
29311
|
} catch {
|
|
28894
29312
|
}
|
|
28895
29313
|
return Array.from(dirs);
|
|
@@ -28926,7 +29344,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
28926
29344
|
};
|
|
28927
29345
|
|
|
28928
29346
|
// src/providers/acp-provider-instance.ts
|
|
28929
|
-
var
|
|
29347
|
+
var path22 = __toESM(require("path"));
|
|
28930
29348
|
var import_stream = require("stream");
|
|
28931
29349
|
var import_child_process4 = require("child_process");
|
|
28932
29350
|
var import_sdk = require("@agentclientprotocol/sdk");
|
|
@@ -29701,7 +30119,7 @@ var AcpProviderInstance = class {
|
|
|
29701
30119
|
return b.uri ? {
|
|
29702
30120
|
type: "resource_link",
|
|
29703
30121
|
uri: b.uri,
|
|
29704
|
-
name:
|
|
30122
|
+
name: path22.basename(b.uri),
|
|
29705
30123
|
mimeType: b.mimeType,
|
|
29706
30124
|
...b.transcript ? { description: b.transcript } : {}
|
|
29707
30125
|
} : { type: "text", text: b.transcript || `[Video attachment: ${b.mimeType}]` };
|
|
@@ -30159,11 +30577,11 @@ function shouldRestoreHostedRuntime(record, managerTag) {
|
|
|
30159
30577
|
// src/commands/cli-manager.ts
|
|
30160
30578
|
function isExplicitCommand(command) {
|
|
30161
30579
|
const trimmed = command.trim();
|
|
30162
|
-
return
|
|
30580
|
+
return path23.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
|
|
30163
30581
|
}
|
|
30164
30582
|
function expandExecutable(command) {
|
|
30165
30583
|
const trimmed = command.trim();
|
|
30166
|
-
return trimmed.startsWith("~") ?
|
|
30584
|
+
return trimmed.startsWith("~") ? path23.join(os17.homedir(), trimmed.slice(1)) : trimmed;
|
|
30167
30585
|
}
|
|
30168
30586
|
function commandExists(command) {
|
|
30169
30587
|
const trimmed = command.trim();
|
|
@@ -30290,10 +30708,10 @@ function hasCliArg(args, flag) {
|
|
|
30290
30708
|
return args.some((arg) => arg === flag || arg.startsWith(`${flag}=`));
|
|
30291
30709
|
}
|
|
30292
30710
|
function ensureEmptyDelegatedMcpConfig(workspace) {
|
|
30293
|
-
const baseDir =
|
|
30711
|
+
const baseDir = path23.join(os17.tmpdir(), "adhdev-delegated-agent-empty-mcp");
|
|
30294
30712
|
(0, import_fs12.mkdirSync)(baseDir, { recursive: true });
|
|
30295
|
-
const workspaceHash = crypto5.createHash("sha256").update(
|
|
30296
|
-
const filePath =
|
|
30713
|
+
const workspaceHash = crypto5.createHash("sha256").update(path23.resolve(workspace || os17.tmpdir())).digest("hex").slice(0, 16);
|
|
30714
|
+
const filePath = path23.join(baseDir, `${workspaceHash}.json`);
|
|
30297
30715
|
(0, import_fs12.writeFileSync)(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
|
|
30298
30716
|
return filePath;
|
|
30299
30717
|
}
|
|
@@ -30587,7 +31005,7 @@ var DaemonCliManager = class {
|
|
|
30587
31005
|
async startSession(cliType, workingDir, cliArgs, initialModel, options) {
|
|
30588
31006
|
const trimmed = (workingDir || "").trim();
|
|
30589
31007
|
if (!trimmed) throw new Error("working directory required");
|
|
30590
|
-
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/,
|
|
31008
|
+
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os17.homedir()) : path23.resolve(trimmed);
|
|
30591
31009
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
30592
31010
|
const rawProvider = this.providerLoader.getByAlias(cliType);
|
|
30593
31011
|
const provider = rawProvider ? this.providerLoader.resolve(normalizedType) || rawProvider : void 0;
|
|
@@ -30972,6 +31390,20 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
30972
31390
|
cliArgs: args?.cliArgs,
|
|
30973
31391
|
env: args?.env
|
|
30974
31392
|
}) : null;
|
|
31393
|
+
const provLookup = this.providerLoader.getMeta(this.providerLoader.resolveAlias(cliType));
|
|
31394
|
+
const provTrust = provLookup?._sourceTrust;
|
|
31395
|
+
if (provTrust === "external-untrusted" && args?.confirmExternalUntrusted !== true) {
|
|
31396
|
+
return {
|
|
31397
|
+
success: false,
|
|
31398
|
+
error: "untrusted_external_provider",
|
|
31399
|
+
provider: {
|
|
31400
|
+
type: provLookup?.type ?? cliType,
|
|
31401
|
+
sourceName: provLookup?._sourceName ?? null,
|
|
31402
|
+
trust: provTrust
|
|
31403
|
+
},
|
|
31404
|
+
hint: "Resend launch_cli with confirmExternalUntrusted=true after the user explicitly approves running JavaScript from this 3rd-party source."
|
|
31405
|
+
};
|
|
31406
|
+
}
|
|
30975
31407
|
const started = await this.startSession(
|
|
30976
31408
|
cliType,
|
|
30977
31409
|
dir,
|
|
@@ -31158,13 +31590,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
31158
31590
|
// src/launch.ts
|
|
31159
31591
|
var import_child_process6 = require("child_process");
|
|
31160
31592
|
var net = __toESM(require("net"));
|
|
31161
|
-
var
|
|
31162
|
-
var
|
|
31593
|
+
var os23 = __toESM(require("os"));
|
|
31594
|
+
var path32 = __toESM(require("path"));
|
|
31163
31595
|
|
|
31164
31596
|
// src/providers/provider-loader.ts
|
|
31165
|
-
var
|
|
31166
|
-
var
|
|
31167
|
-
var
|
|
31597
|
+
var fs19 = __toESM(require("fs"));
|
|
31598
|
+
var path31 = __toESM(require("path"));
|
|
31599
|
+
var os22 = __toESM(require("os"));
|
|
31168
31600
|
var chokidar = __toESM(require("chokidar"));
|
|
31169
31601
|
init_logger();
|
|
31170
31602
|
|
|
@@ -31537,9 +31969,9 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31537
31969
|
static siblingStderrLogged = /* @__PURE__ */ new Set();
|
|
31538
31970
|
static looksLikeProviderRoot(candidate) {
|
|
31539
31971
|
try {
|
|
31540
|
-
if (!
|
|
31972
|
+
if (!fs19.existsSync(candidate) || !fs19.statSync(candidate).isDirectory()) return false;
|
|
31541
31973
|
return ["ide", "extension", "cli", "acp"].some(
|
|
31542
|
-
(category) =>
|
|
31974
|
+
(category) => fs19.existsSync(path31.join(candidate, category))
|
|
31543
31975
|
);
|
|
31544
31976
|
} catch {
|
|
31545
31977
|
return false;
|
|
@@ -31547,20 +31979,20 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31547
31979
|
}
|
|
31548
31980
|
static hasProviderRootMarker(candidate) {
|
|
31549
31981
|
try {
|
|
31550
|
-
return
|
|
31982
|
+
return fs19.existsSync(path31.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
|
|
31551
31983
|
} catch {
|
|
31552
31984
|
return false;
|
|
31553
31985
|
}
|
|
31554
31986
|
}
|
|
31555
31987
|
detectDefaultUserDir() {
|
|
31556
|
-
const fallback =
|
|
31988
|
+
const fallback = path31.join(os22.homedir(), ".adhdev", "providers");
|
|
31557
31989
|
const envOptIn = process.env[_ProviderLoader.SIBLING_ENV_VAR] === "1";
|
|
31558
31990
|
const visited = /* @__PURE__ */ new Set();
|
|
31559
31991
|
for (const start of this.probeStarts) {
|
|
31560
|
-
let current =
|
|
31992
|
+
let current = path31.resolve(start);
|
|
31561
31993
|
while (!visited.has(current)) {
|
|
31562
31994
|
visited.add(current);
|
|
31563
|
-
const siblingCandidate =
|
|
31995
|
+
const siblingCandidate = path31.join(path31.dirname(current), _ProviderLoader.REPO_PROVIDER_DIRNAME);
|
|
31564
31996
|
if (_ProviderLoader.looksLikeProviderRoot(siblingCandidate)) {
|
|
31565
31997
|
const hasMarker = _ProviderLoader.hasProviderRootMarker(siblingCandidate);
|
|
31566
31998
|
if (envOptIn || hasMarker) {
|
|
@@ -31582,7 +32014,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31582
32014
|
return { path: siblingCandidate, source };
|
|
31583
32015
|
}
|
|
31584
32016
|
}
|
|
31585
|
-
const parent =
|
|
32017
|
+
const parent = path31.dirname(current);
|
|
31586
32018
|
if (parent === current) break;
|
|
31587
32019
|
current = parent;
|
|
31588
32020
|
}
|
|
@@ -31592,17 +32024,34 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31592
32024
|
constructor(options) {
|
|
31593
32025
|
this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
|
|
31594
32026
|
this.probeStarts = options?.probeStarts ?? [process.cwd(), __dirname];
|
|
31595
|
-
this.defaultProvidersDir =
|
|
32027
|
+
this.defaultProvidersDir = path31.join(os22.homedir(), ".adhdev", "providers");
|
|
31596
32028
|
const detected = this.detectDefaultUserDir();
|
|
31597
32029
|
this.userDir = detected.path;
|
|
31598
32030
|
this.userDirSource = detected.source;
|
|
31599
|
-
this.upstreamDir =
|
|
32031
|
+
this.upstreamDir = path31.join(this.defaultProvidersDir, ".upstream");
|
|
31600
32032
|
this.disableUpstream = false;
|
|
31601
32033
|
this.applySourceConfig({
|
|
31602
32034
|
userDir: options?.userDir,
|
|
31603
32035
|
sourceMode: options?.sourceMode,
|
|
31604
32036
|
disableUpstream: options?.disableUpstream
|
|
31605
32037
|
});
|
|
32038
|
+
this.migrateMarketplaceDirToExternal();
|
|
32039
|
+
}
|
|
32040
|
+
migrateMarketplaceDirToExternal() {
|
|
32041
|
+
try {
|
|
32042
|
+
const home = os22.homedir();
|
|
32043
|
+
const oldDir = path31.join(home, ".adhdev", "marketplace");
|
|
32044
|
+
const newDir = path31.join(home, ".adhdev", "external");
|
|
32045
|
+
if (!fs19.existsSync(oldDir)) return;
|
|
32046
|
+
if (fs19.existsSync(newDir)) {
|
|
32047
|
+
this.log(`Migration skipped: both ~/.adhdev/marketplace and ~/.adhdev/external exist (marketplace dir is now inert and can be removed manually).`);
|
|
32048
|
+
return;
|
|
32049
|
+
}
|
|
32050
|
+
fs19.renameSync(oldDir, newDir);
|
|
32051
|
+
this.log(`Migrated ~/.adhdev/marketplace \u2192 ~/.adhdev/external (one-time rename after provider source-layer cleanup).`);
|
|
32052
|
+
} catch (e) {
|
|
32053
|
+
this.log(`Marketplace\u2192external migration failed: ${e?.message || e}`);
|
|
32054
|
+
}
|
|
31606
32055
|
}
|
|
31607
32056
|
log(msg) {
|
|
31608
32057
|
this.logFn(`[ProviderLoader] ${msg}`);
|
|
@@ -31628,8 +32077,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31628
32077
|
* Highest-priority editable overrides come first.
|
|
31629
32078
|
*/
|
|
31630
32079
|
getProviderRoots() {
|
|
31631
|
-
const
|
|
31632
|
-
return [this.userDir,
|
|
32080
|
+
const externalDir = path31.join(os22.homedir(), ".adhdev", "external");
|
|
32081
|
+
return [this.userDir, externalDir, this.upstreamDir];
|
|
31633
32082
|
}
|
|
31634
32083
|
getSourceConfig() {
|
|
31635
32084
|
return {
|
|
@@ -31656,7 +32105,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31656
32105
|
this.userDir = detected.path;
|
|
31657
32106
|
this.userDirSource = detected.source;
|
|
31658
32107
|
}
|
|
31659
|
-
this.upstreamDir =
|
|
32108
|
+
this.upstreamDir = path31.join(this.defaultProvidersDir, ".upstream");
|
|
31660
32109
|
this.disableUpstream = this.sourceMode === "no-upstream";
|
|
31661
32110
|
if (this.explicitProviderDir) {
|
|
31662
32111
|
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
@@ -31670,7 +32119,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31670
32119
|
* Canonical provider directory shape for a given root.
|
|
31671
32120
|
*/
|
|
31672
32121
|
getProviderDir(root, category, type) {
|
|
31673
|
-
return
|
|
32122
|
+
return path31.join(root, category, type);
|
|
31674
32123
|
}
|
|
31675
32124
|
/**
|
|
31676
32125
|
* Canonical user override directory for a provider.
|
|
@@ -31697,20 +32146,23 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31697
32146
|
resolveProviderFile(type, ...segments) {
|
|
31698
32147
|
const dir = this.findProviderDirInternal(type);
|
|
31699
32148
|
if (!dir) return null;
|
|
31700
|
-
return
|
|
32149
|
+
return path31.join(dir, ...segments);
|
|
31701
32150
|
}
|
|
31702
32151
|
/**
|
|
31703
32152
|
* Load all providers (3-tier priority)
|
|
31704
|
-
* 1.
|
|
31705
|
-
* 2.
|
|
31706
|
-
*
|
|
32153
|
+
* 1. ~/.adhdev/providers/.upstream/ — official git, auto-synced
|
|
32154
|
+
* 2. ~/.adhdev/external/ — 3rd-party git sources, user-added,
|
|
32155
|
+
* bundled providers may include arbitrary JS (untrusted by default)
|
|
32156
|
+
* 3. ~/.adhdev/providers/ (excluding .upstream) — user-authored customs,
|
|
32157
|
+
* always wins
|
|
32158
|
+
* Highest priority listed last (overwrites earlier loads).
|
|
31707
32159
|
* If .upstream/ is empty, call fetchLatest() before loadAll().
|
|
31708
32160
|
*/
|
|
31709
32161
|
loadAll() {
|
|
31710
32162
|
this.providers.clear();
|
|
31711
32163
|
this.providerAvailability.clear();
|
|
31712
32164
|
let upstreamCount = 0;
|
|
31713
|
-
if (!this.disableUpstream &&
|
|
32165
|
+
if (!this.disableUpstream && fs19.existsSync(this.upstreamDir)) {
|
|
31714
32166
|
upstreamCount = this.loadDir(this.upstreamDir);
|
|
31715
32167
|
if (upstreamCount > 0) {
|
|
31716
32168
|
this.log(`Loaded ${upstreamCount} upstream providers (auto-updated)`);
|
|
@@ -31718,14 +32170,64 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31718
32170
|
} else if (this.disableUpstream) {
|
|
31719
32171
|
this.log("Upstream loading disabled (sourceMode=no-upstream)");
|
|
31720
32172
|
}
|
|
31721
|
-
const
|
|
31722
|
-
if (
|
|
31723
|
-
const
|
|
31724
|
-
|
|
31725
|
-
|
|
32173
|
+
const externalDir = path31.join(os22.homedir(), ".adhdev", "external");
|
|
32174
|
+
if (fs19.existsSync(externalDir)) {
|
|
32175
|
+
const rootEntries = (() => {
|
|
32176
|
+
try {
|
|
32177
|
+
return fs19.readdirSync(externalDir, { withFileTypes: true });
|
|
32178
|
+
} catch {
|
|
32179
|
+
return [];
|
|
32180
|
+
}
|
|
32181
|
+
})();
|
|
32182
|
+
const KNOWN_CATEGORIES = /* @__PURE__ */ new Set(["cli", "ide", "extension", "acp"]);
|
|
32183
|
+
const looksLegacy = rootEntries.some((e) => e.isDirectory() && KNOWN_CATEGORIES.has(e.name));
|
|
32184
|
+
if (looksLegacy) {
|
|
32185
|
+
const externalCount = this.loadDir(externalDir);
|
|
32186
|
+
if (externalCount > 0) {
|
|
32187
|
+
this.log(`Loaded ${externalCount} external providers (legacy unnamed source)`);
|
|
32188
|
+
}
|
|
32189
|
+
} else {
|
|
32190
|
+
const {
|
|
32191
|
+
loadProvidersActive: loadProvidersActive2,
|
|
32192
|
+
resolveActiveSource: resolveActiveSource2
|
|
32193
|
+
} = (init_external_sources(), __toCommonJS(external_sources_exports));
|
|
32194
|
+
const activeFile = loadProvidersActive2();
|
|
32195
|
+
let totalLoaded = 0;
|
|
32196
|
+
const ambiguousTypes = [];
|
|
32197
|
+
for (const sourceEntry of rootEntries) {
|
|
32198
|
+
if (!sourceEntry.isDirectory()) continue;
|
|
32199
|
+
const sourceDir = path31.join(externalDir, sourceEntry.name);
|
|
32200
|
+
const sourceLoaded = this.loadDir(sourceDir);
|
|
32201
|
+
if (sourceLoaded > 0) {
|
|
32202
|
+
totalLoaded += sourceLoaded;
|
|
32203
|
+
this.log(`Loaded ${sourceLoaded} providers from external source "${sourceEntry.name}"`);
|
|
32204
|
+
}
|
|
32205
|
+
}
|
|
32206
|
+
for (const [type] of this.providers) {
|
|
32207
|
+
const prov = this.providers.get(type);
|
|
32208
|
+
if (!prov) continue;
|
|
32209
|
+
const resolved = resolveActiveSource2(prov.category, type, activeFile);
|
|
32210
|
+
if (resolved.candidates.length <= 1) continue;
|
|
32211
|
+
if (resolved.ambiguous) {
|
|
32212
|
+
ambiguousTypes.push({ type, chosen: resolved.source ?? "?", candidates: resolved.candidates });
|
|
32213
|
+
}
|
|
32214
|
+
if (resolved.source && resolved.source !== "?") {
|
|
32215
|
+
const sourceDir = path31.join(externalDir, resolved.source);
|
|
32216
|
+
const reloadCount = this.loadDir(sourceDir);
|
|
32217
|
+
if (reloadCount === 0) {
|
|
32218
|
+
this.log(`Active source "${resolved.source}" no longer provides ${type}`);
|
|
32219
|
+
}
|
|
32220
|
+
}
|
|
32221
|
+
}
|
|
32222
|
+
if (totalLoaded > 0) {
|
|
32223
|
+
this.log(`Loaded ${totalLoaded} external providers (3rd-party sources)`);
|
|
32224
|
+
}
|
|
32225
|
+
for (const a of ambiguousTypes) {
|
|
32226
|
+
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.`);
|
|
32227
|
+
}
|
|
31726
32228
|
}
|
|
31727
32229
|
}
|
|
31728
|
-
if (
|
|
32230
|
+
if (fs19.existsSync(this.userDir)) {
|
|
31729
32231
|
const userCount = this.loadDir(this.userDir, [".upstream"]);
|
|
31730
32232
|
if (userCount > 0) {
|
|
31731
32233
|
this.log(`Loaded ${userCount} user custom providers (never auto-updated)`);
|
|
@@ -31740,10 +32242,10 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
31740
32242
|
* Check if upstream directory exists and has providers.
|
|
31741
32243
|
*/
|
|
31742
32244
|
hasUpstream() {
|
|
31743
|
-
if (!
|
|
32245
|
+
if (!fs19.existsSync(this.upstreamDir)) return false;
|
|
31744
32246
|
try {
|
|
31745
|
-
return
|
|
31746
|
-
(d) =>
|
|
32247
|
+
return fs19.readdirSync(this.upstreamDir).some(
|
|
32248
|
+
(d) => fs19.statSync(path31.join(this.upstreamDir, d)).isDirectory()
|
|
31747
32249
|
);
|
|
31748
32250
|
} catch {
|
|
31749
32251
|
return false;
|
|
@@ -32241,8 +32743,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32241
32743
|
resolved._resolvedScriptDir = entry.scriptDir;
|
|
32242
32744
|
resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
|
|
32243
32745
|
if (providerDir) {
|
|
32244
|
-
const fullDir =
|
|
32245
|
-
resolved._resolvedScriptsPath =
|
|
32746
|
+
const fullDir = path31.join(providerDir, entry.scriptDir);
|
|
32747
|
+
resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
|
|
32246
32748
|
}
|
|
32247
32749
|
matched = true;
|
|
32248
32750
|
}
|
|
@@ -32260,8 +32762,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32260
32762
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
32261
32763
|
resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
|
|
32262
32764
|
if (providerDir) {
|
|
32263
|
-
const fullDir =
|
|
32264
|
-
resolved._resolvedScriptsPath =
|
|
32765
|
+
const fullDir = path31.join(providerDir, base.defaultScriptDir);
|
|
32766
|
+
resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
|
|
32265
32767
|
}
|
|
32266
32768
|
}
|
|
32267
32769
|
resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
|
|
@@ -32278,8 +32780,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32278
32780
|
resolved._resolvedScriptDir = dirOverride;
|
|
32279
32781
|
resolved._resolvedScriptsSource = `versions:${range}`;
|
|
32280
32782
|
if (providerDir) {
|
|
32281
|
-
const fullDir =
|
|
32282
|
-
resolved._resolvedScriptsPath =
|
|
32783
|
+
const fullDir = path31.join(providerDir, dirOverride);
|
|
32784
|
+
resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
|
|
32283
32785
|
}
|
|
32284
32786
|
}
|
|
32285
32787
|
} else if (override.scripts) {
|
|
@@ -32295,8 +32797,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32295
32797
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
32296
32798
|
resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
|
|
32297
32799
|
if (providerDir) {
|
|
32298
|
-
const fullDir =
|
|
32299
|
-
resolved._resolvedScriptsPath =
|
|
32800
|
+
const fullDir = path31.join(providerDir, base.defaultScriptDir);
|
|
32801
|
+
resolved._resolvedScriptsPath = fs19.existsSync(path31.join(fullDir, "scripts.js")) ? path31.join(fullDir, "scripts.js") : fullDir;
|
|
32300
32802
|
}
|
|
32301
32803
|
}
|
|
32302
32804
|
}
|
|
@@ -32313,13 +32815,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32313
32815
|
if (providerDir2) {
|
|
32314
32816
|
for (const [scriptName, override] of Object.entries(base.overrides)) {
|
|
32315
32817
|
if (!override || typeof override.path !== "string") continue;
|
|
32316
|
-
const fullPath =
|
|
32317
|
-
if (!
|
|
32818
|
+
const fullPath = path31.join(providerDir2, override.path);
|
|
32819
|
+
if (!fs19.existsSync(fullPath)) {
|
|
32318
32820
|
this.log(` [overrides] ${base.type}: ${scriptName} path not found: ${fullPath}`);
|
|
32319
32821
|
continue;
|
|
32320
32822
|
}
|
|
32321
32823
|
try {
|
|
32322
|
-
registerProviderScriptRootSafely(
|
|
32824
|
+
registerProviderScriptRootSafely(path31.dirname(path31.dirname(providerDir2)));
|
|
32323
32825
|
delete require.cache[require.resolve(fullPath)];
|
|
32324
32826
|
const fn = require(fullPath);
|
|
32325
32827
|
const target = typeof fn === "function" ? fn : fn && fn[scriptName];
|
|
@@ -32344,19 +32846,19 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32344
32846
|
}
|
|
32345
32847
|
if (providerDir) {
|
|
32346
32848
|
try {
|
|
32347
|
-
const
|
|
32348
|
-
const
|
|
32849
|
+
const fs28 = require("fs");
|
|
32850
|
+
const path40 = require("path");
|
|
32349
32851
|
const candidates = [];
|
|
32350
32852
|
if (Array.isArray(base.compatibility)) {
|
|
32351
32853
|
for (const entry of base.compatibility) {
|
|
32352
32854
|
if (typeof entry?.spec !== "string") continue;
|
|
32353
32855
|
const matches = !entry.ideVersion || currentVersion && this.matchesVersion(currentVersion, entry.ideVersion) || !currentVersion;
|
|
32354
|
-
if (matches) candidates.push(
|
|
32856
|
+
if (matches) candidates.push(path40.join(providerDir, entry.spec));
|
|
32355
32857
|
}
|
|
32356
32858
|
}
|
|
32357
|
-
candidates.push(
|
|
32358
|
-
candidates.push(
|
|
32359
|
-
const specPath = candidates.find((p) =>
|
|
32859
|
+
candidates.push(path40.join(providerDir, "specs", "default.json"));
|
|
32860
|
+
candidates.push(path40.join(providerDir, "spec.json"));
|
|
32861
|
+
const specPath = candidates.find((p) => fs28.existsSync(p));
|
|
32360
32862
|
if (specPath) {
|
|
32361
32863
|
resolved._resolvedSpecPath = specPath;
|
|
32362
32864
|
const { loadSpec: loadSpec2 } = (init_loader(), __toCommonJS(loader_exports));
|
|
@@ -32385,10 +32887,10 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32385
32887
|
format = `spec-${nh.source.kind}`;
|
|
32386
32888
|
reader = (input) => executeNativeHistory2(nh, input);
|
|
32387
32889
|
} else if (nh.override_path) {
|
|
32388
|
-
const overrideFile =
|
|
32389
|
-
if (
|
|
32890
|
+
const overrideFile = path40.resolve(providerDir, nh.override_path);
|
|
32891
|
+
if (fs28.existsSync(overrideFile)) {
|
|
32390
32892
|
try {
|
|
32391
|
-
registerProviderScriptRootSafely(
|
|
32893
|
+
registerProviderScriptRootSafely(path40.dirname(path40.dirname(providerDir)));
|
|
32392
32894
|
delete require.cache[require.resolve(overrideFile)];
|
|
32393
32895
|
const mod = require(overrideFile);
|
|
32394
32896
|
const fn = typeof mod === "function" ? mod : mod && typeof mod.default === "function" ? mod.default : null;
|
|
@@ -32432,16 +32934,16 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32432
32934
|
this.debugLog(`[loadScriptsFromDir] ${type}: providerDir not found`);
|
|
32433
32935
|
return null;
|
|
32434
32936
|
}
|
|
32435
|
-
const dir =
|
|
32436
|
-
if (!
|
|
32937
|
+
const dir = path31.join(providerDir, scriptDir);
|
|
32938
|
+
if (!fs19.existsSync(dir)) {
|
|
32437
32939
|
this.debugLog(`[loadScriptsFromDir] ${type}: dir not found: ${dir}`);
|
|
32438
32940
|
return null;
|
|
32439
32941
|
}
|
|
32440
|
-
registerProviderScriptRootSafely(
|
|
32942
|
+
registerProviderScriptRootSafely(path31.dirname(path31.dirname(providerDir)));
|
|
32441
32943
|
const cached = this.scriptsCache.get(dir);
|
|
32442
32944
|
if (cached) return cached;
|
|
32443
|
-
const scriptsJs =
|
|
32444
|
-
if (
|
|
32945
|
+
const scriptsJs = path31.join(dir, "scripts.js");
|
|
32946
|
+
if (fs19.existsSync(scriptsJs)) {
|
|
32445
32947
|
try {
|
|
32446
32948
|
delete require.cache[require.resolve(scriptsJs)];
|
|
32447
32949
|
const loaded = require(scriptsJs);
|
|
@@ -32462,9 +32964,9 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32462
32964
|
watch() {
|
|
32463
32965
|
this.stopWatch();
|
|
32464
32966
|
const watchDir = (dir) => {
|
|
32465
|
-
if (!
|
|
32967
|
+
if (!fs19.existsSync(dir)) {
|
|
32466
32968
|
try {
|
|
32467
|
-
|
|
32969
|
+
fs19.mkdirSync(dir, { recursive: true });
|
|
32468
32970
|
} catch {
|
|
32469
32971
|
return;
|
|
32470
32972
|
}
|
|
@@ -32485,7 +32987,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32485
32987
|
if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
|
|
32486
32988
|
if (reloadTimer) clearTimeout(reloadTimer);
|
|
32487
32989
|
reloadTimer = setTimeout(() => {
|
|
32488
|
-
this.log(`File changed: ${
|
|
32990
|
+
this.log(`File changed: ${path31.basename(filePath)}, reloading...`);
|
|
32489
32991
|
this.reload();
|
|
32490
32992
|
}, 300);
|
|
32491
32993
|
}
|
|
@@ -32553,11 +33055,11 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32553
33055
|
}
|
|
32554
33056
|
this.log(`Registry sync starting (${_ProviderLoader.REGISTRY_BASE_URL})...`);
|
|
32555
33057
|
const https = require("https");
|
|
32556
|
-
const regMetaPath =
|
|
33058
|
+
const regMetaPath = path31.join(this.upstreamDir, _ProviderLoader.REGISTRY_META_FILE);
|
|
32557
33059
|
let cachedChecksums = {};
|
|
32558
33060
|
try {
|
|
32559
|
-
if (
|
|
32560
|
-
cachedChecksums = JSON.parse(
|
|
33061
|
+
if (fs19.existsSync(regMetaPath)) {
|
|
33062
|
+
cachedChecksums = JSON.parse(fs19.readFileSync(regMetaPath, "utf-8")).checksums ?? {};
|
|
32561
33063
|
}
|
|
32562
33064
|
} catch {
|
|
32563
33065
|
}
|
|
@@ -32611,15 +33113,15 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32611
33113
|
this.log(`\u26A0 Registry checksum mismatch for ${type}@${version} \u2014 skipping`);
|
|
32612
33114
|
continue;
|
|
32613
33115
|
}
|
|
32614
|
-
const providerDir =
|
|
32615
|
-
|
|
32616
|
-
|
|
33116
|
+
const providerDir = path31.join(this.upstreamDir, category, type);
|
|
33117
|
+
fs19.mkdirSync(providerDir, { recursive: true });
|
|
33118
|
+
fs19.writeFileSync(path31.join(providerDir, "provider.json"), manifestBody, "utf-8");
|
|
32617
33119
|
cachedChecksums[cacheKey] = checksum;
|
|
32618
33120
|
updatedCount++;
|
|
32619
33121
|
this.log(`\u2713 Registry updated: ${category}/${type}@${version}`);
|
|
32620
33122
|
}
|
|
32621
|
-
|
|
32622
|
-
|
|
33123
|
+
fs19.mkdirSync(this.upstreamDir, { recursive: true });
|
|
33124
|
+
fs19.writeFileSync(regMetaPath, JSON.stringify({
|
|
32623
33125
|
checksums: cachedChecksums,
|
|
32624
33126
|
syncedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
32625
33127
|
providerCount: list.providers.length
|
|
@@ -32640,12 +33142,12 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32640
33142
|
const { exec: exec7 } = require("child_process");
|
|
32641
33143
|
const { promisify: promisify7 } = require("util");
|
|
32642
33144
|
const execAsync5 = promisify7(exec7);
|
|
32643
|
-
const metaPath =
|
|
33145
|
+
const metaPath = path31.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
32644
33146
|
let prevEtag = "";
|
|
32645
33147
|
let prevTimestamp = 0;
|
|
32646
33148
|
try {
|
|
32647
|
-
if (
|
|
32648
|
-
const meta = JSON.parse(
|
|
33149
|
+
if (fs19.existsSync(metaPath)) {
|
|
33150
|
+
const meta = JSON.parse(fs19.readFileSync(metaPath, "utf-8"));
|
|
32649
33151
|
prevEtag = meta.etag || "";
|
|
32650
33152
|
prevTimestamp = meta.timestamp || 0;
|
|
32651
33153
|
}
|
|
@@ -32700,39 +33202,39 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32700
33202
|
return { updated: false };
|
|
32701
33203
|
}
|
|
32702
33204
|
this.log("Downloading latest providers from GitHub...");
|
|
32703
|
-
const tmpTar =
|
|
32704
|
-
const tmpExtract =
|
|
33205
|
+
const tmpTar = path31.join(os22.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
|
|
33206
|
+
const tmpExtract = path31.join(os22.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
|
|
32705
33207
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
32706
|
-
|
|
33208
|
+
fs19.mkdirSync(tmpExtract, { recursive: true });
|
|
32707
33209
|
await execAsync5(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
32708
|
-
const extracted =
|
|
33210
|
+
const extracted = fs19.readdirSync(tmpExtract);
|
|
32709
33211
|
const rootDir = extracted.find(
|
|
32710
|
-
(d) =>
|
|
33212
|
+
(d) => fs19.statSync(path31.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
|
|
32711
33213
|
);
|
|
32712
33214
|
if (!rootDir) throw new Error("Unexpected tarball structure");
|
|
32713
|
-
const sourceDir =
|
|
33215
|
+
const sourceDir = path31.join(tmpExtract, rootDir);
|
|
32714
33216
|
const backupDir = this.upstreamDir + ".bak";
|
|
32715
|
-
if (
|
|
32716
|
-
if (
|
|
32717
|
-
|
|
33217
|
+
if (fs19.existsSync(this.upstreamDir)) {
|
|
33218
|
+
if (fs19.existsSync(backupDir)) fs19.rmSync(backupDir, { recursive: true, force: true });
|
|
33219
|
+
fs19.renameSync(this.upstreamDir, backupDir);
|
|
32718
33220
|
}
|
|
32719
33221
|
try {
|
|
32720
33222
|
this.copyDirRecursive(sourceDir, this.upstreamDir);
|
|
32721
33223
|
this.writeMeta(metaPath, etag || `ts-${Date.now()}`, Date.now());
|
|
32722
|
-
if (
|
|
33224
|
+
if (fs19.existsSync(backupDir)) fs19.rmSync(backupDir, { recursive: true, force: true });
|
|
32723
33225
|
} catch (e) {
|
|
32724
|
-
if (
|
|
32725
|
-
if (
|
|
32726
|
-
|
|
33226
|
+
if (fs19.existsSync(backupDir)) {
|
|
33227
|
+
if (fs19.existsSync(this.upstreamDir)) fs19.rmSync(this.upstreamDir, { recursive: true, force: true });
|
|
33228
|
+
fs19.renameSync(backupDir, this.upstreamDir);
|
|
32727
33229
|
}
|
|
32728
33230
|
throw e;
|
|
32729
33231
|
}
|
|
32730
33232
|
try {
|
|
32731
|
-
|
|
33233
|
+
fs19.rmSync(tmpTar, { force: true });
|
|
32732
33234
|
} catch {
|
|
32733
33235
|
}
|
|
32734
33236
|
try {
|
|
32735
|
-
|
|
33237
|
+
fs19.rmSync(tmpExtract, { recursive: true, force: true });
|
|
32736
33238
|
} catch {
|
|
32737
33239
|
}
|
|
32738
33240
|
const upstreamCount = this.countProviders(this.upstreamDir);
|
|
@@ -32764,7 +33266,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32764
33266
|
reject(new Error(`HTTP ${res.statusCode}`));
|
|
32765
33267
|
return;
|
|
32766
33268
|
}
|
|
32767
|
-
const ws =
|
|
33269
|
+
const ws = fs19.createWriteStream(destPath);
|
|
32768
33270
|
res.pipe(ws);
|
|
32769
33271
|
ws.on("finish", () => {
|
|
32770
33272
|
ws.close();
|
|
@@ -32783,22 +33285,22 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32783
33285
|
}
|
|
32784
33286
|
/** Recursive directory copy */
|
|
32785
33287
|
copyDirRecursive(src, dest) {
|
|
32786
|
-
|
|
32787
|
-
for (const entry of
|
|
32788
|
-
const srcPath =
|
|
32789
|
-
const destPath =
|
|
33288
|
+
fs19.mkdirSync(dest, { recursive: true });
|
|
33289
|
+
for (const entry of fs19.readdirSync(src, { withFileTypes: true })) {
|
|
33290
|
+
const srcPath = path31.join(src, entry.name);
|
|
33291
|
+
const destPath = path31.join(dest, entry.name);
|
|
32790
33292
|
if (entry.isDirectory()) {
|
|
32791
33293
|
this.copyDirRecursive(srcPath, destPath);
|
|
32792
33294
|
} else {
|
|
32793
|
-
|
|
33295
|
+
fs19.copyFileSync(srcPath, destPath);
|
|
32794
33296
|
}
|
|
32795
33297
|
}
|
|
32796
33298
|
}
|
|
32797
33299
|
/** .meta.json save */
|
|
32798
33300
|
writeMeta(metaPath, etag, timestamp) {
|
|
32799
33301
|
try {
|
|
32800
|
-
|
|
32801
|
-
|
|
33302
|
+
fs19.mkdirSync(path31.dirname(metaPath), { recursive: true });
|
|
33303
|
+
fs19.writeFileSync(metaPath, JSON.stringify({
|
|
32802
33304
|
etag,
|
|
32803
33305
|
timestamp,
|
|
32804
33306
|
lastCheck: new Date(timestamp).toISOString(),
|
|
@@ -32809,15 +33311,15 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
32809
33311
|
}
|
|
32810
33312
|
/** Count provider files (provider.v1.json or provider.json — at most one per dir). */
|
|
32811
33313
|
countProviders(dir) {
|
|
32812
|
-
if (!
|
|
33314
|
+
if (!fs19.existsSync(dir)) return 0;
|
|
32813
33315
|
let count = 0;
|
|
32814
33316
|
const scan = (d) => {
|
|
32815
33317
|
try {
|
|
32816
|
-
const entries =
|
|
33318
|
+
const entries = fs19.readdirSync(d, { withFileTypes: true });
|
|
32817
33319
|
const hasManifest = entries.some((e) => e.name === "provider.v1.json" || e.name === "provider.json");
|
|
32818
33320
|
if (hasManifest) count++;
|
|
32819
33321
|
for (const entry of entries) {
|
|
32820
|
-
if (entry.isDirectory()) scan(
|
|
33322
|
+
if (entry.isDirectory()) scan(path31.join(d, entry.name));
|
|
32821
33323
|
}
|
|
32822
33324
|
} catch {
|
|
32823
33325
|
}
|
|
@@ -33043,13 +33545,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
33043
33545
|
if (!provider) return null;
|
|
33044
33546
|
const cat = provider.category;
|
|
33045
33547
|
const searchRoots = this.getProviderRoots();
|
|
33046
|
-
const hasManifest = (dir) =>
|
|
33548
|
+
const hasManifest = (dir) => fs19.existsSync(path31.join(dir, "provider.v1.json")) || fs19.existsSync(path31.join(dir, "provider.json"));
|
|
33047
33549
|
const readManifestType = (dir) => {
|
|
33048
33550
|
for (const file of ["provider.v1.json", "provider.json"]) {
|
|
33049
|
-
const p =
|
|
33050
|
-
if (!
|
|
33551
|
+
const p = path31.join(dir, file);
|
|
33552
|
+
if (!fs19.existsSync(p)) continue;
|
|
33051
33553
|
try {
|
|
33052
|
-
const data = JSON.parse(
|
|
33554
|
+
const data = JSON.parse(fs19.readFileSync(p, "utf-8"));
|
|
33053
33555
|
if (typeof data?.type === "string") return data.type;
|
|
33054
33556
|
} catch {
|
|
33055
33557
|
}
|
|
@@ -33057,15 +33559,15 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
33057
33559
|
return null;
|
|
33058
33560
|
};
|
|
33059
33561
|
for (const root of searchRoots) {
|
|
33060
|
-
if (!
|
|
33562
|
+
if (!fs19.existsSync(root)) continue;
|
|
33061
33563
|
const candidate = this.getProviderDir(root, cat, type);
|
|
33062
33564
|
if (hasManifest(candidate)) return candidate;
|
|
33063
|
-
const catDir =
|
|
33064
|
-
if (
|
|
33565
|
+
const catDir = path31.join(root, cat);
|
|
33566
|
+
if (fs19.existsSync(catDir)) {
|
|
33065
33567
|
try {
|
|
33066
|
-
for (const entry of
|
|
33568
|
+
for (const entry of fs19.readdirSync(catDir, { withFileTypes: true })) {
|
|
33067
33569
|
if (!entry.isDirectory()) continue;
|
|
33068
|
-
const entryDir =
|
|
33570
|
+
const entryDir = path31.join(catDir, entry.name);
|
|
33069
33571
|
const manifestType = readManifestType(entryDir);
|
|
33070
33572
|
if (manifestType === type) return entryDir;
|
|
33071
33573
|
}
|
|
@@ -33081,8 +33583,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
33081
33583
|
* (template substitution is NOT applied here — scripts.js handles that)
|
|
33082
33584
|
*/
|
|
33083
33585
|
buildScriptWrappersFromDir(dir) {
|
|
33084
|
-
const scriptsJs =
|
|
33085
|
-
if (
|
|
33586
|
+
const scriptsJs = path31.join(dir, "scripts.js");
|
|
33587
|
+
if (fs19.existsSync(scriptsJs)) {
|
|
33086
33588
|
try {
|
|
33087
33589
|
delete require.cache[require.resolve(scriptsJs)];
|
|
33088
33590
|
return require(scriptsJs);
|
|
@@ -33092,13 +33594,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
33092
33594
|
const toCamel = (name) => name.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
|
|
33093
33595
|
const result = {};
|
|
33094
33596
|
try {
|
|
33095
|
-
for (const file of
|
|
33597
|
+
for (const file of fs19.readdirSync(dir)) {
|
|
33096
33598
|
if (!file.endsWith(".js")) continue;
|
|
33097
33599
|
const scriptName = toCamel(file.replace(".js", ""));
|
|
33098
|
-
const filePath =
|
|
33600
|
+
const filePath = path31.join(dir, file);
|
|
33099
33601
|
result[scriptName] = (...args) => {
|
|
33100
33602
|
try {
|
|
33101
|
-
let content =
|
|
33603
|
+
let content = fs19.readFileSync(filePath, "utf-8");
|
|
33102
33604
|
if (args[0] && typeof args[0] === "object") {
|
|
33103
33605
|
for (const [key, val] of Object.entries(args[0])) {
|
|
33104
33606
|
let v = val;
|
|
@@ -33144,12 +33646,12 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
33144
33646
|
* Structure: dir/category/agent-name/provider.{json,js}
|
|
33145
33647
|
*/
|
|
33146
33648
|
loadDir(dir, excludeDirs) {
|
|
33147
|
-
if (!
|
|
33649
|
+
if (!fs19.existsSync(dir)) return 0;
|
|
33148
33650
|
let count = 0;
|
|
33149
33651
|
const scan = (d) => {
|
|
33150
33652
|
let entries;
|
|
33151
33653
|
try {
|
|
33152
|
-
entries =
|
|
33654
|
+
entries = fs19.readdirSync(d, { withFileTypes: true });
|
|
33153
33655
|
} catch {
|
|
33154
33656
|
return;
|
|
33155
33657
|
}
|
|
@@ -33157,9 +33659,9 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
33157
33659
|
const hasJson = entries.some((e) => e.name === "provider.json");
|
|
33158
33660
|
if (hasV1 || hasJson) {
|
|
33159
33661
|
const manifestFile = hasV1 ? "provider.v1.json" : "provider.json";
|
|
33160
|
-
const jsonPath =
|
|
33662
|
+
const jsonPath = path31.join(d, manifestFile);
|
|
33161
33663
|
try {
|
|
33162
|
-
const raw =
|
|
33664
|
+
const raw = fs19.readFileSync(jsonPath, "utf-8");
|
|
33163
33665
|
const mod = JSON.parse(raw);
|
|
33164
33666
|
if (hasV1 && mod?.category === "cli") {
|
|
33165
33667
|
try {
|
|
@@ -33197,10 +33699,10 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
33197
33699
|
this.log(`\u26A0 Invalid provider at ${jsonPath}: ${validation.errors.join("; ")}`);
|
|
33198
33700
|
} else {
|
|
33199
33701
|
const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
|
|
33200
|
-
const scriptsPath =
|
|
33201
|
-
if (!hasCompatibility &&
|
|
33702
|
+
const scriptsPath = path31.join(d, "scripts.js");
|
|
33703
|
+
if (!hasCompatibility && fs19.existsSync(scriptsPath)) {
|
|
33202
33704
|
try {
|
|
33203
|
-
registerProviderScriptRootSafely(
|
|
33705
|
+
registerProviderScriptRootSafely(path31.dirname(path31.dirname(d)));
|
|
33204
33706
|
delete require.cache[require.resolve(scriptsPath)];
|
|
33205
33707
|
const scripts = require(scriptsPath);
|
|
33206
33708
|
normalizedProvider.scripts = scripts;
|
|
@@ -33208,12 +33710,30 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
33208
33710
|
this.log(`\u26A0 Failed to load scripts: ${scriptsPath}: ${e.message}`);
|
|
33209
33711
|
}
|
|
33210
33712
|
}
|
|
33713
|
+
const externalDirAbs = path31.join(os22.homedir(), ".adhdev", "external");
|
|
33714
|
+
const layer = d.startsWith(externalDirAbs) ? "external" : d.startsWith(this.userDir) && !d.includes(".upstream") ? "user" : "upstream";
|
|
33715
|
+
try {
|
|
33716
|
+
const { inspectManifestShape: inspectManifestShape2, classifyTrust: classifyTrust2 } = (init_provider_trust(), __toCommonJS(provider_trust_exports));
|
|
33717
|
+
const shape = inspectManifestShape2(mod);
|
|
33718
|
+
const trust = classifyTrust2(layer, shape);
|
|
33719
|
+
normalizedProvider._sourceLayer = layer;
|
|
33720
|
+
normalizedProvider._sourceTrust = trust;
|
|
33721
|
+
normalizedProvider._manifestShape = shape;
|
|
33722
|
+
if (layer === "external") {
|
|
33723
|
+
const rel = path31.relative(externalDirAbs, d);
|
|
33724
|
+
const firstSeg = rel.split(path31.sep)[0];
|
|
33725
|
+
if (firstSeg && firstSeg !== "..") normalizedProvider._sourceName = firstSeg;
|
|
33726
|
+
}
|
|
33727
|
+
} catch {
|
|
33728
|
+
}
|
|
33211
33729
|
const existed = this.providers.has(normalizedProvider.type);
|
|
33212
33730
|
this.providers.set(normalizedProvider.type, normalizedProvider);
|
|
33213
33731
|
count++;
|
|
33214
|
-
const source =
|
|
33732
|
+
const source = normalizedProvider._sourceLayer ?? "upstream";
|
|
33215
33733
|
const overrideWarning = existed && source === "user" ? " \u26A0 OVERRIDES upstream" : "";
|
|
33216
|
-
|
|
33734
|
+
const sourceName = normalizedProvider._sourceName;
|
|
33735
|
+
const sourceLabel = sourceName ? `${source}/${sourceName}` : source;
|
|
33736
|
+
this.log(` ${existed ? "\u{1F504}" : "\u2705"} ${normalizedProvider.type} (${normalizedProvider.category}) \u2014 ${normalizedProvider.name} [${sourceLabel}]${overrideWarning}`);
|
|
33217
33737
|
}
|
|
33218
33738
|
} catch (e) {
|
|
33219
33739
|
this.log(`\u26A0 Failed to load ${jsonPath}: ${e.message}`);
|
|
@@ -33223,8 +33743,9 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
33223
33743
|
for (const entry of entries) {
|
|
33224
33744
|
if (!entry.isDirectory()) continue;
|
|
33225
33745
|
if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
|
|
33746
|
+
if (d === dir && entry.name === "examples") continue;
|
|
33226
33747
|
if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
|
|
33227
|
-
scan(
|
|
33748
|
+
scan(path31.join(d, entry.name));
|
|
33228
33749
|
}
|
|
33229
33750
|
}
|
|
33230
33751
|
};
|
|
@@ -33422,7 +33943,7 @@ async function isCdpActive(port) {
|
|
|
33422
33943
|
});
|
|
33423
33944
|
}
|
|
33424
33945
|
async function killIdeProcess(ideId) {
|
|
33425
|
-
const plat =
|
|
33946
|
+
const plat = os23.platform();
|
|
33426
33947
|
const appName = getMacAppIdentifiers()[ideId];
|
|
33427
33948
|
const winProcesses = getWinProcessNames()[ideId];
|
|
33428
33949
|
try {
|
|
@@ -33483,7 +34004,7 @@ async function killIdeProcess(ideId) {
|
|
|
33483
34004
|
}
|
|
33484
34005
|
}
|
|
33485
34006
|
async function isIdeRunning(ideId) {
|
|
33486
|
-
const plat =
|
|
34007
|
+
const plat = os23.platform();
|
|
33487
34008
|
try {
|
|
33488
34009
|
if (plat === "darwin") {
|
|
33489
34010
|
const appName = getMacAppIdentifiers()[ideId];
|
|
@@ -33538,7 +34059,7 @@ async function isIdeRunning(ideId) {
|
|
|
33538
34059
|
}
|
|
33539
34060
|
}
|
|
33540
34061
|
async function detectCurrentWorkspace(ideId) {
|
|
33541
|
-
const plat =
|
|
34062
|
+
const plat = os23.platform();
|
|
33542
34063
|
if (plat === "darwin") {
|
|
33543
34064
|
try {
|
|
33544
34065
|
const appName = getMacAppIdentifiers()[ideId];
|
|
@@ -33553,17 +34074,17 @@ async function detectCurrentWorkspace(ideId) {
|
|
|
33553
34074
|
}
|
|
33554
34075
|
} else if (plat === "win32") {
|
|
33555
34076
|
try {
|
|
33556
|
-
const
|
|
34077
|
+
const fs28 = require("fs");
|
|
33557
34078
|
const appNameMap = getMacAppIdentifiers();
|
|
33558
34079
|
const appName = appNameMap[ideId];
|
|
33559
34080
|
if (appName) {
|
|
33560
|
-
const storagePath =
|
|
33561
|
-
process.env.APPDATA ||
|
|
34081
|
+
const storagePath = path32.join(
|
|
34082
|
+
process.env.APPDATA || path32.join(os23.homedir(), "AppData", "Roaming"),
|
|
33562
34083
|
appName,
|
|
33563
34084
|
"storage.json"
|
|
33564
34085
|
);
|
|
33565
|
-
if (
|
|
33566
|
-
const data = JSON.parse(
|
|
34086
|
+
if (fs28.existsSync(storagePath)) {
|
|
34087
|
+
const data = JSON.parse(fs28.readFileSync(storagePath, "utf-8"));
|
|
33567
34088
|
const workspaces = data?.openedPathsList?.workspaces3 || data?.openedPathsList?.entries || [];
|
|
33568
34089
|
if (workspaces.length > 0) {
|
|
33569
34090
|
const recent = workspaces[0];
|
|
@@ -33580,7 +34101,7 @@ async function detectCurrentWorkspace(ideId) {
|
|
|
33580
34101
|
return void 0;
|
|
33581
34102
|
}
|
|
33582
34103
|
async function launchWithCdp(options = {}) {
|
|
33583
|
-
const platform10 =
|
|
34104
|
+
const platform10 = os23.platform();
|
|
33584
34105
|
let targetIde;
|
|
33585
34106
|
const ides = await detectIDEs(getProviderLoader());
|
|
33586
34107
|
if (options.ideId) {
|
|
@@ -33747,14 +34268,14 @@ init_cli_detector();
|
|
|
33747
34268
|
init_logger();
|
|
33748
34269
|
|
|
33749
34270
|
// src/logging/command-log.ts
|
|
33750
|
-
var
|
|
33751
|
-
var
|
|
33752
|
-
var
|
|
33753
|
-
var LOG_DIR2 = process.platform === "win32" ?
|
|
34271
|
+
var fs20 = __toESM(require("fs"));
|
|
34272
|
+
var path33 = __toESM(require("path"));
|
|
34273
|
+
var os24 = __toESM(require("os"));
|
|
34274
|
+
var LOG_DIR2 = process.platform === "win32" ? path33.join(process.env.LOCALAPPDATA || process.env.APPDATA || path33.join(os24.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path33.join(os24.homedir(), "Library", "Logs", "adhdev") : path33.join(os24.homedir(), ".local", "share", "adhdev", "logs");
|
|
33754
34275
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
33755
34276
|
var MAX_DAYS = 7;
|
|
33756
34277
|
try {
|
|
33757
|
-
|
|
34278
|
+
fs20.mkdirSync(LOG_DIR2, { recursive: true });
|
|
33758
34279
|
} catch {
|
|
33759
34280
|
}
|
|
33760
34281
|
var SENSITIVE_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -33788,19 +34309,19 @@ function getDateStr2() {
|
|
|
33788
34309
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
33789
34310
|
}
|
|
33790
34311
|
var currentDate2 = getDateStr2();
|
|
33791
|
-
var currentFile =
|
|
34312
|
+
var currentFile = path33.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
33792
34313
|
var writeCount2 = 0;
|
|
33793
34314
|
function checkRotation() {
|
|
33794
34315
|
const today = getDateStr2();
|
|
33795
34316
|
if (today !== currentDate2) {
|
|
33796
34317
|
currentDate2 = today;
|
|
33797
|
-
currentFile =
|
|
34318
|
+
currentFile = path33.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
33798
34319
|
cleanOldFiles();
|
|
33799
34320
|
}
|
|
33800
34321
|
}
|
|
33801
34322
|
function cleanOldFiles() {
|
|
33802
34323
|
try {
|
|
33803
|
-
const files =
|
|
34324
|
+
const files = fs20.readdirSync(LOG_DIR2).filter((f) => f.startsWith("commands-") && f.endsWith(".jsonl"));
|
|
33804
34325
|
const cutoff = /* @__PURE__ */ new Date();
|
|
33805
34326
|
cutoff.setDate(cutoff.getDate() - MAX_DAYS);
|
|
33806
34327
|
const cutoffStr = cutoff.toISOString().slice(0, 10);
|
|
@@ -33808,7 +34329,7 @@ function cleanOldFiles() {
|
|
|
33808
34329
|
const dateMatch = file.match(/commands-(\d{4}-\d{2}-\d{2})/);
|
|
33809
34330
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
33810
34331
|
try {
|
|
33811
|
-
|
|
34332
|
+
fs20.unlinkSync(path33.join(LOG_DIR2, file));
|
|
33812
34333
|
} catch {
|
|
33813
34334
|
}
|
|
33814
34335
|
}
|
|
@@ -33818,14 +34339,14 @@ function cleanOldFiles() {
|
|
|
33818
34339
|
}
|
|
33819
34340
|
function checkSize() {
|
|
33820
34341
|
try {
|
|
33821
|
-
const stat2 =
|
|
34342
|
+
const stat2 = fs20.statSync(currentFile);
|
|
33822
34343
|
if (stat2.size > MAX_FILE_SIZE) {
|
|
33823
34344
|
const backup = currentFile.replace(".jsonl", ".1.jsonl");
|
|
33824
34345
|
try {
|
|
33825
|
-
|
|
34346
|
+
fs20.unlinkSync(backup);
|
|
33826
34347
|
} catch {
|
|
33827
34348
|
}
|
|
33828
|
-
|
|
34349
|
+
fs20.renameSync(currentFile, backup);
|
|
33829
34350
|
}
|
|
33830
34351
|
} catch {
|
|
33831
34352
|
}
|
|
@@ -33858,14 +34379,14 @@ function logCommand(entry) {
|
|
|
33858
34379
|
...entry.error ? { err: entry.error } : {},
|
|
33859
34380
|
...entry.durationMs !== void 0 ? { ms: entry.durationMs } : {}
|
|
33860
34381
|
});
|
|
33861
|
-
|
|
34382
|
+
fs20.appendFileSync(currentFile, line + "\n");
|
|
33862
34383
|
} catch {
|
|
33863
34384
|
}
|
|
33864
34385
|
}
|
|
33865
34386
|
function getRecentCommands(count = 50) {
|
|
33866
34387
|
try {
|
|
33867
|
-
if (!
|
|
33868
|
-
const content =
|
|
34388
|
+
if (!fs20.existsSync(currentFile)) return [];
|
|
34389
|
+
const content = fs20.readFileSync(currentFile, "utf-8");
|
|
33869
34390
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
33870
34391
|
return lines.slice(-count).map((line) => {
|
|
33871
34392
|
try {
|
|
@@ -33915,10 +34436,10 @@ function runGit2(repoRoot, args) {
|
|
|
33915
34436
|
}
|
|
33916
34437
|
}
|
|
33917
34438
|
function readRecord3(repoRoot) {
|
|
33918
|
-
const
|
|
33919
|
-
if (!(0, import_node_fs4.existsSync)(
|
|
34439
|
+
const path40 = (0, import_node_path2.resolve)(repoRoot, PREVIEW_DEPLOY_RECORD);
|
|
34440
|
+
if (!(0, import_node_fs4.existsSync)(path40)) return null;
|
|
33920
34441
|
try {
|
|
33921
|
-
const parsed = JSON.parse((0, import_node_fs4.readFileSync)(
|
|
34442
|
+
const parsed = JSON.parse((0, import_node_fs4.readFileSync)(path40, "utf8"));
|
|
33922
34443
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
33923
34444
|
} catch {
|
|
33924
34445
|
return null;
|
|
@@ -33980,7 +34501,7 @@ function buildPreviewFreshness(repoRoot) {
|
|
|
33980
34501
|
}
|
|
33981
34502
|
|
|
33982
34503
|
// src/status/snapshot.ts
|
|
33983
|
-
var
|
|
34504
|
+
var os25 = __toESM(require("os"));
|
|
33984
34505
|
init_config();
|
|
33985
34506
|
init_terminal_screen();
|
|
33986
34507
|
init_logger();
|
|
@@ -34019,25 +34540,50 @@ function buildDetectedIdeInfos(detectedIdes, cdpManagers) {
|
|
|
34019
34540
|
}
|
|
34020
34541
|
function buildAvailableProviders(providerLoader) {
|
|
34021
34542
|
const providers = providerLoader.getAvailableProviderInfos?.() || providerLoader.getAll();
|
|
34022
|
-
|
|
34023
|
-
|
|
34024
|
-
|
|
34025
|
-
|
|
34026
|
-
|
|
34027
|
-
|
|
34028
|
-
|
|
34029
|
-
|
|
34030
|
-
|
|
34031
|
-
|
|
34032
|
-
|
|
34033
|
-
|
|
34034
|
-
|
|
34035
|
-
|
|
34543
|
+
let describeTrust2 = () => "";
|
|
34544
|
+
let requiresConfirmation2 = () => false;
|
|
34545
|
+
try {
|
|
34546
|
+
const mod = (init_provider_trust(), __toCommonJS(provider_trust_exports));
|
|
34547
|
+
describeTrust2 = mod.describeTrust;
|
|
34548
|
+
requiresConfirmation2 = mod.requiresConfirmation;
|
|
34549
|
+
} catch {
|
|
34550
|
+
}
|
|
34551
|
+
return providers.map((provider) => {
|
|
34552
|
+
const trust = provider._sourceTrust;
|
|
34553
|
+
const sourceLayer = provider._sourceLayer;
|
|
34554
|
+
const sourceName = provider._sourceName;
|
|
34555
|
+
return {
|
|
34556
|
+
type: provider.type,
|
|
34557
|
+
name: provider.displayName || provider.type,
|
|
34558
|
+
displayName: provider.displayName || provider.type,
|
|
34559
|
+
icon: provider.icon || "\u{1F4BB}",
|
|
34560
|
+
category: provider.category,
|
|
34561
|
+
...provider.installed !== void 0 ? { installed: provider.installed } : {},
|
|
34562
|
+
...provider.detectedPath !== void 0 ? { detectedPath: provider.detectedPath } : {},
|
|
34563
|
+
...provider.enabled !== void 0 ? { enabled: provider.enabled } : {},
|
|
34564
|
+
...provider.machineStatus !== void 0 ? { machineStatus: provider.machineStatus } : {},
|
|
34565
|
+
...provider.lastDetection !== void 0 ? { lastDetection: provider.lastDetection } : {},
|
|
34566
|
+
...provider.lastVerification !== void 0 ? { lastVerification: provider.lastVerification } : {},
|
|
34567
|
+
...provider.meshCoordinator !== void 0 ? { meshCoordinator: provider.meshCoordinator } : {},
|
|
34568
|
+
...trust ? {
|
|
34569
|
+
trust,
|
|
34570
|
+
trustDescription: describeTrust2(trust),
|
|
34571
|
+
requiresConfirmation: requiresConfirmation2(trust)
|
|
34572
|
+
} : {},
|
|
34573
|
+
...sourceLayer ? { sourceLayer } : {},
|
|
34574
|
+
...sourceName ? { sourceName } : {},
|
|
34575
|
+
...provider.providerVersion ? { providerVersion: provider.providerVersion } : {},
|
|
34576
|
+
...provider.binary ? { binary: provider.binary } : {},
|
|
34577
|
+
...provider.status ? { status: provider.status } : {},
|
|
34578
|
+
...provider.details ? { details: provider.details } : {},
|
|
34579
|
+
...provider.links ? { links: provider.links } : {}
|
|
34580
|
+
};
|
|
34581
|
+
});
|
|
34036
34582
|
}
|
|
34037
34583
|
function buildMachineInfo(profile = "full") {
|
|
34038
34584
|
const base = {
|
|
34039
|
-
hostname:
|
|
34040
|
-
platform:
|
|
34585
|
+
hostname: os25.hostname(),
|
|
34586
|
+
platform: os25.platform()
|
|
34041
34587
|
};
|
|
34042
34588
|
if (profile === "live") {
|
|
34043
34589
|
return base;
|
|
@@ -34046,23 +34592,23 @@ function buildMachineInfo(profile = "full") {
|
|
|
34046
34592
|
const memSnap2 = getHostMemorySnapshot();
|
|
34047
34593
|
return {
|
|
34048
34594
|
...base,
|
|
34049
|
-
arch:
|
|
34050
|
-
cpus:
|
|
34595
|
+
arch: os25.arch(),
|
|
34596
|
+
cpus: os25.cpus().length,
|
|
34051
34597
|
totalMem: memSnap2.totalMem,
|
|
34052
|
-
release:
|
|
34598
|
+
release: os25.release()
|
|
34053
34599
|
};
|
|
34054
34600
|
}
|
|
34055
34601
|
const memSnap = getHostMemorySnapshot();
|
|
34056
34602
|
return {
|
|
34057
34603
|
...base,
|
|
34058
|
-
arch:
|
|
34059
|
-
cpus:
|
|
34604
|
+
arch: os25.arch(),
|
|
34605
|
+
cpus: os25.cpus().length,
|
|
34060
34606
|
totalMem: memSnap.totalMem,
|
|
34061
34607
|
freeMem: memSnap.freeMem,
|
|
34062
34608
|
availableMem: memSnap.availableMem,
|
|
34063
|
-
loadavg:
|
|
34064
|
-
uptime:
|
|
34065
|
-
release:
|
|
34609
|
+
loadavg: os25.loadavg(),
|
|
34610
|
+
uptime: os25.uptime(),
|
|
34611
|
+
release: os25.release()
|
|
34066
34612
|
};
|
|
34067
34613
|
}
|
|
34068
34614
|
function parseMessageTime(value) {
|
|
@@ -34303,42 +34849,42 @@ function buildStatusSnapshot(options) {
|
|
|
34303
34849
|
// src/commands/upgrade-helper.ts
|
|
34304
34850
|
var import_child_process7 = require("child_process");
|
|
34305
34851
|
var import_child_process8 = require("child_process");
|
|
34306
|
-
var
|
|
34307
|
-
var
|
|
34308
|
-
var
|
|
34852
|
+
var fs21 = __toESM(require("fs"));
|
|
34853
|
+
var os26 = __toESM(require("os"));
|
|
34854
|
+
var path34 = __toESM(require("path"));
|
|
34309
34855
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
34310
34856
|
function getUpgradeLogPath() {
|
|
34311
|
-
const home =
|
|
34312
|
-
const dir =
|
|
34313
|
-
|
|
34314
|
-
return
|
|
34857
|
+
const home = os26.homedir();
|
|
34858
|
+
const dir = path34.join(home, ".adhdev");
|
|
34859
|
+
fs21.mkdirSync(dir, { recursive: true });
|
|
34860
|
+
return path34.join(dir, "daemon-upgrade.log");
|
|
34315
34861
|
}
|
|
34316
34862
|
function appendUpgradeLog(message) {
|
|
34317
34863
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
|
|
34318
34864
|
`;
|
|
34319
34865
|
try {
|
|
34320
|
-
|
|
34866
|
+
fs21.appendFileSync(getUpgradeLogPath(), line, "utf8");
|
|
34321
34867
|
} catch {
|
|
34322
34868
|
}
|
|
34323
34869
|
}
|
|
34324
34870
|
function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platform) {
|
|
34325
|
-
const binDir =
|
|
34871
|
+
const binDir = path34.dirname(nodeExecutable);
|
|
34326
34872
|
if (platform10 === "win32") {
|
|
34327
|
-
const npmCliPath =
|
|
34328
|
-
if (
|
|
34873
|
+
const npmCliPath = path34.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
|
|
34874
|
+
if (fs21.existsSync(npmCliPath)) {
|
|
34329
34875
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
34330
34876
|
}
|
|
34331
34877
|
for (const candidate of ["npm.exe", "npm"]) {
|
|
34332
|
-
const candidatePath =
|
|
34333
|
-
if (
|
|
34878
|
+
const candidatePath = path34.join(binDir, candidate);
|
|
34879
|
+
if (fs21.existsSync(candidatePath)) {
|
|
34334
34880
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
34335
34881
|
}
|
|
34336
34882
|
}
|
|
34337
34883
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
34338
34884
|
}
|
|
34339
34885
|
for (const candidate of ["npm"]) {
|
|
34340
|
-
const candidatePath =
|
|
34341
|
-
if (
|
|
34886
|
+
const candidatePath = path34.join(binDir, candidate);
|
|
34887
|
+
if (fs21.existsSync(candidatePath)) {
|
|
34342
34888
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
34343
34889
|
}
|
|
34344
34890
|
}
|
|
@@ -34348,22 +34894,22 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
34348
34894
|
if (!currentCliPath) return null;
|
|
34349
34895
|
let resolvedPath = currentCliPath;
|
|
34350
34896
|
try {
|
|
34351
|
-
resolvedPath =
|
|
34897
|
+
resolvedPath = fs21.realpathSync.native(currentCliPath);
|
|
34352
34898
|
} catch {
|
|
34353
34899
|
}
|
|
34354
34900
|
let currentDir = resolvedPath;
|
|
34355
34901
|
try {
|
|
34356
|
-
if (
|
|
34357
|
-
currentDir =
|
|
34902
|
+
if (fs21.statSync(resolvedPath).isFile()) {
|
|
34903
|
+
currentDir = path34.dirname(resolvedPath);
|
|
34358
34904
|
}
|
|
34359
34905
|
} catch {
|
|
34360
|
-
currentDir =
|
|
34906
|
+
currentDir = path34.dirname(resolvedPath);
|
|
34361
34907
|
}
|
|
34362
34908
|
while (true) {
|
|
34363
|
-
const packageJsonPath =
|
|
34909
|
+
const packageJsonPath = path34.join(currentDir, "package.json");
|
|
34364
34910
|
try {
|
|
34365
|
-
if (
|
|
34366
|
-
const parsed = JSON.parse(
|
|
34911
|
+
if (fs21.existsSync(packageJsonPath)) {
|
|
34912
|
+
const parsed = JSON.parse(fs21.readFileSync(packageJsonPath, "utf8"));
|
|
34367
34913
|
if (parsed?.name === packageName) {
|
|
34368
34914
|
const normalized = currentDir.replace(/\\/g, "/");
|
|
34369
34915
|
return normalized.includes("/node_modules/") ? currentDir : null;
|
|
@@ -34371,7 +34917,7 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
34371
34917
|
}
|
|
34372
34918
|
} catch {
|
|
34373
34919
|
}
|
|
34374
|
-
const parentDir =
|
|
34920
|
+
const parentDir = path34.dirname(currentDir);
|
|
34375
34921
|
if (parentDir === currentDir) {
|
|
34376
34922
|
return null;
|
|
34377
34923
|
}
|
|
@@ -34379,13 +34925,13 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
34379
34925
|
}
|
|
34380
34926
|
}
|
|
34381
34927
|
function resolveInstallPrefixFromPackageRoot(packageRoot, packageName) {
|
|
34382
|
-
const nodeModulesDir = packageName.startsWith("@") ?
|
|
34383
|
-
if (
|
|
34928
|
+
const nodeModulesDir = packageName.startsWith("@") ? path34.dirname(path34.dirname(packageRoot)) : path34.dirname(packageRoot);
|
|
34929
|
+
if (path34.basename(nodeModulesDir) !== "node_modules") {
|
|
34384
34930
|
return null;
|
|
34385
34931
|
}
|
|
34386
|
-
const maybeLibDir =
|
|
34387
|
-
if (
|
|
34388
|
-
return
|
|
34932
|
+
const maybeLibDir = path34.dirname(nodeModulesDir);
|
|
34933
|
+
if (path34.basename(maybeLibDir) === "lib") {
|
|
34934
|
+
return path34.dirname(maybeLibDir);
|
|
34389
34935
|
}
|
|
34390
34936
|
return maybeLibDir;
|
|
34391
34937
|
}
|
|
@@ -34500,10 +35046,10 @@ async function waitForPidExit(pid, timeoutMs) {
|
|
|
34500
35046
|
}
|
|
34501
35047
|
}
|
|
34502
35048
|
function stopSessionHostProcesses(appName) {
|
|
34503
|
-
const pidFile =
|
|
35049
|
+
const pidFile = path34.join(os26.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
34504
35050
|
try {
|
|
34505
|
-
if (
|
|
34506
|
-
const pid = Number.parseInt(
|
|
35051
|
+
if (fs21.existsSync(pidFile)) {
|
|
35052
|
+
const pid = Number.parseInt(fs21.readFileSync(pidFile, "utf8").trim(), 10);
|
|
34507
35053
|
if (Number.isFinite(pid) && pid !== process.pid && isManagedSessionHostPid(pid)) {
|
|
34508
35054
|
killPid(pid);
|
|
34509
35055
|
}
|
|
@@ -34511,15 +35057,15 @@ function stopSessionHostProcesses(appName) {
|
|
|
34511
35057
|
} catch {
|
|
34512
35058
|
} finally {
|
|
34513
35059
|
try {
|
|
34514
|
-
|
|
35060
|
+
fs21.unlinkSync(pidFile);
|
|
34515
35061
|
} catch {
|
|
34516
35062
|
}
|
|
34517
35063
|
}
|
|
34518
35064
|
}
|
|
34519
35065
|
function removeDaemonPidFile() {
|
|
34520
|
-
const pidFile =
|
|
35066
|
+
const pidFile = path34.join(os26.homedir(), ".adhdev", "daemon.pid");
|
|
34521
35067
|
try {
|
|
34522
|
-
|
|
35068
|
+
fs21.unlinkSync(pidFile);
|
|
34523
35069
|
} catch {
|
|
34524
35070
|
}
|
|
34525
35071
|
}
|
|
@@ -34528,7 +35074,7 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
34528
35074
|
const npmRoot = String(execNpmCommandSync(["root", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
34529
35075
|
if (!npmRoot) return;
|
|
34530
35076
|
const npmPrefix = surface.installPrefix || String(execNpmCommandSync(["prefix", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
34531
|
-
const binDir = process.platform === "win32" ? npmPrefix :
|
|
35077
|
+
const binDir = process.platform === "win32" ? npmPrefix : path34.join(npmPrefix, "bin");
|
|
34532
35078
|
const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
|
|
34533
35079
|
const binNames = /* @__PURE__ */ new Set([packageBaseName]);
|
|
34534
35080
|
if (pkgName === "@adhdev/daemon-standalone") {
|
|
@@ -34536,25 +35082,25 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
34536
35082
|
}
|
|
34537
35083
|
if (pkgName.startsWith("@")) {
|
|
34538
35084
|
const [scope, name] = pkgName.split("/");
|
|
34539
|
-
const scopeDir =
|
|
34540
|
-
if (!
|
|
34541
|
-
for (const entry of
|
|
35085
|
+
const scopeDir = path34.join(npmRoot, scope);
|
|
35086
|
+
if (!fs21.existsSync(scopeDir)) return;
|
|
35087
|
+
for (const entry of fs21.readdirSync(scopeDir)) {
|
|
34542
35088
|
if (!entry.startsWith(`.${name}-`)) continue;
|
|
34543
|
-
|
|
34544
|
-
appendUpgradeLog(`Removed stale scoped staging dir: ${
|
|
35089
|
+
fs21.rmSync(path34.join(scopeDir, entry), { recursive: true, force: true });
|
|
35090
|
+
appendUpgradeLog(`Removed stale scoped staging dir: ${path34.join(scopeDir, entry)}`);
|
|
34545
35091
|
}
|
|
34546
35092
|
} else {
|
|
34547
|
-
for (const entry of
|
|
35093
|
+
for (const entry of fs21.readdirSync(npmRoot)) {
|
|
34548
35094
|
if (!entry.startsWith(`.${pkgName}-`)) continue;
|
|
34549
|
-
|
|
34550
|
-
appendUpgradeLog(`Removed stale staging dir: ${
|
|
35095
|
+
fs21.rmSync(path34.join(npmRoot, entry), { recursive: true, force: true });
|
|
35096
|
+
appendUpgradeLog(`Removed stale staging dir: ${path34.join(npmRoot, entry)}`);
|
|
34551
35097
|
}
|
|
34552
35098
|
}
|
|
34553
|
-
if (
|
|
34554
|
-
for (const entry of
|
|
35099
|
+
if (fs21.existsSync(binDir)) {
|
|
35100
|
+
for (const entry of fs21.readdirSync(binDir)) {
|
|
34555
35101
|
if (!Array.from(binNames).some((name) => entry.startsWith(`.${name}-`))) continue;
|
|
34556
|
-
|
|
34557
|
-
appendUpgradeLog(`Removed stale bin staging entry: ${
|
|
35102
|
+
fs21.rmSync(path34.join(binDir, entry), { recursive: true, force: true });
|
|
35103
|
+
appendUpgradeLog(`Removed stale bin staging entry: ${path34.join(binDir, entry)}`);
|
|
34558
35104
|
}
|
|
34559
35105
|
}
|
|
34560
35106
|
}
|
|
@@ -34642,7 +35188,7 @@ async function maybeRunDaemonUpgradeHelperFromEnv() {
|
|
|
34642
35188
|
init_mesh_work_queue();
|
|
34643
35189
|
var import_os3 = require("os");
|
|
34644
35190
|
var import_path10 = require("path");
|
|
34645
|
-
var
|
|
35191
|
+
var fs22 = __toESM(require("fs"));
|
|
34646
35192
|
var import_node_child_process5 = require("child_process");
|
|
34647
35193
|
var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
|
|
34648
35194
|
var CHANNEL_SERVER_URL = {
|
|
@@ -34769,12 +35315,12 @@ function readGitSubmodules(value, parentRepoRoot) {
|
|
|
34769
35315
|
if (!Array.isArray(value)) return void 0;
|
|
34770
35316
|
const submodules = value.map((entry) => {
|
|
34771
35317
|
const submodule = readObjectRecord(entry);
|
|
34772
|
-
const
|
|
35318
|
+
const path40 = readStringValue(submodule.path);
|
|
34773
35319
|
const commit = readStringValue(submodule.commit);
|
|
34774
|
-
const repoPath = readStringValue(submodule.repoPath, submodule.repo_root) ?? joinRepoPath(parentRepoRoot,
|
|
34775
|
-
if (!
|
|
35320
|
+
const repoPath = readStringValue(submodule.repoPath, submodule.repo_root) ?? joinRepoPath(parentRepoRoot, path40);
|
|
35321
|
+
if (!path40 || !commit || !repoPath) return null;
|
|
34776
35322
|
return {
|
|
34777
|
-
path:
|
|
35323
|
+
path: path40,
|
|
34778
35324
|
commit,
|
|
34779
35325
|
repoPath,
|
|
34780
35326
|
dirty: readBooleanValue(submodule.dirty) ?? false,
|
|
@@ -35416,7 +35962,7 @@ async function hydrateInlineMeshDirectTruth(args) {
|
|
|
35416
35962
|
if (!isSelfNode && daemonId) unavailableNodeIds.push(nodeId);
|
|
35417
35963
|
continue;
|
|
35418
35964
|
}
|
|
35419
|
-
if (
|
|
35965
|
+
if (fs22.existsSync(workspace)) {
|
|
35420
35966
|
try {
|
|
35421
35967
|
const localGit = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
|
|
35422
35968
|
if (localGit?.isGitRepo) {
|
|
@@ -35501,7 +36047,7 @@ function readLiveMeshNodeWorkspace(args) {
|
|
|
35501
36047
|
}
|
|
35502
36048
|
function collectLiveMeshSessionRecords(args) {
|
|
35503
36049
|
const nodeWorkspace = readStringValue(args.node?.workspace);
|
|
35504
|
-
const nodeIsMissingLocalWorktree = args.node?.isLocalWorktree === true && !!nodeWorkspace && !
|
|
36050
|
+
const nodeIsMissingLocalWorktree = args.node?.isLocalWorktree === true && !!nodeWorkspace && !fs22.existsSync(nodeWorkspace);
|
|
35505
36051
|
const matches = args.liveSessionRecords.filter((record) => {
|
|
35506
36052
|
const recordNodeId = readStringValue(record?.meta?.meshNodeId);
|
|
35507
36053
|
if (recordNodeId && recordNodeId !== args.nodeId) return false;
|
|
@@ -35528,7 +36074,7 @@ function buildHistoricalMeshSessions(args) {
|
|
|
35528
36074
|
const workspace = readStringValue(node?.workspace);
|
|
35529
36075
|
if (nodeId) liveNodeIds.add(nodeId);
|
|
35530
36076
|
if (workspace) liveWorkspaces.add(workspace);
|
|
35531
|
-
if (nodeId && node?.isLocalWorktree === true && workspace && !
|
|
36077
|
+
if (nodeId && node?.isLocalWorktree === true && workspace && !fs22.existsSync(workspace)) {
|
|
35532
36078
|
missingLocalWorktreeNodeIds.add(nodeId);
|
|
35533
36079
|
}
|
|
35534
36080
|
}
|
|
@@ -35727,10 +36273,10 @@ ${e?.stderr || ""}`
|
|
|
35727
36273
|
}
|
|
35728
36274
|
function buildPatchEquivalenceSubmoduleConflictHint(repoRoot, baseHead, branchHead, output) {
|
|
35729
36275
|
if (!/(submodule|160000)/i.test(output) || !/(conflict|failed to merge)/i.test(output)) return void 0;
|
|
35730
|
-
const conflicts = readChangedGitlinkPaths(repoRoot, baseHead, branchHead).map((
|
|
35731
|
-
path:
|
|
35732
|
-
baseCommit: readTreeObject(repoRoot, baseHead,
|
|
35733
|
-
branchCommit: readTreeObject(repoRoot, branchHead,
|
|
36276
|
+
const conflicts = readChangedGitlinkPaths(repoRoot, baseHead, branchHead).map((path40) => ({
|
|
36277
|
+
path: path40,
|
|
36278
|
+
baseCommit: readTreeObject(repoRoot, baseHead, path40),
|
|
36279
|
+
branchCommit: readTreeObject(repoRoot, branchHead, path40)
|
|
35734
36280
|
}));
|
|
35735
36281
|
if (conflicts.length === 0) return void 0;
|
|
35736
36282
|
return {
|
|
@@ -35756,11 +36302,11 @@ function readChangedGitlinkPaths(repoRoot, fromRef, toRef) {
|
|
|
35756
36302
|
if (!line.trim()) continue;
|
|
35757
36303
|
const metaAndPath = line.split(" ");
|
|
35758
36304
|
const meta = metaAndPath[0] || "";
|
|
35759
|
-
const
|
|
35760
|
-
if (!
|
|
36305
|
+
const path40 = metaAndPath[metaAndPath.length - 1]?.trim();
|
|
36306
|
+
if (!path40) continue;
|
|
35761
36307
|
const parts = meta.split(/\s+/);
|
|
35762
36308
|
if (parts[0]?.includes("160000") || parts[1]?.includes("160000")) {
|
|
35763
|
-
paths.add(
|
|
36309
|
+
paths.add(path40);
|
|
35764
36310
|
}
|
|
35765
36311
|
}
|
|
35766
36312
|
return [...paths].sort();
|
|
@@ -35768,9 +36314,9 @@ function readChangedGitlinkPaths(repoRoot, fromRef, toRef) {
|
|
|
35768
36314
|
return [];
|
|
35769
36315
|
}
|
|
35770
36316
|
}
|
|
35771
|
-
function readTreeObject(repoRoot, ref,
|
|
36317
|
+
function readTreeObject(repoRoot, ref, path40) {
|
|
35772
36318
|
try {
|
|
35773
|
-
const output = (0, import_node_child_process5.execFileSync)("git", ["ls-tree", ref, "--",
|
|
36319
|
+
const output = (0, import_node_child_process5.execFileSync)("git", ["ls-tree", ref, "--", path40], {
|
|
35774
36320
|
cwd: repoRoot,
|
|
35775
36321
|
encoding: "utf8",
|
|
35776
36322
|
maxBuffer: 1024 * 1024
|
|
@@ -35783,7 +36329,7 @@ function readTreeObject(repoRoot, ref, path39) {
|
|
|
35783
36329
|
}
|
|
35784
36330
|
async function alignRefinerySubmodulesAfterMerge(repoRoot, previousBaseHead, currentHead, options = {}) {
|
|
35785
36331
|
const startedAt = Date.now();
|
|
35786
|
-
const changedGitlinkPaths = readChangedGitlinkPaths(repoRoot, previousBaseHead, currentHead).filter((
|
|
36332
|
+
const changedGitlinkPaths = readChangedGitlinkPaths(repoRoot, previousBaseHead, currentHead).filter((path40) => !(options.submoduleIgnorePaths || []).includes(path40));
|
|
35787
36333
|
const preStatus = await getGitRepoStatus(repoRoot, {
|
|
35788
36334
|
includeSubmodules: true,
|
|
35789
36335
|
submoduleIgnorePaths: options.submoduleIgnorePaths,
|
|
@@ -35824,7 +36370,7 @@ async function alignRefinerySubmodulesAfterMerge(repoRoot, previousBaseHead, cur
|
|
|
35824
36370
|
changedGitlinkPaths,
|
|
35825
36371
|
outOfSyncPaths,
|
|
35826
36372
|
updatedPaths: updatePaths,
|
|
35827
|
-
verifiedPaths: updatePaths.filter((
|
|
36373
|
+
verifiedPaths: updatePaths.filter((path40) => !remaining.some((submodule) => submodule.path === path40)),
|
|
35828
36374
|
durationMs: Date.now() - startedAt,
|
|
35829
36375
|
command: `git ${commandArgs.join(" ")}`,
|
|
35830
36376
|
stdout: truncateValidationOutput(result.stdout),
|
|
@@ -35879,7 +36425,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
35879
36425
|
return { stdout: String(stdout || ""), stderr: String(stderr || ""), refspec };
|
|
35880
36426
|
};
|
|
35881
36427
|
const importCommitFromWorktreeSubmodule = async (submodulePath, worktreeSubmodulePath, commit) => {
|
|
35882
|
-
if (!
|
|
36428
|
+
if (!fs22.existsSync(worktreeSubmodulePath)) return false;
|
|
35883
36429
|
try {
|
|
35884
36430
|
await runGit3(worktreeSubmodulePath, ["cat-file", "-e", `${commit}^{commit}`]);
|
|
35885
36431
|
} catch {
|
|
@@ -35902,7 +36448,7 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
35902
36448
|
reachable: false
|
|
35903
36449
|
};
|
|
35904
36450
|
try {
|
|
35905
|
-
if (!
|
|
36451
|
+
if (!fs22.existsSync(submodulePath)) {
|
|
35906
36452
|
entry.error = `Submodule checkout missing at ${gitlink.path}`;
|
|
35907
36453
|
entry.publishRequired = true;
|
|
35908
36454
|
if (options.allowAutoPublishSubmoduleMainCommits === true) {
|
|
@@ -36094,9 +36640,9 @@ async function runMeshRefineValidationGate(mesh, workspace) {
|
|
|
36094
36640
|
return ["npm", "pnpm", "yarn", "bun"].includes(command) && candidate.args.some((arg) => arg === "run" || arg === "test" || arg === "exec");
|
|
36095
36641
|
};
|
|
36096
36642
|
const dependenciesLikelyMissing = (cwd) => {
|
|
36097
|
-
if (!
|
|
36098
|
-
if (
|
|
36099
|
-
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) =>
|
|
36643
|
+
if (!fs22.existsSync((0, import_path10.join)(cwd, "package.json"))) return false;
|
|
36644
|
+
if (fs22.existsSync((0, import_path10.join)(cwd, "node_modules"))) return false;
|
|
36645
|
+
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) => fs22.existsSync((0, import_path10.join)(cwd, lock)));
|
|
36100
36646
|
};
|
|
36101
36647
|
for (const candidate of selection.bootstrapCommands) {
|
|
36102
36648
|
const startedAt = Date.now();
|
|
@@ -36193,9 +36739,9 @@ function resolveHermesUserHome() {
|
|
|
36193
36739
|
function loadHermesCoordinatorBaseConfig(targetConfigPath) {
|
|
36194
36740
|
const sourceHome = resolveHermesUserHome();
|
|
36195
36741
|
const sourceConfigPath = (0, import_path10.join)(sourceHome, "config.yaml");
|
|
36196
|
-
if (!
|
|
36742
|
+
if (!fs22.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
36197
36743
|
if ((0, import_path10.resolve)(sourceConfigPath) === (0, import_path10.resolve)(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
36198
|
-
const parsed = parseMeshCoordinatorMcpConfig(
|
|
36744
|
+
const parsed = parseMeshCoordinatorMcpConfig(fs22.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
|
|
36199
36745
|
const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
|
|
36200
36746
|
return { config: baseConfig, sourceHome, sourceConfigPath };
|
|
36201
36747
|
}
|
|
@@ -36232,9 +36778,9 @@ function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
|
|
|
36232
36778
|
for (const fileName of [".env", "auth.json"]) {
|
|
36233
36779
|
const sourcePath = (0, import_path10.join)(sourceHome, fileName);
|
|
36234
36780
|
const targetPath = (0, import_path10.join)(targetHome, fileName);
|
|
36235
|
-
if (!
|
|
36781
|
+
if (!fs22.existsSync(sourcePath)) continue;
|
|
36236
36782
|
try {
|
|
36237
|
-
|
|
36783
|
+
fs22.copyFileSync(sourcePath, targetPath);
|
|
36238
36784
|
} catch (error) {
|
|
36239
36785
|
LOG.warn("MeshCoordinator", `Could not copy Hermes ${fileName} into isolated coordinator home: ${error?.message || error}`);
|
|
36240
36786
|
}
|
|
@@ -36589,13 +37135,13 @@ var DaemonCommandRouter = class {
|
|
|
36589
37135
|
recoveryHint: "Inspect the mesh node record before removing it, or remove stale metadata manually only after confirming no managed worktree remains."
|
|
36590
37136
|
};
|
|
36591
37137
|
}
|
|
36592
|
-
const worktreeExists =
|
|
37138
|
+
const worktreeExists = fs22.existsSync(workspace);
|
|
36593
37139
|
const sourceNode = args.node?.clonedFromNodeId ? args.mesh?.nodes?.find((n) => n.id === args.node.clonedFromNodeId || n.nodeId === args.node.clonedFromNodeId) : args.mesh?.nodes?.find((n) => !n.isLocalWorktree);
|
|
36594
37140
|
const repoRoot = typeof sourceNode?.repoRoot === "string" && sourceNode.repoRoot.trim() ? sourceNode.repoRoot.trim() : typeof sourceNode?.workspace === "string" && sourceNode.workspace.trim() ? sourceNode.workspace.trim() : "";
|
|
36595
37141
|
if (!worktreeExists) {
|
|
36596
37142
|
return { success: true, skipped: true, removedPath: workspace, repoRoot: repoRoot || void 0, reason: "worktree_path_missing" };
|
|
36597
37143
|
}
|
|
36598
|
-
if (!repoRoot || !
|
|
37144
|
+
if (!repoRoot || !fs22.existsSync(repoRoot)) {
|
|
36599
37145
|
return {
|
|
36600
37146
|
success: false,
|
|
36601
37147
|
code: "mesh_worktree_cleanup_missing_source_repo",
|
|
@@ -36615,7 +37161,7 @@ var DaemonCommandRouter = class {
|
|
|
36615
37161
|
const normalizePath = (value) => {
|
|
36616
37162
|
const resolved = (0, import_path10.resolve)(value);
|
|
36617
37163
|
try {
|
|
36618
|
-
return
|
|
37164
|
+
return fs22.realpathSync(resolved);
|
|
36619
37165
|
} catch {
|
|
36620
37166
|
return resolved;
|
|
36621
37167
|
}
|
|
@@ -37554,8 +38100,8 @@ var DaemonCommandRouter = class {
|
|
|
37554
38100
|
if (sinceTs > 0) {
|
|
37555
38101
|
return { success: true, logs: [], totalBuffered: 0 };
|
|
37556
38102
|
}
|
|
37557
|
-
if (
|
|
37558
|
-
const content =
|
|
38103
|
+
if (fs22.existsSync(LOG_PATH)) {
|
|
38104
|
+
const content = fs22.readFileSync(LOG_PATH, "utf-8");
|
|
37559
38105
|
const allLines = content.split("\n");
|
|
37560
38106
|
const recent = allLines.slice(-count).join("\n");
|
|
37561
38107
|
return { success: true, logs: recent, totalLines: allLines.length };
|
|
@@ -37945,24 +38491,24 @@ var DaemonCommandRouter = class {
|
|
|
37945
38491
|
// Settings page in the dashboard reads/writes via these two
|
|
37946
38492
|
// commands instead of going through fs from the browser.
|
|
37947
38493
|
case "list_coordinator_prompts": {
|
|
37948
|
-
const
|
|
37949
|
-
const
|
|
37950
|
-
const
|
|
37951
|
-
const dir =
|
|
38494
|
+
const fs28 = await import("fs");
|
|
38495
|
+
const path40 = await import("path");
|
|
38496
|
+
const os29 = await import("os");
|
|
38497
|
+
const dir = path40.join(os29.homedir(), ".adhdev", "coordinator-prompts");
|
|
37952
38498
|
const entries = {};
|
|
37953
38499
|
try {
|
|
37954
|
-
if (
|
|
37955
|
-
for (const name of
|
|
38500
|
+
if (fs28.existsSync(dir)) {
|
|
38501
|
+
for (const name of fs28.readdirSync(dir)) {
|
|
37956
38502
|
const matchOverride = name.match(/^([a-zA-Z0-9_.-]+)\.md$/);
|
|
37957
38503
|
const matchAppend = name.match(/^([a-zA-Z0-9_.-]+)\.append\.md$/);
|
|
37958
38504
|
const m = matchAppend || matchOverride;
|
|
37959
38505
|
if (!m) continue;
|
|
37960
38506
|
const isAppend = !!matchAppend;
|
|
37961
38507
|
const key = m[1];
|
|
37962
|
-
const full =
|
|
38508
|
+
const full = path40.join(dir, name);
|
|
37963
38509
|
let content = "";
|
|
37964
38510
|
try {
|
|
37965
|
-
content =
|
|
38511
|
+
content = fs28.readFileSync(full, "utf8");
|
|
37966
38512
|
} catch {
|
|
37967
38513
|
}
|
|
37968
38514
|
if (!entries[key]) entries[key] = { override: "", append: "" };
|
|
@@ -37976,24 +38522,24 @@ var DaemonCommandRouter = class {
|
|
|
37976
38522
|
return { success: true, dir, entries };
|
|
37977
38523
|
}
|
|
37978
38524
|
case "write_coordinator_prompt": {
|
|
37979
|
-
const
|
|
37980
|
-
const
|
|
37981
|
-
const
|
|
38525
|
+
const fs28 = await import("fs");
|
|
38526
|
+
const path40 = await import("path");
|
|
38527
|
+
const os29 = await import("os");
|
|
37982
38528
|
const key = typeof args?.key === "string" ? args.key.trim() : "";
|
|
37983
38529
|
const kind = args?.kind === "append" ? "append" : "override";
|
|
37984
38530
|
const content = typeof args?.content === "string" ? args.content : "";
|
|
37985
38531
|
if (!key || !/^[a-zA-Z0-9_.-]+$/.test(key)) {
|
|
37986
38532
|
return { success: false, error: "key must match [a-zA-Z0-9_.-]+" };
|
|
37987
38533
|
}
|
|
37988
|
-
const dir =
|
|
38534
|
+
const dir = path40.join(os29.homedir(), ".adhdev", "coordinator-prompts");
|
|
37989
38535
|
const filename = kind === "append" ? `${key}.append.md` : `${key}.md`;
|
|
37990
|
-
const full =
|
|
38536
|
+
const full = path40.join(dir, filename);
|
|
37991
38537
|
try {
|
|
37992
|
-
|
|
38538
|
+
fs28.mkdirSync(dir, { recursive: true });
|
|
37993
38539
|
if (content.trim()) {
|
|
37994
|
-
|
|
37995
|
-
} else if (
|
|
37996
|
-
|
|
38540
|
+
fs28.writeFileSync(full, content, { encoding: "utf8", mode: 384 });
|
|
38541
|
+
} else if (fs28.existsSync(full)) {
|
|
38542
|
+
fs28.unlinkSync(full);
|
|
37997
38543
|
}
|
|
37998
38544
|
return { success: true, path: full, kind, key };
|
|
37999
38545
|
} catch (error) {
|
|
@@ -39202,7 +39748,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
39202
39748
|
workspace
|
|
39203
39749
|
};
|
|
39204
39750
|
}
|
|
39205
|
-
const { existsSync:
|
|
39751
|
+
const { existsSync: existsSync39, readFileSync: readFileSync33, writeFileSync: writeFileSync20, copyFileSync: copyFileSync4, mkdirSync: mkdirSync19 } = await import("fs");
|
|
39206
39752
|
const { dirname: dirname11 } = await import("path");
|
|
39207
39753
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
39208
39754
|
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
@@ -39238,21 +39784,21 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
39238
39784
|
};
|
|
39239
39785
|
}
|
|
39240
39786
|
try {
|
|
39241
|
-
|
|
39787
|
+
mkdirSync19(dirname11(mcpConfigPath), { recursive: true });
|
|
39242
39788
|
} catch (error) {
|
|
39243
39789
|
const message = `Could not prepare MCP config path for automatic setup: ${error?.message || error}`;
|
|
39244
39790
|
LOG.error("MeshCoordinator", message);
|
|
39245
39791
|
if (hermesManualFallback) return returnManualFallback(message);
|
|
39246
39792
|
return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
|
|
39247
39793
|
}
|
|
39248
|
-
const hadExistingMcpConfig =
|
|
39794
|
+
const hadExistingMcpConfig = existsSync39(mcpConfigPath);
|
|
39249
39795
|
let existingMcpConfig = hermesBaseConfig?.config || {};
|
|
39250
39796
|
if (hermesBaseConfig) {
|
|
39251
39797
|
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname11(mcpConfigPath));
|
|
39252
39798
|
}
|
|
39253
39799
|
if (hadExistingMcpConfig) {
|
|
39254
39800
|
try {
|
|
39255
|
-
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(
|
|
39801
|
+
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync33(mcpConfigPath, "utf-8"), configFormat);
|
|
39256
39802
|
const existingCoordinatorConfig = hermesManualFallback ? stripHermesCoordinatorTempModelProviderOverrides(parsedExistingMcpConfig) : parsedExistingMcpConfig;
|
|
39257
39803
|
existingMcpConfig = { ...existingMcpConfig, ...existingCoordinatorConfig };
|
|
39258
39804
|
copyFileSync4(mcpConfigPath, mcpConfigPath + ".backup");
|
|
@@ -39275,7 +39821,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
39275
39821
|
}
|
|
39276
39822
|
};
|
|
39277
39823
|
try {
|
|
39278
|
-
|
|
39824
|
+
writeFileSync20(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
|
|
39279
39825
|
} catch (error) {
|
|
39280
39826
|
const message = `Could not write MCP config for automatic setup: ${error?.message || error}`;
|
|
39281
39827
|
LOG.error("MeshCoordinator", message);
|
|
@@ -39554,7 +40100,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
39554
40100
|
}
|
|
39555
40101
|
}
|
|
39556
40102
|
if (workspace) {
|
|
39557
|
-
if (!
|
|
40103
|
+
if (!fs22.existsSync(workspace)) {
|
|
39558
40104
|
const inlineTransitGit = buildInlineMeshTransitGitStatus(node);
|
|
39559
40105
|
let remoteProbeApplied = false;
|
|
39560
40106
|
if (inlineTransitGit) {
|
|
@@ -39667,7 +40213,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
39667
40213
|
const callerCoordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : this.deps.statusInstanceId || void 0;
|
|
39668
40214
|
const pendingCoordinatorEvents = drainPendingMeshCoordinatorEvents(meshId, callerCoordinatorDaemonId);
|
|
39669
40215
|
const previewFreshness = (() => {
|
|
39670
|
-
const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate &&
|
|
40216
|
+
const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate && fs22.existsSync(candidate));
|
|
39671
40217
|
return localRepoRoot ? buildPreviewFreshness(localRepoRoot) : void 0;
|
|
39672
40218
|
})();
|
|
39673
40219
|
const asyncRefineJobs = buildMeshAsyncRefineJobs({
|
|
@@ -41414,12 +41960,12 @@ var ProviderInstanceManager = class {
|
|
|
41414
41960
|
};
|
|
41415
41961
|
|
|
41416
41962
|
// src/providers/version-archive.ts
|
|
41417
|
-
var
|
|
41418
|
-
var
|
|
41419
|
-
var
|
|
41963
|
+
var fs23 = __toESM(require("fs"));
|
|
41964
|
+
var path35 = __toESM(require("path"));
|
|
41965
|
+
var os27 = __toESM(require("os"));
|
|
41420
41966
|
var import_os4 = require("os");
|
|
41421
41967
|
var import_child_process9 = require("child_process");
|
|
41422
|
-
var ARCHIVE_PATH =
|
|
41968
|
+
var ARCHIVE_PATH = path35.join(os27.homedir(), ".adhdev", "version-history.json");
|
|
41423
41969
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
41424
41970
|
var VersionArchive = class {
|
|
41425
41971
|
history = {};
|
|
@@ -41428,8 +41974,8 @@ var VersionArchive = class {
|
|
|
41428
41974
|
}
|
|
41429
41975
|
load() {
|
|
41430
41976
|
try {
|
|
41431
|
-
if (
|
|
41432
|
-
this.history = JSON.parse(
|
|
41977
|
+
if (fs23.existsSync(ARCHIVE_PATH)) {
|
|
41978
|
+
this.history = JSON.parse(fs23.readFileSync(ARCHIVE_PATH, "utf-8"));
|
|
41433
41979
|
}
|
|
41434
41980
|
} catch {
|
|
41435
41981
|
this.history = {};
|
|
@@ -41466,8 +42012,8 @@ var VersionArchive = class {
|
|
|
41466
42012
|
}
|
|
41467
42013
|
save() {
|
|
41468
42014
|
try {
|
|
41469
|
-
|
|
41470
|
-
|
|
42015
|
+
fs23.mkdirSync(path35.dirname(ARCHIVE_PATH), { recursive: true });
|
|
42016
|
+
fs23.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
41471
42017
|
} catch {
|
|
41472
42018
|
}
|
|
41473
42019
|
}
|
|
@@ -41490,10 +42036,10 @@ function findBinary2(name) {
|
|
|
41490
42036
|
for (const p of paths) {
|
|
41491
42037
|
if (!p) continue;
|
|
41492
42038
|
for (const ext of exes) {
|
|
41493
|
-
const fullPath =
|
|
42039
|
+
const fullPath = path35.join(p, name + ext);
|
|
41494
42040
|
try {
|
|
41495
|
-
if (
|
|
41496
|
-
const stat2 =
|
|
42041
|
+
if (fs23.existsSync(fullPath)) {
|
|
42042
|
+
const stat2 = fs23.statSync(fullPath);
|
|
41497
42043
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
41498
42044
|
return fullPath;
|
|
41499
42045
|
}
|
|
@@ -41538,19 +42084,19 @@ async function getVersion(binary, versionCommand) {
|
|
|
41538
42084
|
function checkPathExists2(paths) {
|
|
41539
42085
|
for (const p of paths) {
|
|
41540
42086
|
if (p.includes("*")) {
|
|
41541
|
-
const home =
|
|
41542
|
-
const resolved = p.replace(/\*/g, home.split(
|
|
41543
|
-
if (
|
|
42087
|
+
const home = os27.homedir();
|
|
42088
|
+
const resolved = p.replace(/\*/g, home.split(path35.sep).pop() || "");
|
|
42089
|
+
if (fs23.existsSync(resolved)) return resolved;
|
|
41544
42090
|
} else {
|
|
41545
|
-
if (
|
|
42091
|
+
if (fs23.existsSync(p)) return p;
|
|
41546
42092
|
}
|
|
41547
42093
|
}
|
|
41548
42094
|
return null;
|
|
41549
42095
|
}
|
|
41550
42096
|
async function getMacAppVersion(appPath) {
|
|
41551
42097
|
if ((0, import_os4.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
41552
|
-
const plistPath =
|
|
41553
|
-
if (!
|
|
42098
|
+
const plistPath = path35.join(appPath, "Contents", "Info.plist");
|
|
42099
|
+
if (!fs23.existsSync(plistPath)) return null;
|
|
41554
42100
|
const raw = await runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
41555
42101
|
return raw || null;
|
|
41556
42102
|
}
|
|
@@ -41575,8 +42121,8 @@ async function detectAllVersions(loader, archive) {
|
|
|
41575
42121
|
const cliBin = provider.cli ? findBinary2(provider.cli) : null;
|
|
41576
42122
|
let resolvedBin = cliBin;
|
|
41577
42123
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
41578
|
-
const bundled =
|
|
41579
|
-
if (provider.cli &&
|
|
42124
|
+
const bundled = path35.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
42125
|
+
if (provider.cli && fs23.existsSync(bundled)) resolvedBin = bundled;
|
|
41580
42126
|
}
|
|
41581
42127
|
info.installed = !!(appPath || resolvedBin);
|
|
41582
42128
|
info.path = appPath || null;
|
|
@@ -41615,8 +42161,8 @@ async function detectAllVersions(loader, archive) {
|
|
|
41615
42161
|
|
|
41616
42162
|
// src/daemon/dev-server.ts
|
|
41617
42163
|
var http2 = __toESM(require("http"));
|
|
41618
|
-
var
|
|
41619
|
-
var
|
|
42164
|
+
var fs27 = __toESM(require("fs"));
|
|
42165
|
+
var path39 = __toESM(require("path"));
|
|
41620
42166
|
init_config();
|
|
41621
42167
|
|
|
41622
42168
|
// src/daemon/scaffold-template.ts
|
|
@@ -41966,8 +42512,8 @@ async (params) => {
|
|
|
41966
42512
|
init_logger();
|
|
41967
42513
|
|
|
41968
42514
|
// src/daemon/dev-cdp-handlers.ts
|
|
41969
|
-
var
|
|
41970
|
-
var
|
|
42515
|
+
var fs24 = __toESM(require("fs"));
|
|
42516
|
+
var path36 = __toESM(require("path"));
|
|
41971
42517
|
init_logger();
|
|
41972
42518
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
41973
42519
|
const body = await ctx.readBody(req);
|
|
@@ -42146,18 +42692,18 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
42146
42692
|
return;
|
|
42147
42693
|
}
|
|
42148
42694
|
let scriptsPath = "";
|
|
42149
|
-
const directScripts =
|
|
42150
|
-
if (
|
|
42695
|
+
const directScripts = path36.join(dir, "scripts.js");
|
|
42696
|
+
if (fs24.existsSync(directScripts)) {
|
|
42151
42697
|
scriptsPath = directScripts;
|
|
42152
42698
|
} else {
|
|
42153
|
-
const scriptsDir =
|
|
42154
|
-
if (
|
|
42155
|
-
const versions =
|
|
42156
|
-
return
|
|
42699
|
+
const scriptsDir = path36.join(dir, "scripts");
|
|
42700
|
+
if (fs24.existsSync(scriptsDir)) {
|
|
42701
|
+
const versions = fs24.readdirSync(scriptsDir).filter((d) => {
|
|
42702
|
+
return fs24.statSync(path36.join(scriptsDir, d)).isDirectory();
|
|
42157
42703
|
}).sort().reverse();
|
|
42158
42704
|
for (const ver of versions) {
|
|
42159
|
-
const p =
|
|
42160
|
-
if (
|
|
42705
|
+
const p = path36.join(scriptsDir, ver, "scripts.js");
|
|
42706
|
+
if (fs24.existsSync(p)) {
|
|
42161
42707
|
scriptsPath = p;
|
|
42162
42708
|
break;
|
|
42163
42709
|
}
|
|
@@ -42169,7 +42715,7 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
42169
42715
|
return;
|
|
42170
42716
|
}
|
|
42171
42717
|
try {
|
|
42172
|
-
const source =
|
|
42718
|
+
const source = fs24.readFileSync(scriptsPath, "utf-8");
|
|
42173
42719
|
const hints = {};
|
|
42174
42720
|
const funcRegex = /module\.exports\.(\w+)\s*=\s*function\s+\w+\s*\(params\)/g;
|
|
42175
42721
|
let match;
|
|
@@ -42984,8 +43530,8 @@ async function handleDomContext(ctx, type, req, res) {
|
|
|
42984
43530
|
}
|
|
42985
43531
|
|
|
42986
43532
|
// src/daemon/dev-cli-debug.ts
|
|
42987
|
-
var
|
|
42988
|
-
var
|
|
43533
|
+
var fs25 = __toESM(require("fs"));
|
|
43534
|
+
var path37 = __toESM(require("path"));
|
|
42989
43535
|
function slugifyFixtureName(value) {
|
|
42990
43536
|
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
42991
43537
|
return normalized || `fixture-${Date.now()}`;
|
|
@@ -42995,15 +43541,15 @@ function getCliFixtureDir(ctx, type) {
|
|
|
42995
43541
|
if (!providerDir) {
|
|
42996
43542
|
throw new Error(`Provider directory not found for '${type}'`);
|
|
42997
43543
|
}
|
|
42998
|
-
return
|
|
43544
|
+
return path37.join(providerDir, "fixtures");
|
|
42999
43545
|
}
|
|
43000
43546
|
function readCliFixture(ctx, type, name) {
|
|
43001
43547
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
43002
|
-
const filePath =
|
|
43003
|
-
if (!
|
|
43548
|
+
const filePath = path37.join(fixtureDir, `${name}.json`);
|
|
43549
|
+
if (!fs25.existsSync(filePath)) {
|
|
43004
43550
|
throw new Error(`Fixture not found: ${filePath}`);
|
|
43005
43551
|
}
|
|
43006
|
-
return JSON.parse(
|
|
43552
|
+
return JSON.parse(fs25.readFileSync(filePath, "utf-8"));
|
|
43007
43553
|
}
|
|
43008
43554
|
function getExerciseTranscriptText(result) {
|
|
43009
43555
|
const parts = [];
|
|
@@ -43748,7 +44294,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
43748
44294
|
return;
|
|
43749
44295
|
}
|
|
43750
44296
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
43751
|
-
|
|
44297
|
+
fs25.mkdirSync(fixtureDir, { recursive: true });
|
|
43752
44298
|
const name = slugifyFixtureName(String(body?.name || `${type}-${Date.now()}`));
|
|
43753
44299
|
const result = await runCliExerciseInternal(ctx, { ...request, type });
|
|
43754
44300
|
const fixture = {
|
|
@@ -43775,8 +44321,8 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
43775
44321
|
},
|
|
43776
44322
|
notes: typeof body?.notes === "string" ? body.notes : void 0
|
|
43777
44323
|
};
|
|
43778
|
-
const filePath =
|
|
43779
|
-
|
|
44324
|
+
const filePath = path37.join(fixtureDir, `${name}.json`);
|
|
44325
|
+
fs25.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
|
|
43780
44326
|
ctx.json(res, 200, {
|
|
43781
44327
|
saved: true,
|
|
43782
44328
|
name,
|
|
@@ -43794,14 +44340,14 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
43794
44340
|
async function handleCliFixtureList(ctx, type, _req, res) {
|
|
43795
44341
|
try {
|
|
43796
44342
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
43797
|
-
if (!
|
|
44343
|
+
if (!fs25.existsSync(fixtureDir)) {
|
|
43798
44344
|
ctx.json(res, 200, { fixtures: [], count: 0 });
|
|
43799
44345
|
return;
|
|
43800
44346
|
}
|
|
43801
|
-
const fixtures =
|
|
43802
|
-
const fullPath =
|
|
44347
|
+
const fixtures = fs25.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
|
|
44348
|
+
const fullPath = path37.join(fixtureDir, file);
|
|
43803
44349
|
try {
|
|
43804
|
-
const raw = JSON.parse(
|
|
44350
|
+
const raw = JSON.parse(fs25.readFileSync(fullPath, "utf-8"));
|
|
43805
44351
|
return {
|
|
43806
44352
|
name: raw.name || file.replace(/\.json$/i, ""),
|
|
43807
44353
|
path: fullPath,
|
|
@@ -43934,9 +44480,9 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
43934
44480
|
}
|
|
43935
44481
|
|
|
43936
44482
|
// src/daemon/dev-auto-implement.ts
|
|
43937
|
-
var
|
|
43938
|
-
var
|
|
43939
|
-
var
|
|
44483
|
+
var fs26 = __toESM(require("fs"));
|
|
44484
|
+
var path38 = __toESM(require("path"));
|
|
44485
|
+
var os28 = __toESM(require("os"));
|
|
43940
44486
|
function getAutoImplPid(ctx) {
|
|
43941
44487
|
const pid = ctx.autoImplProcess?.pid;
|
|
43942
44488
|
return typeof pid === "number" && pid > 0 ? pid : null;
|
|
@@ -43982,38 +44528,38 @@ function resolveAutoImplReference(ctx, category, requestedReference, targetType)
|
|
|
43982
44528
|
return fallback?.type || null;
|
|
43983
44529
|
}
|
|
43984
44530
|
function getLatestScriptVersionDir(scriptsDir) {
|
|
43985
|
-
if (!
|
|
43986
|
-
const versions =
|
|
44531
|
+
if (!fs26.existsSync(scriptsDir)) return null;
|
|
44532
|
+
const versions = fs26.readdirSync(scriptsDir).filter((d) => {
|
|
43987
44533
|
try {
|
|
43988
|
-
return
|
|
44534
|
+
return fs26.statSync(path38.join(scriptsDir, d)).isDirectory();
|
|
43989
44535
|
} catch {
|
|
43990
44536
|
return false;
|
|
43991
44537
|
}
|
|
43992
44538
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
43993
44539
|
if (versions.length === 0) return null;
|
|
43994
|
-
return
|
|
44540
|
+
return path38.join(scriptsDir, versions[0]);
|
|
43995
44541
|
}
|
|
43996
44542
|
function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
43997
|
-
const canonicalUserDir =
|
|
43998
|
-
const desiredDir = requestedDir ?
|
|
43999
|
-
const upstreamRoot =
|
|
44000
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
44543
|
+
const canonicalUserDir = path38.resolve(ctx.providerLoader.getUserProviderDir(category, type));
|
|
44544
|
+
const desiredDir = requestedDir ? path38.resolve(requestedDir) : canonicalUserDir;
|
|
44545
|
+
const upstreamRoot = path38.resolve(ctx.providerLoader.getUpstreamDir());
|
|
44546
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path38.sep}`)) {
|
|
44001
44547
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
44002
44548
|
}
|
|
44003
|
-
if (
|
|
44549
|
+
if (path38.basename(desiredDir) !== type) {
|
|
44004
44550
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
44005
44551
|
}
|
|
44006
44552
|
const sourceDir = ctx.findProviderDir(type);
|
|
44007
44553
|
if (!sourceDir) {
|
|
44008
44554
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
44009
44555
|
}
|
|
44010
|
-
if (!
|
|
44011
|
-
|
|
44012
|
-
|
|
44556
|
+
if (!fs26.existsSync(desiredDir)) {
|
|
44557
|
+
fs26.mkdirSync(path38.dirname(desiredDir), { recursive: true });
|
|
44558
|
+
fs26.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
44013
44559
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
44014
44560
|
}
|
|
44015
|
-
const providerJson =
|
|
44016
|
-
if (!
|
|
44561
|
+
const providerJson = path38.join(desiredDir, "provider.json");
|
|
44562
|
+
if (!fs26.existsSync(providerJson)) {
|
|
44017
44563
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
44018
44564
|
}
|
|
44019
44565
|
return { dir: desiredDir };
|
|
@@ -44021,15 +44567,15 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
44021
44567
|
function loadAutoImplReferenceScripts(ctx, referenceType) {
|
|
44022
44568
|
if (!referenceType) return {};
|
|
44023
44569
|
const refDir = ctx.findProviderDir(referenceType);
|
|
44024
|
-
if (!refDir || !
|
|
44570
|
+
if (!refDir || !fs26.existsSync(refDir)) return {};
|
|
44025
44571
|
const referenceScripts = {};
|
|
44026
|
-
const scriptsDir =
|
|
44572
|
+
const scriptsDir = path38.join(refDir, "scripts");
|
|
44027
44573
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
44028
44574
|
if (!latestDir) return referenceScripts;
|
|
44029
|
-
for (const file of
|
|
44575
|
+
for (const file of fs26.readdirSync(latestDir)) {
|
|
44030
44576
|
if (!file.endsWith(".js")) continue;
|
|
44031
44577
|
try {
|
|
44032
|
-
referenceScripts[file] =
|
|
44578
|
+
referenceScripts[file] = fs26.readFileSync(path38.join(latestDir, file), "utf-8");
|
|
44033
44579
|
} catch {
|
|
44034
44580
|
}
|
|
44035
44581
|
}
|
|
@@ -44137,16 +44683,16 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
44137
44683
|
});
|
|
44138
44684
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
44139
44685
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
44140
|
-
const tmpDir =
|
|
44141
|
-
if (!
|
|
44142
|
-
const promptFile =
|
|
44143
|
-
|
|
44686
|
+
const tmpDir = path38.join(os28.tmpdir(), "adhdev-autoimpl");
|
|
44687
|
+
if (!fs26.existsSync(tmpDir)) fs26.mkdirSync(tmpDir, { recursive: true });
|
|
44688
|
+
const promptFile = path38.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
44689
|
+
fs26.writeFileSync(promptFile, prompt, "utf-8");
|
|
44144
44690
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
44145
44691
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
44146
44692
|
const spawn4 = agentProvider?.spawn;
|
|
44147
44693
|
if (!spawn4?.command) {
|
|
44148
44694
|
try {
|
|
44149
|
-
|
|
44695
|
+
fs26.unlinkSync(promptFile);
|
|
44150
44696
|
} catch {
|
|
44151
44697
|
}
|
|
44152
44698
|
ctx.json(res, 400, { error: `Agent '${agent}' has no spawn config. Select a CLI provider with a spawn configuration.` });
|
|
@@ -44248,7 +44794,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
44248
44794
|
} catch {
|
|
44249
44795
|
}
|
|
44250
44796
|
try {
|
|
44251
|
-
|
|
44797
|
+
fs26.unlinkSync(promptFile);
|
|
44252
44798
|
} catch {
|
|
44253
44799
|
}
|
|
44254
44800
|
ctx.log(`Auto-implement (ACP) ${success ? "completed" : "failed"}: ${type} (exit: ${code})`);
|
|
@@ -44292,7 +44838,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
44292
44838
|
const interactiveFlags = ["--yolo", "--interactive", "-i"];
|
|
44293
44839
|
const baseArgs = [...spawn4.args || []].filter((a) => !interactiveFlags.includes(a));
|
|
44294
44840
|
let shellCmd;
|
|
44295
|
-
const isWin =
|
|
44841
|
+
const isWin = os28.platform() === "win32";
|
|
44296
44842
|
const escapeArg = (a) => isWin ? `"${a.replace(/"/g, '""')}"` : `'${a.replace(/'/g, "'\\''")}'`;
|
|
44297
44843
|
const promptMode = autoImpl?.promptMode ?? "stdin";
|
|
44298
44844
|
const extraArgs = autoImpl?.extraArgs ?? [];
|
|
@@ -44331,7 +44877,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
44331
44877
|
try {
|
|
44332
44878
|
const pty = require("node-pty");
|
|
44333
44879
|
ctx.log(`Auto-implement spawn (PTY): ${shellCmd}`);
|
|
44334
|
-
const isWin2 =
|
|
44880
|
+
const isWin2 = os28.platform() === "win32";
|
|
44335
44881
|
child = pty.spawn(isWin2 ? "cmd.exe" : process.env.SHELL || "/bin/zsh", [isWin2 ? "/c" : "-c", shellCmd], {
|
|
44336
44882
|
name: "xterm-256color",
|
|
44337
44883
|
cols: 120,
|
|
@@ -44474,7 +45020,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
44474
45020
|
}
|
|
44475
45021
|
});
|
|
44476
45022
|
try {
|
|
44477
|
-
|
|
45023
|
+
fs26.unlinkSync(promptFile);
|
|
44478
45024
|
} catch {
|
|
44479
45025
|
}
|
|
44480
45026
|
ctx.log(`Auto-implement ${success ? "completed" : "failed"}: ${type} (exit: ${code})${verificationSummary ? ` verify=${verificationSummary.pass ? "pass" : "fail"}` : ""}`);
|
|
@@ -44571,7 +45117,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
44571
45117
|
setMode: "set_mode.js"
|
|
44572
45118
|
};
|
|
44573
45119
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
44574
|
-
const scriptsDir =
|
|
45120
|
+
const scriptsDir = path38.join(providerDir, "scripts");
|
|
44575
45121
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
44576
45122
|
if (latestScriptsDir) {
|
|
44577
45123
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -44579,10 +45125,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
44579
45125
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
44580
45126
|
lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
|
|
44581
45127
|
lines.push("");
|
|
44582
|
-
for (const file of
|
|
45128
|
+
for (const file of fs26.readdirSync(latestScriptsDir)) {
|
|
44583
45129
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
44584
45130
|
try {
|
|
44585
|
-
const content =
|
|
45131
|
+
const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
|
|
44586
45132
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
44587
45133
|
lines.push("```javascript");
|
|
44588
45134
|
lines.push(content);
|
|
@@ -44592,14 +45138,14 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
44592
45138
|
}
|
|
44593
45139
|
}
|
|
44594
45140
|
}
|
|
44595
|
-
const refFiles =
|
|
45141
|
+
const refFiles = fs26.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
44596
45142
|
if (refFiles.length > 0) {
|
|
44597
45143
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
44598
45144
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
44599
45145
|
lines.push("");
|
|
44600
45146
|
for (const file of refFiles) {
|
|
44601
45147
|
try {
|
|
44602
|
-
const content =
|
|
45148
|
+
const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
|
|
44603
45149
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
44604
45150
|
lines.push("```javascript");
|
|
44605
45151
|
lines.push(content);
|
|
@@ -44640,11 +45186,11 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
44640
45186
|
lines.push("");
|
|
44641
45187
|
}
|
|
44642
45188
|
}
|
|
44643
|
-
const docsDir =
|
|
45189
|
+
const docsDir = path38.join(providerDir, "../../docs");
|
|
44644
45190
|
const loadGuide = (name) => {
|
|
44645
45191
|
try {
|
|
44646
|
-
const p =
|
|
44647
|
-
if (
|
|
45192
|
+
const p = path38.join(docsDir, name);
|
|
45193
|
+
if (fs26.existsSync(p)) return fs26.readFileSync(p, "utf-8");
|
|
44648
45194
|
} catch {
|
|
44649
45195
|
}
|
|
44650
45196
|
return null;
|
|
@@ -44880,7 +45426,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
44880
45426
|
parseApproval: "parse_approval.js"
|
|
44881
45427
|
};
|
|
44882
45428
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
44883
|
-
const scriptsDir =
|
|
45429
|
+
const scriptsDir = path38.join(providerDir, "scripts");
|
|
44884
45430
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
44885
45431
|
if (latestScriptsDir) {
|
|
44886
45432
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -44888,11 +45434,11 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
44888
45434
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
44889
45435
|
lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
|
|
44890
45436
|
lines.push("");
|
|
44891
|
-
for (const file of
|
|
45437
|
+
for (const file of fs26.readdirSync(latestScriptsDir)) {
|
|
44892
45438
|
if (!file.endsWith(".js")) continue;
|
|
44893
45439
|
if (!targetFileNames.has(file)) continue;
|
|
44894
45440
|
try {
|
|
44895
|
-
const content =
|
|
45441
|
+
const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
|
|
44896
45442
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
44897
45443
|
lines.push("```javascript");
|
|
44898
45444
|
lines.push(content);
|
|
@@ -44901,14 +45447,14 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
44901
45447
|
} catch {
|
|
44902
45448
|
}
|
|
44903
45449
|
}
|
|
44904
|
-
const refFiles =
|
|
45450
|
+
const refFiles = fs26.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
44905
45451
|
if (refFiles.length > 0) {
|
|
44906
45452
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
44907
45453
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
44908
45454
|
lines.push("");
|
|
44909
45455
|
for (const file of refFiles) {
|
|
44910
45456
|
try {
|
|
44911
|
-
const content =
|
|
45457
|
+
const content = fs26.readFileSync(path38.join(latestScriptsDir, file), "utf-8");
|
|
44912
45458
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
44913
45459
|
lines.push("```javascript");
|
|
44914
45460
|
lines.push(content);
|
|
@@ -44941,11 +45487,11 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
44941
45487
|
lines.push("");
|
|
44942
45488
|
}
|
|
44943
45489
|
}
|
|
44944
|
-
const docsDir =
|
|
45490
|
+
const docsDir = path38.join(providerDir, "../../docs");
|
|
44945
45491
|
const loadGuide = (name) => {
|
|
44946
45492
|
try {
|
|
44947
|
-
const p =
|
|
44948
|
-
if (
|
|
45493
|
+
const p = path38.join(docsDir, name);
|
|
45494
|
+
if (fs26.existsSync(p)) return fs26.readFileSync(p, "utf-8");
|
|
44949
45495
|
} catch {
|
|
44950
45496
|
}
|
|
44951
45497
|
return null;
|
|
@@ -45391,8 +45937,8 @@ var DevServer = class _DevServer {
|
|
|
45391
45937
|
}
|
|
45392
45938
|
getEndpointList() {
|
|
45393
45939
|
return this.routes.map((r) => {
|
|
45394
|
-
const
|
|
45395
|
-
return `${r.method.padEnd(5)} ${
|
|
45940
|
+
const path40 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
|
|
45941
|
+
return `${r.method.padEnd(5)} ${path40}`;
|
|
45396
45942
|
});
|
|
45397
45943
|
}
|
|
45398
45944
|
async start(port = DEV_SERVER_PORT) {
|
|
@@ -45680,12 +46226,12 @@ var DevServer = class _DevServer {
|
|
|
45680
46226
|
// ─── DevConsole SPA ───
|
|
45681
46227
|
getConsoleDistDir() {
|
|
45682
46228
|
const candidates = [
|
|
45683
|
-
|
|
45684
|
-
|
|
45685
|
-
|
|
46229
|
+
path39.resolve(__dirname, "../../web-devconsole/dist"),
|
|
46230
|
+
path39.resolve(__dirname, "../../../web-devconsole/dist"),
|
|
46231
|
+
path39.join(process.cwd(), "packages/web-devconsole/dist")
|
|
45686
46232
|
];
|
|
45687
46233
|
for (const dir of candidates) {
|
|
45688
|
-
if (
|
|
46234
|
+
if (fs27.existsSync(path39.join(dir, "index.html"))) return dir;
|
|
45689
46235
|
}
|
|
45690
46236
|
return null;
|
|
45691
46237
|
}
|
|
@@ -45695,9 +46241,9 @@ var DevServer = class _DevServer {
|
|
|
45695
46241
|
this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
|
|
45696
46242
|
return;
|
|
45697
46243
|
}
|
|
45698
|
-
const htmlPath =
|
|
46244
|
+
const htmlPath = path39.join(distDir, "index.html");
|
|
45699
46245
|
try {
|
|
45700
|
-
const html =
|
|
46246
|
+
const html = fs27.readFileSync(htmlPath, "utf-8");
|
|
45701
46247
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
45702
46248
|
res.end(html);
|
|
45703
46249
|
} catch (e) {
|
|
@@ -45720,15 +46266,15 @@ var DevServer = class _DevServer {
|
|
|
45720
46266
|
this.json(res, 404, { error: "Not found" });
|
|
45721
46267
|
return;
|
|
45722
46268
|
}
|
|
45723
|
-
const safePath =
|
|
45724
|
-
const filePath =
|
|
46269
|
+
const safePath = path39.normalize(pathname).replace(/^\.\.\//, "");
|
|
46270
|
+
const filePath = path39.join(distDir, safePath);
|
|
45725
46271
|
if (!filePath.startsWith(distDir)) {
|
|
45726
46272
|
this.json(res, 403, { error: "Forbidden" });
|
|
45727
46273
|
return;
|
|
45728
46274
|
}
|
|
45729
46275
|
try {
|
|
45730
|
-
const content =
|
|
45731
|
-
const ext =
|
|
46276
|
+
const content = fs27.readFileSync(filePath);
|
|
46277
|
+
const ext = path39.extname(filePath);
|
|
45732
46278
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
45733
46279
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
45734
46280
|
res.end(content);
|
|
@@ -45836,14 +46382,14 @@ var DevServer = class _DevServer {
|
|
|
45836
46382
|
const files = [];
|
|
45837
46383
|
const scan = (d, prefix) => {
|
|
45838
46384
|
try {
|
|
45839
|
-
for (const entry of
|
|
46385
|
+
for (const entry of fs27.readdirSync(d, { withFileTypes: true })) {
|
|
45840
46386
|
if (entry.name.startsWith(".") || entry.name.endsWith(".bak")) continue;
|
|
45841
46387
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
45842
46388
|
if (entry.isDirectory()) {
|
|
45843
46389
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
45844
|
-
scan(
|
|
46390
|
+
scan(path39.join(d, entry.name), rel);
|
|
45845
46391
|
} else {
|
|
45846
|
-
const stat2 =
|
|
46392
|
+
const stat2 = fs27.statSync(path39.join(d, entry.name));
|
|
45847
46393
|
files.push({ path: rel, size: stat2.size, type: "file" });
|
|
45848
46394
|
}
|
|
45849
46395
|
}
|
|
@@ -45866,16 +46412,16 @@ var DevServer = class _DevServer {
|
|
|
45866
46412
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
45867
46413
|
return;
|
|
45868
46414
|
}
|
|
45869
|
-
const fullPath =
|
|
46415
|
+
const fullPath = path39.resolve(dir, path39.normalize(filePath));
|
|
45870
46416
|
if (!fullPath.startsWith(dir)) {
|
|
45871
46417
|
this.json(res, 403, { error: "Forbidden" });
|
|
45872
46418
|
return;
|
|
45873
46419
|
}
|
|
45874
|
-
if (!
|
|
46420
|
+
if (!fs27.existsSync(fullPath) || fs27.statSync(fullPath).isDirectory()) {
|
|
45875
46421
|
this.json(res, 404, { error: `File not found: ${filePath}` });
|
|
45876
46422
|
return;
|
|
45877
46423
|
}
|
|
45878
|
-
const content =
|
|
46424
|
+
const content = fs27.readFileSync(fullPath, "utf-8");
|
|
45879
46425
|
this.json(res, 200, { type, path: filePath, content, lines: content.split("\n").length });
|
|
45880
46426
|
}
|
|
45881
46427
|
/** POST /api/providers/:type/file — write a file { path, content } */
|
|
@@ -45891,15 +46437,15 @@ var DevServer = class _DevServer {
|
|
|
45891
46437
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
45892
46438
|
return;
|
|
45893
46439
|
}
|
|
45894
|
-
const fullPath =
|
|
46440
|
+
const fullPath = path39.resolve(dir, path39.normalize(filePath));
|
|
45895
46441
|
if (!fullPath.startsWith(dir)) {
|
|
45896
46442
|
this.json(res, 403, { error: "Forbidden" });
|
|
45897
46443
|
return;
|
|
45898
46444
|
}
|
|
45899
46445
|
try {
|
|
45900
|
-
if (
|
|
45901
|
-
|
|
45902
|
-
|
|
46446
|
+
if (fs27.existsSync(fullPath)) fs27.copyFileSync(fullPath, fullPath + ".bak");
|
|
46447
|
+
fs27.mkdirSync(path39.dirname(fullPath), { recursive: true });
|
|
46448
|
+
fs27.writeFileSync(fullPath, content, "utf-8");
|
|
45903
46449
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
45904
46450
|
this.providerLoader.reload();
|
|
45905
46451
|
this.json(res, 200, { saved: true, path: filePath, chars: content.length });
|
|
@@ -45915,9 +46461,9 @@ var DevServer = class _DevServer {
|
|
|
45915
46461
|
return;
|
|
45916
46462
|
}
|
|
45917
46463
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
45918
|
-
const p =
|
|
45919
|
-
if (
|
|
45920
|
-
const source =
|
|
46464
|
+
const p = path39.join(dir, name);
|
|
46465
|
+
if (fs27.existsSync(p)) {
|
|
46466
|
+
const source = fs27.readFileSync(p, "utf-8");
|
|
45921
46467
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
45922
46468
|
return;
|
|
45923
46469
|
}
|
|
@@ -45936,11 +46482,11 @@ var DevServer = class _DevServer {
|
|
|
45936
46482
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
45937
46483
|
return;
|
|
45938
46484
|
}
|
|
45939
|
-
const target =
|
|
45940
|
-
const targetPath =
|
|
46485
|
+
const target = fs27.existsSync(path39.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
46486
|
+
const targetPath = path39.join(dir, target);
|
|
45941
46487
|
try {
|
|
45942
|
-
if (
|
|
45943
|
-
|
|
46488
|
+
if (fs27.existsSync(targetPath)) fs27.copyFileSync(targetPath, targetPath + ".bak");
|
|
46489
|
+
fs27.writeFileSync(targetPath, source, "utf-8");
|
|
45944
46490
|
this.log(`Saved provider: ${targetPath} (${source.length} chars)`);
|
|
45945
46491
|
this.providerLoader.reload();
|
|
45946
46492
|
this.json(res, 200, { saved: true, path: targetPath, chars: source.length });
|
|
@@ -46084,21 +46630,21 @@ var DevServer = class _DevServer {
|
|
|
46084
46630
|
}
|
|
46085
46631
|
let targetDir;
|
|
46086
46632
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
46087
|
-
const jsonPath =
|
|
46088
|
-
if (
|
|
46633
|
+
const jsonPath = path39.join(targetDir, "provider.json");
|
|
46634
|
+
if (fs27.existsSync(jsonPath)) {
|
|
46089
46635
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
46090
46636
|
return;
|
|
46091
46637
|
}
|
|
46092
46638
|
try {
|
|
46093
46639
|
const result = generateFiles(type, name, category, { cdpPorts, cli, processName, installPath, binary, extensionId, version, osPaths, processNames });
|
|
46094
|
-
|
|
46095
|
-
|
|
46640
|
+
fs27.mkdirSync(targetDir, { recursive: true });
|
|
46641
|
+
fs27.writeFileSync(jsonPath, result["provider.json"], "utf-8");
|
|
46096
46642
|
const createdFiles = ["provider.json"];
|
|
46097
46643
|
if (result.files) {
|
|
46098
46644
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
46099
|
-
const fullPath =
|
|
46100
|
-
|
|
46101
|
-
|
|
46645
|
+
const fullPath = path39.join(targetDir, relPath);
|
|
46646
|
+
fs27.mkdirSync(path39.dirname(fullPath), { recursive: true });
|
|
46647
|
+
fs27.writeFileSync(fullPath, content, "utf-8");
|
|
46102
46648
|
createdFiles.push(relPath);
|
|
46103
46649
|
}
|
|
46104
46650
|
}
|
|
@@ -46147,38 +46693,38 @@ var DevServer = class _DevServer {
|
|
|
46147
46693
|
}
|
|
46148
46694
|
// ─── Phase 2: Auto-Implement Backend ───
|
|
46149
46695
|
getLatestScriptVersionDir(scriptsDir) {
|
|
46150
|
-
if (!
|
|
46151
|
-
const versions =
|
|
46696
|
+
if (!fs27.existsSync(scriptsDir)) return null;
|
|
46697
|
+
const versions = fs27.readdirSync(scriptsDir).filter((d) => {
|
|
46152
46698
|
try {
|
|
46153
|
-
return
|
|
46699
|
+
return fs27.statSync(path39.join(scriptsDir, d)).isDirectory();
|
|
46154
46700
|
} catch {
|
|
46155
46701
|
return false;
|
|
46156
46702
|
}
|
|
46157
46703
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
46158
46704
|
if (versions.length === 0) return null;
|
|
46159
|
-
return
|
|
46705
|
+
return path39.join(scriptsDir, versions[0]);
|
|
46160
46706
|
}
|
|
46161
46707
|
resolveAutoImplWritableProviderDir(category, type, requestedDir) {
|
|
46162
|
-
const canonicalUserDir =
|
|
46163
|
-
const desiredDir = requestedDir ?
|
|
46164
|
-
const upstreamRoot =
|
|
46165
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
46708
|
+
const canonicalUserDir = path39.resolve(this.providerLoader.getUserProviderDir(category, type));
|
|
46709
|
+
const desiredDir = requestedDir ? path39.resolve(requestedDir) : canonicalUserDir;
|
|
46710
|
+
const upstreamRoot = path39.resolve(this.providerLoader.getUpstreamDir());
|
|
46711
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path39.sep}`)) {
|
|
46166
46712
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
46167
46713
|
}
|
|
46168
|
-
if (
|
|
46714
|
+
if (path39.basename(desiredDir) !== type) {
|
|
46169
46715
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
46170
46716
|
}
|
|
46171
46717
|
const sourceDir = this.findProviderDir(type);
|
|
46172
46718
|
if (!sourceDir) {
|
|
46173
46719
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
46174
46720
|
}
|
|
46175
|
-
if (!
|
|
46176
|
-
|
|
46177
|
-
|
|
46721
|
+
if (!fs27.existsSync(desiredDir)) {
|
|
46722
|
+
fs27.mkdirSync(path39.dirname(desiredDir), { recursive: true });
|
|
46723
|
+
fs27.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
46178
46724
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
46179
46725
|
}
|
|
46180
|
-
const providerJson =
|
|
46181
|
-
if (!
|
|
46726
|
+
const providerJson = path39.join(desiredDir, "provider.json");
|
|
46727
|
+
if (!fs27.existsSync(providerJson)) {
|
|
46182
46728
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
46183
46729
|
}
|
|
46184
46730
|
return { dir: desiredDir };
|
|
@@ -46213,7 +46759,7 @@ var DevServer = class _DevServer {
|
|
|
46213
46759
|
setMode: "set_mode.js"
|
|
46214
46760
|
};
|
|
46215
46761
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
46216
|
-
const scriptsDir =
|
|
46762
|
+
const scriptsDir = path39.join(providerDir, "scripts");
|
|
46217
46763
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
46218
46764
|
if (latestScriptsDir) {
|
|
46219
46765
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -46221,10 +46767,10 @@ var DevServer = class _DevServer {
|
|
|
46221
46767
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
46222
46768
|
lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
|
|
46223
46769
|
lines.push("");
|
|
46224
|
-
for (const file of
|
|
46770
|
+
for (const file of fs27.readdirSync(latestScriptsDir)) {
|
|
46225
46771
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
46226
46772
|
try {
|
|
46227
|
-
const content =
|
|
46773
|
+
const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
46228
46774
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
46229
46775
|
lines.push("```javascript");
|
|
46230
46776
|
lines.push(content);
|
|
@@ -46234,14 +46780,14 @@ var DevServer = class _DevServer {
|
|
|
46234
46780
|
}
|
|
46235
46781
|
}
|
|
46236
46782
|
}
|
|
46237
|
-
const refFiles =
|
|
46783
|
+
const refFiles = fs27.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
46238
46784
|
if (refFiles.length > 0) {
|
|
46239
46785
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
46240
46786
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
46241
46787
|
lines.push("");
|
|
46242
46788
|
for (const file of refFiles) {
|
|
46243
46789
|
try {
|
|
46244
|
-
const content =
|
|
46790
|
+
const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
46245
46791
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
46246
46792
|
lines.push("```javascript");
|
|
46247
46793
|
lines.push(content);
|
|
@@ -46282,11 +46828,11 @@ var DevServer = class _DevServer {
|
|
|
46282
46828
|
lines.push("");
|
|
46283
46829
|
}
|
|
46284
46830
|
}
|
|
46285
|
-
const docsDir =
|
|
46831
|
+
const docsDir = path39.join(providerDir, "../../docs");
|
|
46286
46832
|
const loadGuide = (name) => {
|
|
46287
46833
|
try {
|
|
46288
|
-
const p =
|
|
46289
|
-
if (
|
|
46834
|
+
const p = path39.join(docsDir, name);
|
|
46835
|
+
if (fs27.existsSync(p)) return fs27.readFileSync(p, "utf-8");
|
|
46290
46836
|
} catch {
|
|
46291
46837
|
}
|
|
46292
46838
|
return null;
|
|
@@ -46459,7 +47005,7 @@ var DevServer = class _DevServer {
|
|
|
46459
47005
|
parseApproval: "parse_approval.js"
|
|
46460
47006
|
};
|
|
46461
47007
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
46462
|
-
const scriptsDir =
|
|
47008
|
+
const scriptsDir = path39.join(providerDir, "scripts");
|
|
46463
47009
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
46464
47010
|
if (latestScriptsDir) {
|
|
46465
47011
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -46467,11 +47013,11 @@ var DevServer = class _DevServer {
|
|
|
46467
47013
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
46468
47014
|
lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
|
|
46469
47015
|
lines.push("");
|
|
46470
|
-
for (const file of
|
|
47016
|
+
for (const file of fs27.readdirSync(latestScriptsDir)) {
|
|
46471
47017
|
if (!file.endsWith(".js")) continue;
|
|
46472
47018
|
if (!targetFileNames.has(file)) continue;
|
|
46473
47019
|
try {
|
|
46474
|
-
const content =
|
|
47020
|
+
const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
46475
47021
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
46476
47022
|
lines.push("```javascript");
|
|
46477
47023
|
lines.push(content);
|
|
@@ -46480,14 +47026,14 @@ var DevServer = class _DevServer {
|
|
|
46480
47026
|
} catch {
|
|
46481
47027
|
}
|
|
46482
47028
|
}
|
|
46483
|
-
const refFiles =
|
|
47029
|
+
const refFiles = fs27.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
46484
47030
|
if (refFiles.length > 0) {
|
|
46485
47031
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
46486
47032
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
46487
47033
|
lines.push("");
|
|
46488
47034
|
for (const file of refFiles) {
|
|
46489
47035
|
try {
|
|
46490
|
-
const content =
|
|
47036
|
+
const content = fs27.readFileSync(path39.join(latestScriptsDir, file), "utf-8");
|
|
46491
47037
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
46492
47038
|
lines.push("```javascript");
|
|
46493
47039
|
lines.push(content);
|
|
@@ -46520,11 +47066,11 @@ var DevServer = class _DevServer {
|
|
|
46520
47066
|
lines.push("");
|
|
46521
47067
|
}
|
|
46522
47068
|
}
|
|
46523
|
-
const docsDir =
|
|
47069
|
+
const docsDir = path39.join(providerDir, "../../docs");
|
|
46524
47070
|
const loadGuide = (name) => {
|
|
46525
47071
|
try {
|
|
46526
|
-
const p =
|
|
46527
|
-
if (
|
|
47072
|
+
const p = path39.join(docsDir, name);
|
|
47073
|
+
if (fs27.existsSync(p)) return fs27.readFileSync(p, "utf-8");
|
|
46528
47074
|
} catch {
|
|
46529
47075
|
}
|
|
46530
47076
|
return null;
|
|
@@ -47429,8 +47975,8 @@ async function installExtension(ide, extension) {
|
|
|
47429
47975
|
const res = await fetch(extension.vsixUrl);
|
|
47430
47976
|
if (res.ok) {
|
|
47431
47977
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
47432
|
-
const
|
|
47433
|
-
|
|
47978
|
+
const fs28 = await import("fs");
|
|
47979
|
+
fs28.writeFileSync(vsixPath, buffer);
|
|
47434
47980
|
return new Promise((resolve23) => {
|
|
47435
47981
|
const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
|
|
47436
47982
|
(0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
|