@adhdev/daemon-core 0.9.76-rc.61 → 0.9.76-rc.62
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/chat-commands.d.ts +2 -0
- package/dist/index.js +634 -291
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +639 -296
- package/dist/index.mjs.map +1 -1
- package/dist/providers/cli-provider-instance.d.ts +4 -1
- package/dist/providers/contracts.d.ts +20 -1
- package/dist/providers/io-contracts.d.ts +17 -1
- package/dist/providers/provider-input-support.d.ts +18 -2
- package/dist/providers/provider-instance.d.ts +2 -0
- package/dist/shared-types.d.ts +4 -0
- package/package.json +1 -1
- package/src/commands/chat-commands.ts +40 -5
- package/src/commands/mesh-coordinator.ts +8 -1
- package/src/commands/router.ts +4 -0
- package/src/mesh/coordinator-prompt.ts +7 -0
- package/src/providers/acp-provider-instance.ts +118 -30
- package/src/providers/cli-provider-instance.ts +96 -5
- package/src/providers/contracts.ts +25 -1
- package/src/providers/io-contracts.ts +63 -5
- package/src/providers/provider-input-support.ts +125 -1
- package/src/providers/provider-instance.ts +2 -0
- package/src/providers/provider-schema.ts +38 -8
- package/src/shared-types.ts +4 -0
- package/src/status/builders.ts +5 -3
package/dist/index.js
CHANGED
|
@@ -433,10 +433,10 @@ function getMeshConfigPath() {
|
|
|
433
433
|
return (0, import_path2.join)(getConfigDir(), "meshes.json");
|
|
434
434
|
}
|
|
435
435
|
function loadMeshConfig() {
|
|
436
|
-
const
|
|
437
|
-
if (!(0, import_fs2.existsSync)(
|
|
436
|
+
const path28 = getMeshConfigPath();
|
|
437
|
+
if (!(0, import_fs2.existsSync)(path28)) return { meshes: [] };
|
|
438
438
|
try {
|
|
439
|
-
const raw = JSON.parse((0, import_fs2.readFileSync)(
|
|
439
|
+
const raw = JSON.parse((0, import_fs2.readFileSync)(path28, "utf-8"));
|
|
440
440
|
if (!raw || !Array.isArray(raw.meshes)) return { meshes: [] };
|
|
441
441
|
return raw;
|
|
442
442
|
} catch {
|
|
@@ -444,16 +444,16 @@ function loadMeshConfig() {
|
|
|
444
444
|
}
|
|
445
445
|
}
|
|
446
446
|
function saveMeshConfig(config) {
|
|
447
|
-
const
|
|
448
|
-
(0, import_fs2.writeFileSync)(
|
|
447
|
+
const path28 = getMeshConfigPath();
|
|
448
|
+
(0, import_fs2.writeFileSync)(path28, JSON.stringify(config, null, 2), { encoding: "utf-8", mode: 384 });
|
|
449
449
|
}
|
|
450
450
|
function normalizeRepoIdentity(remoteUrl) {
|
|
451
451
|
let identity = remoteUrl.trim();
|
|
452
452
|
if (identity.startsWith("http://") || identity.startsWith("https://")) {
|
|
453
453
|
try {
|
|
454
454
|
const url = new URL(identity);
|
|
455
|
-
const
|
|
456
|
-
return `${url.hostname}/${
|
|
455
|
+
const path28 = url.pathname.replace(/^\//, "").replace(/\.git$/, "");
|
|
456
|
+
return `${url.hostname}/${path28}`;
|
|
457
457
|
} catch {
|
|
458
458
|
}
|
|
459
459
|
}
|
|
@@ -610,6 +610,7 @@ Default branch: \`${mesh.defaultBranch}\`` : ""}`);
|
|
|
610
610
|
}
|
|
611
611
|
sections.push(buildPolicySection({ ...DEFAULT_MESH_POLICY, ...mesh.policy || {} }));
|
|
612
612
|
sections.push(TOOLS_SECTION);
|
|
613
|
+
sections.push(TOOL_EXPOSURE_PREFLIGHT_SECTION);
|
|
613
614
|
sections.push(WORKFLOW_SECTION);
|
|
614
615
|
sections.push(buildRulesSection(coordinatorCliType));
|
|
615
616
|
if (userInstruction) {
|
|
@@ -679,7 +680,7 @@ function buildRulesSection(coordinatorCliType) {
|
|
|
679
680
|
- **Clean up worktree nodes.** After a worktree task completes and its changes are merged or checkpointed, call \`mesh_remove_node\` to free resources.
|
|
680
681
|
- **Name worktree branches meaningfully.** Use descriptive names like \`feat/auth-refactor\` or \`fix/build-123\`.${coordinatorNote}`;
|
|
681
682
|
}
|
|
682
|
-
var TOOLS_SECTION, WORKFLOW_SECTION;
|
|
683
|
+
var TOOLS_SECTION, TOOL_EXPOSURE_PREFLIGHT_SECTION, WORKFLOW_SECTION;
|
|
683
684
|
var init_coordinator_prompt = __esm({
|
|
684
685
|
"src/mesh/coordinator-prompt.ts"() {
|
|
685
686
|
"use strict";
|
|
@@ -698,6 +699,9 @@ var init_coordinator_prompt = __esm({
|
|
|
698
699
|
| \`mesh_approve\` | Approve/reject a pending agent action |
|
|
699
700
|
| \`mesh_clone_node\` | Create a worktree node for isolated parallel branch work |
|
|
700
701
|
| \`mesh_remove_node\` | Remove a node (cleans up worktree if applicable) |`;
|
|
702
|
+
TOOL_EXPOSURE_PREFLIGHT_SECTION = `## Tool Exposure Preflight
|
|
703
|
+
|
|
704
|
+
Before doing any coordinator work, confirm that the actual callable tool list includes \`mesh_status\` and the other \`mesh_*\` tools from the table above. If this Repo Mesh coordinator prompt is present but the callable \`mesh_*\` tools are missing, the MCP server/tool manifest is stale or not injected yet. Do not substitute terminal/file/git tools, do not inspect or edit the repository directly, and do not continue as a non-mesh local coding agent. Stop immediately and tell the user to run \`/reload-mcp\` or start a fresh coordinator session so ADHDev can reconnect \`adhdev-mesh\`.`;
|
|
701
705
|
WORKFLOW_SECTION = `## Orchestration Workflow
|
|
702
706
|
|
|
703
707
|
1. **Assess** \u2014 Call \`mesh_status\` to see which nodes are healthy and available.
|
|
@@ -7732,6 +7736,10 @@ function flattenMessageParts(parts) {
|
|
|
7732
7736
|
return parts.map((part) => {
|
|
7733
7737
|
if (part.type === "text") return part.text;
|
|
7734
7738
|
if (part.type === "resource") return part.resource.text || "";
|
|
7739
|
+
if (part.type === "image") return part.alt || (part.data ? `[image: ${part.mimeType}]` : "");
|
|
7740
|
+
if (part.type === "audio") return part.transcript || (part.data ? `[audio: ${part.mimeType}]` : "");
|
|
7741
|
+
if (part.type === "video") return part.transcript || (part.data ? `[video: ${part.mimeType}]` : "");
|
|
7742
|
+
if (part.type === "resource_link") return [part.name, part.description].filter(Boolean).join("\n");
|
|
7735
7743
|
return "";
|
|
7736
7744
|
}).filter((value) => value.length > 0).join("\n");
|
|
7737
7745
|
}
|
|
@@ -7818,6 +7826,7 @@ function normalizeInputPartObject(raw) {
|
|
|
7818
7826
|
mimeType: raw.mimeType,
|
|
7819
7827
|
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7820
7828
|
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7829
|
+
...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {},
|
|
7821
7830
|
...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
|
|
7822
7831
|
};
|
|
7823
7832
|
}
|
|
@@ -7833,10 +7842,14 @@ function normalizeInputPartObject(raw) {
|
|
|
7833
7842
|
}
|
|
7834
7843
|
if (type === "resource_link" && typeof raw.uri === "string") {
|
|
7835
7844
|
return {
|
|
7836
|
-
type
|
|
7845
|
+
type,
|
|
7837
7846
|
uri: raw.uri,
|
|
7847
|
+
name: typeof raw.name === "string" ? raw.name : getUriDisplayName(raw.uri, "resource"),
|
|
7848
|
+
...typeof raw.title === "string" ? { title: raw.title } : {},
|
|
7849
|
+
...typeof raw.description === "string" ? { description: raw.description } : {},
|
|
7838
7850
|
...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
|
|
7839
|
-
...typeof raw.
|
|
7851
|
+
...typeof raw.size === "number" && Number.isFinite(raw.size) ? { size: raw.size } : {},
|
|
7852
|
+
...normalizeAnnotationsProperty(raw.annotations)
|
|
7840
7853
|
};
|
|
7841
7854
|
}
|
|
7842
7855
|
return null;
|
|
@@ -7851,7 +7864,8 @@ function normalizeMessagePartObject(raw) {
|
|
|
7851
7864
|
type,
|
|
7852
7865
|
mimeType: raw.mimeType,
|
|
7853
7866
|
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7854
|
-
...typeof raw.data === "string" ? { data: raw.data } : {}
|
|
7867
|
+
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7868
|
+
...typeof raw.alt === "string" ? { alt: raw.alt } : {}
|
|
7855
7869
|
};
|
|
7856
7870
|
}
|
|
7857
7871
|
if (type === "audio" && typeof raw.mimeType === "string") {
|
|
@@ -7869,6 +7883,7 @@ function normalizeMessagePartObject(raw) {
|
|
|
7869
7883
|
mimeType: raw.mimeType,
|
|
7870
7884
|
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7871
7885
|
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7886
|
+
...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {},
|
|
7872
7887
|
...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
|
|
7873
7888
|
};
|
|
7874
7889
|
}
|
|
@@ -7877,8 +7892,11 @@ function normalizeMessagePartObject(raw) {
|
|
|
7877
7892
|
type,
|
|
7878
7893
|
uri: raw.uri,
|
|
7879
7894
|
name: raw.name,
|
|
7895
|
+
...typeof raw.title === "string" ? { title: raw.title } : {},
|
|
7896
|
+
...typeof raw.description === "string" ? { description: raw.description } : {},
|
|
7880
7897
|
...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
|
|
7881
|
-
...typeof raw.size === "number" ? { size: raw.size } : {}
|
|
7898
|
+
...typeof raw.size === "number" && Number.isFinite(raw.size) ? { size: raw.size } : {},
|
|
7899
|
+
...normalizeAnnotationsProperty(raw.annotations)
|
|
7882
7900
|
};
|
|
7883
7901
|
}
|
|
7884
7902
|
if (type === "resource" && raw.resource && typeof raw.resource === "object") {
|
|
@@ -7899,11 +7917,35 @@ function normalizeMessagePartObject(raw) {
|
|
|
7899
7917
|
function flattenInputParts(parts) {
|
|
7900
7918
|
return parts.map((part) => {
|
|
7901
7919
|
if (part.type === "text") return part.text;
|
|
7902
|
-
if (part.type === "
|
|
7903
|
-
if (part.type === "
|
|
7920
|
+
if (part.type === "image") return part.alt || (part.data ? `[image: ${part.mimeType}]` : "");
|
|
7921
|
+
if (part.type === "audio") return part.transcript || (part.data ? `[audio: ${part.mimeType}]` : "");
|
|
7922
|
+
if (part.type === "video") return part.transcript || (part.data ? `[video: ${part.mimeType}]` : "");
|
|
7923
|
+
if (part.type === "resource_link") return [part.title, part.name, part.description, part.uri].filter(Boolean).join("\n");
|
|
7924
|
+
if (part.type === "resource") return part.text || part.name || part.uri;
|
|
7904
7925
|
return "";
|
|
7905
7926
|
}).filter((value) => value.length > 0).join("\n");
|
|
7906
7927
|
}
|
|
7928
|
+
function getUriDisplayName(uri, fallback) {
|
|
7929
|
+
try {
|
|
7930
|
+
const pathname = uri.startsWith("file://") ? new URL(uri).pathname : uri;
|
|
7931
|
+
return pathname.split(/[\\/]/).filter(Boolean).pop() || fallback;
|
|
7932
|
+
} catch {
|
|
7933
|
+
return uri.split(/[\\/]/).filter(Boolean).pop() || fallback;
|
|
7934
|
+
}
|
|
7935
|
+
}
|
|
7936
|
+
function normalizeAnnotationsProperty(value) {
|
|
7937
|
+
if (!value || typeof value !== "object") return {};
|
|
7938
|
+
const record = value;
|
|
7939
|
+
const annotations = {};
|
|
7940
|
+
if (Array.isArray(record.audience)) {
|
|
7941
|
+
const audience = record.audience.filter((item) => item === "user" || item === "assistant");
|
|
7942
|
+
if (audience.length > 0) annotations.audience = audience;
|
|
7943
|
+
}
|
|
7944
|
+
if (typeof record.priority === "number" && Number.isFinite(record.priority)) {
|
|
7945
|
+
annotations.priority = record.priority;
|
|
7946
|
+
}
|
|
7947
|
+
return Object.keys(annotations).length > 0 ? { annotations } : {};
|
|
7948
|
+
}
|
|
7907
7949
|
|
|
7908
7950
|
// src/providers/contracts.ts
|
|
7909
7951
|
function flattenContent(content) {
|
|
@@ -11563,6 +11605,147 @@ function normalizeActiveChatData(activeChat, options = FULL_STATUS_ACTIVE_CHAT_O
|
|
|
11563
11605
|
return normalized;
|
|
11564
11606
|
}
|
|
11565
11607
|
|
|
11608
|
+
// src/providers/provider-input-support.ts
|
|
11609
|
+
var VALID_INPUT_MEDIA_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "resource"]);
|
|
11610
|
+
var VALID_INPUT_STRATEGIES = /* @__PURE__ */ new Set(["native", "native_acp", "resource_link", "text_fallback", "paste", "upload"]);
|
|
11611
|
+
var TEXT_ONLY_MESSAGE_INPUT_SUPPORT = Object.freeze({
|
|
11612
|
+
text: true,
|
|
11613
|
+
multipart: false,
|
|
11614
|
+
mediaTypes: ["text"],
|
|
11615
|
+
strategies: []
|
|
11616
|
+
});
|
|
11617
|
+
function getProviderLabel(provider) {
|
|
11618
|
+
return provider?.name || provider?.type || "This provider";
|
|
11619
|
+
}
|
|
11620
|
+
function hasNonEmptyFallbackText(input) {
|
|
11621
|
+
return typeof input.textFallback === "string" && input.textFallback.trim().length > 0;
|
|
11622
|
+
}
|
|
11623
|
+
function getRequestedInputMediaTypes(input) {
|
|
11624
|
+
const types = /* @__PURE__ */ new Set();
|
|
11625
|
+
if (hasNonEmptyFallbackText(input) && !input.parts.some((part) => part.type === "text")) {
|
|
11626
|
+
types.add("text");
|
|
11627
|
+
}
|
|
11628
|
+
for (const part of input.parts) {
|
|
11629
|
+
if (VALID_INPUT_MEDIA_TYPES.has(part.type)) {
|
|
11630
|
+
types.add(part.type);
|
|
11631
|
+
}
|
|
11632
|
+
}
|
|
11633
|
+
return Array.from(types);
|
|
11634
|
+
}
|
|
11635
|
+
function getEffectiveSemanticPartCount(input) {
|
|
11636
|
+
let count = input.parts.length;
|
|
11637
|
+
if (hasNonEmptyFallbackText(input) && !input.parts.some((part) => part.type === "text")) {
|
|
11638
|
+
count += 1;
|
|
11639
|
+
}
|
|
11640
|
+
return count;
|
|
11641
|
+
}
|
|
11642
|
+
function assertTextOnlyInput(provider, input) {
|
|
11643
|
+
const unsupported = getRequestedInputMediaTypes(input).filter((type) => type !== "text");
|
|
11644
|
+
if (unsupported.length === 0) return;
|
|
11645
|
+
const label = getProviderLabel(provider);
|
|
11646
|
+
const suffix = unsupported.length === 1 ? "" : "s";
|
|
11647
|
+
throw new Error(`${label} only supports text input; unsupported input type${suffix}: ${unsupported.join(", ")}`);
|
|
11648
|
+
}
|
|
11649
|
+
function getDeclaredProviderInputSupport(provider) {
|
|
11650
|
+
const rawMediaTypes = Array.isArray(provider?.capabilities?.input?.mediaTypes) ? provider?.capabilities?.input?.mediaTypes.filter((type) => VALID_INPUT_MEDIA_TYPES.has(type)) : [];
|
|
11651
|
+
const strategies = normalizeInputStrategyDescriptors(provider?.capabilities?.input?.strategies);
|
|
11652
|
+
return {
|
|
11653
|
+
multipart: provider?.capabilities?.input?.multipart === true,
|
|
11654
|
+
mediaTypes: new Set(rawMediaTypes.length > 0 ? rawMediaTypes : ["text"]),
|
|
11655
|
+
strategies
|
|
11656
|
+
};
|
|
11657
|
+
}
|
|
11658
|
+
function normalizeInputStrategyDescriptors(raw) {
|
|
11659
|
+
if (!Array.isArray(raw)) return [];
|
|
11660
|
+
const result = [];
|
|
11661
|
+
for (const entry of raw) {
|
|
11662
|
+
if (!entry || typeof entry !== "object") continue;
|
|
11663
|
+
const record = entry;
|
|
11664
|
+
const mediaType = record.mediaType;
|
|
11665
|
+
if (typeof mediaType !== "string" || !VALID_INPUT_MEDIA_TYPES.has(mediaType)) continue;
|
|
11666
|
+
const strategies = Array.isArray(record.strategies) ? record.strategies.filter((value) => typeof value === "string" && VALID_INPUT_STRATEGIES.has(value)) : [];
|
|
11667
|
+
const degradation = Array.isArray(record.degradation) ? record.degradation.filter((value) => typeof value === "string" && VALID_INPUT_STRATEGIES.has(value)) : [];
|
|
11668
|
+
if (strategies.length === 0 && degradation.length === 0) continue;
|
|
11669
|
+
result.push({
|
|
11670
|
+
mediaType,
|
|
11671
|
+
strategies,
|
|
11672
|
+
...typeof record.native === "boolean" ? { native: record.native } : {},
|
|
11673
|
+
...degradation.length > 0 ? { degradation } : {}
|
|
11674
|
+
});
|
|
11675
|
+
}
|
|
11676
|
+
return result;
|
|
11677
|
+
}
|
|
11678
|
+
function promptCapabilityFlags(runtimeCapabilities) {
|
|
11679
|
+
const prompt = runtimeCapabilities?.promptCapabilities || {};
|
|
11680
|
+
return {
|
|
11681
|
+
image: prompt.image === true,
|
|
11682
|
+
audio: prompt.audio === true,
|
|
11683
|
+
embeddedContext: prompt.embeddedContext === true
|
|
11684
|
+
};
|
|
11685
|
+
}
|
|
11686
|
+
function supportFromDeclared(provider) {
|
|
11687
|
+
const declared = getDeclaredProviderInputSupport(provider);
|
|
11688
|
+
return {
|
|
11689
|
+
text: true,
|
|
11690
|
+
multipart: declared.multipart,
|
|
11691
|
+
mediaTypes: Array.from(declared.mediaTypes),
|
|
11692
|
+
strategies: declared.strategies
|
|
11693
|
+
};
|
|
11694
|
+
}
|
|
11695
|
+
function getEffectiveMessageInputSupport(provider, runtimeCapabilities) {
|
|
11696
|
+
if (provider?.category !== "acp") {
|
|
11697
|
+
const declared2 = supportFromDeclared(provider);
|
|
11698
|
+
return {
|
|
11699
|
+
...declared2,
|
|
11700
|
+
mediaTypes: [...declared2.mediaTypes],
|
|
11701
|
+
strategies: declared2.strategies.map((strategy) => ({
|
|
11702
|
+
...strategy,
|
|
11703
|
+
strategies: [...strategy.strategies],
|
|
11704
|
+
...strategy.degradation ? { degradation: [...strategy.degradation] } : {}
|
|
11705
|
+
}))
|
|
11706
|
+
};
|
|
11707
|
+
}
|
|
11708
|
+
const declared = supportFromDeclared(provider);
|
|
11709
|
+
const caps = promptCapabilityFlags(runtimeCapabilities);
|
|
11710
|
+
const mediaTypes = /* @__PURE__ */ new Set(["text"]);
|
|
11711
|
+
const strategies = [];
|
|
11712
|
+
if (declared.mediaTypes.includes("resource")) {
|
|
11713
|
+
mediaTypes.add("resource");
|
|
11714
|
+
strategies.push({ mediaType: "resource", strategies: caps.embeddedContext ? ["native_acp", "resource_link", "text_fallback"] : ["resource_link", "text_fallback"], native: caps.embeddedContext, degradation: ["resource_link", "text_fallback"] });
|
|
11715
|
+
}
|
|
11716
|
+
if (declared.mediaTypes.includes("video")) {
|
|
11717
|
+
mediaTypes.add("video");
|
|
11718
|
+
strategies.push({ mediaType: "video", strategies: ["resource_link", "text_fallback"], native: false, degradation: ["resource_link", "text_fallback"] });
|
|
11719
|
+
}
|
|
11720
|
+
if (declared.mediaTypes.includes("image")) {
|
|
11721
|
+
mediaTypes.add("image");
|
|
11722
|
+
strategies.push({ mediaType: "image", strategies: caps.image ? ["native_acp", "resource_link", "text_fallback"] : ["resource_link", "text_fallback"], native: caps.image, degradation: ["resource_link", "text_fallback"] });
|
|
11723
|
+
}
|
|
11724
|
+
if (declared.mediaTypes.includes("audio")) {
|
|
11725
|
+
mediaTypes.add("audio");
|
|
11726
|
+
strategies.push({ mediaType: "audio", strategies: caps.audio ? ["native_acp", "resource_link", "text_fallback"] : ["resource_link", "text_fallback"], native: caps.audio, degradation: ["resource_link", "text_fallback"] });
|
|
11727
|
+
}
|
|
11728
|
+
return {
|
|
11729
|
+
text: true,
|
|
11730
|
+
multipart: declared.multipart && mediaTypes.size > 1,
|
|
11731
|
+
mediaTypes: Array.from(mediaTypes),
|
|
11732
|
+
strategies
|
|
11733
|
+
};
|
|
11734
|
+
}
|
|
11735
|
+
function assertProviderSupportsDeclaredInput(provider, input) {
|
|
11736
|
+
const label = getProviderLabel(provider);
|
|
11737
|
+
const support = getDeclaredProviderInputSupport(provider);
|
|
11738
|
+
const requestedTypes = getRequestedInputMediaTypes(input);
|
|
11739
|
+
const unsupported = requestedTypes.filter((type) => !support.mediaTypes.has(type));
|
|
11740
|
+
if (unsupported.length > 0) {
|
|
11741
|
+
const suffix = unsupported.length === 1 ? "" : "s";
|
|
11742
|
+
throw new Error(`${label} does not support input type${suffix}: ${unsupported.join(", ")}`);
|
|
11743
|
+
}
|
|
11744
|
+
if (getEffectiveSemanticPartCount(input) > 1 && !support.multipart) {
|
|
11745
|
+
throw new Error(`${label} does not support multipart input`);
|
|
11746
|
+
}
|
|
11747
|
+
}
|
|
11748
|
+
|
|
11566
11749
|
// src/status/builders.ts
|
|
11567
11750
|
function getActiveChatOptions(profile) {
|
|
11568
11751
|
if (profile === "full") return {};
|
|
@@ -11660,7 +11843,7 @@ function buildIdeWorkspaceSession(state, cdpManagers, options) {
|
|
|
11660
11843
|
...git && { git },
|
|
11661
11844
|
activeChat,
|
|
11662
11845
|
...summaryMetadata && { summaryMetadata },
|
|
11663
|
-
...includeSessionMetadata && { capabilities: state.sessionCapabilities || IDE_SESSION_CAPABILITIES },
|
|
11846
|
+
...includeSessionMetadata && { capabilities: state.sessionCapabilities || IDE_SESSION_CAPABILITIES, messageInput: state.messageInput || TEXT_ONLY_MESSAGE_INPUT_SUPPORT },
|
|
11664
11847
|
cdpConnected: state.cdpConnected ?? isCdpConnected(cdpManagers, state.type),
|
|
11665
11848
|
...includeSessionControls && {
|
|
11666
11849
|
...controlValues && { controlValues },
|
|
@@ -11695,7 +11878,7 @@ function buildExtensionAgentSession(parent, ext, options) {
|
|
|
11695
11878
|
...git && { git },
|
|
11696
11879
|
activeChat,
|
|
11697
11880
|
...summaryMetadata && { summaryMetadata },
|
|
11698
|
-
...includeSessionMetadata && { capabilities: ext.sessionCapabilities || EXTENSION_SESSION_CAPABILITIES },
|
|
11881
|
+
...includeSessionMetadata && { capabilities: ext.sessionCapabilities || EXTENSION_SESSION_CAPABILITIES, messageInput: ext.messageInput || TEXT_ONLY_MESSAGE_INPUT_SUPPORT },
|
|
11699
11882
|
...includeSessionControls && {
|
|
11700
11883
|
...controlValues && { controlValues },
|
|
11701
11884
|
providerControls: ext.providerControls
|
|
@@ -11759,7 +11942,8 @@ function buildCliSession(state, options) {
|
|
|
11759
11942
|
activeChat,
|
|
11760
11943
|
...summaryMetadata && { summaryMetadata },
|
|
11761
11944
|
...includeSessionMetadata && {
|
|
11762
|
-
capabilities: state.mode === "terminal" ? PTY_SESSION_CAPABILITIES : CLI_CHAT_SESSION_CAPABILITIES
|
|
11945
|
+
capabilities: state.mode === "terminal" ? PTY_SESSION_CAPABILITIES : CLI_CHAT_SESSION_CAPABILITIES,
|
|
11946
|
+
messageInput: state.messageInput || TEXT_ONLY_MESSAGE_INPUT_SUPPORT
|
|
11763
11947
|
},
|
|
11764
11948
|
...includeSessionControls && {
|
|
11765
11949
|
...controlValues && { controlValues },
|
|
@@ -11793,7 +11977,7 @@ function buildAcpSession(state, options) {
|
|
|
11793
11977
|
...git && { git },
|
|
11794
11978
|
activeChat,
|
|
11795
11979
|
...summaryMetadata && { summaryMetadata },
|
|
11796
|
-
...includeSessionMetadata && { capabilities: ACP_SESSION_CAPABILITIES },
|
|
11980
|
+
...includeSessionMetadata && { capabilities: ACP_SESSION_CAPABILITIES, messageInput: state.messageInput || TEXT_ONLY_MESSAGE_INPUT_SUPPORT },
|
|
11797
11981
|
...includeSessionControls && {
|
|
11798
11982
|
...controlValues && { controlValues },
|
|
11799
11983
|
providerControls: state.providerControls
|
|
@@ -11912,63 +12096,6 @@ var fs4 = __toESM(require("fs"));
|
|
|
11912
12096
|
var os6 = __toESM(require("os"));
|
|
11913
12097
|
var path12 = __toESM(require("path"));
|
|
11914
12098
|
var import_node_crypto = require("crypto");
|
|
11915
|
-
|
|
11916
|
-
// src/providers/provider-input-support.ts
|
|
11917
|
-
var VALID_INPUT_MEDIA_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "resource"]);
|
|
11918
|
-
function getProviderLabel(provider) {
|
|
11919
|
-
return provider?.name || provider?.type || "This provider";
|
|
11920
|
-
}
|
|
11921
|
-
function hasNonEmptyFallbackText(input) {
|
|
11922
|
-
return typeof input.textFallback === "string" && input.textFallback.trim().length > 0;
|
|
11923
|
-
}
|
|
11924
|
-
function getRequestedInputMediaTypes(input) {
|
|
11925
|
-
const types = /* @__PURE__ */ new Set();
|
|
11926
|
-
if (hasNonEmptyFallbackText(input) && !input.parts.some((part) => part.type === "text")) {
|
|
11927
|
-
types.add("text");
|
|
11928
|
-
}
|
|
11929
|
-
for (const part of input.parts) {
|
|
11930
|
-
if (VALID_INPUT_MEDIA_TYPES.has(part.type)) {
|
|
11931
|
-
types.add(part.type);
|
|
11932
|
-
}
|
|
11933
|
-
}
|
|
11934
|
-
return Array.from(types);
|
|
11935
|
-
}
|
|
11936
|
-
function getEffectiveSemanticPartCount(input) {
|
|
11937
|
-
let count = input.parts.length;
|
|
11938
|
-
if (hasNonEmptyFallbackText(input) && !input.parts.some((part) => part.type === "text")) {
|
|
11939
|
-
count += 1;
|
|
11940
|
-
}
|
|
11941
|
-
return count;
|
|
11942
|
-
}
|
|
11943
|
-
function assertTextOnlyInput(provider, input) {
|
|
11944
|
-
const unsupported = getRequestedInputMediaTypes(input).filter((type) => type !== "text");
|
|
11945
|
-
if (unsupported.length === 0) return;
|
|
11946
|
-
const label = getProviderLabel(provider);
|
|
11947
|
-
const suffix = unsupported.length === 1 ? "" : "s";
|
|
11948
|
-
throw new Error(`${label} only supports text input; unsupported input type${suffix}: ${unsupported.join(", ")}`);
|
|
11949
|
-
}
|
|
11950
|
-
function getDeclaredProviderInputSupport(provider) {
|
|
11951
|
-
const rawMediaTypes = Array.isArray(provider?.capabilities?.input?.mediaTypes) ? provider?.capabilities?.input?.mediaTypes.filter((type) => VALID_INPUT_MEDIA_TYPES.has(type)) : [];
|
|
11952
|
-
return {
|
|
11953
|
-
multipart: provider?.capabilities?.input?.multipart === true,
|
|
11954
|
-
mediaTypes: new Set(rawMediaTypes.length > 0 ? rawMediaTypes : ["text"])
|
|
11955
|
-
};
|
|
11956
|
-
}
|
|
11957
|
-
function assertProviderSupportsDeclaredInput(provider, input) {
|
|
11958
|
-
const label = getProviderLabel(provider);
|
|
11959
|
-
const support = getDeclaredProviderInputSupport(provider);
|
|
11960
|
-
const requestedTypes = getRequestedInputMediaTypes(input);
|
|
11961
|
-
const unsupported = requestedTypes.filter((type) => !support.mediaTypes.has(type));
|
|
11962
|
-
if (unsupported.length > 0) {
|
|
11963
|
-
const suffix = unsupported.length === 1 ? "" : "s";
|
|
11964
|
-
throw new Error(`${label} does not support input type${suffix}: ${unsupported.join(", ")}`);
|
|
11965
|
-
}
|
|
11966
|
-
if (getEffectiveSemanticPartCount(input) > 1 && !support.multipart) {
|
|
11967
|
-
throw new Error(`${label} does not support multipart input`);
|
|
11968
|
-
}
|
|
11969
|
-
}
|
|
11970
|
-
|
|
11971
|
-
// src/commands/chat-commands.ts
|
|
11972
12099
|
init_logger();
|
|
11973
12100
|
|
|
11974
12101
|
// src/logging/debug-trace.ts
|
|
@@ -12158,10 +12285,25 @@ function buildRecentSendKey(h, args, provider, signature) {
|
|
|
12158
12285
|
const target = args?.targetSessionId || args?.agentType || h.currentSession?.providerType || h.currentProviderType || h.currentManagerKey || "unknown";
|
|
12159
12286
|
return `${transport}:${target}:${signature.trim()}`;
|
|
12160
12287
|
}
|
|
12288
|
+
function summarizeSendInputPart(part) {
|
|
12289
|
+
if (!part || typeof part !== "object") return String(part ?? "");
|
|
12290
|
+
if (part.type === "text") return `text:${String(part.text || "").trim()}`;
|
|
12291
|
+
const fields = [
|
|
12292
|
+
`type=${String(part.type || "")}`,
|
|
12293
|
+
`mime=${String(part.mimeType || "")}`,
|
|
12294
|
+
`uri=${String(part.uri || "")}`,
|
|
12295
|
+
`name=${String(part.name || "")}`
|
|
12296
|
+
];
|
|
12297
|
+
const data = typeof part.data === "string" ? part.data : typeof part.resource?.blob === "string" ? part.resource.blob : "";
|
|
12298
|
+
if (data) fields.push(`dataLen=${data.length}`, `dataHash=${hashSignatureParts([data]).slice(0, 12)}`);
|
|
12299
|
+
const textish = [part.alt, part.transcript, part.description, part.title, part.resource?.uri].filter((value) => typeof value === "string" && value.trim()).join("");
|
|
12300
|
+
if (textish) fields.push(`meta=${hashSignatureParts([textish]).slice(0, 12)}`);
|
|
12301
|
+
return fields.join(";");
|
|
12302
|
+
}
|
|
12161
12303
|
function buildSendInputSignature(input) {
|
|
12162
12304
|
const text = typeof input.textFallback === "string" ? input.textFallback.trim() : "";
|
|
12163
|
-
|
|
12164
|
-
return
|
|
12305
|
+
const partSummaries = (input.parts || []).map(summarizeSendInputPart);
|
|
12306
|
+
return hashSignatureParts([text, ...partSummaries]);
|
|
12165
12307
|
}
|
|
12166
12308
|
function getSendChatInputEnvelope(args) {
|
|
12167
12309
|
return normalizeInputEnvelope(args?.input ? { input: args.input } : args);
|
|
@@ -13042,6 +13184,17 @@ async function handleSendChat(h, args) {
|
|
|
13042
13184
|
if (adapter) {
|
|
13043
13185
|
_log(`${transport} adapter: ${adapter.cliType}`);
|
|
13044
13186
|
try {
|
|
13187
|
+
const hasStructuredParts = input.parts.some((part) => part.type !== "text");
|
|
13188
|
+
if (hasStructuredParts) {
|
|
13189
|
+
const target = getTargetInstance(h, args);
|
|
13190
|
+
if (!target || target.category !== "cli") {
|
|
13191
|
+
return { success: false, error: `CLI instance not found for ${provider?.type || args?.agentType || "unknown"}` };
|
|
13192
|
+
}
|
|
13193
|
+
assertProviderSupportsDeclaredInput(provider, input);
|
|
13194
|
+
await waitOnceForFreshHermesCliStart(adapter, _log);
|
|
13195
|
+
target.onEvent("send_message", { input });
|
|
13196
|
+
return _logSendSuccess(`${transport}-instance`, target.type);
|
|
13197
|
+
}
|
|
13045
13198
|
assertTextOnlyInput(provider, input);
|
|
13046
13199
|
if (!text) return { success: false, error: "text required for PTY send" };
|
|
13047
13200
|
await waitOnceForFreshHermesCliStart(adapter, _log);
|
|
@@ -15131,7 +15284,7 @@ var DaemonCommandHandler = class {
|
|
|
15131
15284
|
|
|
15132
15285
|
// src/commands/cli-manager.ts
|
|
15133
15286
|
var os13 = __toESM(require("os"));
|
|
15134
|
-
var
|
|
15287
|
+
var path18 = __toESM(require("path"));
|
|
15135
15288
|
var crypto4 = __toESM(require("crypto"));
|
|
15136
15289
|
var import_fs6 = require("fs");
|
|
15137
15290
|
var import_child_process6 = require("child_process");
|
|
@@ -15166,6 +15319,79 @@ function normalizeProviderSessionId(provider, providerSessionId) {
|
|
|
15166
15319
|
}
|
|
15167
15320
|
|
|
15168
15321
|
// src/providers/cli-provider-instance.ts
|
|
15322
|
+
var IMAGE_MIME_EXTENSIONS = {
|
|
15323
|
+
"image/png": ".png",
|
|
15324
|
+
"image/jpeg": ".jpg",
|
|
15325
|
+
"image/jpg": ".jpg",
|
|
15326
|
+
"image/gif": ".gif",
|
|
15327
|
+
"image/webp": ".webp",
|
|
15328
|
+
"image/bmp": ".bmp",
|
|
15329
|
+
"image/tiff": ".tiff",
|
|
15330
|
+
"image/svg+xml": ".svg"
|
|
15331
|
+
};
|
|
15332
|
+
function filePathFromUri(uri) {
|
|
15333
|
+
if (!uri) return null;
|
|
15334
|
+
if (uri.startsWith("file://")) {
|
|
15335
|
+
try {
|
|
15336
|
+
return decodeURIComponent(new URL(uri).pathname);
|
|
15337
|
+
} catch {
|
|
15338
|
+
return uri.slice("file://".length);
|
|
15339
|
+
}
|
|
15340
|
+
}
|
|
15341
|
+
if (path16.isAbsolute(uri)) return uri;
|
|
15342
|
+
return null;
|
|
15343
|
+
}
|
|
15344
|
+
function extensionForImageMime(mimeType) {
|
|
15345
|
+
return IMAGE_MIME_EXTENSIONS[mimeType.toLowerCase()] || ".img";
|
|
15346
|
+
}
|
|
15347
|
+
function safeInputImageBasename(index, mimeType) {
|
|
15348
|
+
const extension = extensionForImageMime(mimeType);
|
|
15349
|
+
const suffix = crypto3.randomBytes(6).toString("hex");
|
|
15350
|
+
return `adhdev-input-image-${Date.now()}-${index}-${suffix}${extension}`;
|
|
15351
|
+
}
|
|
15352
|
+
function materializeImageDataPart(part, index, dir) {
|
|
15353
|
+
if (!part.data) return null;
|
|
15354
|
+
const rawData = part.data.includes(",") ? part.data.split(",").pop() || "" : part.data;
|
|
15355
|
+
if (!rawData) return null;
|
|
15356
|
+
fs6.mkdirSync(dir, { recursive: true });
|
|
15357
|
+
const filePath = path16.join(dir, safeInputImageBasename(index, part.mimeType));
|
|
15358
|
+
fs6.writeFileSync(filePath, Buffer.from(rawData, "base64"));
|
|
15359
|
+
return filePath;
|
|
15360
|
+
}
|
|
15361
|
+
function buildCliStructuredInputPrompt(input, options = {}) {
|
|
15362
|
+
const promptParts = [];
|
|
15363
|
+
const imageRefs = [];
|
|
15364
|
+
const resourceRefs = [];
|
|
15365
|
+
const materializeDir = options.materializeDir || path16.join(os12.tmpdir(), "adhdev-input-media");
|
|
15366
|
+
input.parts.forEach((part, index) => {
|
|
15367
|
+
if (part.type === "text" && part.text.trim()) {
|
|
15368
|
+
promptParts.push(part.text.trim());
|
|
15369
|
+
return;
|
|
15370
|
+
}
|
|
15371
|
+
if (part.type === "image") {
|
|
15372
|
+
const localPath = typeof part.uri === "string" ? filePathFromUri(part.uri) : null;
|
|
15373
|
+
const materializedPath = !localPath && part.data ? materializeImageDataPart(part, index, materializeDir) : null;
|
|
15374
|
+
const ref = localPath || materializedPath || part.uri || "";
|
|
15375
|
+
if (ref) imageRefs.push(ref);
|
|
15376
|
+
if (part.alt?.trim()) promptParts.push(part.alt.trim());
|
|
15377
|
+
return;
|
|
15378
|
+
}
|
|
15379
|
+
if (part.type === "resource_link") {
|
|
15380
|
+
resourceRefs.push([part.title, part.name, part.description, part.uri].filter(Boolean).join("\n"));
|
|
15381
|
+
return;
|
|
15382
|
+
}
|
|
15383
|
+
if (part.type === "resource") {
|
|
15384
|
+
resourceRefs.push([part.name, part.text, part.uri].filter(Boolean).join("\n"));
|
|
15385
|
+
}
|
|
15386
|
+
});
|
|
15387
|
+
if (input.textFallback.trim()) promptParts.push(input.textFallback.trim());
|
|
15388
|
+
const ordered = [
|
|
15389
|
+
...imageRefs,
|
|
15390
|
+
...promptParts,
|
|
15391
|
+
...resourceRefs
|
|
15392
|
+
].filter((value, index, values) => value.trim().length > 0 && values.indexOf(value) === index);
|
|
15393
|
+
return ordered.join("\n");
|
|
15394
|
+
}
|
|
15169
15395
|
function normalizePersistableCliHistoryContent(content) {
|
|
15170
15396
|
return flattenContent(content).replace(/\s+/g, " ").trim();
|
|
15171
15397
|
}
|
|
@@ -15485,6 +15711,7 @@ var CliProviderInstance = class {
|
|
|
15485
15711
|
resume: this.provider.resume,
|
|
15486
15712
|
controlValues: surface.controlValues,
|
|
15487
15713
|
providerControls: this.provider.controls,
|
|
15714
|
+
messageInput: getEffectiveMessageInputSupport(this.provider),
|
|
15488
15715
|
summaryMetadata: surface.summaryMetadata,
|
|
15489
15716
|
errorMessage: this.errorMessage,
|
|
15490
15717
|
errorReason: this.errorReason
|
|
@@ -15535,9 +15762,10 @@ var CliProviderInstance = class {
|
|
|
15535
15762
|
onEvent(event, data) {
|
|
15536
15763
|
if (event === "send_message") {
|
|
15537
15764
|
const input = normalizeInputEnvelope(data);
|
|
15538
|
-
|
|
15539
|
-
|
|
15540
|
-
|
|
15765
|
+
assertProviderSupportsDeclaredInput(this.provider, input);
|
|
15766
|
+
const promptText = buildCliStructuredInputPrompt(input);
|
|
15767
|
+
if (promptText) {
|
|
15768
|
+
void this.adapter.sendMessage(promptText).catch((e) => {
|
|
15541
15769
|
LOG.warn("CLI", `[${this.type}] send_message failed: ${e?.message || e}`);
|
|
15542
15770
|
});
|
|
15543
15771
|
}
|
|
@@ -16166,6 +16394,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
16166
16394
|
};
|
|
16167
16395
|
|
|
16168
16396
|
// src/providers/acp-provider-instance.ts
|
|
16397
|
+
var path17 = __toESM(require("path"));
|
|
16169
16398
|
var import_stream = require("stream");
|
|
16170
16399
|
var import_child_process5 = require("child_process");
|
|
16171
16400
|
var import_sdk = require("@agentclientprotocol/sdk");
|
|
@@ -16185,6 +16414,31 @@ function appendPromptText(promptParts, text) {
|
|
|
16185
16414
|
if (last?.type === "text" && last.text === normalized) return;
|
|
16186
16415
|
promptParts.push({ type: "text", text: normalized });
|
|
16187
16416
|
}
|
|
16417
|
+
function getUriDisplayName2(uri, fallback) {
|
|
16418
|
+
if (!uri) return fallback;
|
|
16419
|
+
try {
|
|
16420
|
+
const pathname = uri.startsWith("file://") ? new URL(uri).pathname : uri;
|
|
16421
|
+
return pathname.split(/[\\/]/).filter(Boolean).pop() || fallback;
|
|
16422
|
+
} catch {
|
|
16423
|
+
return uri.split(/[\\/]/).filter(Boolean).pop() || fallback;
|
|
16424
|
+
}
|
|
16425
|
+
}
|
|
16426
|
+
function appendResourceLink(promptParts, uri, fallbackName, mimeType, description, metadata) {
|
|
16427
|
+
promptParts.push({
|
|
16428
|
+
type: "resource_link",
|
|
16429
|
+
uri,
|
|
16430
|
+
name: metadata?.name || getUriDisplayName2(uri, fallbackName),
|
|
16431
|
+
...metadata?.title ? { title: metadata.title } : {},
|
|
16432
|
+
...mimeType ? { mimeType } : {},
|
|
16433
|
+
...description ? { description } : {},
|
|
16434
|
+
...typeof metadata?.size === "number" ? { size: metadata.size } : {},
|
|
16435
|
+
...metadata?.annotations ? { annotations: metadata.annotations } : {}
|
|
16436
|
+
});
|
|
16437
|
+
}
|
|
16438
|
+
function appendMediaFallbackText(promptParts, label, details) {
|
|
16439
|
+
const normalizedDetails = details.map((value) => typeof value === "string" ? value.trim() : "").filter(Boolean);
|
|
16440
|
+
appendPromptText(promptParts, `[${[label, ...normalizedDetails].join(": ")}]`);
|
|
16441
|
+
}
|
|
16188
16442
|
function buildAcpPromptParts(input, agentCapabilities) {
|
|
16189
16443
|
const caps = getPromptCapabilityFlags(agentCapabilities);
|
|
16190
16444
|
const promptParts = [];
|
|
@@ -16194,56 +16448,76 @@ function buildAcpPromptParts(input, agentCapabilities) {
|
|
|
16194
16448
|
continue;
|
|
16195
16449
|
}
|
|
16196
16450
|
if (part.type === "image") {
|
|
16197
|
-
if (
|
|
16198
|
-
|
|
16199
|
-
|
|
16200
|
-
|
|
16201
|
-
|
|
16451
|
+
if (caps.image && part.data) {
|
|
16452
|
+
promptParts.push({
|
|
16453
|
+
type: "image",
|
|
16454
|
+
data: part.data,
|
|
16455
|
+
mimeType: part.mimeType,
|
|
16456
|
+
...part.uri ? { uri: part.uri } : {},
|
|
16457
|
+
...part.alt ? { alt: part.alt } : {}
|
|
16458
|
+
});
|
|
16459
|
+
if (part.alt) appendPromptText(promptParts, part.alt);
|
|
16460
|
+
} else if (part.uri) {
|
|
16461
|
+
appendResourceLink(promptParts, part.uri, "image", part.mimeType, part.alt);
|
|
16462
|
+
if (part.alt) appendPromptText(promptParts, part.alt);
|
|
16463
|
+
} else {
|
|
16464
|
+
appendMediaFallbackText(promptParts, "Image attachment", [part.alt, part.mimeType]);
|
|
16202
16465
|
}
|
|
16203
|
-
promptParts.push({
|
|
16204
|
-
type: "image",
|
|
16205
|
-
data: part.data,
|
|
16206
|
-
mimeType: part.mimeType,
|
|
16207
|
-
...part.uri ? { uri: part.uri } : {}
|
|
16208
|
-
});
|
|
16209
16466
|
continue;
|
|
16210
16467
|
}
|
|
16211
16468
|
if (part.type === "audio") {
|
|
16212
|
-
if (
|
|
16213
|
-
|
|
16214
|
-
|
|
16215
|
-
|
|
16216
|
-
|
|
16469
|
+
if (caps.audio && part.data) {
|
|
16470
|
+
promptParts.push({
|
|
16471
|
+
type: "audio",
|
|
16472
|
+
data: part.data,
|
|
16473
|
+
mimeType: part.mimeType,
|
|
16474
|
+
...part.uri ? { uri: part.uri } : {},
|
|
16475
|
+
...part.transcript ? { transcript: part.transcript } : {}
|
|
16476
|
+
});
|
|
16477
|
+
if (part.transcript) appendPromptText(promptParts, part.transcript);
|
|
16478
|
+
} else if (part.uri) {
|
|
16479
|
+
appendResourceLink(promptParts, part.uri, "audio", part.mimeType, part.transcript);
|
|
16480
|
+
if (part.transcript) appendPromptText(promptParts, part.transcript);
|
|
16481
|
+
} else {
|
|
16482
|
+
appendMediaFallbackText(promptParts, "Audio attachment", [part.transcript, part.mimeType]);
|
|
16217
16483
|
}
|
|
16218
|
-
promptParts.push({
|
|
16219
|
-
type: "audio",
|
|
16220
|
-
data: part.data,
|
|
16221
|
-
mimeType: part.mimeType
|
|
16222
|
-
});
|
|
16223
16484
|
continue;
|
|
16224
16485
|
}
|
|
16225
16486
|
if (part.type === "resource") {
|
|
16226
|
-
if (
|
|
16227
|
-
throw new Error("ACP agent does not support input type: resource");
|
|
16228
|
-
}
|
|
16229
|
-
if (part.text) {
|
|
16487
|
+
if (caps.embeddedContext && part.text) {
|
|
16230
16488
|
promptParts.push({
|
|
16231
16489
|
type: "resource",
|
|
16232
16490
|
resource: { uri: part.uri, text: part.text, mimeType: part.mimeType ?? null }
|
|
16233
16491
|
});
|
|
16234
16492
|
continue;
|
|
16235
16493
|
}
|
|
16236
|
-
if (part.data) {
|
|
16494
|
+
if (caps.embeddedContext && part.data) {
|
|
16237
16495
|
promptParts.push({
|
|
16238
16496
|
type: "resource",
|
|
16239
16497
|
resource: { uri: part.uri, blob: part.data, mimeType: part.mimeType ?? null }
|
|
16240
16498
|
});
|
|
16241
16499
|
continue;
|
|
16242
16500
|
}
|
|
16243
|
-
|
|
16501
|
+
appendResourceLink(promptParts, part.uri, part.name || "resource", part.mimeType, part.text);
|
|
16502
|
+
if (part.text) appendPromptText(promptParts, part.text);
|
|
16503
|
+
continue;
|
|
16504
|
+
}
|
|
16505
|
+
if (part.type === "resource_link") {
|
|
16506
|
+
appendResourceLink(promptParts, part.uri, part.name, part.mimeType, part.description, {
|
|
16507
|
+
name: part.name,
|
|
16508
|
+
...part.title ? { title: part.title } : {},
|
|
16509
|
+
...typeof part.size === "number" ? { size: part.size } : {},
|
|
16510
|
+
...part.annotations ? { annotations: part.annotations } : {}
|
|
16511
|
+
});
|
|
16512
|
+
continue;
|
|
16244
16513
|
}
|
|
16245
16514
|
if (part.type === "video") {
|
|
16246
|
-
|
|
16515
|
+
if (part.uri) {
|
|
16516
|
+
appendResourceLink(promptParts, part.uri, "video", part.mimeType, part.transcript);
|
|
16517
|
+
if (part.transcript) appendPromptText(promptParts, part.transcript);
|
|
16518
|
+
} else {
|
|
16519
|
+
appendMediaFallbackText(promptParts, "Video attachment", [part.transcript, part.mimeType]);
|
|
16520
|
+
}
|
|
16247
16521
|
}
|
|
16248
16522
|
}
|
|
16249
16523
|
if (!promptParts.some((part) => part.type === "text") && input.textFallback) {
|
|
@@ -16376,6 +16650,7 @@ var AcpProviderInstance = class {
|
|
|
16376
16650
|
lastUpdated: Date.now(),
|
|
16377
16651
|
settings: this.settings,
|
|
16378
16652
|
pendingEvents: this.flushEvents(),
|
|
16653
|
+
messageInput: getEffectiveMessageInputSupport(this.provider, this.agentCapabilities),
|
|
16379
16654
|
// ACP-specific: expose available models/modes for dashboard
|
|
16380
16655
|
acpConfigOptions: this.configOptions,
|
|
16381
16656
|
acpModes: this.availableModes,
|
|
@@ -16877,22 +17152,38 @@ var AcpProviderInstance = class {
|
|
|
16877
17152
|
type: "image",
|
|
16878
17153
|
data: b.data,
|
|
16879
17154
|
mimeType: b.mimeType,
|
|
16880
|
-
...b.uri ? { uri: b.uri } : {}
|
|
17155
|
+
...b.uri ? { uri: b.uri } : {},
|
|
17156
|
+
...b.alt ? { alt: b.alt } : {}
|
|
16881
17157
|
};
|
|
16882
17158
|
}
|
|
16883
17159
|
if (b.type === "audio") {
|
|
16884
17160
|
return {
|
|
16885
17161
|
type: "audio",
|
|
16886
17162
|
data: b.data,
|
|
16887
|
-
mimeType: b.mimeType
|
|
17163
|
+
mimeType: b.mimeType,
|
|
17164
|
+
...b.uri ? { uri: b.uri } : {},
|
|
17165
|
+
...b.transcript ? { transcript: b.transcript } : {}
|
|
16888
17166
|
};
|
|
16889
17167
|
}
|
|
17168
|
+
if (b.type === "video") {
|
|
17169
|
+
return b.uri ? {
|
|
17170
|
+
type: "resource_link",
|
|
17171
|
+
uri: b.uri,
|
|
17172
|
+
name: path17.basename(b.uri),
|
|
17173
|
+
mimeType: b.mimeType,
|
|
17174
|
+
...b.transcript ? { description: b.transcript } : {}
|
|
17175
|
+
} : { type: "text", text: b.transcript || `[Video attachment: ${b.mimeType}]` };
|
|
17176
|
+
}
|
|
16890
17177
|
if (b.type === "resource_link") {
|
|
16891
17178
|
return {
|
|
16892
17179
|
type: "resource_link",
|
|
16893
17180
|
uri: b.uri,
|
|
16894
17181
|
name: b.name,
|
|
16895
|
-
...b.
|
|
17182
|
+
...b.title ? { title: b.title } : {},
|
|
17183
|
+
...b.description ? { description: b.description } : {},
|
|
17184
|
+
...b.mimeType ? { mimeType: b.mimeType } : {},
|
|
17185
|
+
...typeof b.size === "number" ? { size: b.size } : {},
|
|
17186
|
+
...b.annotations ? { annotations: b.annotations } : {}
|
|
16896
17187
|
};
|
|
16897
17188
|
}
|
|
16898
17189
|
if (b.type === "resource") return { type: "resource", resource: b.resource };
|
|
@@ -16968,7 +17259,18 @@ var AcpProviderInstance = class {
|
|
|
16968
17259
|
this.partialBlocks.push({
|
|
16969
17260
|
type: "audio",
|
|
16970
17261
|
data: content.data,
|
|
16971
|
-
mimeType: content.mimeType
|
|
17262
|
+
mimeType: content.mimeType,
|
|
17263
|
+
...content.uri ? { uri: content.uri } : {},
|
|
17264
|
+
...content.transcript ? { transcript: content.transcript } : {}
|
|
17265
|
+
});
|
|
17266
|
+
} else if (content.type === "video") {
|
|
17267
|
+
this.partialBlocks.push({
|
|
17268
|
+
type: "video",
|
|
17269
|
+
data: content.data,
|
|
17270
|
+
mimeType: content.mimeType,
|
|
17271
|
+
...content.uri ? { uri: content.uri } : {},
|
|
17272
|
+
...content.transcript ? { transcript: content.transcript } : {},
|
|
17273
|
+
...content.posterUri ? { posterUri: content.posterUri } : {}
|
|
16972
17274
|
});
|
|
16973
17275
|
} else if (content.type === "resource_link") {
|
|
16974
17276
|
this.partialBlocks.push({
|
|
@@ -17325,11 +17627,11 @@ function shouldRestoreHostedRuntime(record, managerTag) {
|
|
|
17325
17627
|
// src/commands/cli-manager.ts
|
|
17326
17628
|
function isExplicitCommand(command) {
|
|
17327
17629
|
const trimmed = command.trim();
|
|
17328
|
-
return
|
|
17630
|
+
return path18.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
|
|
17329
17631
|
}
|
|
17330
17632
|
function expandExecutable(command) {
|
|
17331
17633
|
const trimmed = command.trim();
|
|
17332
|
-
return trimmed.startsWith("~") ?
|
|
17634
|
+
return trimmed.startsWith("~") ? path18.join(os13.homedir(), trimmed.slice(1)) : trimmed;
|
|
17333
17635
|
}
|
|
17334
17636
|
function commandExists(command) {
|
|
17335
17637
|
const trimmed = command.trim();
|
|
@@ -17363,10 +17665,10 @@ function hasCliArg(args, flag) {
|
|
|
17363
17665
|
return args.some((arg) => arg === flag || arg.startsWith(`${flag}=`));
|
|
17364
17666
|
}
|
|
17365
17667
|
function ensureEmptyDelegatedMcpConfig(workspace) {
|
|
17366
|
-
const baseDir =
|
|
17668
|
+
const baseDir = path18.join(os13.tmpdir(), "adhdev-delegated-agent-empty-mcp");
|
|
17367
17669
|
(0, import_fs6.mkdirSync)(baseDir, { recursive: true });
|
|
17368
|
-
const workspaceHash = crypto4.createHash("sha256").update(
|
|
17369
|
-
const filePath =
|
|
17670
|
+
const workspaceHash = crypto4.createHash("sha256").update(path18.resolve(workspace || os13.tmpdir())).digest("hex").slice(0, 16);
|
|
17671
|
+
const filePath = path18.join(baseDir, `${workspaceHash}.json`);
|
|
17370
17672
|
(0, import_fs6.writeFileSync)(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
|
|
17371
17673
|
return filePath;
|
|
17372
17674
|
}
|
|
@@ -17639,7 +17941,7 @@ var DaemonCliManager = class {
|
|
|
17639
17941
|
async startSession(cliType, workingDir, cliArgs, initialModel, options) {
|
|
17640
17942
|
const trimmed = (workingDir || "").trim();
|
|
17641
17943
|
if (!trimmed) throw new Error("working directory required");
|
|
17642
|
-
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) :
|
|
17944
|
+
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) : path18.resolve(trimmed);
|
|
17643
17945
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
17644
17946
|
const rawProvider = this.providerLoader.getByAlias(cliType);
|
|
17645
17947
|
const provider = rawProvider ? this.providerLoader.resolve(normalizedType) || rawProvider : void 0;
|
|
@@ -18153,17 +18455,18 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
18153
18455
|
var import_child_process7 = require("child_process");
|
|
18154
18456
|
var net = __toESM(require("net"));
|
|
18155
18457
|
var os15 = __toESM(require("os"));
|
|
18156
|
-
var
|
|
18458
|
+
var path20 = __toESM(require("path"));
|
|
18157
18459
|
|
|
18158
18460
|
// src/providers/provider-loader.ts
|
|
18159
18461
|
var fs7 = __toESM(require("fs"));
|
|
18160
|
-
var
|
|
18462
|
+
var path19 = __toESM(require("path"));
|
|
18161
18463
|
var os14 = __toESM(require("os"));
|
|
18162
18464
|
var chokidar = __toESM(require("chokidar"));
|
|
18163
18465
|
init_logger();
|
|
18164
18466
|
|
|
18165
18467
|
// src/providers/provider-schema.ts
|
|
18166
18468
|
var VALID_CAPABILITY_MEDIA_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "resource"]);
|
|
18469
|
+
var VALID_INPUT_STRATEGIES2 = /* @__PURE__ */ new Set(["native", "native_acp", "resource_link", "text_fallback", "paste", "upload"]);
|
|
18167
18470
|
var KNOWN_PROVIDER_FIELDS = /* @__PURE__ */ new Set([
|
|
18168
18471
|
"type",
|
|
18169
18472
|
"name",
|
|
@@ -18293,16 +18596,45 @@ function validateCapabilities(provider, controls, errors) {
|
|
|
18293
18596
|
return;
|
|
18294
18597
|
}
|
|
18295
18598
|
const input = capabilities.input;
|
|
18296
|
-
if (
|
|
18297
|
-
|
|
18298
|
-
|
|
18299
|
-
if (typeof input.multipart !== "boolean") {
|
|
18599
|
+
if (input !== void 0) {
|
|
18600
|
+
if (!input || typeof input !== "object") {
|
|
18601
|
+
errors.push("capabilities.input must be an object when provided");
|
|
18602
|
+
} else if (typeof input.multipart !== "boolean") {
|
|
18300
18603
|
errors.push("capabilities.input.multipart must be boolean");
|
|
18301
18604
|
}
|
|
18302
|
-
if (
|
|
18303
|
-
|
|
18304
|
-
|
|
18305
|
-
|
|
18605
|
+
if (input && typeof input === "object") {
|
|
18606
|
+
const mediaTypes = Array.isArray(input.mediaTypes) ? input.mediaTypes : void 0;
|
|
18607
|
+
if (!mediaTypes || mediaTypes.length === 0) {
|
|
18608
|
+
errors.push("capabilities.input.mediaTypes must be a non-empty array");
|
|
18609
|
+
} else if (mediaTypes.some((type) => typeof type !== "string" || !VALID_CAPABILITY_MEDIA_TYPES.has(type))) {
|
|
18610
|
+
errors.push(`capabilities.input.mediaTypes must only include: ${Array.from(VALID_CAPABILITY_MEDIA_TYPES).join(", ")}`);
|
|
18611
|
+
}
|
|
18612
|
+
}
|
|
18613
|
+
if (input && typeof input === "object" && input.strategies !== void 0) {
|
|
18614
|
+
if (!Array.isArray(input.strategies)) {
|
|
18615
|
+
errors.push("capabilities.input.strategies must be an array when provided");
|
|
18616
|
+
} else {
|
|
18617
|
+
for (const strategy of input.strategies) {
|
|
18618
|
+
if (!strategy || typeof strategy !== "object" || Array.isArray(strategy)) {
|
|
18619
|
+
errors.push("capabilities.input.strategies entries must be objects");
|
|
18620
|
+
continue;
|
|
18621
|
+
}
|
|
18622
|
+
const entry = strategy;
|
|
18623
|
+
if (typeof entry.mediaType !== "string" || !VALID_CAPABILITY_MEDIA_TYPES.has(entry.mediaType)) {
|
|
18624
|
+
errors.push(`capabilities.input.strategies.mediaType must only include: ${Array.from(VALID_CAPABILITY_MEDIA_TYPES).join(", ")}`);
|
|
18625
|
+
}
|
|
18626
|
+
for (const field of ["strategies", "degradation"]) {
|
|
18627
|
+
const values = entry[field];
|
|
18628
|
+
if (values === void 0) continue;
|
|
18629
|
+
if (!Array.isArray(values) || values.some((value) => typeof value !== "string" || !VALID_INPUT_STRATEGIES2.has(value))) {
|
|
18630
|
+
errors.push(`capabilities.input.strategies.${field} must only include: ${Array.from(VALID_INPUT_STRATEGIES2).join(", ")}`);
|
|
18631
|
+
}
|
|
18632
|
+
}
|
|
18633
|
+
if (entry.native !== void 0 && typeof entry.native !== "boolean") {
|
|
18634
|
+
errors.push("capabilities.input.strategies.native must be boolean when provided");
|
|
18635
|
+
}
|
|
18636
|
+
}
|
|
18637
|
+
}
|
|
18306
18638
|
}
|
|
18307
18639
|
}
|
|
18308
18640
|
const output = capabilities.output;
|
|
@@ -18481,7 +18813,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18481
18813
|
try {
|
|
18482
18814
|
if (!fs7.existsSync(candidate) || !fs7.statSync(candidate).isDirectory()) return false;
|
|
18483
18815
|
return ["ide", "extension", "cli", "acp"].some(
|
|
18484
|
-
(category) => fs7.existsSync(
|
|
18816
|
+
(category) => fs7.existsSync(path19.join(candidate, category))
|
|
18485
18817
|
);
|
|
18486
18818
|
} catch {
|
|
18487
18819
|
return false;
|
|
@@ -18489,20 +18821,20 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18489
18821
|
}
|
|
18490
18822
|
static hasProviderRootMarker(candidate) {
|
|
18491
18823
|
try {
|
|
18492
|
-
return fs7.existsSync(
|
|
18824
|
+
return fs7.existsSync(path19.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
|
|
18493
18825
|
} catch {
|
|
18494
18826
|
return false;
|
|
18495
18827
|
}
|
|
18496
18828
|
}
|
|
18497
18829
|
detectDefaultUserDir() {
|
|
18498
|
-
const fallback =
|
|
18830
|
+
const fallback = path19.join(os14.homedir(), ".adhdev", "providers");
|
|
18499
18831
|
const envOptIn = process.env[_ProviderLoader.SIBLING_ENV_VAR] === "1";
|
|
18500
18832
|
const visited = /* @__PURE__ */ new Set();
|
|
18501
18833
|
for (const start of this.probeStarts) {
|
|
18502
|
-
let current =
|
|
18834
|
+
let current = path19.resolve(start);
|
|
18503
18835
|
while (!visited.has(current)) {
|
|
18504
18836
|
visited.add(current);
|
|
18505
|
-
const siblingCandidate =
|
|
18837
|
+
const siblingCandidate = path19.join(path19.dirname(current), _ProviderLoader.REPO_PROVIDER_DIRNAME);
|
|
18506
18838
|
if (_ProviderLoader.looksLikeProviderRoot(siblingCandidate)) {
|
|
18507
18839
|
const hasMarker = _ProviderLoader.hasProviderRootMarker(siblingCandidate);
|
|
18508
18840
|
if (envOptIn || hasMarker) {
|
|
@@ -18524,7 +18856,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18524
18856
|
return { path: siblingCandidate, source };
|
|
18525
18857
|
}
|
|
18526
18858
|
}
|
|
18527
|
-
const parent =
|
|
18859
|
+
const parent = path19.dirname(current);
|
|
18528
18860
|
if (parent === current) break;
|
|
18529
18861
|
current = parent;
|
|
18530
18862
|
}
|
|
@@ -18534,11 +18866,11 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18534
18866
|
constructor(options) {
|
|
18535
18867
|
this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
|
|
18536
18868
|
this.probeStarts = options?.probeStarts ?? [process.cwd(), __dirname];
|
|
18537
|
-
this.defaultProvidersDir =
|
|
18869
|
+
this.defaultProvidersDir = path19.join(os14.homedir(), ".adhdev", "providers");
|
|
18538
18870
|
const detected = this.detectDefaultUserDir();
|
|
18539
18871
|
this.userDir = detected.path;
|
|
18540
18872
|
this.userDirSource = detected.source;
|
|
18541
|
-
this.upstreamDir =
|
|
18873
|
+
this.upstreamDir = path19.join(this.defaultProvidersDir, ".upstream");
|
|
18542
18874
|
this.disableUpstream = false;
|
|
18543
18875
|
this.applySourceConfig({
|
|
18544
18876
|
userDir: options?.userDir,
|
|
@@ -18597,7 +18929,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18597
18929
|
this.userDir = detected.path;
|
|
18598
18930
|
this.userDirSource = detected.source;
|
|
18599
18931
|
}
|
|
18600
|
-
this.upstreamDir =
|
|
18932
|
+
this.upstreamDir = path19.join(this.defaultProvidersDir, ".upstream");
|
|
18601
18933
|
this.disableUpstream = this.sourceMode === "no-upstream";
|
|
18602
18934
|
if (this.explicitProviderDir) {
|
|
18603
18935
|
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
@@ -18611,7 +18943,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18611
18943
|
* Canonical provider directory shape for a given root.
|
|
18612
18944
|
*/
|
|
18613
18945
|
getProviderDir(root, category, type) {
|
|
18614
|
-
return
|
|
18946
|
+
return path19.join(root, category, type);
|
|
18615
18947
|
}
|
|
18616
18948
|
/**
|
|
18617
18949
|
* Canonical user override directory for a provider.
|
|
@@ -18638,7 +18970,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18638
18970
|
resolveProviderFile(type, ...segments) {
|
|
18639
18971
|
const dir = this.findProviderDirInternal(type);
|
|
18640
18972
|
if (!dir) return null;
|
|
18641
|
-
return
|
|
18973
|
+
return path19.join(dir, ...segments);
|
|
18642
18974
|
}
|
|
18643
18975
|
/**
|
|
18644
18976
|
* Load all providers (3-tier priority)
|
|
@@ -18677,7 +19009,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18677
19009
|
if (!fs7.existsSync(this.upstreamDir)) return false;
|
|
18678
19010
|
try {
|
|
18679
19011
|
return fs7.readdirSync(this.upstreamDir).some(
|
|
18680
|
-
(d) => fs7.statSync(
|
|
19012
|
+
(d) => fs7.statSync(path19.join(this.upstreamDir, d)).isDirectory()
|
|
18681
19013
|
);
|
|
18682
19014
|
} catch {
|
|
18683
19015
|
return false;
|
|
@@ -19174,8 +19506,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19174
19506
|
resolved._resolvedScriptDir = entry.scriptDir;
|
|
19175
19507
|
resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
|
|
19176
19508
|
if (providerDir) {
|
|
19177
|
-
const fullDir =
|
|
19178
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
19509
|
+
const fullDir = path19.join(providerDir, entry.scriptDir);
|
|
19510
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path19.join(fullDir, "scripts.js")) ? path19.join(fullDir, "scripts.js") : fullDir;
|
|
19179
19511
|
}
|
|
19180
19512
|
matched = true;
|
|
19181
19513
|
}
|
|
@@ -19190,8 +19522,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19190
19522
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
19191
19523
|
resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
|
|
19192
19524
|
if (providerDir) {
|
|
19193
|
-
const fullDir =
|
|
19194
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
19525
|
+
const fullDir = path19.join(providerDir, base.defaultScriptDir);
|
|
19526
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path19.join(fullDir, "scripts.js")) ? path19.join(fullDir, "scripts.js") : fullDir;
|
|
19195
19527
|
}
|
|
19196
19528
|
}
|
|
19197
19529
|
resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
|
|
@@ -19208,8 +19540,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19208
19540
|
resolved._resolvedScriptDir = dirOverride;
|
|
19209
19541
|
resolved._resolvedScriptsSource = `versions:${range}`;
|
|
19210
19542
|
if (providerDir) {
|
|
19211
|
-
const fullDir =
|
|
19212
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
19543
|
+
const fullDir = path19.join(providerDir, dirOverride);
|
|
19544
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path19.join(fullDir, "scripts.js")) ? path19.join(fullDir, "scripts.js") : fullDir;
|
|
19213
19545
|
}
|
|
19214
19546
|
}
|
|
19215
19547
|
} else if (override.scripts) {
|
|
@@ -19225,8 +19557,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19225
19557
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
19226
19558
|
resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
|
|
19227
19559
|
if (providerDir) {
|
|
19228
|
-
const fullDir =
|
|
19229
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
19560
|
+
const fullDir = path19.join(providerDir, base.defaultScriptDir);
|
|
19561
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path19.join(fullDir, "scripts.js")) ? path19.join(fullDir, "scripts.js") : fullDir;
|
|
19230
19562
|
}
|
|
19231
19563
|
}
|
|
19232
19564
|
}
|
|
@@ -19258,14 +19590,14 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19258
19590
|
this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
|
|
19259
19591
|
return null;
|
|
19260
19592
|
}
|
|
19261
|
-
const dir =
|
|
19593
|
+
const dir = path19.join(providerDir, scriptDir);
|
|
19262
19594
|
if (!fs7.existsSync(dir)) {
|
|
19263
19595
|
this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
|
|
19264
19596
|
return null;
|
|
19265
19597
|
}
|
|
19266
19598
|
const cached = this.scriptsCache.get(dir);
|
|
19267
19599
|
if (cached) return cached;
|
|
19268
|
-
const scriptsJs =
|
|
19600
|
+
const scriptsJs = path19.join(dir, "scripts.js");
|
|
19269
19601
|
if (fs7.existsSync(scriptsJs)) {
|
|
19270
19602
|
try {
|
|
19271
19603
|
delete require.cache[require.resolve(scriptsJs)];
|
|
@@ -19307,7 +19639,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19307
19639
|
return;
|
|
19308
19640
|
}
|
|
19309
19641
|
if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
|
|
19310
|
-
this.log(`File changed: ${
|
|
19642
|
+
this.log(`File changed: ${path19.basename(filePath)}, reloading...`);
|
|
19311
19643
|
this.reload();
|
|
19312
19644
|
}
|
|
19313
19645
|
};
|
|
@@ -19362,7 +19694,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19362
19694
|
}
|
|
19363
19695
|
const https = require("https");
|
|
19364
19696
|
const { execSync: execSync7 } = require("child_process");
|
|
19365
|
-
const metaPath =
|
|
19697
|
+
const metaPath = path19.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
19366
19698
|
let prevEtag = "";
|
|
19367
19699
|
let prevTimestamp = 0;
|
|
19368
19700
|
try {
|
|
@@ -19422,17 +19754,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19422
19754
|
return { updated: false };
|
|
19423
19755
|
}
|
|
19424
19756
|
this.log("Downloading latest providers from GitHub...");
|
|
19425
|
-
const tmpTar =
|
|
19426
|
-
const tmpExtract =
|
|
19757
|
+
const tmpTar = path19.join(os14.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
|
|
19758
|
+
const tmpExtract = path19.join(os14.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
|
|
19427
19759
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
19428
19760
|
fs7.mkdirSync(tmpExtract, { recursive: true });
|
|
19429
19761
|
execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
19430
19762
|
const extracted = fs7.readdirSync(tmpExtract);
|
|
19431
19763
|
const rootDir = extracted.find(
|
|
19432
|
-
(d) => fs7.statSync(
|
|
19764
|
+
(d) => fs7.statSync(path19.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
|
|
19433
19765
|
);
|
|
19434
19766
|
if (!rootDir) throw new Error("Unexpected tarball structure");
|
|
19435
|
-
const sourceDir =
|
|
19767
|
+
const sourceDir = path19.join(tmpExtract, rootDir);
|
|
19436
19768
|
const backupDir = this.upstreamDir + ".bak";
|
|
19437
19769
|
if (fs7.existsSync(this.upstreamDir)) {
|
|
19438
19770
|
if (fs7.existsSync(backupDir)) fs7.rmSync(backupDir, { recursive: true, force: true });
|
|
@@ -19507,8 +19839,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19507
19839
|
copyDirRecursive(src, dest) {
|
|
19508
19840
|
fs7.mkdirSync(dest, { recursive: true });
|
|
19509
19841
|
for (const entry of fs7.readdirSync(src, { withFileTypes: true })) {
|
|
19510
|
-
const srcPath =
|
|
19511
|
-
const destPath =
|
|
19842
|
+
const srcPath = path19.join(src, entry.name);
|
|
19843
|
+
const destPath = path19.join(dest, entry.name);
|
|
19512
19844
|
if (entry.isDirectory()) {
|
|
19513
19845
|
this.copyDirRecursive(srcPath, destPath);
|
|
19514
19846
|
} else {
|
|
@@ -19519,7 +19851,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19519
19851
|
/** .meta.json save */
|
|
19520
19852
|
writeMeta(metaPath, etag, timestamp) {
|
|
19521
19853
|
try {
|
|
19522
|
-
fs7.mkdirSync(
|
|
19854
|
+
fs7.mkdirSync(path19.dirname(metaPath), { recursive: true });
|
|
19523
19855
|
fs7.writeFileSync(metaPath, JSON.stringify({
|
|
19524
19856
|
etag,
|
|
19525
19857
|
timestamp,
|
|
@@ -19536,7 +19868,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19536
19868
|
const scan = (d) => {
|
|
19537
19869
|
try {
|
|
19538
19870
|
for (const entry of fs7.readdirSync(d, { withFileTypes: true })) {
|
|
19539
|
-
if (entry.isDirectory()) scan(
|
|
19871
|
+
if (entry.isDirectory()) scan(path19.join(d, entry.name));
|
|
19540
19872
|
else if (entry.name === "provider.json") count++;
|
|
19541
19873
|
}
|
|
19542
19874
|
} catch {
|
|
@@ -19764,17 +20096,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19764
20096
|
for (const root of searchRoots) {
|
|
19765
20097
|
if (!fs7.existsSync(root)) continue;
|
|
19766
20098
|
const candidate = this.getProviderDir(root, cat, type);
|
|
19767
|
-
if (fs7.existsSync(
|
|
19768
|
-
const catDir =
|
|
20099
|
+
if (fs7.existsSync(path19.join(candidate, "provider.json"))) return candidate;
|
|
20100
|
+
const catDir = path19.join(root, cat);
|
|
19769
20101
|
if (fs7.existsSync(catDir)) {
|
|
19770
20102
|
try {
|
|
19771
20103
|
for (const entry of fs7.readdirSync(catDir, { withFileTypes: true })) {
|
|
19772
20104
|
if (!entry.isDirectory()) continue;
|
|
19773
|
-
const jsonPath =
|
|
20105
|
+
const jsonPath = path19.join(catDir, entry.name, "provider.json");
|
|
19774
20106
|
if (fs7.existsSync(jsonPath)) {
|
|
19775
20107
|
try {
|
|
19776
20108
|
const data = JSON.parse(fs7.readFileSync(jsonPath, "utf-8"));
|
|
19777
|
-
if (data.type === type) return
|
|
20109
|
+
if (data.type === type) return path19.join(catDir, entry.name);
|
|
19778
20110
|
} catch {
|
|
19779
20111
|
}
|
|
19780
20112
|
}
|
|
@@ -19791,7 +20123,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19791
20123
|
* (template substitution is NOT applied here — scripts.js handles that)
|
|
19792
20124
|
*/
|
|
19793
20125
|
buildScriptWrappersFromDir(dir) {
|
|
19794
|
-
const scriptsJs =
|
|
20126
|
+
const scriptsJs = path19.join(dir, "scripts.js");
|
|
19795
20127
|
if (fs7.existsSync(scriptsJs)) {
|
|
19796
20128
|
try {
|
|
19797
20129
|
delete require.cache[require.resolve(scriptsJs)];
|
|
@@ -19805,7 +20137,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19805
20137
|
for (const file of fs7.readdirSync(dir)) {
|
|
19806
20138
|
if (!file.endsWith(".js")) continue;
|
|
19807
20139
|
const scriptName = toCamel(file.replace(".js", ""));
|
|
19808
|
-
const filePath =
|
|
20140
|
+
const filePath = path19.join(dir, file);
|
|
19809
20141
|
result[scriptName] = (...args) => {
|
|
19810
20142
|
try {
|
|
19811
20143
|
let content = fs7.readFileSync(filePath, "utf-8");
|
|
@@ -19865,7 +20197,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19865
20197
|
}
|
|
19866
20198
|
const hasJson = entries.some((e) => e.name === "provider.json");
|
|
19867
20199
|
if (hasJson) {
|
|
19868
|
-
const jsonPath =
|
|
20200
|
+
const jsonPath = path19.join(d, "provider.json");
|
|
19869
20201
|
try {
|
|
19870
20202
|
const raw = fs7.readFileSync(jsonPath, "utf-8");
|
|
19871
20203
|
const mod = JSON.parse(raw);
|
|
@@ -19886,7 +20218,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19886
20218
|
this.log(`\u26A0 Invalid provider at ${jsonPath}: ${validation.errors.join("; ")}`);
|
|
19887
20219
|
} else {
|
|
19888
20220
|
const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
|
|
19889
|
-
const scriptsPath =
|
|
20221
|
+
const scriptsPath = path19.join(d, "scripts.js");
|
|
19890
20222
|
if (!hasCompatibility && fs7.existsSync(scriptsPath)) {
|
|
19891
20223
|
try {
|
|
19892
20224
|
delete require.cache[require.resolve(scriptsPath)];
|
|
@@ -19912,7 +20244,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19912
20244
|
if (!entry.isDirectory()) continue;
|
|
19913
20245
|
if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
|
|
19914
20246
|
if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
|
|
19915
|
-
scan(
|
|
20247
|
+
scan(path19.join(d, entry.name));
|
|
19916
20248
|
}
|
|
19917
20249
|
}
|
|
19918
20250
|
};
|
|
@@ -20237,8 +20569,8 @@ function detectCurrentWorkspace(ideId) {
|
|
|
20237
20569
|
const appNameMap = getMacAppIdentifiers();
|
|
20238
20570
|
const appName = appNameMap[ideId];
|
|
20239
20571
|
if (appName) {
|
|
20240
|
-
const storagePath =
|
|
20241
|
-
process.env.APPDATA ||
|
|
20572
|
+
const storagePath = path20.join(
|
|
20573
|
+
process.env.APPDATA || path20.join(os15.homedir(), "AppData", "Roaming"),
|
|
20242
20574
|
appName,
|
|
20243
20575
|
"storage.json"
|
|
20244
20576
|
);
|
|
@@ -20427,9 +20759,9 @@ init_logger();
|
|
|
20427
20759
|
|
|
20428
20760
|
// src/logging/command-log.ts
|
|
20429
20761
|
var fs8 = __toESM(require("fs"));
|
|
20430
|
-
var
|
|
20762
|
+
var path21 = __toESM(require("path"));
|
|
20431
20763
|
var os16 = __toESM(require("os"));
|
|
20432
|
-
var LOG_DIR2 = process.platform === "win32" ?
|
|
20764
|
+
var LOG_DIR2 = process.platform === "win32" ? path21.join(process.env.LOCALAPPDATA || process.env.APPDATA || path21.join(os16.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path21.join(os16.homedir(), "Library", "Logs", "adhdev") : path21.join(os16.homedir(), ".local", "share", "adhdev", "logs");
|
|
20433
20765
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
20434
20766
|
var MAX_DAYS = 7;
|
|
20435
20767
|
try {
|
|
@@ -20467,13 +20799,13 @@ function getDateStr2() {
|
|
|
20467
20799
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
20468
20800
|
}
|
|
20469
20801
|
var currentDate2 = getDateStr2();
|
|
20470
|
-
var currentFile =
|
|
20802
|
+
var currentFile = path21.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
20471
20803
|
var writeCount2 = 0;
|
|
20472
20804
|
function checkRotation() {
|
|
20473
20805
|
const today = getDateStr2();
|
|
20474
20806
|
if (today !== currentDate2) {
|
|
20475
20807
|
currentDate2 = today;
|
|
20476
|
-
currentFile =
|
|
20808
|
+
currentFile = path21.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
20477
20809
|
cleanOldFiles();
|
|
20478
20810
|
}
|
|
20479
20811
|
}
|
|
@@ -20487,7 +20819,7 @@ function cleanOldFiles() {
|
|
|
20487
20819
|
const dateMatch = file.match(/commands-(\d{4}-\d{2}-\d{2})/);
|
|
20488
20820
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
20489
20821
|
try {
|
|
20490
|
-
fs8.unlinkSync(
|
|
20822
|
+
fs8.unlinkSync(path21.join(LOG_DIR2, file));
|
|
20491
20823
|
} catch {
|
|
20492
20824
|
}
|
|
20493
20825
|
}
|
|
@@ -20575,6 +20907,7 @@ init_logger();
|
|
|
20575
20907
|
|
|
20576
20908
|
// src/commands/mesh-coordinator.ts
|
|
20577
20909
|
var import_node_child_process3 = require("child_process");
|
|
20910
|
+
var import_node_crypto2 = require("crypto");
|
|
20578
20911
|
var import_node_fs3 = require("fs");
|
|
20579
20912
|
var import_node_module2 = require("module");
|
|
20580
20913
|
var os17 = __toESM(require("os"));
|
|
@@ -20599,7 +20932,7 @@ function resolveHermesMeshCoordinatorSetup(options) {
|
|
|
20599
20932
|
reason: "Could not resolve the ADHDev MCP server entrypoint and a Node runtime with WebSocket support for daemon IPC mode"
|
|
20600
20933
|
};
|
|
20601
20934
|
}
|
|
20602
|
-
const configPath =
|
|
20935
|
+
const configPath = (0, import_node_path.join)(resolveHermesCoordinatorHome(options.meshId, options.workspace), "config.yaml");
|
|
20603
20936
|
if (!configPath.trim()) {
|
|
20604
20937
|
return createHermesManualMeshCoordinatorSetup(options.meshId, options.workspace);
|
|
20605
20938
|
}
|
|
@@ -20651,8 +20984,8 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
20651
20984
|
}
|
|
20652
20985
|
const serverName = mcpConfig.serverName?.trim() || DEFAULT_SERVER_NAME;
|
|
20653
20986
|
if (mcpConfig.mode === "auto_import") {
|
|
20654
|
-
const
|
|
20655
|
-
if (!
|
|
20987
|
+
const path28 = mcpConfig.path?.trim();
|
|
20988
|
+
if (!path28) {
|
|
20656
20989
|
return { kind: "unsupported", reason: "Provider auto-import MCP config is missing a config path" };
|
|
20657
20990
|
}
|
|
20658
20991
|
const mcpServer = resolveAdhdevMcpServerLaunch({
|
|
@@ -20669,7 +21002,7 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
20669
21002
|
return {
|
|
20670
21003
|
kind: "auto_import",
|
|
20671
21004
|
serverName,
|
|
20672
|
-
configPath: resolveMcpConfigPath(
|
|
21005
|
+
configPath: resolveMcpConfigPath(path28, workspace),
|
|
20673
21006
|
configFormat: mcpConfig.format,
|
|
20674
21007
|
mcpServer
|
|
20675
21008
|
};
|
|
@@ -20703,6 +21036,12 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
20703
21036
|
function renderMeshCoordinatorTemplate(template, values) {
|
|
20704
21037
|
return template.replace(/\{\{\s*(meshId|workspace|serverName|adhdevMcpCommand)\s*\}\}/g, (_, key) => values[key] || "");
|
|
20705
21038
|
}
|
|
21039
|
+
function resolveHermesCoordinatorHome(meshId, workspace) {
|
|
21040
|
+
const key = `${meshId || "mesh"}
|
|
21041
|
+
${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
|
|
21042
|
+
const hash = (0, import_node_crypto2.createHash)("sha256").update(key).digest("hex").slice(0, 16);
|
|
21043
|
+
return (0, import_node_path.join)(os17.tmpdir(), `adhdev-hermes-mesh-coordinator-${hash}`);
|
|
21044
|
+
}
|
|
20706
21045
|
function resolveMcpConfigPath(configPath, workspace) {
|
|
20707
21046
|
const trimmed = configPath.trim();
|
|
20708
21047
|
if (trimmed === "~") return os17.homedir();
|
|
@@ -21236,13 +21575,13 @@ var import_child_process8 = require("child_process");
|
|
|
21236
21575
|
var import_child_process9 = require("child_process");
|
|
21237
21576
|
var fs9 = __toESM(require("fs"));
|
|
21238
21577
|
var os19 = __toESM(require("os"));
|
|
21239
|
-
var
|
|
21578
|
+
var path22 = __toESM(require("path"));
|
|
21240
21579
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
21241
21580
|
function getUpgradeLogPath() {
|
|
21242
21581
|
const home = os19.homedir();
|
|
21243
|
-
const dir =
|
|
21582
|
+
const dir = path22.join(home, ".adhdev");
|
|
21244
21583
|
fs9.mkdirSync(dir, { recursive: true });
|
|
21245
|
-
return
|
|
21584
|
+
return path22.join(dir, "daemon-upgrade.log");
|
|
21246
21585
|
}
|
|
21247
21586
|
function appendUpgradeLog(message) {
|
|
21248
21587
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
|
|
@@ -21253,14 +21592,14 @@ function appendUpgradeLog(message) {
|
|
|
21253
21592
|
}
|
|
21254
21593
|
}
|
|
21255
21594
|
function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platform) {
|
|
21256
|
-
const binDir =
|
|
21595
|
+
const binDir = path22.dirname(nodeExecutable);
|
|
21257
21596
|
if (platform10 === "win32") {
|
|
21258
|
-
const npmCliPath =
|
|
21597
|
+
const npmCliPath = path22.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
|
|
21259
21598
|
if (fs9.existsSync(npmCliPath)) {
|
|
21260
21599
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
21261
21600
|
}
|
|
21262
21601
|
for (const candidate of ["npm.exe", "npm"]) {
|
|
21263
|
-
const candidatePath =
|
|
21602
|
+
const candidatePath = path22.join(binDir, candidate);
|
|
21264
21603
|
if (fs9.existsSync(candidatePath)) {
|
|
21265
21604
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
21266
21605
|
}
|
|
@@ -21268,7 +21607,7 @@ function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platfo
|
|
|
21268
21607
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
21269
21608
|
}
|
|
21270
21609
|
for (const candidate of ["npm"]) {
|
|
21271
|
-
const candidatePath =
|
|
21610
|
+
const candidatePath = path22.join(binDir, candidate);
|
|
21272
21611
|
if (fs9.existsSync(candidatePath)) {
|
|
21273
21612
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
21274
21613
|
}
|
|
@@ -21285,13 +21624,13 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
21285
21624
|
let currentDir = resolvedPath;
|
|
21286
21625
|
try {
|
|
21287
21626
|
if (fs9.statSync(resolvedPath).isFile()) {
|
|
21288
|
-
currentDir =
|
|
21627
|
+
currentDir = path22.dirname(resolvedPath);
|
|
21289
21628
|
}
|
|
21290
21629
|
} catch {
|
|
21291
|
-
currentDir =
|
|
21630
|
+
currentDir = path22.dirname(resolvedPath);
|
|
21292
21631
|
}
|
|
21293
21632
|
while (true) {
|
|
21294
|
-
const packageJsonPath =
|
|
21633
|
+
const packageJsonPath = path22.join(currentDir, "package.json");
|
|
21295
21634
|
try {
|
|
21296
21635
|
if (fs9.existsSync(packageJsonPath)) {
|
|
21297
21636
|
const parsed = JSON.parse(fs9.readFileSync(packageJsonPath, "utf8"));
|
|
@@ -21302,7 +21641,7 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
21302
21641
|
}
|
|
21303
21642
|
} catch {
|
|
21304
21643
|
}
|
|
21305
|
-
const parentDir =
|
|
21644
|
+
const parentDir = path22.dirname(currentDir);
|
|
21306
21645
|
if (parentDir === currentDir) {
|
|
21307
21646
|
return null;
|
|
21308
21647
|
}
|
|
@@ -21310,13 +21649,13 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
21310
21649
|
}
|
|
21311
21650
|
}
|
|
21312
21651
|
function resolveInstallPrefixFromPackageRoot(packageRoot, packageName) {
|
|
21313
|
-
const nodeModulesDir = packageName.startsWith("@") ?
|
|
21314
|
-
if (
|
|
21652
|
+
const nodeModulesDir = packageName.startsWith("@") ? path22.dirname(path22.dirname(packageRoot)) : path22.dirname(packageRoot);
|
|
21653
|
+
if (path22.basename(nodeModulesDir) !== "node_modules") {
|
|
21315
21654
|
return null;
|
|
21316
21655
|
}
|
|
21317
|
-
const maybeLibDir =
|
|
21318
|
-
if (
|
|
21319
|
-
return
|
|
21656
|
+
const maybeLibDir = path22.dirname(nodeModulesDir);
|
|
21657
|
+
if (path22.basename(maybeLibDir) === "lib") {
|
|
21658
|
+
return path22.dirname(maybeLibDir);
|
|
21320
21659
|
}
|
|
21321
21660
|
return maybeLibDir;
|
|
21322
21661
|
}
|
|
@@ -21431,7 +21770,7 @@ async function waitForPidExit(pid, timeoutMs) {
|
|
|
21431
21770
|
}
|
|
21432
21771
|
}
|
|
21433
21772
|
function stopSessionHostProcesses(appName) {
|
|
21434
|
-
const pidFile =
|
|
21773
|
+
const pidFile = path22.join(os19.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
21435
21774
|
try {
|
|
21436
21775
|
if (fs9.existsSync(pidFile)) {
|
|
21437
21776
|
const pid = Number.parseInt(fs9.readFileSync(pidFile, "utf8").trim(), 10);
|
|
@@ -21448,7 +21787,7 @@ function stopSessionHostProcesses(appName) {
|
|
|
21448
21787
|
}
|
|
21449
21788
|
}
|
|
21450
21789
|
function removeDaemonPidFile() {
|
|
21451
|
-
const pidFile =
|
|
21790
|
+
const pidFile = path22.join(os19.homedir(), ".adhdev", "daemon.pid");
|
|
21452
21791
|
try {
|
|
21453
21792
|
fs9.unlinkSync(pidFile);
|
|
21454
21793
|
} catch {
|
|
@@ -21459,7 +21798,7 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
21459
21798
|
const npmRoot = String(execNpmCommandSync(["root", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
21460
21799
|
if (!npmRoot) return;
|
|
21461
21800
|
const npmPrefix = surface.installPrefix || String(execNpmCommandSync(["prefix", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
21462
|
-
const binDir = process.platform === "win32" ? npmPrefix :
|
|
21801
|
+
const binDir = process.platform === "win32" ? npmPrefix : path22.join(npmPrefix, "bin");
|
|
21463
21802
|
const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
|
|
21464
21803
|
const binNames = /* @__PURE__ */ new Set([packageBaseName]);
|
|
21465
21804
|
if (pkgName === "@adhdev/daemon-standalone") {
|
|
@@ -21467,25 +21806,25 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
21467
21806
|
}
|
|
21468
21807
|
if (pkgName.startsWith("@")) {
|
|
21469
21808
|
const [scope, name] = pkgName.split("/");
|
|
21470
|
-
const scopeDir =
|
|
21809
|
+
const scopeDir = path22.join(npmRoot, scope);
|
|
21471
21810
|
if (!fs9.existsSync(scopeDir)) return;
|
|
21472
21811
|
for (const entry of fs9.readdirSync(scopeDir)) {
|
|
21473
21812
|
if (!entry.startsWith(`.${name}-`)) continue;
|
|
21474
|
-
fs9.rmSync(
|
|
21475
|
-
appendUpgradeLog(`Removed stale scoped staging dir: ${
|
|
21813
|
+
fs9.rmSync(path22.join(scopeDir, entry), { recursive: true, force: true });
|
|
21814
|
+
appendUpgradeLog(`Removed stale scoped staging dir: ${path22.join(scopeDir, entry)}`);
|
|
21476
21815
|
}
|
|
21477
21816
|
} else {
|
|
21478
21817
|
for (const entry of fs9.readdirSync(npmRoot)) {
|
|
21479
21818
|
if (!entry.startsWith(`.${pkgName}-`)) continue;
|
|
21480
|
-
fs9.rmSync(
|
|
21481
|
-
appendUpgradeLog(`Removed stale staging dir: ${
|
|
21819
|
+
fs9.rmSync(path22.join(npmRoot, entry), { recursive: true, force: true });
|
|
21820
|
+
appendUpgradeLog(`Removed stale staging dir: ${path22.join(npmRoot, entry)}`);
|
|
21482
21821
|
}
|
|
21483
21822
|
}
|
|
21484
21823
|
if (fs9.existsSync(binDir)) {
|
|
21485
21824
|
for (const entry of fs9.readdirSync(binDir)) {
|
|
21486
21825
|
if (!Array.from(binNames).some((name) => entry.startsWith(`.${name}-`))) continue;
|
|
21487
|
-
fs9.rmSync(
|
|
21488
|
-
appendUpgradeLog(`Removed stale bin staging entry: ${
|
|
21826
|
+
fs9.rmSync(path22.join(binDir, entry), { recursive: true, force: true });
|
|
21827
|
+
appendUpgradeLog(`Removed stale bin staging entry: ${path22.join(binDir, entry)}`);
|
|
21489
21828
|
}
|
|
21490
21829
|
}
|
|
21491
21830
|
}
|
|
@@ -22857,7 +23196,7 @@ var DaemonCommandRouter = class {
|
|
|
22857
23196
|
workspace
|
|
22858
23197
|
};
|
|
22859
23198
|
}
|
|
22860
|
-
const { existsSync: existsSync23, readFileSync: readFileSync15, writeFileSync:
|
|
23199
|
+
const { existsSync: existsSync23, readFileSync: readFileSync15, writeFileSync: writeFileSync14, copyFileSync: copyFileSync3, mkdirSync: mkdirSync16 } = await import("fs");
|
|
22861
23200
|
const { dirname: dirname9 } = await import("path");
|
|
22862
23201
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
22863
23202
|
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
@@ -22881,7 +23220,7 @@ var DaemonCommandRouter = class {
|
|
|
22881
23220
|
};
|
|
22882
23221
|
}
|
|
22883
23222
|
try {
|
|
22884
|
-
|
|
23223
|
+
mkdirSync16(dirname9(mcpConfigPath), { recursive: true });
|
|
22885
23224
|
} catch (error) {
|
|
22886
23225
|
const message = `Could not prepare MCP config path for automatic setup: ${error?.message || error}`;
|
|
22887
23226
|
LOG.error("MeshCoordinator", message);
|
|
@@ -22913,7 +23252,7 @@ var DaemonCommandRouter = class {
|
|
|
22913
23252
|
}
|
|
22914
23253
|
};
|
|
22915
23254
|
try {
|
|
22916
|
-
|
|
23255
|
+
writeFileSync14(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
|
|
22917
23256
|
} catch (error) {
|
|
22918
23257
|
const message = `Could not write MCP config for automatic setup: ${error?.message || error}`;
|
|
22919
23258
|
LOG.error("MeshCoordinator", message);
|
|
@@ -22923,6 +23262,10 @@ var DaemonCommandRouter = class {
|
|
|
22923
23262
|
LOG.info("MeshCoordinator", `Wrote ${mcpConfigPath} with ${coordinatorSetup.serverName} server`);
|
|
22924
23263
|
const cliArgs = [];
|
|
22925
23264
|
const launchEnv = {};
|
|
23265
|
+
if (configFormat === "hermes_config_yaml") {
|
|
23266
|
+
launchEnv.HERMES_HOME = dirname9(mcpConfigPath);
|
|
23267
|
+
launchEnv.HERMES_IGNORE_USER_CONFIG = "";
|
|
23268
|
+
}
|
|
22926
23269
|
if (systemPrompt) {
|
|
22927
23270
|
if (configFormat === "hermes_config_yaml") {
|
|
22928
23271
|
launchEnv.HERMES_EPHEMERAL_SYSTEM_PROMPT = systemPrompt;
|
|
@@ -24619,11 +24962,11 @@ var ProviderInstanceManager = class {
|
|
|
24619
24962
|
|
|
24620
24963
|
// src/providers/version-archive.ts
|
|
24621
24964
|
var fs11 = __toESM(require("fs"));
|
|
24622
|
-
var
|
|
24965
|
+
var path23 = __toESM(require("path"));
|
|
24623
24966
|
var os20 = __toESM(require("os"));
|
|
24624
24967
|
var import_child_process10 = require("child_process");
|
|
24625
24968
|
var import_os3 = require("os");
|
|
24626
|
-
var ARCHIVE_PATH =
|
|
24969
|
+
var ARCHIVE_PATH = path23.join(os20.homedir(), ".adhdev", "version-history.json");
|
|
24627
24970
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
24628
24971
|
var VersionArchive = class {
|
|
24629
24972
|
history = {};
|
|
@@ -24670,7 +25013,7 @@ var VersionArchive = class {
|
|
|
24670
25013
|
}
|
|
24671
25014
|
save() {
|
|
24672
25015
|
try {
|
|
24673
|
-
fs11.mkdirSync(
|
|
25016
|
+
fs11.mkdirSync(path23.dirname(ARCHIVE_PATH), { recursive: true });
|
|
24674
25017
|
fs11.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
24675
25018
|
} catch {
|
|
24676
25019
|
}
|
|
@@ -24727,7 +25070,7 @@ function checkPathExists2(paths) {
|
|
|
24727
25070
|
for (const p of paths) {
|
|
24728
25071
|
if (p.includes("*")) {
|
|
24729
25072
|
const home = os20.homedir();
|
|
24730
|
-
const resolved = p.replace(/\*/g, home.split(
|
|
25073
|
+
const resolved = p.replace(/\*/g, home.split(path23.sep).pop() || "");
|
|
24731
25074
|
if (fs11.existsSync(resolved)) return resolved;
|
|
24732
25075
|
} else {
|
|
24733
25076
|
if (fs11.existsSync(p)) return p;
|
|
@@ -24737,7 +25080,7 @@ function checkPathExists2(paths) {
|
|
|
24737
25080
|
}
|
|
24738
25081
|
function getMacAppVersion(appPath) {
|
|
24739
25082
|
if ((0, import_os3.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
24740
|
-
const plistPath =
|
|
25083
|
+
const plistPath = path23.join(appPath, "Contents", "Info.plist");
|
|
24741
25084
|
if (!fs11.existsSync(plistPath)) return null;
|
|
24742
25085
|
const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
24743
25086
|
return raw || null;
|
|
@@ -24763,7 +25106,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
24763
25106
|
const cliBin = provider.cli ? findBinary2(provider.cli) : null;
|
|
24764
25107
|
let resolvedBin = cliBin;
|
|
24765
25108
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
24766
|
-
const bundled =
|
|
25109
|
+
const bundled = path23.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
24767
25110
|
if (provider.cli && fs11.existsSync(bundled)) resolvedBin = bundled;
|
|
24768
25111
|
}
|
|
24769
25112
|
info.installed = !!(appPath || resolvedBin);
|
|
@@ -24804,7 +25147,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
24804
25147
|
// src/daemon/dev-server.ts
|
|
24805
25148
|
var http2 = __toESM(require("http"));
|
|
24806
25149
|
var fs15 = __toESM(require("fs"));
|
|
24807
|
-
var
|
|
25150
|
+
var path27 = __toESM(require("path"));
|
|
24808
25151
|
init_config();
|
|
24809
25152
|
|
|
24810
25153
|
// src/daemon/scaffold-template.ts
|
|
@@ -25155,7 +25498,7 @@ init_logger();
|
|
|
25155
25498
|
|
|
25156
25499
|
// src/daemon/dev-cdp-handlers.ts
|
|
25157
25500
|
var fs12 = __toESM(require("fs"));
|
|
25158
|
-
var
|
|
25501
|
+
var path24 = __toESM(require("path"));
|
|
25159
25502
|
init_logger();
|
|
25160
25503
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
25161
25504
|
const body = await ctx.readBody(req);
|
|
@@ -25334,17 +25677,17 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
25334
25677
|
return;
|
|
25335
25678
|
}
|
|
25336
25679
|
let scriptsPath = "";
|
|
25337
|
-
const directScripts =
|
|
25680
|
+
const directScripts = path24.join(dir, "scripts.js");
|
|
25338
25681
|
if (fs12.existsSync(directScripts)) {
|
|
25339
25682
|
scriptsPath = directScripts;
|
|
25340
25683
|
} else {
|
|
25341
|
-
const scriptsDir =
|
|
25684
|
+
const scriptsDir = path24.join(dir, "scripts");
|
|
25342
25685
|
if (fs12.existsSync(scriptsDir)) {
|
|
25343
25686
|
const versions = fs12.readdirSync(scriptsDir).filter((d) => {
|
|
25344
|
-
return fs12.statSync(
|
|
25687
|
+
return fs12.statSync(path24.join(scriptsDir, d)).isDirectory();
|
|
25345
25688
|
}).sort().reverse();
|
|
25346
25689
|
for (const ver of versions) {
|
|
25347
|
-
const p =
|
|
25690
|
+
const p = path24.join(scriptsDir, ver, "scripts.js");
|
|
25348
25691
|
if (fs12.existsSync(p)) {
|
|
25349
25692
|
scriptsPath = p;
|
|
25350
25693
|
break;
|
|
@@ -26173,7 +26516,7 @@ async function handleDomContext(ctx, type, req, res) {
|
|
|
26173
26516
|
|
|
26174
26517
|
// src/daemon/dev-cli-debug.ts
|
|
26175
26518
|
var fs13 = __toESM(require("fs"));
|
|
26176
|
-
var
|
|
26519
|
+
var path25 = __toESM(require("path"));
|
|
26177
26520
|
function slugifyFixtureName(value) {
|
|
26178
26521
|
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
26179
26522
|
return normalized || `fixture-${Date.now()}`;
|
|
@@ -26183,11 +26526,11 @@ function getCliFixtureDir(ctx, type) {
|
|
|
26183
26526
|
if (!providerDir) {
|
|
26184
26527
|
throw new Error(`Provider directory not found for '${type}'`);
|
|
26185
26528
|
}
|
|
26186
|
-
return
|
|
26529
|
+
return path25.join(providerDir, "fixtures");
|
|
26187
26530
|
}
|
|
26188
26531
|
function readCliFixture(ctx, type, name) {
|
|
26189
26532
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
26190
|
-
const filePath =
|
|
26533
|
+
const filePath = path25.join(fixtureDir, `${name}.json`);
|
|
26191
26534
|
if (!fs13.existsSync(filePath)) {
|
|
26192
26535
|
throw new Error(`Fixture not found: ${filePath}`);
|
|
26193
26536
|
}
|
|
@@ -26954,7 +27297,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
26954
27297
|
},
|
|
26955
27298
|
notes: typeof body?.notes === "string" ? body.notes : void 0
|
|
26956
27299
|
};
|
|
26957
|
-
const filePath =
|
|
27300
|
+
const filePath = path25.join(fixtureDir, `${name}.json`);
|
|
26958
27301
|
fs13.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
|
|
26959
27302
|
ctx.json(res, 200, {
|
|
26960
27303
|
saved: true,
|
|
@@ -26978,7 +27321,7 @@ async function handleCliFixtureList(ctx, type, _req, res) {
|
|
|
26978
27321
|
return;
|
|
26979
27322
|
}
|
|
26980
27323
|
const fixtures = fs13.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
|
|
26981
|
-
const fullPath =
|
|
27324
|
+
const fullPath = path25.join(fixtureDir, file);
|
|
26982
27325
|
try {
|
|
26983
27326
|
const raw = JSON.parse(fs13.readFileSync(fullPath, "utf-8"));
|
|
26984
27327
|
return {
|
|
@@ -27114,7 +27457,7 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
27114
27457
|
|
|
27115
27458
|
// src/daemon/dev-auto-implement.ts
|
|
27116
27459
|
var fs14 = __toESM(require("fs"));
|
|
27117
|
-
var
|
|
27460
|
+
var path26 = __toESM(require("path"));
|
|
27118
27461
|
var os21 = __toESM(require("os"));
|
|
27119
27462
|
function getAutoImplPid(ctx) {
|
|
27120
27463
|
const pid = ctx.autoImplProcess?.pid;
|
|
@@ -27164,22 +27507,22 @@ function getLatestScriptVersionDir(scriptsDir) {
|
|
|
27164
27507
|
if (!fs14.existsSync(scriptsDir)) return null;
|
|
27165
27508
|
const versions = fs14.readdirSync(scriptsDir).filter((d) => {
|
|
27166
27509
|
try {
|
|
27167
|
-
return fs14.statSync(
|
|
27510
|
+
return fs14.statSync(path26.join(scriptsDir, d)).isDirectory();
|
|
27168
27511
|
} catch {
|
|
27169
27512
|
return false;
|
|
27170
27513
|
}
|
|
27171
27514
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
27172
27515
|
if (versions.length === 0) return null;
|
|
27173
|
-
return
|
|
27516
|
+
return path26.join(scriptsDir, versions[0]);
|
|
27174
27517
|
}
|
|
27175
27518
|
function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
27176
|
-
const canonicalUserDir =
|
|
27177
|
-
const desiredDir = requestedDir ?
|
|
27178
|
-
const upstreamRoot =
|
|
27179
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
27519
|
+
const canonicalUserDir = path26.resolve(ctx.providerLoader.getUserProviderDir(category, type));
|
|
27520
|
+
const desiredDir = requestedDir ? path26.resolve(requestedDir) : canonicalUserDir;
|
|
27521
|
+
const upstreamRoot = path26.resolve(ctx.providerLoader.getUpstreamDir());
|
|
27522
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path26.sep}`)) {
|
|
27180
27523
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
27181
27524
|
}
|
|
27182
|
-
if (
|
|
27525
|
+
if (path26.basename(desiredDir) !== type) {
|
|
27183
27526
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
27184
27527
|
}
|
|
27185
27528
|
const sourceDir = ctx.findProviderDir(type);
|
|
@@ -27187,11 +27530,11 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
27187
27530
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
27188
27531
|
}
|
|
27189
27532
|
if (!fs14.existsSync(desiredDir)) {
|
|
27190
|
-
fs14.mkdirSync(
|
|
27533
|
+
fs14.mkdirSync(path26.dirname(desiredDir), { recursive: true });
|
|
27191
27534
|
fs14.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
27192
27535
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
27193
27536
|
}
|
|
27194
|
-
const providerJson =
|
|
27537
|
+
const providerJson = path26.join(desiredDir, "provider.json");
|
|
27195
27538
|
if (!fs14.existsSync(providerJson)) {
|
|
27196
27539
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
27197
27540
|
}
|
|
@@ -27202,13 +27545,13 @@ function loadAutoImplReferenceScripts(ctx, referenceType) {
|
|
|
27202
27545
|
const refDir = ctx.findProviderDir(referenceType);
|
|
27203
27546
|
if (!refDir || !fs14.existsSync(refDir)) return {};
|
|
27204
27547
|
const referenceScripts = {};
|
|
27205
|
-
const scriptsDir =
|
|
27548
|
+
const scriptsDir = path26.join(refDir, "scripts");
|
|
27206
27549
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
27207
27550
|
if (!latestDir) return referenceScripts;
|
|
27208
27551
|
for (const file of fs14.readdirSync(latestDir)) {
|
|
27209
27552
|
if (!file.endsWith(".js")) continue;
|
|
27210
27553
|
try {
|
|
27211
|
-
referenceScripts[file] = fs14.readFileSync(
|
|
27554
|
+
referenceScripts[file] = fs14.readFileSync(path26.join(latestDir, file), "utf-8");
|
|
27212
27555
|
} catch {
|
|
27213
27556
|
}
|
|
27214
27557
|
}
|
|
@@ -27316,9 +27659,9 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
27316
27659
|
});
|
|
27317
27660
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
27318
27661
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
27319
|
-
const tmpDir =
|
|
27662
|
+
const tmpDir = path26.join(os21.tmpdir(), "adhdev-autoimpl");
|
|
27320
27663
|
if (!fs14.existsSync(tmpDir)) fs14.mkdirSync(tmpDir, { recursive: true });
|
|
27321
|
-
const promptFile =
|
|
27664
|
+
const promptFile = path26.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
27322
27665
|
fs14.writeFileSync(promptFile, prompt, "utf-8");
|
|
27323
27666
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
27324
27667
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
@@ -27750,7 +28093,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
27750
28093
|
setMode: "set_mode.js"
|
|
27751
28094
|
};
|
|
27752
28095
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
27753
|
-
const scriptsDir =
|
|
28096
|
+
const scriptsDir = path26.join(providerDir, "scripts");
|
|
27754
28097
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
27755
28098
|
if (latestScriptsDir) {
|
|
27756
28099
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -27761,7 +28104,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
27761
28104
|
for (const file of fs14.readdirSync(latestScriptsDir)) {
|
|
27762
28105
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
27763
28106
|
try {
|
|
27764
|
-
const content = fs14.readFileSync(
|
|
28107
|
+
const content = fs14.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
|
|
27765
28108
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
27766
28109
|
lines.push("```javascript");
|
|
27767
28110
|
lines.push(content);
|
|
@@ -27778,7 +28121,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
27778
28121
|
lines.push("");
|
|
27779
28122
|
for (const file of refFiles) {
|
|
27780
28123
|
try {
|
|
27781
|
-
const content = fs14.readFileSync(
|
|
28124
|
+
const content = fs14.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
|
|
27782
28125
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
27783
28126
|
lines.push("```javascript");
|
|
27784
28127
|
lines.push(content);
|
|
@@ -27819,10 +28162,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
27819
28162
|
lines.push("");
|
|
27820
28163
|
}
|
|
27821
28164
|
}
|
|
27822
|
-
const docsDir =
|
|
28165
|
+
const docsDir = path26.join(providerDir, "../../docs");
|
|
27823
28166
|
const loadGuide = (name) => {
|
|
27824
28167
|
try {
|
|
27825
|
-
const p =
|
|
28168
|
+
const p = path26.join(docsDir, name);
|
|
27826
28169
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
27827
28170
|
} catch {
|
|
27828
28171
|
}
|
|
@@ -28059,7 +28402,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
28059
28402
|
parseApproval: "parse_approval.js"
|
|
28060
28403
|
};
|
|
28061
28404
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
28062
|
-
const scriptsDir =
|
|
28405
|
+
const scriptsDir = path26.join(providerDir, "scripts");
|
|
28063
28406
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
28064
28407
|
if (latestScriptsDir) {
|
|
28065
28408
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -28071,7 +28414,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
28071
28414
|
if (!file.endsWith(".js")) continue;
|
|
28072
28415
|
if (!targetFileNames.has(file)) continue;
|
|
28073
28416
|
try {
|
|
28074
|
-
const content = fs14.readFileSync(
|
|
28417
|
+
const content = fs14.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
|
|
28075
28418
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
28076
28419
|
lines.push("```javascript");
|
|
28077
28420
|
lines.push(content);
|
|
@@ -28087,7 +28430,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
28087
28430
|
lines.push("");
|
|
28088
28431
|
for (const file of refFiles) {
|
|
28089
28432
|
try {
|
|
28090
|
-
const content = fs14.readFileSync(
|
|
28433
|
+
const content = fs14.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
|
|
28091
28434
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
28092
28435
|
lines.push("```javascript");
|
|
28093
28436
|
lines.push(content);
|
|
@@ -28120,10 +28463,10 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
28120
28463
|
lines.push("");
|
|
28121
28464
|
}
|
|
28122
28465
|
}
|
|
28123
|
-
const docsDir =
|
|
28466
|
+
const docsDir = path26.join(providerDir, "../../docs");
|
|
28124
28467
|
const loadGuide = (name) => {
|
|
28125
28468
|
try {
|
|
28126
|
-
const p =
|
|
28469
|
+
const p = path26.join(docsDir, name);
|
|
28127
28470
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
28128
28471
|
} catch {
|
|
28129
28472
|
}
|
|
@@ -28570,8 +28913,8 @@ var DevServer = class _DevServer {
|
|
|
28570
28913
|
}
|
|
28571
28914
|
getEndpointList() {
|
|
28572
28915
|
return this.routes.map((r) => {
|
|
28573
|
-
const
|
|
28574
|
-
return `${r.method.padEnd(5)} ${
|
|
28916
|
+
const path28 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
|
|
28917
|
+
return `${r.method.padEnd(5)} ${path28}`;
|
|
28575
28918
|
});
|
|
28576
28919
|
}
|
|
28577
28920
|
async start(port = DEV_SERVER_PORT) {
|
|
@@ -28859,12 +29202,12 @@ var DevServer = class _DevServer {
|
|
|
28859
29202
|
// ─── DevConsole SPA ───
|
|
28860
29203
|
getConsoleDistDir() {
|
|
28861
29204
|
const candidates = [
|
|
28862
|
-
|
|
28863
|
-
|
|
28864
|
-
|
|
29205
|
+
path27.resolve(__dirname, "../../web-devconsole/dist"),
|
|
29206
|
+
path27.resolve(__dirname, "../../../web-devconsole/dist"),
|
|
29207
|
+
path27.join(process.cwd(), "packages/web-devconsole/dist")
|
|
28865
29208
|
];
|
|
28866
29209
|
for (const dir of candidates) {
|
|
28867
|
-
if (fs15.existsSync(
|
|
29210
|
+
if (fs15.existsSync(path27.join(dir, "index.html"))) return dir;
|
|
28868
29211
|
}
|
|
28869
29212
|
return null;
|
|
28870
29213
|
}
|
|
@@ -28874,7 +29217,7 @@ var DevServer = class _DevServer {
|
|
|
28874
29217
|
this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
|
|
28875
29218
|
return;
|
|
28876
29219
|
}
|
|
28877
|
-
const htmlPath =
|
|
29220
|
+
const htmlPath = path27.join(distDir, "index.html");
|
|
28878
29221
|
try {
|
|
28879
29222
|
const html = fs15.readFileSync(htmlPath, "utf-8");
|
|
28880
29223
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
@@ -28899,15 +29242,15 @@ var DevServer = class _DevServer {
|
|
|
28899
29242
|
this.json(res, 404, { error: "Not found" });
|
|
28900
29243
|
return;
|
|
28901
29244
|
}
|
|
28902
|
-
const safePath =
|
|
28903
|
-
const filePath =
|
|
29245
|
+
const safePath = path27.normalize(pathname).replace(/^\.\.\//, "");
|
|
29246
|
+
const filePath = path27.join(distDir, safePath);
|
|
28904
29247
|
if (!filePath.startsWith(distDir)) {
|
|
28905
29248
|
this.json(res, 403, { error: "Forbidden" });
|
|
28906
29249
|
return;
|
|
28907
29250
|
}
|
|
28908
29251
|
try {
|
|
28909
29252
|
const content = fs15.readFileSync(filePath);
|
|
28910
|
-
const ext =
|
|
29253
|
+
const ext = path27.extname(filePath);
|
|
28911
29254
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
28912
29255
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
28913
29256
|
res.end(content);
|
|
@@ -29020,9 +29363,9 @@ var DevServer = class _DevServer {
|
|
|
29020
29363
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
29021
29364
|
if (entry.isDirectory()) {
|
|
29022
29365
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
29023
|
-
scan(
|
|
29366
|
+
scan(path27.join(d, entry.name), rel);
|
|
29024
29367
|
} else {
|
|
29025
|
-
const stat2 = fs15.statSync(
|
|
29368
|
+
const stat2 = fs15.statSync(path27.join(d, entry.name));
|
|
29026
29369
|
files.push({ path: rel, size: stat2.size, type: "file" });
|
|
29027
29370
|
}
|
|
29028
29371
|
}
|
|
@@ -29045,7 +29388,7 @@ var DevServer = class _DevServer {
|
|
|
29045
29388
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
29046
29389
|
return;
|
|
29047
29390
|
}
|
|
29048
|
-
const fullPath =
|
|
29391
|
+
const fullPath = path27.resolve(dir, path27.normalize(filePath));
|
|
29049
29392
|
if (!fullPath.startsWith(dir)) {
|
|
29050
29393
|
this.json(res, 403, { error: "Forbidden" });
|
|
29051
29394
|
return;
|
|
@@ -29070,14 +29413,14 @@ var DevServer = class _DevServer {
|
|
|
29070
29413
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
29071
29414
|
return;
|
|
29072
29415
|
}
|
|
29073
|
-
const fullPath =
|
|
29416
|
+
const fullPath = path27.resolve(dir, path27.normalize(filePath));
|
|
29074
29417
|
if (!fullPath.startsWith(dir)) {
|
|
29075
29418
|
this.json(res, 403, { error: "Forbidden" });
|
|
29076
29419
|
return;
|
|
29077
29420
|
}
|
|
29078
29421
|
try {
|
|
29079
29422
|
if (fs15.existsSync(fullPath)) fs15.copyFileSync(fullPath, fullPath + ".bak");
|
|
29080
|
-
fs15.mkdirSync(
|
|
29423
|
+
fs15.mkdirSync(path27.dirname(fullPath), { recursive: true });
|
|
29081
29424
|
fs15.writeFileSync(fullPath, content, "utf-8");
|
|
29082
29425
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
29083
29426
|
this.providerLoader.reload();
|
|
@@ -29094,7 +29437,7 @@ var DevServer = class _DevServer {
|
|
|
29094
29437
|
return;
|
|
29095
29438
|
}
|
|
29096
29439
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
29097
|
-
const p =
|
|
29440
|
+
const p = path27.join(dir, name);
|
|
29098
29441
|
if (fs15.existsSync(p)) {
|
|
29099
29442
|
const source = fs15.readFileSync(p, "utf-8");
|
|
29100
29443
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
@@ -29115,8 +29458,8 @@ var DevServer = class _DevServer {
|
|
|
29115
29458
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
29116
29459
|
return;
|
|
29117
29460
|
}
|
|
29118
|
-
const target = fs15.existsSync(
|
|
29119
|
-
const targetPath =
|
|
29461
|
+
const target = fs15.existsSync(path27.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
29462
|
+
const targetPath = path27.join(dir, target);
|
|
29120
29463
|
try {
|
|
29121
29464
|
if (fs15.existsSync(targetPath)) fs15.copyFileSync(targetPath, targetPath + ".bak");
|
|
29122
29465
|
fs15.writeFileSync(targetPath, source, "utf-8");
|
|
@@ -29263,7 +29606,7 @@ var DevServer = class _DevServer {
|
|
|
29263
29606
|
}
|
|
29264
29607
|
let targetDir;
|
|
29265
29608
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
29266
|
-
const jsonPath =
|
|
29609
|
+
const jsonPath = path27.join(targetDir, "provider.json");
|
|
29267
29610
|
if (fs15.existsSync(jsonPath)) {
|
|
29268
29611
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
29269
29612
|
return;
|
|
@@ -29275,8 +29618,8 @@ var DevServer = class _DevServer {
|
|
|
29275
29618
|
const createdFiles = ["provider.json"];
|
|
29276
29619
|
if (result.files) {
|
|
29277
29620
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
29278
|
-
const fullPath =
|
|
29279
|
-
fs15.mkdirSync(
|
|
29621
|
+
const fullPath = path27.join(targetDir, relPath);
|
|
29622
|
+
fs15.mkdirSync(path27.dirname(fullPath), { recursive: true });
|
|
29280
29623
|
fs15.writeFileSync(fullPath, content, "utf-8");
|
|
29281
29624
|
createdFiles.push(relPath);
|
|
29282
29625
|
}
|
|
@@ -29329,22 +29672,22 @@ var DevServer = class _DevServer {
|
|
|
29329
29672
|
if (!fs15.existsSync(scriptsDir)) return null;
|
|
29330
29673
|
const versions = fs15.readdirSync(scriptsDir).filter((d) => {
|
|
29331
29674
|
try {
|
|
29332
|
-
return fs15.statSync(
|
|
29675
|
+
return fs15.statSync(path27.join(scriptsDir, d)).isDirectory();
|
|
29333
29676
|
} catch {
|
|
29334
29677
|
return false;
|
|
29335
29678
|
}
|
|
29336
29679
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
29337
29680
|
if (versions.length === 0) return null;
|
|
29338
|
-
return
|
|
29681
|
+
return path27.join(scriptsDir, versions[0]);
|
|
29339
29682
|
}
|
|
29340
29683
|
resolveAutoImplWritableProviderDir(category, type, requestedDir) {
|
|
29341
|
-
const canonicalUserDir =
|
|
29342
|
-
const desiredDir = requestedDir ?
|
|
29343
|
-
const upstreamRoot =
|
|
29344
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
29684
|
+
const canonicalUserDir = path27.resolve(this.providerLoader.getUserProviderDir(category, type));
|
|
29685
|
+
const desiredDir = requestedDir ? path27.resolve(requestedDir) : canonicalUserDir;
|
|
29686
|
+
const upstreamRoot = path27.resolve(this.providerLoader.getUpstreamDir());
|
|
29687
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path27.sep}`)) {
|
|
29345
29688
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
29346
29689
|
}
|
|
29347
|
-
if (
|
|
29690
|
+
if (path27.basename(desiredDir) !== type) {
|
|
29348
29691
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
29349
29692
|
}
|
|
29350
29693
|
const sourceDir = this.findProviderDir(type);
|
|
@@ -29352,11 +29695,11 @@ var DevServer = class _DevServer {
|
|
|
29352
29695
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
29353
29696
|
}
|
|
29354
29697
|
if (!fs15.existsSync(desiredDir)) {
|
|
29355
|
-
fs15.mkdirSync(
|
|
29698
|
+
fs15.mkdirSync(path27.dirname(desiredDir), { recursive: true });
|
|
29356
29699
|
fs15.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
29357
29700
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
29358
29701
|
}
|
|
29359
|
-
const providerJson =
|
|
29702
|
+
const providerJson = path27.join(desiredDir, "provider.json");
|
|
29360
29703
|
if (!fs15.existsSync(providerJson)) {
|
|
29361
29704
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
29362
29705
|
}
|
|
@@ -29392,7 +29735,7 @@ var DevServer = class _DevServer {
|
|
|
29392
29735
|
setMode: "set_mode.js"
|
|
29393
29736
|
};
|
|
29394
29737
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
29395
|
-
const scriptsDir =
|
|
29738
|
+
const scriptsDir = path27.join(providerDir, "scripts");
|
|
29396
29739
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
29397
29740
|
if (latestScriptsDir) {
|
|
29398
29741
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -29403,7 +29746,7 @@ var DevServer = class _DevServer {
|
|
|
29403
29746
|
for (const file of fs15.readdirSync(latestScriptsDir)) {
|
|
29404
29747
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
29405
29748
|
try {
|
|
29406
|
-
const content = fs15.readFileSync(
|
|
29749
|
+
const content = fs15.readFileSync(path27.join(latestScriptsDir, file), "utf-8");
|
|
29407
29750
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
29408
29751
|
lines.push("```javascript");
|
|
29409
29752
|
lines.push(content);
|
|
@@ -29420,7 +29763,7 @@ var DevServer = class _DevServer {
|
|
|
29420
29763
|
lines.push("");
|
|
29421
29764
|
for (const file of refFiles) {
|
|
29422
29765
|
try {
|
|
29423
|
-
const content = fs15.readFileSync(
|
|
29766
|
+
const content = fs15.readFileSync(path27.join(latestScriptsDir, file), "utf-8");
|
|
29424
29767
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
29425
29768
|
lines.push("```javascript");
|
|
29426
29769
|
lines.push(content);
|
|
@@ -29461,10 +29804,10 @@ var DevServer = class _DevServer {
|
|
|
29461
29804
|
lines.push("");
|
|
29462
29805
|
}
|
|
29463
29806
|
}
|
|
29464
|
-
const docsDir =
|
|
29807
|
+
const docsDir = path27.join(providerDir, "../../docs");
|
|
29465
29808
|
const loadGuide = (name) => {
|
|
29466
29809
|
try {
|
|
29467
|
-
const p =
|
|
29810
|
+
const p = path27.join(docsDir, name);
|
|
29468
29811
|
if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
|
|
29469
29812
|
} catch {
|
|
29470
29813
|
}
|
|
@@ -29638,7 +29981,7 @@ var DevServer = class _DevServer {
|
|
|
29638
29981
|
parseApproval: "parse_approval.js"
|
|
29639
29982
|
};
|
|
29640
29983
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
29641
|
-
const scriptsDir =
|
|
29984
|
+
const scriptsDir = path27.join(providerDir, "scripts");
|
|
29642
29985
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
29643
29986
|
if (latestScriptsDir) {
|
|
29644
29987
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -29650,7 +29993,7 @@ var DevServer = class _DevServer {
|
|
|
29650
29993
|
if (!file.endsWith(".js")) continue;
|
|
29651
29994
|
if (!targetFileNames.has(file)) continue;
|
|
29652
29995
|
try {
|
|
29653
|
-
const content = fs15.readFileSync(
|
|
29996
|
+
const content = fs15.readFileSync(path27.join(latestScriptsDir, file), "utf-8");
|
|
29654
29997
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
29655
29998
|
lines.push("```javascript");
|
|
29656
29999
|
lines.push(content);
|
|
@@ -29666,7 +30009,7 @@ var DevServer = class _DevServer {
|
|
|
29666
30009
|
lines.push("");
|
|
29667
30010
|
for (const file of refFiles) {
|
|
29668
30011
|
try {
|
|
29669
|
-
const content = fs15.readFileSync(
|
|
30012
|
+
const content = fs15.readFileSync(path27.join(latestScriptsDir, file), "utf-8");
|
|
29670
30013
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
29671
30014
|
lines.push("```javascript");
|
|
29672
30015
|
lines.push(content);
|
|
@@ -29699,10 +30042,10 @@ var DevServer = class _DevServer {
|
|
|
29699
30042
|
lines.push("");
|
|
29700
30043
|
}
|
|
29701
30044
|
}
|
|
29702
|
-
const docsDir =
|
|
30045
|
+
const docsDir = path27.join(providerDir, "../../docs");
|
|
29703
30046
|
const loadGuide = (name) => {
|
|
29704
30047
|
try {
|
|
29705
|
-
const p =
|
|
30048
|
+
const p = path27.join(docsDir, name);
|
|
29706
30049
|
if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
|
|
29707
30050
|
} catch {
|
|
29708
30051
|
}
|