@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.mjs
CHANGED
|
@@ -431,10 +431,10 @@ function getMeshConfigPath() {
|
|
|
431
431
|
return join4(getConfigDir(), "meshes.json");
|
|
432
432
|
}
|
|
433
433
|
function loadMeshConfig() {
|
|
434
|
-
const
|
|
435
|
-
if (!existsSync4(
|
|
434
|
+
const path28 = getMeshConfigPath();
|
|
435
|
+
if (!existsSync4(path28)) return { meshes: [] };
|
|
436
436
|
try {
|
|
437
|
-
const raw = JSON.parse(readFileSync2(
|
|
437
|
+
const raw = JSON.parse(readFileSync2(path28, "utf-8"));
|
|
438
438
|
if (!raw || !Array.isArray(raw.meshes)) return { meshes: [] };
|
|
439
439
|
return raw;
|
|
440
440
|
} catch {
|
|
@@ -442,16 +442,16 @@ function loadMeshConfig() {
|
|
|
442
442
|
}
|
|
443
443
|
}
|
|
444
444
|
function saveMeshConfig(config) {
|
|
445
|
-
const
|
|
446
|
-
writeFileSync2(
|
|
445
|
+
const path28 = getMeshConfigPath();
|
|
446
|
+
writeFileSync2(path28, JSON.stringify(config, null, 2), { encoding: "utf-8", mode: 384 });
|
|
447
447
|
}
|
|
448
448
|
function normalizeRepoIdentity(remoteUrl) {
|
|
449
449
|
let identity = remoteUrl.trim();
|
|
450
450
|
if (identity.startsWith("http://") || identity.startsWith("https://")) {
|
|
451
451
|
try {
|
|
452
452
|
const url = new URL(identity);
|
|
453
|
-
const
|
|
454
|
-
return `${url.hostname}/${
|
|
453
|
+
const path28 = url.pathname.replace(/^\//, "").replace(/\.git$/, "");
|
|
454
|
+
return `${url.hostname}/${path28}`;
|
|
455
455
|
} catch {
|
|
456
456
|
}
|
|
457
457
|
}
|
|
@@ -605,6 +605,7 @@ Default branch: \`${mesh.defaultBranch}\`` : ""}`);
|
|
|
605
605
|
}
|
|
606
606
|
sections.push(buildPolicySection({ ...DEFAULT_MESH_POLICY, ...mesh.policy || {} }));
|
|
607
607
|
sections.push(TOOLS_SECTION);
|
|
608
|
+
sections.push(TOOL_EXPOSURE_PREFLIGHT_SECTION);
|
|
608
609
|
sections.push(WORKFLOW_SECTION);
|
|
609
610
|
sections.push(buildRulesSection(coordinatorCliType));
|
|
610
611
|
if (userInstruction) {
|
|
@@ -674,7 +675,7 @@ function buildRulesSection(coordinatorCliType) {
|
|
|
674
675
|
- **Clean up worktree nodes.** After a worktree task completes and its changes are merged or checkpointed, call \`mesh_remove_node\` to free resources.
|
|
675
676
|
- **Name worktree branches meaningfully.** Use descriptive names like \`feat/auth-refactor\` or \`fix/build-123\`.${coordinatorNote}`;
|
|
676
677
|
}
|
|
677
|
-
var TOOLS_SECTION, WORKFLOW_SECTION;
|
|
678
|
+
var TOOLS_SECTION, TOOL_EXPOSURE_PREFLIGHT_SECTION, WORKFLOW_SECTION;
|
|
678
679
|
var init_coordinator_prompt = __esm({
|
|
679
680
|
"src/mesh/coordinator-prompt.ts"() {
|
|
680
681
|
"use strict";
|
|
@@ -693,6 +694,9 @@ var init_coordinator_prompt = __esm({
|
|
|
693
694
|
| \`mesh_approve\` | Approve/reject a pending agent action |
|
|
694
695
|
| \`mesh_clone_node\` | Create a worktree node for isolated parallel branch work |
|
|
695
696
|
| \`mesh_remove_node\` | Remove a node (cleans up worktree if applicable) |`;
|
|
697
|
+
TOOL_EXPOSURE_PREFLIGHT_SECTION = `## Tool Exposure Preflight
|
|
698
|
+
|
|
699
|
+
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\`.`;
|
|
696
700
|
WORKFLOW_SECTION = `## Orchestration Workflow
|
|
697
701
|
|
|
698
702
|
1. **Assess** \u2014 Call \`mesh_status\` to see which nodes are healthy and available.
|
|
@@ -7522,6 +7526,10 @@ function flattenMessageParts(parts) {
|
|
|
7522
7526
|
return parts.map((part) => {
|
|
7523
7527
|
if (part.type === "text") return part.text;
|
|
7524
7528
|
if (part.type === "resource") return part.resource.text || "";
|
|
7529
|
+
if (part.type === "image") return part.alt || (part.data ? `[image: ${part.mimeType}]` : "");
|
|
7530
|
+
if (part.type === "audio") return part.transcript || (part.data ? `[audio: ${part.mimeType}]` : "");
|
|
7531
|
+
if (part.type === "video") return part.transcript || (part.data ? `[video: ${part.mimeType}]` : "");
|
|
7532
|
+
if (part.type === "resource_link") return [part.name, part.description].filter(Boolean).join("\n");
|
|
7525
7533
|
return "";
|
|
7526
7534
|
}).filter((value) => value.length > 0).join("\n");
|
|
7527
7535
|
}
|
|
@@ -7608,6 +7616,7 @@ function normalizeInputPartObject(raw) {
|
|
|
7608
7616
|
mimeType: raw.mimeType,
|
|
7609
7617
|
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7610
7618
|
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7619
|
+
...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {},
|
|
7611
7620
|
...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
|
|
7612
7621
|
};
|
|
7613
7622
|
}
|
|
@@ -7623,10 +7632,14 @@ function normalizeInputPartObject(raw) {
|
|
|
7623
7632
|
}
|
|
7624
7633
|
if (type === "resource_link" && typeof raw.uri === "string") {
|
|
7625
7634
|
return {
|
|
7626
|
-
type
|
|
7635
|
+
type,
|
|
7627
7636
|
uri: raw.uri,
|
|
7637
|
+
name: typeof raw.name === "string" ? raw.name : getUriDisplayName(raw.uri, "resource"),
|
|
7638
|
+
...typeof raw.title === "string" ? { title: raw.title } : {},
|
|
7639
|
+
...typeof raw.description === "string" ? { description: raw.description } : {},
|
|
7628
7640
|
...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
|
|
7629
|
-
...typeof raw.
|
|
7641
|
+
...typeof raw.size === "number" && Number.isFinite(raw.size) ? { size: raw.size } : {},
|
|
7642
|
+
...normalizeAnnotationsProperty(raw.annotations)
|
|
7630
7643
|
};
|
|
7631
7644
|
}
|
|
7632
7645
|
return null;
|
|
@@ -7641,7 +7654,8 @@ function normalizeMessagePartObject(raw) {
|
|
|
7641
7654
|
type,
|
|
7642
7655
|
mimeType: raw.mimeType,
|
|
7643
7656
|
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7644
|
-
...typeof raw.data === "string" ? { data: raw.data } : {}
|
|
7657
|
+
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7658
|
+
...typeof raw.alt === "string" ? { alt: raw.alt } : {}
|
|
7645
7659
|
};
|
|
7646
7660
|
}
|
|
7647
7661
|
if (type === "audio" && typeof raw.mimeType === "string") {
|
|
@@ -7659,6 +7673,7 @@ function normalizeMessagePartObject(raw) {
|
|
|
7659
7673
|
mimeType: raw.mimeType,
|
|
7660
7674
|
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7661
7675
|
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7676
|
+
...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {},
|
|
7662
7677
|
...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
|
|
7663
7678
|
};
|
|
7664
7679
|
}
|
|
@@ -7667,8 +7682,11 @@ function normalizeMessagePartObject(raw) {
|
|
|
7667
7682
|
type,
|
|
7668
7683
|
uri: raw.uri,
|
|
7669
7684
|
name: raw.name,
|
|
7685
|
+
...typeof raw.title === "string" ? { title: raw.title } : {},
|
|
7686
|
+
...typeof raw.description === "string" ? { description: raw.description } : {},
|
|
7670
7687
|
...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
|
|
7671
|
-
...typeof raw.size === "number" ? { size: raw.size } : {}
|
|
7688
|
+
...typeof raw.size === "number" && Number.isFinite(raw.size) ? { size: raw.size } : {},
|
|
7689
|
+
...normalizeAnnotationsProperty(raw.annotations)
|
|
7672
7690
|
};
|
|
7673
7691
|
}
|
|
7674
7692
|
if (type === "resource" && raw.resource && typeof raw.resource === "object") {
|
|
@@ -7689,11 +7707,35 @@ function normalizeMessagePartObject(raw) {
|
|
|
7689
7707
|
function flattenInputParts(parts) {
|
|
7690
7708
|
return parts.map((part) => {
|
|
7691
7709
|
if (part.type === "text") return part.text;
|
|
7692
|
-
if (part.type === "
|
|
7693
|
-
if (part.type === "
|
|
7710
|
+
if (part.type === "image") return part.alt || (part.data ? `[image: ${part.mimeType}]` : "");
|
|
7711
|
+
if (part.type === "audio") return part.transcript || (part.data ? `[audio: ${part.mimeType}]` : "");
|
|
7712
|
+
if (part.type === "video") return part.transcript || (part.data ? `[video: ${part.mimeType}]` : "");
|
|
7713
|
+
if (part.type === "resource_link") return [part.title, part.name, part.description, part.uri].filter(Boolean).join("\n");
|
|
7714
|
+
if (part.type === "resource") return part.text || part.name || part.uri;
|
|
7694
7715
|
return "";
|
|
7695
7716
|
}).filter((value) => value.length > 0).join("\n");
|
|
7696
7717
|
}
|
|
7718
|
+
function getUriDisplayName(uri, fallback) {
|
|
7719
|
+
try {
|
|
7720
|
+
const pathname = uri.startsWith("file://") ? new URL(uri).pathname : uri;
|
|
7721
|
+
return pathname.split(/[\\/]/).filter(Boolean).pop() || fallback;
|
|
7722
|
+
} catch {
|
|
7723
|
+
return uri.split(/[\\/]/).filter(Boolean).pop() || fallback;
|
|
7724
|
+
}
|
|
7725
|
+
}
|
|
7726
|
+
function normalizeAnnotationsProperty(value) {
|
|
7727
|
+
if (!value || typeof value !== "object") return {};
|
|
7728
|
+
const record = value;
|
|
7729
|
+
const annotations = {};
|
|
7730
|
+
if (Array.isArray(record.audience)) {
|
|
7731
|
+
const audience = record.audience.filter((item) => item === "user" || item === "assistant");
|
|
7732
|
+
if (audience.length > 0) annotations.audience = audience;
|
|
7733
|
+
}
|
|
7734
|
+
if (typeof record.priority === "number" && Number.isFinite(record.priority)) {
|
|
7735
|
+
annotations.priority = record.priority;
|
|
7736
|
+
}
|
|
7737
|
+
return Object.keys(annotations).length > 0 ? { annotations } : {};
|
|
7738
|
+
}
|
|
7697
7739
|
|
|
7698
7740
|
// src/providers/contracts.ts
|
|
7699
7741
|
function flattenContent(content) {
|
|
@@ -11353,6 +11395,147 @@ function normalizeActiveChatData(activeChat, options = FULL_STATUS_ACTIVE_CHAT_O
|
|
|
11353
11395
|
return normalized;
|
|
11354
11396
|
}
|
|
11355
11397
|
|
|
11398
|
+
// src/providers/provider-input-support.ts
|
|
11399
|
+
var VALID_INPUT_MEDIA_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "resource"]);
|
|
11400
|
+
var VALID_INPUT_STRATEGIES = /* @__PURE__ */ new Set(["native", "native_acp", "resource_link", "text_fallback", "paste", "upload"]);
|
|
11401
|
+
var TEXT_ONLY_MESSAGE_INPUT_SUPPORT = Object.freeze({
|
|
11402
|
+
text: true,
|
|
11403
|
+
multipart: false,
|
|
11404
|
+
mediaTypes: ["text"],
|
|
11405
|
+
strategies: []
|
|
11406
|
+
});
|
|
11407
|
+
function getProviderLabel(provider) {
|
|
11408
|
+
return provider?.name || provider?.type || "This provider";
|
|
11409
|
+
}
|
|
11410
|
+
function hasNonEmptyFallbackText(input) {
|
|
11411
|
+
return typeof input.textFallback === "string" && input.textFallback.trim().length > 0;
|
|
11412
|
+
}
|
|
11413
|
+
function getRequestedInputMediaTypes(input) {
|
|
11414
|
+
const types = /* @__PURE__ */ new Set();
|
|
11415
|
+
if (hasNonEmptyFallbackText(input) && !input.parts.some((part) => part.type === "text")) {
|
|
11416
|
+
types.add("text");
|
|
11417
|
+
}
|
|
11418
|
+
for (const part of input.parts) {
|
|
11419
|
+
if (VALID_INPUT_MEDIA_TYPES.has(part.type)) {
|
|
11420
|
+
types.add(part.type);
|
|
11421
|
+
}
|
|
11422
|
+
}
|
|
11423
|
+
return Array.from(types);
|
|
11424
|
+
}
|
|
11425
|
+
function getEffectiveSemanticPartCount(input) {
|
|
11426
|
+
let count = input.parts.length;
|
|
11427
|
+
if (hasNonEmptyFallbackText(input) && !input.parts.some((part) => part.type === "text")) {
|
|
11428
|
+
count += 1;
|
|
11429
|
+
}
|
|
11430
|
+
return count;
|
|
11431
|
+
}
|
|
11432
|
+
function assertTextOnlyInput(provider, input) {
|
|
11433
|
+
const unsupported = getRequestedInputMediaTypes(input).filter((type) => type !== "text");
|
|
11434
|
+
if (unsupported.length === 0) return;
|
|
11435
|
+
const label = getProviderLabel(provider);
|
|
11436
|
+
const suffix = unsupported.length === 1 ? "" : "s";
|
|
11437
|
+
throw new Error(`${label} only supports text input; unsupported input type${suffix}: ${unsupported.join(", ")}`);
|
|
11438
|
+
}
|
|
11439
|
+
function getDeclaredProviderInputSupport(provider) {
|
|
11440
|
+
const rawMediaTypes = Array.isArray(provider?.capabilities?.input?.mediaTypes) ? provider?.capabilities?.input?.mediaTypes.filter((type) => VALID_INPUT_MEDIA_TYPES.has(type)) : [];
|
|
11441
|
+
const strategies = normalizeInputStrategyDescriptors(provider?.capabilities?.input?.strategies);
|
|
11442
|
+
return {
|
|
11443
|
+
multipart: provider?.capabilities?.input?.multipart === true,
|
|
11444
|
+
mediaTypes: new Set(rawMediaTypes.length > 0 ? rawMediaTypes : ["text"]),
|
|
11445
|
+
strategies
|
|
11446
|
+
};
|
|
11447
|
+
}
|
|
11448
|
+
function normalizeInputStrategyDescriptors(raw) {
|
|
11449
|
+
if (!Array.isArray(raw)) return [];
|
|
11450
|
+
const result = [];
|
|
11451
|
+
for (const entry of raw) {
|
|
11452
|
+
if (!entry || typeof entry !== "object") continue;
|
|
11453
|
+
const record = entry;
|
|
11454
|
+
const mediaType = record.mediaType;
|
|
11455
|
+
if (typeof mediaType !== "string" || !VALID_INPUT_MEDIA_TYPES.has(mediaType)) continue;
|
|
11456
|
+
const strategies = Array.isArray(record.strategies) ? record.strategies.filter((value) => typeof value === "string" && VALID_INPUT_STRATEGIES.has(value)) : [];
|
|
11457
|
+
const degradation = Array.isArray(record.degradation) ? record.degradation.filter((value) => typeof value === "string" && VALID_INPUT_STRATEGIES.has(value)) : [];
|
|
11458
|
+
if (strategies.length === 0 && degradation.length === 0) continue;
|
|
11459
|
+
result.push({
|
|
11460
|
+
mediaType,
|
|
11461
|
+
strategies,
|
|
11462
|
+
...typeof record.native === "boolean" ? { native: record.native } : {},
|
|
11463
|
+
...degradation.length > 0 ? { degradation } : {}
|
|
11464
|
+
});
|
|
11465
|
+
}
|
|
11466
|
+
return result;
|
|
11467
|
+
}
|
|
11468
|
+
function promptCapabilityFlags(runtimeCapabilities) {
|
|
11469
|
+
const prompt = runtimeCapabilities?.promptCapabilities || {};
|
|
11470
|
+
return {
|
|
11471
|
+
image: prompt.image === true,
|
|
11472
|
+
audio: prompt.audio === true,
|
|
11473
|
+
embeddedContext: prompt.embeddedContext === true
|
|
11474
|
+
};
|
|
11475
|
+
}
|
|
11476
|
+
function supportFromDeclared(provider) {
|
|
11477
|
+
const declared = getDeclaredProviderInputSupport(provider);
|
|
11478
|
+
return {
|
|
11479
|
+
text: true,
|
|
11480
|
+
multipart: declared.multipart,
|
|
11481
|
+
mediaTypes: Array.from(declared.mediaTypes),
|
|
11482
|
+
strategies: declared.strategies
|
|
11483
|
+
};
|
|
11484
|
+
}
|
|
11485
|
+
function getEffectiveMessageInputSupport(provider, runtimeCapabilities) {
|
|
11486
|
+
if (provider?.category !== "acp") {
|
|
11487
|
+
const declared2 = supportFromDeclared(provider);
|
|
11488
|
+
return {
|
|
11489
|
+
...declared2,
|
|
11490
|
+
mediaTypes: [...declared2.mediaTypes],
|
|
11491
|
+
strategies: declared2.strategies.map((strategy) => ({
|
|
11492
|
+
...strategy,
|
|
11493
|
+
strategies: [...strategy.strategies],
|
|
11494
|
+
...strategy.degradation ? { degradation: [...strategy.degradation] } : {}
|
|
11495
|
+
}))
|
|
11496
|
+
};
|
|
11497
|
+
}
|
|
11498
|
+
const declared = supportFromDeclared(provider);
|
|
11499
|
+
const caps = promptCapabilityFlags(runtimeCapabilities);
|
|
11500
|
+
const mediaTypes = /* @__PURE__ */ new Set(["text"]);
|
|
11501
|
+
const strategies = [];
|
|
11502
|
+
if (declared.mediaTypes.includes("resource")) {
|
|
11503
|
+
mediaTypes.add("resource");
|
|
11504
|
+
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"] });
|
|
11505
|
+
}
|
|
11506
|
+
if (declared.mediaTypes.includes("video")) {
|
|
11507
|
+
mediaTypes.add("video");
|
|
11508
|
+
strategies.push({ mediaType: "video", strategies: ["resource_link", "text_fallback"], native: false, degradation: ["resource_link", "text_fallback"] });
|
|
11509
|
+
}
|
|
11510
|
+
if (declared.mediaTypes.includes("image")) {
|
|
11511
|
+
mediaTypes.add("image");
|
|
11512
|
+
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"] });
|
|
11513
|
+
}
|
|
11514
|
+
if (declared.mediaTypes.includes("audio")) {
|
|
11515
|
+
mediaTypes.add("audio");
|
|
11516
|
+
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"] });
|
|
11517
|
+
}
|
|
11518
|
+
return {
|
|
11519
|
+
text: true,
|
|
11520
|
+
multipart: declared.multipart && mediaTypes.size > 1,
|
|
11521
|
+
mediaTypes: Array.from(mediaTypes),
|
|
11522
|
+
strategies
|
|
11523
|
+
};
|
|
11524
|
+
}
|
|
11525
|
+
function assertProviderSupportsDeclaredInput(provider, input) {
|
|
11526
|
+
const label = getProviderLabel(provider);
|
|
11527
|
+
const support = getDeclaredProviderInputSupport(provider);
|
|
11528
|
+
const requestedTypes = getRequestedInputMediaTypes(input);
|
|
11529
|
+
const unsupported = requestedTypes.filter((type) => !support.mediaTypes.has(type));
|
|
11530
|
+
if (unsupported.length > 0) {
|
|
11531
|
+
const suffix = unsupported.length === 1 ? "" : "s";
|
|
11532
|
+
throw new Error(`${label} does not support input type${suffix}: ${unsupported.join(", ")}`);
|
|
11533
|
+
}
|
|
11534
|
+
if (getEffectiveSemanticPartCount(input) > 1 && !support.multipart) {
|
|
11535
|
+
throw new Error(`${label} does not support multipart input`);
|
|
11536
|
+
}
|
|
11537
|
+
}
|
|
11538
|
+
|
|
11356
11539
|
// src/status/builders.ts
|
|
11357
11540
|
function getActiveChatOptions(profile) {
|
|
11358
11541
|
if (profile === "full") return {};
|
|
@@ -11450,7 +11633,7 @@ function buildIdeWorkspaceSession(state, cdpManagers, options) {
|
|
|
11450
11633
|
...git && { git },
|
|
11451
11634
|
activeChat,
|
|
11452
11635
|
...summaryMetadata && { summaryMetadata },
|
|
11453
|
-
...includeSessionMetadata && { capabilities: state.sessionCapabilities || IDE_SESSION_CAPABILITIES },
|
|
11636
|
+
...includeSessionMetadata && { capabilities: state.sessionCapabilities || IDE_SESSION_CAPABILITIES, messageInput: state.messageInput || TEXT_ONLY_MESSAGE_INPUT_SUPPORT },
|
|
11454
11637
|
cdpConnected: state.cdpConnected ?? isCdpConnected(cdpManagers, state.type),
|
|
11455
11638
|
...includeSessionControls && {
|
|
11456
11639
|
...controlValues && { controlValues },
|
|
@@ -11485,7 +11668,7 @@ function buildExtensionAgentSession(parent, ext, options) {
|
|
|
11485
11668
|
...git && { git },
|
|
11486
11669
|
activeChat,
|
|
11487
11670
|
...summaryMetadata && { summaryMetadata },
|
|
11488
|
-
...includeSessionMetadata && { capabilities: ext.sessionCapabilities || EXTENSION_SESSION_CAPABILITIES },
|
|
11671
|
+
...includeSessionMetadata && { capabilities: ext.sessionCapabilities || EXTENSION_SESSION_CAPABILITIES, messageInput: ext.messageInput || TEXT_ONLY_MESSAGE_INPUT_SUPPORT },
|
|
11489
11672
|
...includeSessionControls && {
|
|
11490
11673
|
...controlValues && { controlValues },
|
|
11491
11674
|
providerControls: ext.providerControls
|
|
@@ -11549,7 +11732,8 @@ function buildCliSession(state, options) {
|
|
|
11549
11732
|
activeChat,
|
|
11550
11733
|
...summaryMetadata && { summaryMetadata },
|
|
11551
11734
|
...includeSessionMetadata && {
|
|
11552
|
-
capabilities: state.mode === "terminal" ? PTY_SESSION_CAPABILITIES : CLI_CHAT_SESSION_CAPABILITIES
|
|
11735
|
+
capabilities: state.mode === "terminal" ? PTY_SESSION_CAPABILITIES : CLI_CHAT_SESSION_CAPABILITIES,
|
|
11736
|
+
messageInput: state.messageInput || TEXT_ONLY_MESSAGE_INPUT_SUPPORT
|
|
11553
11737
|
},
|
|
11554
11738
|
...includeSessionControls && {
|
|
11555
11739
|
...controlValues && { controlValues },
|
|
@@ -11583,7 +11767,7 @@ function buildAcpSession(state, options) {
|
|
|
11583
11767
|
...git && { git },
|
|
11584
11768
|
activeChat,
|
|
11585
11769
|
...summaryMetadata && { summaryMetadata },
|
|
11586
|
-
...includeSessionMetadata && { capabilities: ACP_SESSION_CAPABILITIES },
|
|
11770
|
+
...includeSessionMetadata && { capabilities: ACP_SESSION_CAPABILITIES, messageInput: state.messageInput || TEXT_ONLY_MESSAGE_INPUT_SUPPORT },
|
|
11587
11771
|
...includeSessionControls && {
|
|
11588
11772
|
...controlValues && { controlValues },
|
|
11589
11773
|
providerControls: state.providerControls
|
|
@@ -11702,63 +11886,6 @@ import * as fs4 from "fs";
|
|
|
11702
11886
|
import * as os6 from "os";
|
|
11703
11887
|
import * as path12 from "path";
|
|
11704
11888
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
11705
|
-
|
|
11706
|
-
// src/providers/provider-input-support.ts
|
|
11707
|
-
var VALID_INPUT_MEDIA_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "resource"]);
|
|
11708
|
-
function getProviderLabel(provider) {
|
|
11709
|
-
return provider?.name || provider?.type || "This provider";
|
|
11710
|
-
}
|
|
11711
|
-
function hasNonEmptyFallbackText(input) {
|
|
11712
|
-
return typeof input.textFallback === "string" && input.textFallback.trim().length > 0;
|
|
11713
|
-
}
|
|
11714
|
-
function getRequestedInputMediaTypes(input) {
|
|
11715
|
-
const types = /* @__PURE__ */ new Set();
|
|
11716
|
-
if (hasNonEmptyFallbackText(input) && !input.parts.some((part) => part.type === "text")) {
|
|
11717
|
-
types.add("text");
|
|
11718
|
-
}
|
|
11719
|
-
for (const part of input.parts) {
|
|
11720
|
-
if (VALID_INPUT_MEDIA_TYPES.has(part.type)) {
|
|
11721
|
-
types.add(part.type);
|
|
11722
|
-
}
|
|
11723
|
-
}
|
|
11724
|
-
return Array.from(types);
|
|
11725
|
-
}
|
|
11726
|
-
function getEffectiveSemanticPartCount(input) {
|
|
11727
|
-
let count = input.parts.length;
|
|
11728
|
-
if (hasNonEmptyFallbackText(input) && !input.parts.some((part) => part.type === "text")) {
|
|
11729
|
-
count += 1;
|
|
11730
|
-
}
|
|
11731
|
-
return count;
|
|
11732
|
-
}
|
|
11733
|
-
function assertTextOnlyInput(provider, input) {
|
|
11734
|
-
const unsupported = getRequestedInputMediaTypes(input).filter((type) => type !== "text");
|
|
11735
|
-
if (unsupported.length === 0) return;
|
|
11736
|
-
const label = getProviderLabel(provider);
|
|
11737
|
-
const suffix = unsupported.length === 1 ? "" : "s";
|
|
11738
|
-
throw new Error(`${label} only supports text input; unsupported input type${suffix}: ${unsupported.join(", ")}`);
|
|
11739
|
-
}
|
|
11740
|
-
function getDeclaredProviderInputSupport(provider) {
|
|
11741
|
-
const rawMediaTypes = Array.isArray(provider?.capabilities?.input?.mediaTypes) ? provider?.capabilities?.input?.mediaTypes.filter((type) => VALID_INPUT_MEDIA_TYPES.has(type)) : [];
|
|
11742
|
-
return {
|
|
11743
|
-
multipart: provider?.capabilities?.input?.multipart === true,
|
|
11744
|
-
mediaTypes: new Set(rawMediaTypes.length > 0 ? rawMediaTypes : ["text"])
|
|
11745
|
-
};
|
|
11746
|
-
}
|
|
11747
|
-
function assertProviderSupportsDeclaredInput(provider, input) {
|
|
11748
|
-
const label = getProviderLabel(provider);
|
|
11749
|
-
const support = getDeclaredProviderInputSupport(provider);
|
|
11750
|
-
const requestedTypes = getRequestedInputMediaTypes(input);
|
|
11751
|
-
const unsupported = requestedTypes.filter((type) => !support.mediaTypes.has(type));
|
|
11752
|
-
if (unsupported.length > 0) {
|
|
11753
|
-
const suffix = unsupported.length === 1 ? "" : "s";
|
|
11754
|
-
throw new Error(`${label} does not support input type${suffix}: ${unsupported.join(", ")}`);
|
|
11755
|
-
}
|
|
11756
|
-
if (getEffectiveSemanticPartCount(input) > 1 && !support.multipart) {
|
|
11757
|
-
throw new Error(`${label} does not support multipart input`);
|
|
11758
|
-
}
|
|
11759
|
-
}
|
|
11760
|
-
|
|
11761
|
-
// src/commands/chat-commands.ts
|
|
11762
11889
|
init_logger();
|
|
11763
11890
|
|
|
11764
11891
|
// src/logging/debug-trace.ts
|
|
@@ -11948,10 +12075,25 @@ function buildRecentSendKey(h, args, provider, signature) {
|
|
|
11948
12075
|
const target = args?.targetSessionId || args?.agentType || h.currentSession?.providerType || h.currentProviderType || h.currentManagerKey || "unknown";
|
|
11949
12076
|
return `${transport}:${target}:${signature.trim()}`;
|
|
11950
12077
|
}
|
|
12078
|
+
function summarizeSendInputPart(part) {
|
|
12079
|
+
if (!part || typeof part !== "object") return String(part ?? "");
|
|
12080
|
+
if (part.type === "text") return `text:${String(part.text || "").trim()}`;
|
|
12081
|
+
const fields = [
|
|
12082
|
+
`type=${String(part.type || "")}`,
|
|
12083
|
+
`mime=${String(part.mimeType || "")}`,
|
|
12084
|
+
`uri=${String(part.uri || "")}`,
|
|
12085
|
+
`name=${String(part.name || "")}`
|
|
12086
|
+
];
|
|
12087
|
+
const data = typeof part.data === "string" ? part.data : typeof part.resource?.blob === "string" ? part.resource.blob : "";
|
|
12088
|
+
if (data) fields.push(`dataLen=${data.length}`, `dataHash=${hashSignatureParts([data]).slice(0, 12)}`);
|
|
12089
|
+
const textish = [part.alt, part.transcript, part.description, part.title, part.resource?.uri].filter((value) => typeof value === "string" && value.trim()).join("");
|
|
12090
|
+
if (textish) fields.push(`meta=${hashSignatureParts([textish]).slice(0, 12)}`);
|
|
12091
|
+
return fields.join(";");
|
|
12092
|
+
}
|
|
11951
12093
|
function buildSendInputSignature(input) {
|
|
11952
12094
|
const text = typeof input.textFallback === "string" ? input.textFallback.trim() : "";
|
|
11953
|
-
|
|
11954
|
-
return
|
|
12095
|
+
const partSummaries = (input.parts || []).map(summarizeSendInputPart);
|
|
12096
|
+
return hashSignatureParts([text, ...partSummaries]);
|
|
11955
12097
|
}
|
|
11956
12098
|
function getSendChatInputEnvelope(args) {
|
|
11957
12099
|
return normalizeInputEnvelope(args?.input ? { input: args.input } : args);
|
|
@@ -12832,6 +12974,17 @@ async function handleSendChat(h, args) {
|
|
|
12832
12974
|
if (adapter) {
|
|
12833
12975
|
_log(`${transport} adapter: ${adapter.cliType}`);
|
|
12834
12976
|
try {
|
|
12977
|
+
const hasStructuredParts = input.parts.some((part) => part.type !== "text");
|
|
12978
|
+
if (hasStructuredParts) {
|
|
12979
|
+
const target = getTargetInstance(h, args);
|
|
12980
|
+
if (!target || target.category !== "cli") {
|
|
12981
|
+
return { success: false, error: `CLI instance not found for ${provider?.type || args?.agentType || "unknown"}` };
|
|
12982
|
+
}
|
|
12983
|
+
assertProviderSupportsDeclaredInput(provider, input);
|
|
12984
|
+
await waitOnceForFreshHermesCliStart(adapter, _log);
|
|
12985
|
+
target.onEvent("send_message", { input });
|
|
12986
|
+
return _logSendSuccess(`${transport}-instance`, target.type);
|
|
12987
|
+
}
|
|
12835
12988
|
assertTextOnlyInput(provider, input);
|
|
12836
12989
|
if (!text) return { success: false, error: "text required for PTY send" };
|
|
12837
12990
|
await waitOnceForFreshHermesCliStart(adapter, _log);
|
|
@@ -14922,9 +15075,9 @@ var DaemonCommandHandler = class {
|
|
|
14922
15075
|
// src/commands/cli-manager.ts
|
|
14923
15076
|
init_provider_cli_adapter();
|
|
14924
15077
|
import * as os13 from "os";
|
|
14925
|
-
import * as
|
|
15078
|
+
import * as path18 from "path";
|
|
14926
15079
|
import * as crypto4 from "crypto";
|
|
14927
|
-
import { existsSync as existsSync12, mkdirSync as
|
|
15080
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync8, writeFileSync as writeFileSync8 } from "fs";
|
|
14928
15081
|
import { execFileSync } from "child_process";
|
|
14929
15082
|
import chalk from "chalk";
|
|
14930
15083
|
init_config();
|
|
@@ -14956,6 +15109,79 @@ function normalizeProviderSessionId(provider, providerSessionId) {
|
|
|
14956
15109
|
}
|
|
14957
15110
|
|
|
14958
15111
|
// src/providers/cli-provider-instance.ts
|
|
15112
|
+
var IMAGE_MIME_EXTENSIONS = {
|
|
15113
|
+
"image/png": ".png",
|
|
15114
|
+
"image/jpeg": ".jpg",
|
|
15115
|
+
"image/jpg": ".jpg",
|
|
15116
|
+
"image/gif": ".gif",
|
|
15117
|
+
"image/webp": ".webp",
|
|
15118
|
+
"image/bmp": ".bmp",
|
|
15119
|
+
"image/tiff": ".tiff",
|
|
15120
|
+
"image/svg+xml": ".svg"
|
|
15121
|
+
};
|
|
15122
|
+
function filePathFromUri(uri) {
|
|
15123
|
+
if (!uri) return null;
|
|
15124
|
+
if (uri.startsWith("file://")) {
|
|
15125
|
+
try {
|
|
15126
|
+
return decodeURIComponent(new URL(uri).pathname);
|
|
15127
|
+
} catch {
|
|
15128
|
+
return uri.slice("file://".length);
|
|
15129
|
+
}
|
|
15130
|
+
}
|
|
15131
|
+
if (path16.isAbsolute(uri)) return uri;
|
|
15132
|
+
return null;
|
|
15133
|
+
}
|
|
15134
|
+
function extensionForImageMime(mimeType) {
|
|
15135
|
+
return IMAGE_MIME_EXTENSIONS[mimeType.toLowerCase()] || ".img";
|
|
15136
|
+
}
|
|
15137
|
+
function safeInputImageBasename(index, mimeType) {
|
|
15138
|
+
const extension = extensionForImageMime(mimeType);
|
|
15139
|
+
const suffix = crypto3.randomBytes(6).toString("hex");
|
|
15140
|
+
return `adhdev-input-image-${Date.now()}-${index}-${suffix}${extension}`;
|
|
15141
|
+
}
|
|
15142
|
+
function materializeImageDataPart(part, index, dir) {
|
|
15143
|
+
if (!part.data) return null;
|
|
15144
|
+
const rawData = part.data.includes(",") ? part.data.split(",").pop() || "" : part.data;
|
|
15145
|
+
if (!rawData) return null;
|
|
15146
|
+
fs6.mkdirSync(dir, { recursive: true });
|
|
15147
|
+
const filePath = path16.join(dir, safeInputImageBasename(index, part.mimeType));
|
|
15148
|
+
fs6.writeFileSync(filePath, Buffer.from(rawData, "base64"));
|
|
15149
|
+
return filePath;
|
|
15150
|
+
}
|
|
15151
|
+
function buildCliStructuredInputPrompt(input, options = {}) {
|
|
15152
|
+
const promptParts = [];
|
|
15153
|
+
const imageRefs = [];
|
|
15154
|
+
const resourceRefs = [];
|
|
15155
|
+
const materializeDir = options.materializeDir || path16.join(os12.tmpdir(), "adhdev-input-media");
|
|
15156
|
+
input.parts.forEach((part, index) => {
|
|
15157
|
+
if (part.type === "text" && part.text.trim()) {
|
|
15158
|
+
promptParts.push(part.text.trim());
|
|
15159
|
+
return;
|
|
15160
|
+
}
|
|
15161
|
+
if (part.type === "image") {
|
|
15162
|
+
const localPath = typeof part.uri === "string" ? filePathFromUri(part.uri) : null;
|
|
15163
|
+
const materializedPath = !localPath && part.data ? materializeImageDataPart(part, index, materializeDir) : null;
|
|
15164
|
+
const ref = localPath || materializedPath || part.uri || "";
|
|
15165
|
+
if (ref) imageRefs.push(ref);
|
|
15166
|
+
if (part.alt?.trim()) promptParts.push(part.alt.trim());
|
|
15167
|
+
return;
|
|
15168
|
+
}
|
|
15169
|
+
if (part.type === "resource_link") {
|
|
15170
|
+
resourceRefs.push([part.title, part.name, part.description, part.uri].filter(Boolean).join("\n"));
|
|
15171
|
+
return;
|
|
15172
|
+
}
|
|
15173
|
+
if (part.type === "resource") {
|
|
15174
|
+
resourceRefs.push([part.name, part.text, part.uri].filter(Boolean).join("\n"));
|
|
15175
|
+
}
|
|
15176
|
+
});
|
|
15177
|
+
if (input.textFallback.trim()) promptParts.push(input.textFallback.trim());
|
|
15178
|
+
const ordered = [
|
|
15179
|
+
...imageRefs,
|
|
15180
|
+
...promptParts,
|
|
15181
|
+
...resourceRefs
|
|
15182
|
+
].filter((value, index, values) => value.trim().length > 0 && values.indexOf(value) === index);
|
|
15183
|
+
return ordered.join("\n");
|
|
15184
|
+
}
|
|
14959
15185
|
function normalizePersistableCliHistoryContent(content) {
|
|
14960
15186
|
return flattenContent(content).replace(/\s+/g, " ").trim();
|
|
14961
15187
|
}
|
|
@@ -15275,6 +15501,7 @@ var CliProviderInstance = class {
|
|
|
15275
15501
|
resume: this.provider.resume,
|
|
15276
15502
|
controlValues: surface.controlValues,
|
|
15277
15503
|
providerControls: this.provider.controls,
|
|
15504
|
+
messageInput: getEffectiveMessageInputSupport(this.provider),
|
|
15278
15505
|
summaryMetadata: surface.summaryMetadata,
|
|
15279
15506
|
errorMessage: this.errorMessage,
|
|
15280
15507
|
errorReason: this.errorReason
|
|
@@ -15325,9 +15552,10 @@ var CliProviderInstance = class {
|
|
|
15325
15552
|
onEvent(event, data) {
|
|
15326
15553
|
if (event === "send_message") {
|
|
15327
15554
|
const input = normalizeInputEnvelope(data);
|
|
15328
|
-
|
|
15329
|
-
|
|
15330
|
-
|
|
15555
|
+
assertProviderSupportsDeclaredInput(this.provider, input);
|
|
15556
|
+
const promptText = buildCliStructuredInputPrompt(input);
|
|
15557
|
+
if (promptText) {
|
|
15558
|
+
void this.adapter.sendMessage(promptText).catch((e) => {
|
|
15331
15559
|
LOG.warn("CLI", `[${this.type}] send_message failed: ${e?.message || e}`);
|
|
15332
15560
|
});
|
|
15333
15561
|
}
|
|
@@ -15956,6 +16184,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
15956
16184
|
};
|
|
15957
16185
|
|
|
15958
16186
|
// src/providers/acp-provider-instance.ts
|
|
16187
|
+
import * as path17 from "path";
|
|
15959
16188
|
import { Readable, Writable } from "stream";
|
|
15960
16189
|
import { spawn } from "child_process";
|
|
15961
16190
|
import {
|
|
@@ -15980,6 +16209,31 @@ function appendPromptText(promptParts, text) {
|
|
|
15980
16209
|
if (last?.type === "text" && last.text === normalized) return;
|
|
15981
16210
|
promptParts.push({ type: "text", text: normalized });
|
|
15982
16211
|
}
|
|
16212
|
+
function getUriDisplayName2(uri, fallback) {
|
|
16213
|
+
if (!uri) return fallback;
|
|
16214
|
+
try {
|
|
16215
|
+
const pathname = uri.startsWith("file://") ? new URL(uri).pathname : uri;
|
|
16216
|
+
return pathname.split(/[\\/]/).filter(Boolean).pop() || fallback;
|
|
16217
|
+
} catch {
|
|
16218
|
+
return uri.split(/[\\/]/).filter(Boolean).pop() || fallback;
|
|
16219
|
+
}
|
|
16220
|
+
}
|
|
16221
|
+
function appendResourceLink(promptParts, uri, fallbackName, mimeType, description, metadata) {
|
|
16222
|
+
promptParts.push({
|
|
16223
|
+
type: "resource_link",
|
|
16224
|
+
uri,
|
|
16225
|
+
name: metadata?.name || getUriDisplayName2(uri, fallbackName),
|
|
16226
|
+
...metadata?.title ? { title: metadata.title } : {},
|
|
16227
|
+
...mimeType ? { mimeType } : {},
|
|
16228
|
+
...description ? { description } : {},
|
|
16229
|
+
...typeof metadata?.size === "number" ? { size: metadata.size } : {},
|
|
16230
|
+
...metadata?.annotations ? { annotations: metadata.annotations } : {}
|
|
16231
|
+
});
|
|
16232
|
+
}
|
|
16233
|
+
function appendMediaFallbackText(promptParts, label, details) {
|
|
16234
|
+
const normalizedDetails = details.map((value) => typeof value === "string" ? value.trim() : "").filter(Boolean);
|
|
16235
|
+
appendPromptText(promptParts, `[${[label, ...normalizedDetails].join(": ")}]`);
|
|
16236
|
+
}
|
|
15983
16237
|
function buildAcpPromptParts(input, agentCapabilities) {
|
|
15984
16238
|
const caps = getPromptCapabilityFlags(agentCapabilities);
|
|
15985
16239
|
const promptParts = [];
|
|
@@ -15989,56 +16243,76 @@ function buildAcpPromptParts(input, agentCapabilities) {
|
|
|
15989
16243
|
continue;
|
|
15990
16244
|
}
|
|
15991
16245
|
if (part.type === "image") {
|
|
15992
|
-
if (
|
|
15993
|
-
|
|
15994
|
-
|
|
15995
|
-
|
|
15996
|
-
|
|
16246
|
+
if (caps.image && part.data) {
|
|
16247
|
+
promptParts.push({
|
|
16248
|
+
type: "image",
|
|
16249
|
+
data: part.data,
|
|
16250
|
+
mimeType: part.mimeType,
|
|
16251
|
+
...part.uri ? { uri: part.uri } : {},
|
|
16252
|
+
...part.alt ? { alt: part.alt } : {}
|
|
16253
|
+
});
|
|
16254
|
+
if (part.alt) appendPromptText(promptParts, part.alt);
|
|
16255
|
+
} else if (part.uri) {
|
|
16256
|
+
appendResourceLink(promptParts, part.uri, "image", part.mimeType, part.alt);
|
|
16257
|
+
if (part.alt) appendPromptText(promptParts, part.alt);
|
|
16258
|
+
} else {
|
|
16259
|
+
appendMediaFallbackText(promptParts, "Image attachment", [part.alt, part.mimeType]);
|
|
15997
16260
|
}
|
|
15998
|
-
promptParts.push({
|
|
15999
|
-
type: "image",
|
|
16000
|
-
data: part.data,
|
|
16001
|
-
mimeType: part.mimeType,
|
|
16002
|
-
...part.uri ? { uri: part.uri } : {}
|
|
16003
|
-
});
|
|
16004
16261
|
continue;
|
|
16005
16262
|
}
|
|
16006
16263
|
if (part.type === "audio") {
|
|
16007
|
-
if (
|
|
16008
|
-
|
|
16009
|
-
|
|
16010
|
-
|
|
16011
|
-
|
|
16264
|
+
if (caps.audio && part.data) {
|
|
16265
|
+
promptParts.push({
|
|
16266
|
+
type: "audio",
|
|
16267
|
+
data: part.data,
|
|
16268
|
+
mimeType: part.mimeType,
|
|
16269
|
+
...part.uri ? { uri: part.uri } : {},
|
|
16270
|
+
...part.transcript ? { transcript: part.transcript } : {}
|
|
16271
|
+
});
|
|
16272
|
+
if (part.transcript) appendPromptText(promptParts, part.transcript);
|
|
16273
|
+
} else if (part.uri) {
|
|
16274
|
+
appendResourceLink(promptParts, part.uri, "audio", part.mimeType, part.transcript);
|
|
16275
|
+
if (part.transcript) appendPromptText(promptParts, part.transcript);
|
|
16276
|
+
} else {
|
|
16277
|
+
appendMediaFallbackText(promptParts, "Audio attachment", [part.transcript, part.mimeType]);
|
|
16012
16278
|
}
|
|
16013
|
-
promptParts.push({
|
|
16014
|
-
type: "audio",
|
|
16015
|
-
data: part.data,
|
|
16016
|
-
mimeType: part.mimeType
|
|
16017
|
-
});
|
|
16018
16279
|
continue;
|
|
16019
16280
|
}
|
|
16020
16281
|
if (part.type === "resource") {
|
|
16021
|
-
if (
|
|
16022
|
-
throw new Error("ACP agent does not support input type: resource");
|
|
16023
|
-
}
|
|
16024
|
-
if (part.text) {
|
|
16282
|
+
if (caps.embeddedContext && part.text) {
|
|
16025
16283
|
promptParts.push({
|
|
16026
16284
|
type: "resource",
|
|
16027
16285
|
resource: { uri: part.uri, text: part.text, mimeType: part.mimeType ?? null }
|
|
16028
16286
|
});
|
|
16029
16287
|
continue;
|
|
16030
16288
|
}
|
|
16031
|
-
if (part.data) {
|
|
16289
|
+
if (caps.embeddedContext && part.data) {
|
|
16032
16290
|
promptParts.push({
|
|
16033
16291
|
type: "resource",
|
|
16034
16292
|
resource: { uri: part.uri, blob: part.data, mimeType: part.mimeType ?? null }
|
|
16035
16293
|
});
|
|
16036
16294
|
continue;
|
|
16037
16295
|
}
|
|
16038
|
-
|
|
16296
|
+
appendResourceLink(promptParts, part.uri, part.name || "resource", part.mimeType, part.text);
|
|
16297
|
+
if (part.text) appendPromptText(promptParts, part.text);
|
|
16298
|
+
continue;
|
|
16299
|
+
}
|
|
16300
|
+
if (part.type === "resource_link") {
|
|
16301
|
+
appendResourceLink(promptParts, part.uri, part.name, part.mimeType, part.description, {
|
|
16302
|
+
name: part.name,
|
|
16303
|
+
...part.title ? { title: part.title } : {},
|
|
16304
|
+
...typeof part.size === "number" ? { size: part.size } : {},
|
|
16305
|
+
...part.annotations ? { annotations: part.annotations } : {}
|
|
16306
|
+
});
|
|
16307
|
+
continue;
|
|
16039
16308
|
}
|
|
16040
16309
|
if (part.type === "video") {
|
|
16041
|
-
|
|
16310
|
+
if (part.uri) {
|
|
16311
|
+
appendResourceLink(promptParts, part.uri, "video", part.mimeType, part.transcript);
|
|
16312
|
+
if (part.transcript) appendPromptText(promptParts, part.transcript);
|
|
16313
|
+
} else {
|
|
16314
|
+
appendMediaFallbackText(promptParts, "Video attachment", [part.transcript, part.mimeType]);
|
|
16315
|
+
}
|
|
16042
16316
|
}
|
|
16043
16317
|
}
|
|
16044
16318
|
if (!promptParts.some((part) => part.type === "text") && input.textFallback) {
|
|
@@ -16171,6 +16445,7 @@ var AcpProviderInstance = class {
|
|
|
16171
16445
|
lastUpdated: Date.now(),
|
|
16172
16446
|
settings: this.settings,
|
|
16173
16447
|
pendingEvents: this.flushEvents(),
|
|
16448
|
+
messageInput: getEffectiveMessageInputSupport(this.provider, this.agentCapabilities),
|
|
16174
16449
|
// ACP-specific: expose available models/modes for dashboard
|
|
16175
16450
|
acpConfigOptions: this.configOptions,
|
|
16176
16451
|
acpModes: this.availableModes,
|
|
@@ -16672,22 +16947,38 @@ var AcpProviderInstance = class {
|
|
|
16672
16947
|
type: "image",
|
|
16673
16948
|
data: b.data,
|
|
16674
16949
|
mimeType: b.mimeType,
|
|
16675
|
-
...b.uri ? { uri: b.uri } : {}
|
|
16950
|
+
...b.uri ? { uri: b.uri } : {},
|
|
16951
|
+
...b.alt ? { alt: b.alt } : {}
|
|
16676
16952
|
};
|
|
16677
16953
|
}
|
|
16678
16954
|
if (b.type === "audio") {
|
|
16679
16955
|
return {
|
|
16680
16956
|
type: "audio",
|
|
16681
16957
|
data: b.data,
|
|
16682
|
-
mimeType: b.mimeType
|
|
16958
|
+
mimeType: b.mimeType,
|
|
16959
|
+
...b.uri ? { uri: b.uri } : {},
|
|
16960
|
+
...b.transcript ? { transcript: b.transcript } : {}
|
|
16683
16961
|
};
|
|
16684
16962
|
}
|
|
16963
|
+
if (b.type === "video") {
|
|
16964
|
+
return b.uri ? {
|
|
16965
|
+
type: "resource_link",
|
|
16966
|
+
uri: b.uri,
|
|
16967
|
+
name: path17.basename(b.uri),
|
|
16968
|
+
mimeType: b.mimeType,
|
|
16969
|
+
...b.transcript ? { description: b.transcript } : {}
|
|
16970
|
+
} : { type: "text", text: b.transcript || `[Video attachment: ${b.mimeType}]` };
|
|
16971
|
+
}
|
|
16685
16972
|
if (b.type === "resource_link") {
|
|
16686
16973
|
return {
|
|
16687
16974
|
type: "resource_link",
|
|
16688
16975
|
uri: b.uri,
|
|
16689
16976
|
name: b.name,
|
|
16690
|
-
...b.
|
|
16977
|
+
...b.title ? { title: b.title } : {},
|
|
16978
|
+
...b.description ? { description: b.description } : {},
|
|
16979
|
+
...b.mimeType ? { mimeType: b.mimeType } : {},
|
|
16980
|
+
...typeof b.size === "number" ? { size: b.size } : {},
|
|
16981
|
+
...b.annotations ? { annotations: b.annotations } : {}
|
|
16691
16982
|
};
|
|
16692
16983
|
}
|
|
16693
16984
|
if (b.type === "resource") return { type: "resource", resource: b.resource };
|
|
@@ -16763,7 +17054,18 @@ var AcpProviderInstance = class {
|
|
|
16763
17054
|
this.partialBlocks.push({
|
|
16764
17055
|
type: "audio",
|
|
16765
17056
|
data: content.data,
|
|
16766
|
-
mimeType: content.mimeType
|
|
17057
|
+
mimeType: content.mimeType,
|
|
17058
|
+
...content.uri ? { uri: content.uri } : {},
|
|
17059
|
+
...content.transcript ? { transcript: content.transcript } : {}
|
|
17060
|
+
});
|
|
17061
|
+
} else if (content.type === "video") {
|
|
17062
|
+
this.partialBlocks.push({
|
|
17063
|
+
type: "video",
|
|
17064
|
+
data: content.data,
|
|
17065
|
+
mimeType: content.mimeType,
|
|
17066
|
+
...content.uri ? { uri: content.uri } : {},
|
|
17067
|
+
...content.transcript ? { transcript: content.transcript } : {},
|
|
17068
|
+
...content.posterUri ? { posterUri: content.posterUri } : {}
|
|
16767
17069
|
});
|
|
16768
17070
|
} else if (content.type === "resource_link") {
|
|
16769
17071
|
this.partialBlocks.push({
|
|
@@ -17120,11 +17422,11 @@ function shouldRestoreHostedRuntime(record, managerTag) {
|
|
|
17120
17422
|
// src/commands/cli-manager.ts
|
|
17121
17423
|
function isExplicitCommand(command) {
|
|
17122
17424
|
const trimmed = command.trim();
|
|
17123
|
-
return
|
|
17425
|
+
return path18.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
|
|
17124
17426
|
}
|
|
17125
17427
|
function expandExecutable(command) {
|
|
17126
17428
|
const trimmed = command.trim();
|
|
17127
|
-
return trimmed.startsWith("~") ?
|
|
17429
|
+
return trimmed.startsWith("~") ? path18.join(os13.homedir(), trimmed.slice(1)) : trimmed;
|
|
17128
17430
|
}
|
|
17129
17431
|
function commandExists(command) {
|
|
17130
17432
|
const trimmed = command.trim();
|
|
@@ -17158,11 +17460,11 @@ function hasCliArg(args, flag) {
|
|
|
17158
17460
|
return args.some((arg) => arg === flag || arg.startsWith(`${flag}=`));
|
|
17159
17461
|
}
|
|
17160
17462
|
function ensureEmptyDelegatedMcpConfig(workspace) {
|
|
17161
|
-
const baseDir =
|
|
17162
|
-
|
|
17163
|
-
const workspaceHash = crypto4.createHash("sha256").update(
|
|
17164
|
-
const filePath =
|
|
17165
|
-
|
|
17463
|
+
const baseDir = path18.join(os13.tmpdir(), "adhdev-delegated-agent-empty-mcp");
|
|
17464
|
+
mkdirSync8(baseDir, { recursive: true });
|
|
17465
|
+
const workspaceHash = crypto4.createHash("sha256").update(path18.resolve(workspace || os13.tmpdir())).digest("hex").slice(0, 16);
|
|
17466
|
+
const filePath = path18.join(baseDir, `${workspaceHash}.json`);
|
|
17467
|
+
writeFileSync8(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
|
|
17166
17468
|
return filePath;
|
|
17167
17469
|
}
|
|
17168
17470
|
function buildCoordinatorDelegatedCliLaunchOptions(input) {
|
|
@@ -17434,7 +17736,7 @@ var DaemonCliManager = class {
|
|
|
17434
17736
|
async startSession(cliType, workingDir, cliArgs, initialModel, options) {
|
|
17435
17737
|
const trimmed = (workingDir || "").trim();
|
|
17436
17738
|
if (!trimmed) throw new Error("working directory required");
|
|
17437
|
-
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) :
|
|
17739
|
+
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) : path18.resolve(trimmed);
|
|
17438
17740
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
17439
17741
|
const rawProvider = this.providerLoader.getByAlias(cliType);
|
|
17440
17742
|
const provider = rawProvider ? this.providerLoader.resolve(normalizedType) || rawProvider : void 0;
|
|
@@ -17948,17 +18250,18 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
17948
18250
|
import { execSync as execSync4, spawn as spawn2 } from "child_process";
|
|
17949
18251
|
import * as net from "net";
|
|
17950
18252
|
import * as os15 from "os";
|
|
17951
|
-
import * as
|
|
18253
|
+
import * as path20 from "path";
|
|
17952
18254
|
|
|
17953
18255
|
// src/providers/provider-loader.ts
|
|
17954
18256
|
import * as fs7 from "fs";
|
|
17955
|
-
import * as
|
|
18257
|
+
import * as path19 from "path";
|
|
17956
18258
|
import * as os14 from "os";
|
|
17957
18259
|
import * as chokidar from "chokidar";
|
|
17958
18260
|
init_logger();
|
|
17959
18261
|
|
|
17960
18262
|
// src/providers/provider-schema.ts
|
|
17961
18263
|
var VALID_CAPABILITY_MEDIA_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "resource"]);
|
|
18264
|
+
var VALID_INPUT_STRATEGIES2 = /* @__PURE__ */ new Set(["native", "native_acp", "resource_link", "text_fallback", "paste", "upload"]);
|
|
17962
18265
|
var KNOWN_PROVIDER_FIELDS = /* @__PURE__ */ new Set([
|
|
17963
18266
|
"type",
|
|
17964
18267
|
"name",
|
|
@@ -18088,16 +18391,45 @@ function validateCapabilities(provider, controls, errors) {
|
|
|
18088
18391
|
return;
|
|
18089
18392
|
}
|
|
18090
18393
|
const input = capabilities.input;
|
|
18091
|
-
if (
|
|
18092
|
-
|
|
18093
|
-
|
|
18094
|
-
if (typeof input.multipart !== "boolean") {
|
|
18394
|
+
if (input !== void 0) {
|
|
18395
|
+
if (!input || typeof input !== "object") {
|
|
18396
|
+
errors.push("capabilities.input must be an object when provided");
|
|
18397
|
+
} else if (typeof input.multipart !== "boolean") {
|
|
18095
18398
|
errors.push("capabilities.input.multipart must be boolean");
|
|
18096
18399
|
}
|
|
18097
|
-
if (
|
|
18098
|
-
|
|
18099
|
-
|
|
18100
|
-
|
|
18400
|
+
if (input && typeof input === "object") {
|
|
18401
|
+
const mediaTypes = Array.isArray(input.mediaTypes) ? input.mediaTypes : void 0;
|
|
18402
|
+
if (!mediaTypes || mediaTypes.length === 0) {
|
|
18403
|
+
errors.push("capabilities.input.mediaTypes must be a non-empty array");
|
|
18404
|
+
} else if (mediaTypes.some((type) => typeof type !== "string" || !VALID_CAPABILITY_MEDIA_TYPES.has(type))) {
|
|
18405
|
+
errors.push(`capabilities.input.mediaTypes must only include: ${Array.from(VALID_CAPABILITY_MEDIA_TYPES).join(", ")}`);
|
|
18406
|
+
}
|
|
18407
|
+
}
|
|
18408
|
+
if (input && typeof input === "object" && input.strategies !== void 0) {
|
|
18409
|
+
if (!Array.isArray(input.strategies)) {
|
|
18410
|
+
errors.push("capabilities.input.strategies must be an array when provided");
|
|
18411
|
+
} else {
|
|
18412
|
+
for (const strategy of input.strategies) {
|
|
18413
|
+
if (!strategy || typeof strategy !== "object" || Array.isArray(strategy)) {
|
|
18414
|
+
errors.push("capabilities.input.strategies entries must be objects");
|
|
18415
|
+
continue;
|
|
18416
|
+
}
|
|
18417
|
+
const entry = strategy;
|
|
18418
|
+
if (typeof entry.mediaType !== "string" || !VALID_CAPABILITY_MEDIA_TYPES.has(entry.mediaType)) {
|
|
18419
|
+
errors.push(`capabilities.input.strategies.mediaType must only include: ${Array.from(VALID_CAPABILITY_MEDIA_TYPES).join(", ")}`);
|
|
18420
|
+
}
|
|
18421
|
+
for (const field of ["strategies", "degradation"]) {
|
|
18422
|
+
const values = entry[field];
|
|
18423
|
+
if (values === void 0) continue;
|
|
18424
|
+
if (!Array.isArray(values) || values.some((value) => typeof value !== "string" || !VALID_INPUT_STRATEGIES2.has(value))) {
|
|
18425
|
+
errors.push(`capabilities.input.strategies.${field} must only include: ${Array.from(VALID_INPUT_STRATEGIES2).join(", ")}`);
|
|
18426
|
+
}
|
|
18427
|
+
}
|
|
18428
|
+
if (entry.native !== void 0 && typeof entry.native !== "boolean") {
|
|
18429
|
+
errors.push("capabilities.input.strategies.native must be boolean when provided");
|
|
18430
|
+
}
|
|
18431
|
+
}
|
|
18432
|
+
}
|
|
18101
18433
|
}
|
|
18102
18434
|
}
|
|
18103
18435
|
const output = capabilities.output;
|
|
@@ -18276,7 +18608,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18276
18608
|
try {
|
|
18277
18609
|
if (!fs7.existsSync(candidate) || !fs7.statSync(candidate).isDirectory()) return false;
|
|
18278
18610
|
return ["ide", "extension", "cli", "acp"].some(
|
|
18279
|
-
(category) => fs7.existsSync(
|
|
18611
|
+
(category) => fs7.existsSync(path19.join(candidate, category))
|
|
18280
18612
|
);
|
|
18281
18613
|
} catch {
|
|
18282
18614
|
return false;
|
|
@@ -18284,20 +18616,20 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18284
18616
|
}
|
|
18285
18617
|
static hasProviderRootMarker(candidate) {
|
|
18286
18618
|
try {
|
|
18287
|
-
return fs7.existsSync(
|
|
18619
|
+
return fs7.existsSync(path19.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
|
|
18288
18620
|
} catch {
|
|
18289
18621
|
return false;
|
|
18290
18622
|
}
|
|
18291
18623
|
}
|
|
18292
18624
|
detectDefaultUserDir() {
|
|
18293
|
-
const fallback =
|
|
18625
|
+
const fallback = path19.join(os14.homedir(), ".adhdev", "providers");
|
|
18294
18626
|
const envOptIn = process.env[_ProviderLoader.SIBLING_ENV_VAR] === "1";
|
|
18295
18627
|
const visited = /* @__PURE__ */ new Set();
|
|
18296
18628
|
for (const start of this.probeStarts) {
|
|
18297
|
-
let current =
|
|
18629
|
+
let current = path19.resolve(start);
|
|
18298
18630
|
while (!visited.has(current)) {
|
|
18299
18631
|
visited.add(current);
|
|
18300
|
-
const siblingCandidate =
|
|
18632
|
+
const siblingCandidate = path19.join(path19.dirname(current), _ProviderLoader.REPO_PROVIDER_DIRNAME);
|
|
18301
18633
|
if (_ProviderLoader.looksLikeProviderRoot(siblingCandidate)) {
|
|
18302
18634
|
const hasMarker = _ProviderLoader.hasProviderRootMarker(siblingCandidate);
|
|
18303
18635
|
if (envOptIn || hasMarker) {
|
|
@@ -18319,7 +18651,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18319
18651
|
return { path: siblingCandidate, source };
|
|
18320
18652
|
}
|
|
18321
18653
|
}
|
|
18322
|
-
const parent =
|
|
18654
|
+
const parent = path19.dirname(current);
|
|
18323
18655
|
if (parent === current) break;
|
|
18324
18656
|
current = parent;
|
|
18325
18657
|
}
|
|
@@ -18329,11 +18661,11 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18329
18661
|
constructor(options) {
|
|
18330
18662
|
this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
|
|
18331
18663
|
this.probeStarts = options?.probeStarts ?? [process.cwd(), __dirname];
|
|
18332
|
-
this.defaultProvidersDir =
|
|
18664
|
+
this.defaultProvidersDir = path19.join(os14.homedir(), ".adhdev", "providers");
|
|
18333
18665
|
const detected = this.detectDefaultUserDir();
|
|
18334
18666
|
this.userDir = detected.path;
|
|
18335
18667
|
this.userDirSource = detected.source;
|
|
18336
|
-
this.upstreamDir =
|
|
18668
|
+
this.upstreamDir = path19.join(this.defaultProvidersDir, ".upstream");
|
|
18337
18669
|
this.disableUpstream = false;
|
|
18338
18670
|
this.applySourceConfig({
|
|
18339
18671
|
userDir: options?.userDir,
|
|
@@ -18392,7 +18724,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18392
18724
|
this.userDir = detected.path;
|
|
18393
18725
|
this.userDirSource = detected.source;
|
|
18394
18726
|
}
|
|
18395
|
-
this.upstreamDir =
|
|
18727
|
+
this.upstreamDir = path19.join(this.defaultProvidersDir, ".upstream");
|
|
18396
18728
|
this.disableUpstream = this.sourceMode === "no-upstream";
|
|
18397
18729
|
if (this.explicitProviderDir) {
|
|
18398
18730
|
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
@@ -18406,7 +18738,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18406
18738
|
* Canonical provider directory shape for a given root.
|
|
18407
18739
|
*/
|
|
18408
18740
|
getProviderDir(root, category, type) {
|
|
18409
|
-
return
|
|
18741
|
+
return path19.join(root, category, type);
|
|
18410
18742
|
}
|
|
18411
18743
|
/**
|
|
18412
18744
|
* Canonical user override directory for a provider.
|
|
@@ -18433,7 +18765,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18433
18765
|
resolveProviderFile(type, ...segments) {
|
|
18434
18766
|
const dir = this.findProviderDirInternal(type);
|
|
18435
18767
|
if (!dir) return null;
|
|
18436
|
-
return
|
|
18768
|
+
return path19.join(dir, ...segments);
|
|
18437
18769
|
}
|
|
18438
18770
|
/**
|
|
18439
18771
|
* Load all providers (3-tier priority)
|
|
@@ -18472,7 +18804,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18472
18804
|
if (!fs7.existsSync(this.upstreamDir)) return false;
|
|
18473
18805
|
try {
|
|
18474
18806
|
return fs7.readdirSync(this.upstreamDir).some(
|
|
18475
|
-
(d) => fs7.statSync(
|
|
18807
|
+
(d) => fs7.statSync(path19.join(this.upstreamDir, d)).isDirectory()
|
|
18476
18808
|
);
|
|
18477
18809
|
} catch {
|
|
18478
18810
|
return false;
|
|
@@ -18969,8 +19301,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18969
19301
|
resolved._resolvedScriptDir = entry.scriptDir;
|
|
18970
19302
|
resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
|
|
18971
19303
|
if (providerDir) {
|
|
18972
|
-
const fullDir =
|
|
18973
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
19304
|
+
const fullDir = path19.join(providerDir, entry.scriptDir);
|
|
19305
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path19.join(fullDir, "scripts.js")) ? path19.join(fullDir, "scripts.js") : fullDir;
|
|
18974
19306
|
}
|
|
18975
19307
|
matched = true;
|
|
18976
19308
|
}
|
|
@@ -18985,8 +19317,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
18985
19317
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
18986
19318
|
resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
|
|
18987
19319
|
if (providerDir) {
|
|
18988
|
-
const fullDir =
|
|
18989
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
19320
|
+
const fullDir = path19.join(providerDir, base.defaultScriptDir);
|
|
19321
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path19.join(fullDir, "scripts.js")) ? path19.join(fullDir, "scripts.js") : fullDir;
|
|
18990
19322
|
}
|
|
18991
19323
|
}
|
|
18992
19324
|
resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
|
|
@@ -19003,8 +19335,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19003
19335
|
resolved._resolvedScriptDir = dirOverride;
|
|
19004
19336
|
resolved._resolvedScriptsSource = `versions:${range}`;
|
|
19005
19337
|
if (providerDir) {
|
|
19006
|
-
const fullDir =
|
|
19007
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
19338
|
+
const fullDir = path19.join(providerDir, dirOverride);
|
|
19339
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path19.join(fullDir, "scripts.js")) ? path19.join(fullDir, "scripts.js") : fullDir;
|
|
19008
19340
|
}
|
|
19009
19341
|
}
|
|
19010
19342
|
} else if (override.scripts) {
|
|
@@ -19020,8 +19352,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19020
19352
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
19021
19353
|
resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
|
|
19022
19354
|
if (providerDir) {
|
|
19023
|
-
const fullDir =
|
|
19024
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
19355
|
+
const fullDir = path19.join(providerDir, base.defaultScriptDir);
|
|
19356
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path19.join(fullDir, "scripts.js")) ? path19.join(fullDir, "scripts.js") : fullDir;
|
|
19025
19357
|
}
|
|
19026
19358
|
}
|
|
19027
19359
|
}
|
|
@@ -19053,14 +19385,14 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19053
19385
|
this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
|
|
19054
19386
|
return null;
|
|
19055
19387
|
}
|
|
19056
|
-
const dir =
|
|
19388
|
+
const dir = path19.join(providerDir, scriptDir);
|
|
19057
19389
|
if (!fs7.existsSync(dir)) {
|
|
19058
19390
|
this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
|
|
19059
19391
|
return null;
|
|
19060
19392
|
}
|
|
19061
19393
|
const cached = this.scriptsCache.get(dir);
|
|
19062
19394
|
if (cached) return cached;
|
|
19063
|
-
const scriptsJs =
|
|
19395
|
+
const scriptsJs = path19.join(dir, "scripts.js");
|
|
19064
19396
|
if (fs7.existsSync(scriptsJs)) {
|
|
19065
19397
|
try {
|
|
19066
19398
|
delete __require.cache[__require.resolve(scriptsJs)];
|
|
@@ -19102,7 +19434,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19102
19434
|
return;
|
|
19103
19435
|
}
|
|
19104
19436
|
if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
|
|
19105
|
-
this.log(`File changed: ${
|
|
19437
|
+
this.log(`File changed: ${path19.basename(filePath)}, reloading...`);
|
|
19106
19438
|
this.reload();
|
|
19107
19439
|
}
|
|
19108
19440
|
};
|
|
@@ -19157,7 +19489,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19157
19489
|
}
|
|
19158
19490
|
const https = __require("https");
|
|
19159
19491
|
const { execSync: execSync7 } = __require("child_process");
|
|
19160
|
-
const metaPath =
|
|
19492
|
+
const metaPath = path19.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
19161
19493
|
let prevEtag = "";
|
|
19162
19494
|
let prevTimestamp = 0;
|
|
19163
19495
|
try {
|
|
@@ -19217,17 +19549,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19217
19549
|
return { updated: false };
|
|
19218
19550
|
}
|
|
19219
19551
|
this.log("Downloading latest providers from GitHub...");
|
|
19220
|
-
const tmpTar =
|
|
19221
|
-
const tmpExtract =
|
|
19552
|
+
const tmpTar = path19.join(os14.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
|
|
19553
|
+
const tmpExtract = path19.join(os14.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
|
|
19222
19554
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
19223
19555
|
fs7.mkdirSync(tmpExtract, { recursive: true });
|
|
19224
19556
|
execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
19225
19557
|
const extracted = fs7.readdirSync(tmpExtract);
|
|
19226
19558
|
const rootDir = extracted.find(
|
|
19227
|
-
(d) => fs7.statSync(
|
|
19559
|
+
(d) => fs7.statSync(path19.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
|
|
19228
19560
|
);
|
|
19229
19561
|
if (!rootDir) throw new Error("Unexpected tarball structure");
|
|
19230
|
-
const sourceDir =
|
|
19562
|
+
const sourceDir = path19.join(tmpExtract, rootDir);
|
|
19231
19563
|
const backupDir = this.upstreamDir + ".bak";
|
|
19232
19564
|
if (fs7.existsSync(this.upstreamDir)) {
|
|
19233
19565
|
if (fs7.existsSync(backupDir)) fs7.rmSync(backupDir, { recursive: true, force: true });
|
|
@@ -19302,8 +19634,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19302
19634
|
copyDirRecursive(src, dest) {
|
|
19303
19635
|
fs7.mkdirSync(dest, { recursive: true });
|
|
19304
19636
|
for (const entry of fs7.readdirSync(src, { withFileTypes: true })) {
|
|
19305
|
-
const srcPath =
|
|
19306
|
-
const destPath =
|
|
19637
|
+
const srcPath = path19.join(src, entry.name);
|
|
19638
|
+
const destPath = path19.join(dest, entry.name);
|
|
19307
19639
|
if (entry.isDirectory()) {
|
|
19308
19640
|
this.copyDirRecursive(srcPath, destPath);
|
|
19309
19641
|
} else {
|
|
@@ -19314,7 +19646,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19314
19646
|
/** .meta.json save */
|
|
19315
19647
|
writeMeta(metaPath, etag, timestamp) {
|
|
19316
19648
|
try {
|
|
19317
|
-
fs7.mkdirSync(
|
|
19649
|
+
fs7.mkdirSync(path19.dirname(metaPath), { recursive: true });
|
|
19318
19650
|
fs7.writeFileSync(metaPath, JSON.stringify({
|
|
19319
19651
|
etag,
|
|
19320
19652
|
timestamp,
|
|
@@ -19331,7 +19663,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19331
19663
|
const scan = (d) => {
|
|
19332
19664
|
try {
|
|
19333
19665
|
for (const entry of fs7.readdirSync(d, { withFileTypes: true })) {
|
|
19334
|
-
if (entry.isDirectory()) scan(
|
|
19666
|
+
if (entry.isDirectory()) scan(path19.join(d, entry.name));
|
|
19335
19667
|
else if (entry.name === "provider.json") count++;
|
|
19336
19668
|
}
|
|
19337
19669
|
} catch {
|
|
@@ -19559,17 +19891,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19559
19891
|
for (const root of searchRoots) {
|
|
19560
19892
|
if (!fs7.existsSync(root)) continue;
|
|
19561
19893
|
const candidate = this.getProviderDir(root, cat, type);
|
|
19562
|
-
if (fs7.existsSync(
|
|
19563
|
-
const catDir =
|
|
19894
|
+
if (fs7.existsSync(path19.join(candidate, "provider.json"))) return candidate;
|
|
19895
|
+
const catDir = path19.join(root, cat);
|
|
19564
19896
|
if (fs7.existsSync(catDir)) {
|
|
19565
19897
|
try {
|
|
19566
19898
|
for (const entry of fs7.readdirSync(catDir, { withFileTypes: true })) {
|
|
19567
19899
|
if (!entry.isDirectory()) continue;
|
|
19568
|
-
const jsonPath =
|
|
19900
|
+
const jsonPath = path19.join(catDir, entry.name, "provider.json");
|
|
19569
19901
|
if (fs7.existsSync(jsonPath)) {
|
|
19570
19902
|
try {
|
|
19571
19903
|
const data = JSON.parse(fs7.readFileSync(jsonPath, "utf-8"));
|
|
19572
|
-
if (data.type === type) return
|
|
19904
|
+
if (data.type === type) return path19.join(catDir, entry.name);
|
|
19573
19905
|
} catch {
|
|
19574
19906
|
}
|
|
19575
19907
|
}
|
|
@@ -19586,7 +19918,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19586
19918
|
* (template substitution is NOT applied here — scripts.js handles that)
|
|
19587
19919
|
*/
|
|
19588
19920
|
buildScriptWrappersFromDir(dir) {
|
|
19589
|
-
const scriptsJs =
|
|
19921
|
+
const scriptsJs = path19.join(dir, "scripts.js");
|
|
19590
19922
|
if (fs7.existsSync(scriptsJs)) {
|
|
19591
19923
|
try {
|
|
19592
19924
|
delete __require.cache[__require.resolve(scriptsJs)];
|
|
@@ -19600,7 +19932,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19600
19932
|
for (const file of fs7.readdirSync(dir)) {
|
|
19601
19933
|
if (!file.endsWith(".js")) continue;
|
|
19602
19934
|
const scriptName = toCamel(file.replace(".js", ""));
|
|
19603
|
-
const filePath =
|
|
19935
|
+
const filePath = path19.join(dir, file);
|
|
19604
19936
|
result[scriptName] = (...args) => {
|
|
19605
19937
|
try {
|
|
19606
19938
|
let content = fs7.readFileSync(filePath, "utf-8");
|
|
@@ -19660,7 +19992,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19660
19992
|
}
|
|
19661
19993
|
const hasJson = entries.some((e) => e.name === "provider.json");
|
|
19662
19994
|
if (hasJson) {
|
|
19663
|
-
const jsonPath =
|
|
19995
|
+
const jsonPath = path19.join(d, "provider.json");
|
|
19664
19996
|
try {
|
|
19665
19997
|
const raw = fs7.readFileSync(jsonPath, "utf-8");
|
|
19666
19998
|
const mod = JSON.parse(raw);
|
|
@@ -19681,7 +20013,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19681
20013
|
this.log(`\u26A0 Invalid provider at ${jsonPath}: ${validation.errors.join("; ")}`);
|
|
19682
20014
|
} else {
|
|
19683
20015
|
const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
|
|
19684
|
-
const scriptsPath =
|
|
20016
|
+
const scriptsPath = path19.join(d, "scripts.js");
|
|
19685
20017
|
if (!hasCompatibility && fs7.existsSync(scriptsPath)) {
|
|
19686
20018
|
try {
|
|
19687
20019
|
delete __require.cache[__require.resolve(scriptsPath)];
|
|
@@ -19707,7 +20039,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
19707
20039
|
if (!entry.isDirectory()) continue;
|
|
19708
20040
|
if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
|
|
19709
20041
|
if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
|
|
19710
|
-
scan(
|
|
20042
|
+
scan(path19.join(d, entry.name));
|
|
19711
20043
|
}
|
|
19712
20044
|
}
|
|
19713
20045
|
};
|
|
@@ -20032,8 +20364,8 @@ function detectCurrentWorkspace(ideId) {
|
|
|
20032
20364
|
const appNameMap = getMacAppIdentifiers();
|
|
20033
20365
|
const appName = appNameMap[ideId];
|
|
20034
20366
|
if (appName) {
|
|
20035
|
-
const storagePath =
|
|
20036
|
-
process.env.APPDATA ||
|
|
20367
|
+
const storagePath = path20.join(
|
|
20368
|
+
process.env.APPDATA || path20.join(os15.homedir(), "AppData", "Roaming"),
|
|
20037
20369
|
appName,
|
|
20038
20370
|
"storage.json"
|
|
20039
20371
|
);
|
|
@@ -20222,9 +20554,9 @@ init_logger();
|
|
|
20222
20554
|
|
|
20223
20555
|
// src/logging/command-log.ts
|
|
20224
20556
|
import * as fs8 from "fs";
|
|
20225
|
-
import * as
|
|
20557
|
+
import * as path21 from "path";
|
|
20226
20558
|
import * as os16 from "os";
|
|
20227
|
-
var LOG_DIR2 = process.platform === "win32" ?
|
|
20559
|
+
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");
|
|
20228
20560
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
20229
20561
|
var MAX_DAYS = 7;
|
|
20230
20562
|
try {
|
|
@@ -20262,13 +20594,13 @@ function getDateStr2() {
|
|
|
20262
20594
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
20263
20595
|
}
|
|
20264
20596
|
var currentDate2 = getDateStr2();
|
|
20265
|
-
var currentFile =
|
|
20597
|
+
var currentFile = path21.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
20266
20598
|
var writeCount2 = 0;
|
|
20267
20599
|
function checkRotation() {
|
|
20268
20600
|
const today = getDateStr2();
|
|
20269
20601
|
if (today !== currentDate2) {
|
|
20270
20602
|
currentDate2 = today;
|
|
20271
|
-
currentFile =
|
|
20603
|
+
currentFile = path21.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
20272
20604
|
cleanOldFiles();
|
|
20273
20605
|
}
|
|
20274
20606
|
}
|
|
@@ -20282,7 +20614,7 @@ function cleanOldFiles() {
|
|
|
20282
20614
|
const dateMatch = file.match(/commands-(\d{4}-\d{2}-\d{2})/);
|
|
20283
20615
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
20284
20616
|
try {
|
|
20285
|
-
fs8.unlinkSync(
|
|
20617
|
+
fs8.unlinkSync(path21.join(LOG_DIR2, file));
|
|
20286
20618
|
} catch {
|
|
20287
20619
|
}
|
|
20288
20620
|
}
|
|
@@ -20370,10 +20702,11 @@ import * as yaml from "js-yaml";
|
|
|
20370
20702
|
|
|
20371
20703
|
// src/commands/mesh-coordinator.ts
|
|
20372
20704
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
20705
|
+
import { createHash as createHash2 } from "crypto";
|
|
20373
20706
|
import { existsSync as existsSync15, readdirSync as readdirSync6, realpathSync as realpathSync2 } from "fs";
|
|
20374
20707
|
import { createRequire as createRequire2 } from "module";
|
|
20375
20708
|
import * as os17 from "os";
|
|
20376
|
-
import { dirname as dirname4, isAbsolute as
|
|
20709
|
+
import { dirname as dirname4, isAbsolute as isAbsolute11, join as join18, resolve as resolve13 } from "path";
|
|
20377
20710
|
var DEFAULT_SERVER_NAME = "adhdev-mesh";
|
|
20378
20711
|
var DEFAULT_ADHDEV_MCP_COMMAND = "adhdev-mcp";
|
|
20379
20712
|
var HERMES_CLI_TYPE = "hermes-cli";
|
|
@@ -20394,7 +20727,7 @@ function resolveHermesMeshCoordinatorSetup(options) {
|
|
|
20394
20727
|
reason: "Could not resolve the ADHDev MCP server entrypoint and a Node runtime with WebSocket support for daemon IPC mode"
|
|
20395
20728
|
};
|
|
20396
20729
|
}
|
|
20397
|
-
const configPath =
|
|
20730
|
+
const configPath = join18(resolveHermesCoordinatorHome(options.meshId, options.workspace), "config.yaml");
|
|
20398
20731
|
if (!configPath.trim()) {
|
|
20399
20732
|
return createHermesManualMeshCoordinatorSetup(options.meshId, options.workspace);
|
|
20400
20733
|
}
|
|
@@ -20446,8 +20779,8 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
20446
20779
|
}
|
|
20447
20780
|
const serverName = mcpConfig.serverName?.trim() || DEFAULT_SERVER_NAME;
|
|
20448
20781
|
if (mcpConfig.mode === "auto_import") {
|
|
20449
|
-
const
|
|
20450
|
-
if (!
|
|
20782
|
+
const path28 = mcpConfig.path?.trim();
|
|
20783
|
+
if (!path28) {
|
|
20451
20784
|
return { kind: "unsupported", reason: "Provider auto-import MCP config is missing a config path" };
|
|
20452
20785
|
}
|
|
20453
20786
|
const mcpServer = resolveAdhdevMcpServerLaunch({
|
|
@@ -20464,7 +20797,7 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
20464
20797
|
return {
|
|
20465
20798
|
kind: "auto_import",
|
|
20466
20799
|
serverName,
|
|
20467
|
-
configPath: resolveMcpConfigPath(
|
|
20800
|
+
configPath: resolveMcpConfigPath(path28, workspace),
|
|
20468
20801
|
configFormat: mcpConfig.format,
|
|
20469
20802
|
mcpServer
|
|
20470
20803
|
};
|
|
@@ -20498,11 +20831,17 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
20498
20831
|
function renderMeshCoordinatorTemplate(template, values) {
|
|
20499
20832
|
return template.replace(/\{\{\s*(meshId|workspace|serverName|adhdevMcpCommand)\s*\}\}/g, (_, key) => values[key] || "");
|
|
20500
20833
|
}
|
|
20834
|
+
function resolveHermesCoordinatorHome(meshId, workspace) {
|
|
20835
|
+
const key = `${meshId || "mesh"}
|
|
20836
|
+
${resolve13(workspace || os17.tmpdir())}`;
|
|
20837
|
+
const hash = createHash2("sha256").update(key).digest("hex").slice(0, 16);
|
|
20838
|
+
return join18(os17.tmpdir(), `adhdev-hermes-mesh-coordinator-${hash}`);
|
|
20839
|
+
}
|
|
20501
20840
|
function resolveMcpConfigPath(configPath, workspace) {
|
|
20502
20841
|
const trimmed = configPath.trim();
|
|
20503
20842
|
if (trimmed === "~") return os17.homedir();
|
|
20504
20843
|
if (trimmed.startsWith("~/")) return join18(os17.homedir(), trimmed.slice(2));
|
|
20505
|
-
if (
|
|
20844
|
+
if (isAbsolute11(trimmed)) return trimmed;
|
|
20506
20845
|
return join18(workspace, trimmed);
|
|
20507
20846
|
}
|
|
20508
20847
|
function resolveAdhdevMcpServerLaunch(options) {
|
|
@@ -21031,13 +21370,13 @@ import { execFileSync as execFileSync3 } from "child_process";
|
|
|
21031
21370
|
import { spawn as spawn3 } from "child_process";
|
|
21032
21371
|
import * as fs9 from "fs";
|
|
21033
21372
|
import * as os19 from "os";
|
|
21034
|
-
import * as
|
|
21373
|
+
import * as path22 from "path";
|
|
21035
21374
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
21036
21375
|
function getUpgradeLogPath() {
|
|
21037
21376
|
const home = os19.homedir();
|
|
21038
|
-
const dir =
|
|
21377
|
+
const dir = path22.join(home, ".adhdev");
|
|
21039
21378
|
fs9.mkdirSync(dir, { recursive: true });
|
|
21040
|
-
return
|
|
21379
|
+
return path22.join(dir, "daemon-upgrade.log");
|
|
21041
21380
|
}
|
|
21042
21381
|
function appendUpgradeLog(message) {
|
|
21043
21382
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
|
|
@@ -21048,14 +21387,14 @@ function appendUpgradeLog(message) {
|
|
|
21048
21387
|
}
|
|
21049
21388
|
}
|
|
21050
21389
|
function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platform) {
|
|
21051
|
-
const binDir =
|
|
21390
|
+
const binDir = path22.dirname(nodeExecutable);
|
|
21052
21391
|
if (platform10 === "win32") {
|
|
21053
|
-
const npmCliPath =
|
|
21392
|
+
const npmCliPath = path22.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
|
|
21054
21393
|
if (fs9.existsSync(npmCliPath)) {
|
|
21055
21394
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
21056
21395
|
}
|
|
21057
21396
|
for (const candidate of ["npm.exe", "npm"]) {
|
|
21058
|
-
const candidatePath =
|
|
21397
|
+
const candidatePath = path22.join(binDir, candidate);
|
|
21059
21398
|
if (fs9.existsSync(candidatePath)) {
|
|
21060
21399
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
21061
21400
|
}
|
|
@@ -21063,7 +21402,7 @@ function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platfo
|
|
|
21063
21402
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
21064
21403
|
}
|
|
21065
21404
|
for (const candidate of ["npm"]) {
|
|
21066
|
-
const candidatePath =
|
|
21405
|
+
const candidatePath = path22.join(binDir, candidate);
|
|
21067
21406
|
if (fs9.existsSync(candidatePath)) {
|
|
21068
21407
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
21069
21408
|
}
|
|
@@ -21080,13 +21419,13 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
21080
21419
|
let currentDir = resolvedPath;
|
|
21081
21420
|
try {
|
|
21082
21421
|
if (fs9.statSync(resolvedPath).isFile()) {
|
|
21083
|
-
currentDir =
|
|
21422
|
+
currentDir = path22.dirname(resolvedPath);
|
|
21084
21423
|
}
|
|
21085
21424
|
} catch {
|
|
21086
|
-
currentDir =
|
|
21425
|
+
currentDir = path22.dirname(resolvedPath);
|
|
21087
21426
|
}
|
|
21088
21427
|
while (true) {
|
|
21089
|
-
const packageJsonPath =
|
|
21428
|
+
const packageJsonPath = path22.join(currentDir, "package.json");
|
|
21090
21429
|
try {
|
|
21091
21430
|
if (fs9.existsSync(packageJsonPath)) {
|
|
21092
21431
|
const parsed = JSON.parse(fs9.readFileSync(packageJsonPath, "utf8"));
|
|
@@ -21097,7 +21436,7 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
21097
21436
|
}
|
|
21098
21437
|
} catch {
|
|
21099
21438
|
}
|
|
21100
|
-
const parentDir =
|
|
21439
|
+
const parentDir = path22.dirname(currentDir);
|
|
21101
21440
|
if (parentDir === currentDir) {
|
|
21102
21441
|
return null;
|
|
21103
21442
|
}
|
|
@@ -21105,13 +21444,13 @@ function findCurrentPackageRoot(currentCliPath, packageName) {
|
|
|
21105
21444
|
}
|
|
21106
21445
|
}
|
|
21107
21446
|
function resolveInstallPrefixFromPackageRoot(packageRoot, packageName) {
|
|
21108
|
-
const nodeModulesDir = packageName.startsWith("@") ?
|
|
21109
|
-
if (
|
|
21447
|
+
const nodeModulesDir = packageName.startsWith("@") ? path22.dirname(path22.dirname(packageRoot)) : path22.dirname(packageRoot);
|
|
21448
|
+
if (path22.basename(nodeModulesDir) !== "node_modules") {
|
|
21110
21449
|
return null;
|
|
21111
21450
|
}
|
|
21112
|
-
const maybeLibDir =
|
|
21113
|
-
if (
|
|
21114
|
-
return
|
|
21451
|
+
const maybeLibDir = path22.dirname(nodeModulesDir);
|
|
21452
|
+
if (path22.basename(maybeLibDir) === "lib") {
|
|
21453
|
+
return path22.dirname(maybeLibDir);
|
|
21115
21454
|
}
|
|
21116
21455
|
return maybeLibDir;
|
|
21117
21456
|
}
|
|
@@ -21226,7 +21565,7 @@ async function waitForPidExit(pid, timeoutMs) {
|
|
|
21226
21565
|
}
|
|
21227
21566
|
}
|
|
21228
21567
|
function stopSessionHostProcesses(appName) {
|
|
21229
|
-
const pidFile =
|
|
21568
|
+
const pidFile = path22.join(os19.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
21230
21569
|
try {
|
|
21231
21570
|
if (fs9.existsSync(pidFile)) {
|
|
21232
21571
|
const pid = Number.parseInt(fs9.readFileSync(pidFile, "utf8").trim(), 10);
|
|
@@ -21243,7 +21582,7 @@ function stopSessionHostProcesses(appName) {
|
|
|
21243
21582
|
}
|
|
21244
21583
|
}
|
|
21245
21584
|
function removeDaemonPidFile() {
|
|
21246
|
-
const pidFile =
|
|
21585
|
+
const pidFile = path22.join(os19.homedir(), ".adhdev", "daemon.pid");
|
|
21247
21586
|
try {
|
|
21248
21587
|
fs9.unlinkSync(pidFile);
|
|
21249
21588
|
} catch {
|
|
@@ -21254,7 +21593,7 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
21254
21593
|
const npmRoot = String(execNpmCommandSync(["root", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
21255
21594
|
if (!npmRoot) return;
|
|
21256
21595
|
const npmPrefix = surface.installPrefix || String(execNpmCommandSync(["prefix", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
21257
|
-
const binDir = process.platform === "win32" ? npmPrefix :
|
|
21596
|
+
const binDir = process.platform === "win32" ? npmPrefix : path22.join(npmPrefix, "bin");
|
|
21258
21597
|
const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
|
|
21259
21598
|
const binNames = /* @__PURE__ */ new Set([packageBaseName]);
|
|
21260
21599
|
if (pkgName === "@adhdev/daemon-standalone") {
|
|
@@ -21262,25 +21601,25 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
|
|
|
21262
21601
|
}
|
|
21263
21602
|
if (pkgName.startsWith("@")) {
|
|
21264
21603
|
const [scope, name] = pkgName.split("/");
|
|
21265
|
-
const scopeDir =
|
|
21604
|
+
const scopeDir = path22.join(npmRoot, scope);
|
|
21266
21605
|
if (!fs9.existsSync(scopeDir)) return;
|
|
21267
21606
|
for (const entry of fs9.readdirSync(scopeDir)) {
|
|
21268
21607
|
if (!entry.startsWith(`.${name}-`)) continue;
|
|
21269
|
-
fs9.rmSync(
|
|
21270
|
-
appendUpgradeLog(`Removed stale scoped staging dir: ${
|
|
21608
|
+
fs9.rmSync(path22.join(scopeDir, entry), { recursive: true, force: true });
|
|
21609
|
+
appendUpgradeLog(`Removed stale scoped staging dir: ${path22.join(scopeDir, entry)}`);
|
|
21271
21610
|
}
|
|
21272
21611
|
} else {
|
|
21273
21612
|
for (const entry of fs9.readdirSync(npmRoot)) {
|
|
21274
21613
|
if (!entry.startsWith(`.${pkgName}-`)) continue;
|
|
21275
|
-
fs9.rmSync(
|
|
21276
|
-
appendUpgradeLog(`Removed stale staging dir: ${
|
|
21614
|
+
fs9.rmSync(path22.join(npmRoot, entry), { recursive: true, force: true });
|
|
21615
|
+
appendUpgradeLog(`Removed stale staging dir: ${path22.join(npmRoot, entry)}`);
|
|
21277
21616
|
}
|
|
21278
21617
|
}
|
|
21279
21618
|
if (fs9.existsSync(binDir)) {
|
|
21280
21619
|
for (const entry of fs9.readdirSync(binDir)) {
|
|
21281
21620
|
if (!Array.from(binNames).some((name) => entry.startsWith(`.${name}-`))) continue;
|
|
21282
|
-
fs9.rmSync(
|
|
21283
|
-
appendUpgradeLog(`Removed stale bin staging entry: ${
|
|
21621
|
+
fs9.rmSync(path22.join(binDir, entry), { recursive: true, force: true });
|
|
21622
|
+
appendUpgradeLog(`Removed stale bin staging entry: ${path22.join(binDir, entry)}`);
|
|
21284
21623
|
}
|
|
21285
21624
|
}
|
|
21286
21625
|
}
|
|
@@ -22652,7 +22991,7 @@ var DaemonCommandRouter = class {
|
|
|
22652
22991
|
workspace
|
|
22653
22992
|
};
|
|
22654
22993
|
}
|
|
22655
|
-
const { existsSync: existsSync23, readFileSync: readFileSync15, writeFileSync:
|
|
22994
|
+
const { existsSync: existsSync23, readFileSync: readFileSync15, writeFileSync: writeFileSync14, copyFileSync: copyFileSync3, mkdirSync: mkdirSync16 } = await import("fs");
|
|
22656
22995
|
const { dirname: dirname9 } = await import("path");
|
|
22657
22996
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
22658
22997
|
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
@@ -22676,7 +23015,7 @@ var DaemonCommandRouter = class {
|
|
|
22676
23015
|
};
|
|
22677
23016
|
}
|
|
22678
23017
|
try {
|
|
22679
|
-
|
|
23018
|
+
mkdirSync16(dirname9(mcpConfigPath), { recursive: true });
|
|
22680
23019
|
} catch (error) {
|
|
22681
23020
|
const message = `Could not prepare MCP config path for automatic setup: ${error?.message || error}`;
|
|
22682
23021
|
LOG.error("MeshCoordinator", message);
|
|
@@ -22708,7 +23047,7 @@ var DaemonCommandRouter = class {
|
|
|
22708
23047
|
}
|
|
22709
23048
|
};
|
|
22710
23049
|
try {
|
|
22711
|
-
|
|
23050
|
+
writeFileSync14(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
|
|
22712
23051
|
} catch (error) {
|
|
22713
23052
|
const message = `Could not write MCP config for automatic setup: ${error?.message || error}`;
|
|
22714
23053
|
LOG.error("MeshCoordinator", message);
|
|
@@ -22718,6 +23057,10 @@ var DaemonCommandRouter = class {
|
|
|
22718
23057
|
LOG.info("MeshCoordinator", `Wrote ${mcpConfigPath} with ${coordinatorSetup.serverName} server`);
|
|
22719
23058
|
const cliArgs = [];
|
|
22720
23059
|
const launchEnv = {};
|
|
23060
|
+
if (configFormat === "hermes_config_yaml") {
|
|
23061
|
+
launchEnv.HERMES_HOME = dirname9(mcpConfigPath);
|
|
23062
|
+
launchEnv.HERMES_IGNORE_USER_CONFIG = "";
|
|
23063
|
+
}
|
|
22721
23064
|
if (systemPrompt) {
|
|
22722
23065
|
if (configFormat === "hermes_config_yaml") {
|
|
22723
23066
|
launchEnv.HERMES_EPHEMERAL_SYSTEM_PROMPT = systemPrompt;
|
|
@@ -24414,11 +24757,11 @@ var ProviderInstanceManager = class {
|
|
|
24414
24757
|
|
|
24415
24758
|
// src/providers/version-archive.ts
|
|
24416
24759
|
import * as fs11 from "fs";
|
|
24417
|
-
import * as
|
|
24760
|
+
import * as path23 from "path";
|
|
24418
24761
|
import * as os20 from "os";
|
|
24419
24762
|
import { execSync as execSync5 } from "child_process";
|
|
24420
24763
|
import { platform as platform8 } from "os";
|
|
24421
|
-
var ARCHIVE_PATH =
|
|
24764
|
+
var ARCHIVE_PATH = path23.join(os20.homedir(), ".adhdev", "version-history.json");
|
|
24422
24765
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
24423
24766
|
var VersionArchive = class {
|
|
24424
24767
|
history = {};
|
|
@@ -24465,7 +24808,7 @@ var VersionArchive = class {
|
|
|
24465
24808
|
}
|
|
24466
24809
|
save() {
|
|
24467
24810
|
try {
|
|
24468
|
-
fs11.mkdirSync(
|
|
24811
|
+
fs11.mkdirSync(path23.dirname(ARCHIVE_PATH), { recursive: true });
|
|
24469
24812
|
fs11.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
24470
24813
|
} catch {
|
|
24471
24814
|
}
|
|
@@ -24522,7 +24865,7 @@ function checkPathExists2(paths) {
|
|
|
24522
24865
|
for (const p of paths) {
|
|
24523
24866
|
if (p.includes("*")) {
|
|
24524
24867
|
const home = os20.homedir();
|
|
24525
|
-
const resolved = p.replace(/\*/g, home.split(
|
|
24868
|
+
const resolved = p.replace(/\*/g, home.split(path23.sep).pop() || "");
|
|
24526
24869
|
if (fs11.existsSync(resolved)) return resolved;
|
|
24527
24870
|
} else {
|
|
24528
24871
|
if (fs11.existsSync(p)) return p;
|
|
@@ -24532,7 +24875,7 @@ function checkPathExists2(paths) {
|
|
|
24532
24875
|
}
|
|
24533
24876
|
function getMacAppVersion(appPath) {
|
|
24534
24877
|
if (platform8() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
24535
|
-
const plistPath =
|
|
24878
|
+
const plistPath = path23.join(appPath, "Contents", "Info.plist");
|
|
24536
24879
|
if (!fs11.existsSync(plistPath)) return null;
|
|
24537
24880
|
const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
24538
24881
|
return raw || null;
|
|
@@ -24558,7 +24901,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
24558
24901
|
const cliBin = provider.cli ? findBinary2(provider.cli) : null;
|
|
24559
24902
|
let resolvedBin = cliBin;
|
|
24560
24903
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
24561
|
-
const bundled =
|
|
24904
|
+
const bundled = path23.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
24562
24905
|
if (provider.cli && fs11.existsSync(bundled)) resolvedBin = bundled;
|
|
24563
24906
|
}
|
|
24564
24907
|
info.installed = !!(appPath || resolvedBin);
|
|
@@ -24599,7 +24942,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
24599
24942
|
// src/daemon/dev-server.ts
|
|
24600
24943
|
import * as http2 from "http";
|
|
24601
24944
|
import * as fs15 from "fs";
|
|
24602
|
-
import * as
|
|
24945
|
+
import * as path27 from "path";
|
|
24603
24946
|
init_config();
|
|
24604
24947
|
|
|
24605
24948
|
// src/daemon/scaffold-template.ts
|
|
@@ -24951,7 +25294,7 @@ init_logger();
|
|
|
24951
25294
|
// src/daemon/dev-cdp-handlers.ts
|
|
24952
25295
|
init_logger();
|
|
24953
25296
|
import * as fs12 from "fs";
|
|
24954
|
-
import * as
|
|
25297
|
+
import * as path24 from "path";
|
|
24955
25298
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
24956
25299
|
const body = await ctx.readBody(req);
|
|
24957
25300
|
const { expression, timeout, ideType } = body;
|
|
@@ -25129,17 +25472,17 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
25129
25472
|
return;
|
|
25130
25473
|
}
|
|
25131
25474
|
let scriptsPath = "";
|
|
25132
|
-
const directScripts =
|
|
25475
|
+
const directScripts = path24.join(dir, "scripts.js");
|
|
25133
25476
|
if (fs12.existsSync(directScripts)) {
|
|
25134
25477
|
scriptsPath = directScripts;
|
|
25135
25478
|
} else {
|
|
25136
|
-
const scriptsDir =
|
|
25479
|
+
const scriptsDir = path24.join(dir, "scripts");
|
|
25137
25480
|
if (fs12.existsSync(scriptsDir)) {
|
|
25138
25481
|
const versions = fs12.readdirSync(scriptsDir).filter((d) => {
|
|
25139
|
-
return fs12.statSync(
|
|
25482
|
+
return fs12.statSync(path24.join(scriptsDir, d)).isDirectory();
|
|
25140
25483
|
}).sort().reverse();
|
|
25141
25484
|
for (const ver of versions) {
|
|
25142
|
-
const p =
|
|
25485
|
+
const p = path24.join(scriptsDir, ver, "scripts.js");
|
|
25143
25486
|
if (fs12.existsSync(p)) {
|
|
25144
25487
|
scriptsPath = p;
|
|
25145
25488
|
break;
|
|
@@ -25968,7 +26311,7 @@ async function handleDomContext(ctx, type, req, res) {
|
|
|
25968
26311
|
|
|
25969
26312
|
// src/daemon/dev-cli-debug.ts
|
|
25970
26313
|
import * as fs13 from "fs";
|
|
25971
|
-
import * as
|
|
26314
|
+
import * as path25 from "path";
|
|
25972
26315
|
function slugifyFixtureName(value) {
|
|
25973
26316
|
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
25974
26317
|
return normalized || `fixture-${Date.now()}`;
|
|
@@ -25978,11 +26321,11 @@ function getCliFixtureDir(ctx, type) {
|
|
|
25978
26321
|
if (!providerDir) {
|
|
25979
26322
|
throw new Error(`Provider directory not found for '${type}'`);
|
|
25980
26323
|
}
|
|
25981
|
-
return
|
|
26324
|
+
return path25.join(providerDir, "fixtures");
|
|
25982
26325
|
}
|
|
25983
26326
|
function readCliFixture(ctx, type, name) {
|
|
25984
26327
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
25985
|
-
const filePath =
|
|
26328
|
+
const filePath = path25.join(fixtureDir, `${name}.json`);
|
|
25986
26329
|
if (!fs13.existsSync(filePath)) {
|
|
25987
26330
|
throw new Error(`Fixture not found: ${filePath}`);
|
|
25988
26331
|
}
|
|
@@ -26749,7 +27092,7 @@ async function handleCliFixtureCapture(ctx, req, res) {
|
|
|
26749
27092
|
},
|
|
26750
27093
|
notes: typeof body?.notes === "string" ? body.notes : void 0
|
|
26751
27094
|
};
|
|
26752
|
-
const filePath =
|
|
27095
|
+
const filePath = path25.join(fixtureDir, `${name}.json`);
|
|
26753
27096
|
fs13.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
|
|
26754
27097
|
ctx.json(res, 200, {
|
|
26755
27098
|
saved: true,
|
|
@@ -26773,7 +27116,7 @@ async function handleCliFixtureList(ctx, type, _req, res) {
|
|
|
26773
27116
|
return;
|
|
26774
27117
|
}
|
|
26775
27118
|
const fixtures = fs13.readdirSync(fixtureDir).filter((file) => file.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file) => {
|
|
26776
|
-
const fullPath =
|
|
27119
|
+
const fullPath = path25.join(fixtureDir, file);
|
|
26777
27120
|
try {
|
|
26778
27121
|
const raw = JSON.parse(fs13.readFileSync(fullPath, "utf-8"));
|
|
26779
27122
|
return {
|
|
@@ -26909,7 +27252,7 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
26909
27252
|
|
|
26910
27253
|
// src/daemon/dev-auto-implement.ts
|
|
26911
27254
|
import * as fs14 from "fs";
|
|
26912
|
-
import * as
|
|
27255
|
+
import * as path26 from "path";
|
|
26913
27256
|
import * as os21 from "os";
|
|
26914
27257
|
function getAutoImplPid(ctx) {
|
|
26915
27258
|
const pid = ctx.autoImplProcess?.pid;
|
|
@@ -26959,22 +27302,22 @@ function getLatestScriptVersionDir(scriptsDir) {
|
|
|
26959
27302
|
if (!fs14.existsSync(scriptsDir)) return null;
|
|
26960
27303
|
const versions = fs14.readdirSync(scriptsDir).filter((d) => {
|
|
26961
27304
|
try {
|
|
26962
|
-
return fs14.statSync(
|
|
27305
|
+
return fs14.statSync(path26.join(scriptsDir, d)).isDirectory();
|
|
26963
27306
|
} catch {
|
|
26964
27307
|
return false;
|
|
26965
27308
|
}
|
|
26966
27309
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
26967
27310
|
if (versions.length === 0) return null;
|
|
26968
|
-
return
|
|
27311
|
+
return path26.join(scriptsDir, versions[0]);
|
|
26969
27312
|
}
|
|
26970
27313
|
function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
26971
|
-
const canonicalUserDir =
|
|
26972
|
-
const desiredDir = requestedDir ?
|
|
26973
|
-
const upstreamRoot =
|
|
26974
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
27314
|
+
const canonicalUserDir = path26.resolve(ctx.providerLoader.getUserProviderDir(category, type));
|
|
27315
|
+
const desiredDir = requestedDir ? path26.resolve(requestedDir) : canonicalUserDir;
|
|
27316
|
+
const upstreamRoot = path26.resolve(ctx.providerLoader.getUpstreamDir());
|
|
27317
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path26.sep}`)) {
|
|
26975
27318
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
26976
27319
|
}
|
|
26977
|
-
if (
|
|
27320
|
+
if (path26.basename(desiredDir) !== type) {
|
|
26978
27321
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
26979
27322
|
}
|
|
26980
27323
|
const sourceDir = ctx.findProviderDir(type);
|
|
@@ -26982,11 +27325,11 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
26982
27325
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
26983
27326
|
}
|
|
26984
27327
|
if (!fs14.existsSync(desiredDir)) {
|
|
26985
|
-
fs14.mkdirSync(
|
|
27328
|
+
fs14.mkdirSync(path26.dirname(desiredDir), { recursive: true });
|
|
26986
27329
|
fs14.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
26987
27330
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
26988
27331
|
}
|
|
26989
|
-
const providerJson =
|
|
27332
|
+
const providerJson = path26.join(desiredDir, "provider.json");
|
|
26990
27333
|
if (!fs14.existsSync(providerJson)) {
|
|
26991
27334
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
26992
27335
|
}
|
|
@@ -26997,13 +27340,13 @@ function loadAutoImplReferenceScripts(ctx, referenceType) {
|
|
|
26997
27340
|
const refDir = ctx.findProviderDir(referenceType);
|
|
26998
27341
|
if (!refDir || !fs14.existsSync(refDir)) return {};
|
|
26999
27342
|
const referenceScripts = {};
|
|
27000
|
-
const scriptsDir =
|
|
27343
|
+
const scriptsDir = path26.join(refDir, "scripts");
|
|
27001
27344
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
27002
27345
|
if (!latestDir) return referenceScripts;
|
|
27003
27346
|
for (const file of fs14.readdirSync(latestDir)) {
|
|
27004
27347
|
if (!file.endsWith(".js")) continue;
|
|
27005
27348
|
try {
|
|
27006
|
-
referenceScripts[file] = fs14.readFileSync(
|
|
27349
|
+
referenceScripts[file] = fs14.readFileSync(path26.join(latestDir, file), "utf-8");
|
|
27007
27350
|
} catch {
|
|
27008
27351
|
}
|
|
27009
27352
|
}
|
|
@@ -27111,9 +27454,9 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
27111
27454
|
});
|
|
27112
27455
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
27113
27456
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
27114
|
-
const tmpDir =
|
|
27457
|
+
const tmpDir = path26.join(os21.tmpdir(), "adhdev-autoimpl");
|
|
27115
27458
|
if (!fs14.existsSync(tmpDir)) fs14.mkdirSync(tmpDir, { recursive: true });
|
|
27116
|
-
const promptFile =
|
|
27459
|
+
const promptFile = path26.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
27117
27460
|
fs14.writeFileSync(promptFile, prompt, "utf-8");
|
|
27118
27461
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
27119
27462
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
@@ -27545,7 +27888,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
27545
27888
|
setMode: "set_mode.js"
|
|
27546
27889
|
};
|
|
27547
27890
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
27548
|
-
const scriptsDir =
|
|
27891
|
+
const scriptsDir = path26.join(providerDir, "scripts");
|
|
27549
27892
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
27550
27893
|
if (latestScriptsDir) {
|
|
27551
27894
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -27556,7 +27899,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
27556
27899
|
for (const file of fs14.readdirSync(latestScriptsDir)) {
|
|
27557
27900
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
27558
27901
|
try {
|
|
27559
|
-
const content = fs14.readFileSync(
|
|
27902
|
+
const content = fs14.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
|
|
27560
27903
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
27561
27904
|
lines.push("```javascript");
|
|
27562
27905
|
lines.push(content);
|
|
@@ -27573,7 +27916,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
27573
27916
|
lines.push("");
|
|
27574
27917
|
for (const file of refFiles) {
|
|
27575
27918
|
try {
|
|
27576
|
-
const content = fs14.readFileSync(
|
|
27919
|
+
const content = fs14.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
|
|
27577
27920
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
27578
27921
|
lines.push("```javascript");
|
|
27579
27922
|
lines.push(content);
|
|
@@ -27614,10 +27957,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
27614
27957
|
lines.push("");
|
|
27615
27958
|
}
|
|
27616
27959
|
}
|
|
27617
|
-
const docsDir =
|
|
27960
|
+
const docsDir = path26.join(providerDir, "../../docs");
|
|
27618
27961
|
const loadGuide = (name) => {
|
|
27619
27962
|
try {
|
|
27620
|
-
const p =
|
|
27963
|
+
const p = path26.join(docsDir, name);
|
|
27621
27964
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
27622
27965
|
} catch {
|
|
27623
27966
|
}
|
|
@@ -27854,7 +28197,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
27854
28197
|
parseApproval: "parse_approval.js"
|
|
27855
28198
|
};
|
|
27856
28199
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
27857
|
-
const scriptsDir =
|
|
28200
|
+
const scriptsDir = path26.join(providerDir, "scripts");
|
|
27858
28201
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
27859
28202
|
if (latestScriptsDir) {
|
|
27860
28203
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -27866,7 +28209,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
27866
28209
|
if (!file.endsWith(".js")) continue;
|
|
27867
28210
|
if (!targetFileNames.has(file)) continue;
|
|
27868
28211
|
try {
|
|
27869
|
-
const content = fs14.readFileSync(
|
|
28212
|
+
const content = fs14.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
|
|
27870
28213
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
27871
28214
|
lines.push("```javascript");
|
|
27872
28215
|
lines.push(content);
|
|
@@ -27882,7 +28225,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
27882
28225
|
lines.push("");
|
|
27883
28226
|
for (const file of refFiles) {
|
|
27884
28227
|
try {
|
|
27885
|
-
const content = fs14.readFileSync(
|
|
28228
|
+
const content = fs14.readFileSync(path26.join(latestScriptsDir, file), "utf-8");
|
|
27886
28229
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
27887
28230
|
lines.push("```javascript");
|
|
27888
28231
|
lines.push(content);
|
|
@@ -27915,10 +28258,10 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
27915
28258
|
lines.push("");
|
|
27916
28259
|
}
|
|
27917
28260
|
}
|
|
27918
|
-
const docsDir =
|
|
28261
|
+
const docsDir = path26.join(providerDir, "../../docs");
|
|
27919
28262
|
const loadGuide = (name) => {
|
|
27920
28263
|
try {
|
|
27921
|
-
const p =
|
|
28264
|
+
const p = path26.join(docsDir, name);
|
|
27922
28265
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
27923
28266
|
} catch {
|
|
27924
28267
|
}
|
|
@@ -28365,8 +28708,8 @@ var DevServer = class _DevServer {
|
|
|
28365
28708
|
}
|
|
28366
28709
|
getEndpointList() {
|
|
28367
28710
|
return this.routes.map((r) => {
|
|
28368
|
-
const
|
|
28369
|
-
return `${r.method.padEnd(5)} ${
|
|
28711
|
+
const path28 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
|
|
28712
|
+
return `${r.method.padEnd(5)} ${path28}`;
|
|
28370
28713
|
});
|
|
28371
28714
|
}
|
|
28372
28715
|
async start(port = DEV_SERVER_PORT) {
|
|
@@ -28654,12 +28997,12 @@ var DevServer = class _DevServer {
|
|
|
28654
28997
|
// ─── DevConsole SPA ───
|
|
28655
28998
|
getConsoleDistDir() {
|
|
28656
28999
|
const candidates = [
|
|
28657
|
-
|
|
28658
|
-
|
|
28659
|
-
|
|
29000
|
+
path27.resolve(__dirname, "../../web-devconsole/dist"),
|
|
29001
|
+
path27.resolve(__dirname, "../../../web-devconsole/dist"),
|
|
29002
|
+
path27.join(process.cwd(), "packages/web-devconsole/dist")
|
|
28660
29003
|
];
|
|
28661
29004
|
for (const dir of candidates) {
|
|
28662
|
-
if (fs15.existsSync(
|
|
29005
|
+
if (fs15.existsSync(path27.join(dir, "index.html"))) return dir;
|
|
28663
29006
|
}
|
|
28664
29007
|
return null;
|
|
28665
29008
|
}
|
|
@@ -28669,7 +29012,7 @@ var DevServer = class _DevServer {
|
|
|
28669
29012
|
this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
|
|
28670
29013
|
return;
|
|
28671
29014
|
}
|
|
28672
|
-
const htmlPath =
|
|
29015
|
+
const htmlPath = path27.join(distDir, "index.html");
|
|
28673
29016
|
try {
|
|
28674
29017
|
const html = fs15.readFileSync(htmlPath, "utf-8");
|
|
28675
29018
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
@@ -28694,15 +29037,15 @@ var DevServer = class _DevServer {
|
|
|
28694
29037
|
this.json(res, 404, { error: "Not found" });
|
|
28695
29038
|
return;
|
|
28696
29039
|
}
|
|
28697
|
-
const safePath =
|
|
28698
|
-
const filePath =
|
|
29040
|
+
const safePath = path27.normalize(pathname).replace(/^\.\.\//, "");
|
|
29041
|
+
const filePath = path27.join(distDir, safePath);
|
|
28699
29042
|
if (!filePath.startsWith(distDir)) {
|
|
28700
29043
|
this.json(res, 403, { error: "Forbidden" });
|
|
28701
29044
|
return;
|
|
28702
29045
|
}
|
|
28703
29046
|
try {
|
|
28704
29047
|
const content = fs15.readFileSync(filePath);
|
|
28705
|
-
const ext =
|
|
29048
|
+
const ext = path27.extname(filePath);
|
|
28706
29049
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
28707
29050
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
28708
29051
|
res.end(content);
|
|
@@ -28815,9 +29158,9 @@ var DevServer = class _DevServer {
|
|
|
28815
29158
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
28816
29159
|
if (entry.isDirectory()) {
|
|
28817
29160
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
28818
|
-
scan(
|
|
29161
|
+
scan(path27.join(d, entry.name), rel);
|
|
28819
29162
|
} else {
|
|
28820
|
-
const stat2 = fs15.statSync(
|
|
29163
|
+
const stat2 = fs15.statSync(path27.join(d, entry.name));
|
|
28821
29164
|
files.push({ path: rel, size: stat2.size, type: "file" });
|
|
28822
29165
|
}
|
|
28823
29166
|
}
|
|
@@ -28840,7 +29183,7 @@ var DevServer = class _DevServer {
|
|
|
28840
29183
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
28841
29184
|
return;
|
|
28842
29185
|
}
|
|
28843
|
-
const fullPath =
|
|
29186
|
+
const fullPath = path27.resolve(dir, path27.normalize(filePath));
|
|
28844
29187
|
if (!fullPath.startsWith(dir)) {
|
|
28845
29188
|
this.json(res, 403, { error: "Forbidden" });
|
|
28846
29189
|
return;
|
|
@@ -28865,14 +29208,14 @@ var DevServer = class _DevServer {
|
|
|
28865
29208
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
28866
29209
|
return;
|
|
28867
29210
|
}
|
|
28868
|
-
const fullPath =
|
|
29211
|
+
const fullPath = path27.resolve(dir, path27.normalize(filePath));
|
|
28869
29212
|
if (!fullPath.startsWith(dir)) {
|
|
28870
29213
|
this.json(res, 403, { error: "Forbidden" });
|
|
28871
29214
|
return;
|
|
28872
29215
|
}
|
|
28873
29216
|
try {
|
|
28874
29217
|
if (fs15.existsSync(fullPath)) fs15.copyFileSync(fullPath, fullPath + ".bak");
|
|
28875
|
-
fs15.mkdirSync(
|
|
29218
|
+
fs15.mkdirSync(path27.dirname(fullPath), { recursive: true });
|
|
28876
29219
|
fs15.writeFileSync(fullPath, content, "utf-8");
|
|
28877
29220
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
28878
29221
|
this.providerLoader.reload();
|
|
@@ -28889,7 +29232,7 @@ var DevServer = class _DevServer {
|
|
|
28889
29232
|
return;
|
|
28890
29233
|
}
|
|
28891
29234
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
28892
|
-
const p =
|
|
29235
|
+
const p = path27.join(dir, name);
|
|
28893
29236
|
if (fs15.existsSync(p)) {
|
|
28894
29237
|
const source = fs15.readFileSync(p, "utf-8");
|
|
28895
29238
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
@@ -28910,8 +29253,8 @@ var DevServer = class _DevServer {
|
|
|
28910
29253
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
28911
29254
|
return;
|
|
28912
29255
|
}
|
|
28913
|
-
const target = fs15.existsSync(
|
|
28914
|
-
const targetPath =
|
|
29256
|
+
const target = fs15.existsSync(path27.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
29257
|
+
const targetPath = path27.join(dir, target);
|
|
28915
29258
|
try {
|
|
28916
29259
|
if (fs15.existsSync(targetPath)) fs15.copyFileSync(targetPath, targetPath + ".bak");
|
|
28917
29260
|
fs15.writeFileSync(targetPath, source, "utf-8");
|
|
@@ -29058,7 +29401,7 @@ var DevServer = class _DevServer {
|
|
|
29058
29401
|
}
|
|
29059
29402
|
let targetDir;
|
|
29060
29403
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
29061
|
-
const jsonPath =
|
|
29404
|
+
const jsonPath = path27.join(targetDir, "provider.json");
|
|
29062
29405
|
if (fs15.existsSync(jsonPath)) {
|
|
29063
29406
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
29064
29407
|
return;
|
|
@@ -29070,8 +29413,8 @@ var DevServer = class _DevServer {
|
|
|
29070
29413
|
const createdFiles = ["provider.json"];
|
|
29071
29414
|
if (result.files) {
|
|
29072
29415
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
29073
|
-
const fullPath =
|
|
29074
|
-
fs15.mkdirSync(
|
|
29416
|
+
const fullPath = path27.join(targetDir, relPath);
|
|
29417
|
+
fs15.mkdirSync(path27.dirname(fullPath), { recursive: true });
|
|
29075
29418
|
fs15.writeFileSync(fullPath, content, "utf-8");
|
|
29076
29419
|
createdFiles.push(relPath);
|
|
29077
29420
|
}
|
|
@@ -29124,22 +29467,22 @@ var DevServer = class _DevServer {
|
|
|
29124
29467
|
if (!fs15.existsSync(scriptsDir)) return null;
|
|
29125
29468
|
const versions = fs15.readdirSync(scriptsDir).filter((d) => {
|
|
29126
29469
|
try {
|
|
29127
|
-
return fs15.statSync(
|
|
29470
|
+
return fs15.statSync(path27.join(scriptsDir, d)).isDirectory();
|
|
29128
29471
|
} catch {
|
|
29129
29472
|
return false;
|
|
29130
29473
|
}
|
|
29131
29474
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
29132
29475
|
if (versions.length === 0) return null;
|
|
29133
|
-
return
|
|
29476
|
+
return path27.join(scriptsDir, versions[0]);
|
|
29134
29477
|
}
|
|
29135
29478
|
resolveAutoImplWritableProviderDir(category, type, requestedDir) {
|
|
29136
|
-
const canonicalUserDir =
|
|
29137
|
-
const desiredDir = requestedDir ?
|
|
29138
|
-
const upstreamRoot =
|
|
29139
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
29479
|
+
const canonicalUserDir = path27.resolve(this.providerLoader.getUserProviderDir(category, type));
|
|
29480
|
+
const desiredDir = requestedDir ? path27.resolve(requestedDir) : canonicalUserDir;
|
|
29481
|
+
const upstreamRoot = path27.resolve(this.providerLoader.getUpstreamDir());
|
|
29482
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path27.sep}`)) {
|
|
29140
29483
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
29141
29484
|
}
|
|
29142
|
-
if (
|
|
29485
|
+
if (path27.basename(desiredDir) !== type) {
|
|
29143
29486
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
29144
29487
|
}
|
|
29145
29488
|
const sourceDir = this.findProviderDir(type);
|
|
@@ -29147,11 +29490,11 @@ var DevServer = class _DevServer {
|
|
|
29147
29490
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
29148
29491
|
}
|
|
29149
29492
|
if (!fs15.existsSync(desiredDir)) {
|
|
29150
|
-
fs15.mkdirSync(
|
|
29493
|
+
fs15.mkdirSync(path27.dirname(desiredDir), { recursive: true });
|
|
29151
29494
|
fs15.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
29152
29495
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
29153
29496
|
}
|
|
29154
|
-
const providerJson =
|
|
29497
|
+
const providerJson = path27.join(desiredDir, "provider.json");
|
|
29155
29498
|
if (!fs15.existsSync(providerJson)) {
|
|
29156
29499
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
29157
29500
|
}
|
|
@@ -29187,7 +29530,7 @@ var DevServer = class _DevServer {
|
|
|
29187
29530
|
setMode: "set_mode.js"
|
|
29188
29531
|
};
|
|
29189
29532
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
29190
|
-
const scriptsDir =
|
|
29533
|
+
const scriptsDir = path27.join(providerDir, "scripts");
|
|
29191
29534
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
29192
29535
|
if (latestScriptsDir) {
|
|
29193
29536
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -29198,7 +29541,7 @@ var DevServer = class _DevServer {
|
|
|
29198
29541
|
for (const file of fs15.readdirSync(latestScriptsDir)) {
|
|
29199
29542
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
29200
29543
|
try {
|
|
29201
|
-
const content = fs15.readFileSync(
|
|
29544
|
+
const content = fs15.readFileSync(path27.join(latestScriptsDir, file), "utf-8");
|
|
29202
29545
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
29203
29546
|
lines.push("```javascript");
|
|
29204
29547
|
lines.push(content);
|
|
@@ -29215,7 +29558,7 @@ var DevServer = class _DevServer {
|
|
|
29215
29558
|
lines.push("");
|
|
29216
29559
|
for (const file of refFiles) {
|
|
29217
29560
|
try {
|
|
29218
|
-
const content = fs15.readFileSync(
|
|
29561
|
+
const content = fs15.readFileSync(path27.join(latestScriptsDir, file), "utf-8");
|
|
29219
29562
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
29220
29563
|
lines.push("```javascript");
|
|
29221
29564
|
lines.push(content);
|
|
@@ -29256,10 +29599,10 @@ var DevServer = class _DevServer {
|
|
|
29256
29599
|
lines.push("");
|
|
29257
29600
|
}
|
|
29258
29601
|
}
|
|
29259
|
-
const docsDir =
|
|
29602
|
+
const docsDir = path27.join(providerDir, "../../docs");
|
|
29260
29603
|
const loadGuide = (name) => {
|
|
29261
29604
|
try {
|
|
29262
|
-
const p =
|
|
29605
|
+
const p = path27.join(docsDir, name);
|
|
29263
29606
|
if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
|
|
29264
29607
|
} catch {
|
|
29265
29608
|
}
|
|
@@ -29433,7 +29776,7 @@ var DevServer = class _DevServer {
|
|
|
29433
29776
|
parseApproval: "parse_approval.js"
|
|
29434
29777
|
};
|
|
29435
29778
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
29436
|
-
const scriptsDir =
|
|
29779
|
+
const scriptsDir = path27.join(providerDir, "scripts");
|
|
29437
29780
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
29438
29781
|
if (latestScriptsDir) {
|
|
29439
29782
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -29445,7 +29788,7 @@ var DevServer = class _DevServer {
|
|
|
29445
29788
|
if (!file.endsWith(".js")) continue;
|
|
29446
29789
|
if (!targetFileNames.has(file)) continue;
|
|
29447
29790
|
try {
|
|
29448
|
-
const content = fs15.readFileSync(
|
|
29791
|
+
const content = fs15.readFileSync(path27.join(latestScriptsDir, file), "utf-8");
|
|
29449
29792
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
29450
29793
|
lines.push("```javascript");
|
|
29451
29794
|
lines.push(content);
|
|
@@ -29461,7 +29804,7 @@ var DevServer = class _DevServer {
|
|
|
29461
29804
|
lines.push("");
|
|
29462
29805
|
for (const file of refFiles) {
|
|
29463
29806
|
try {
|
|
29464
|
-
const content = fs15.readFileSync(
|
|
29807
|
+
const content = fs15.readFileSync(path27.join(latestScriptsDir, file), "utf-8");
|
|
29465
29808
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
29466
29809
|
lines.push("```javascript");
|
|
29467
29810
|
lines.push(content);
|
|
@@ -29494,10 +29837,10 @@ var DevServer = class _DevServer {
|
|
|
29494
29837
|
lines.push("");
|
|
29495
29838
|
}
|
|
29496
29839
|
}
|
|
29497
|
-
const docsDir =
|
|
29840
|
+
const docsDir = path27.join(providerDir, "../../docs");
|
|
29498
29841
|
const loadGuide = (name) => {
|
|
29499
29842
|
try {
|
|
29500
|
-
const p =
|
|
29843
|
+
const p = path27.join(docsDir, name);
|
|
29501
29844
|
if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
|
|
29502
29845
|
} catch {
|
|
29503
29846
|
}
|