adhdev 0.9.66 → 0.9.68
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/cli/index.js +838 -57
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +543 -43
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/vendor/mcp-server/index.js +427 -10
- package/vendor/mcp-server/index.js.map +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -554,6 +554,22 @@ var init_source = __esm({
|
|
|
554
554
|
}
|
|
555
555
|
});
|
|
556
556
|
|
|
557
|
+
// ../../oss/packages/daemon-core/src/repo-mesh-types.ts
|
|
558
|
+
var DEFAULT_MESH_POLICY;
|
|
559
|
+
var init_repo_mesh_types = __esm({
|
|
560
|
+
"../../oss/packages/daemon-core/src/repo-mesh-types.ts"() {
|
|
561
|
+
"use strict";
|
|
562
|
+
DEFAULT_MESH_POLICY = {
|
|
563
|
+
requirePreTaskCheckpoint: false,
|
|
564
|
+
requirePostTaskCheckpoint: true,
|
|
565
|
+
requireApprovalForPush: true,
|
|
566
|
+
requireApprovalForDestructiveGit: true,
|
|
567
|
+
dirtyWorkspaceBehavior: "warn",
|
|
568
|
+
maxParallelTasks: 2
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
});
|
|
572
|
+
|
|
557
573
|
// ../../oss/packages/daemon-core/src/git/git-executor.ts
|
|
558
574
|
async function resolveGitRepository(workspace, options = {}) {
|
|
559
575
|
const normalizedWorkspace = await validateWorkspace(workspace);
|
|
@@ -2682,12 +2698,343 @@ var init_saved_sessions = __esm({
|
|
|
2682
2698
|
}
|
|
2683
2699
|
});
|
|
2684
2700
|
|
|
2701
|
+
// ../../oss/packages/daemon-core/src/config/mesh-config.ts
|
|
2702
|
+
var mesh_config_exports = {};
|
|
2703
|
+
__export(mesh_config_exports, {
|
|
2704
|
+
addNode: () => addNode,
|
|
2705
|
+
createMesh: () => createMesh,
|
|
2706
|
+
deleteMesh: () => deleteMesh,
|
|
2707
|
+
getMesh: () => getMesh,
|
|
2708
|
+
getMeshByRepo: () => getMeshByRepo,
|
|
2709
|
+
listMeshes: () => listMeshes,
|
|
2710
|
+
normalizeRepoIdentity: () => normalizeRepoIdentity,
|
|
2711
|
+
removeNode: () => removeNode,
|
|
2712
|
+
updateMesh: () => updateMesh,
|
|
2713
|
+
updateNode: () => updateNode
|
|
2714
|
+
});
|
|
2715
|
+
function getMeshConfigPath() {
|
|
2716
|
+
return (0, import_path2.join)(getConfigDir(), "meshes.json");
|
|
2717
|
+
}
|
|
2718
|
+
function loadMeshConfig() {
|
|
2719
|
+
const path40 = getMeshConfigPath();
|
|
2720
|
+
if (!(0, import_fs2.existsSync)(path40)) return { meshes: [] };
|
|
2721
|
+
try {
|
|
2722
|
+
const raw = JSON.parse((0, import_fs2.readFileSync)(path40, "utf-8"));
|
|
2723
|
+
if (!raw || !Array.isArray(raw.meshes)) return { meshes: [] };
|
|
2724
|
+
return raw;
|
|
2725
|
+
} catch {
|
|
2726
|
+
return { meshes: [] };
|
|
2727
|
+
}
|
|
2728
|
+
}
|
|
2729
|
+
function saveMeshConfig(config2) {
|
|
2730
|
+
const path40 = getMeshConfigPath();
|
|
2731
|
+
(0, import_fs2.writeFileSync)(path40, JSON.stringify(config2, null, 2), { encoding: "utf-8", mode: 384 });
|
|
2732
|
+
}
|
|
2733
|
+
function normalizeRepoIdentity(remoteUrl) {
|
|
2734
|
+
let identity = remoteUrl.trim();
|
|
2735
|
+
if (identity.startsWith("http://") || identity.startsWith("https://")) {
|
|
2736
|
+
try {
|
|
2737
|
+
const url2 = new URL(identity);
|
|
2738
|
+
const path40 = url2.pathname.replace(/^\//, "").replace(/\.git$/, "");
|
|
2739
|
+
return `${url2.hostname}/${path40}`;
|
|
2740
|
+
} catch {
|
|
2741
|
+
}
|
|
2742
|
+
}
|
|
2743
|
+
const sshMatch = identity.match(/^(?:ssh:\/\/)?[\w.-]+@([\w.-]+)[:/]([\w.\-/]+?)(?:\.git)?$/);
|
|
2744
|
+
if (sshMatch) return `${sshMatch[1]}/${sshMatch[2]}`;
|
|
2745
|
+
return identity;
|
|
2746
|
+
}
|
|
2747
|
+
function listMeshes() {
|
|
2748
|
+
return loadMeshConfig().meshes;
|
|
2749
|
+
}
|
|
2750
|
+
function getMesh(meshId) {
|
|
2751
|
+
return loadMeshConfig().meshes.find((m) => m.id === meshId);
|
|
2752
|
+
}
|
|
2753
|
+
function getMeshByRepo(repoIdentity) {
|
|
2754
|
+
return loadMeshConfig().meshes.find((m) => m.repoIdentity === repoIdentity);
|
|
2755
|
+
}
|
|
2756
|
+
function createMesh(opts) {
|
|
2757
|
+
const config2 = loadMeshConfig();
|
|
2758
|
+
if (config2.meshes.length >= 20) {
|
|
2759
|
+
throw new Error("Maximum 20 meshes allowed");
|
|
2760
|
+
}
|
|
2761
|
+
const repoIdentity = opts.repoIdentity || (opts.repoRemoteUrl ? normalizeRepoIdentity(opts.repoRemoteUrl) : "");
|
|
2762
|
+
if (!repoIdentity) throw new Error("Either repoRemoteUrl or repoIdentity is required");
|
|
2763
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2764
|
+
const mesh = {
|
|
2765
|
+
id: `mesh_${(0, import_crypto3.randomUUID)().replace(/-/g, "")}`,
|
|
2766
|
+
name: opts.name.trim().slice(0, 100),
|
|
2767
|
+
repoIdentity,
|
|
2768
|
+
repoRemoteUrl: opts.repoRemoteUrl,
|
|
2769
|
+
defaultBranch: opts.defaultBranch,
|
|
2770
|
+
policy: { ...DEFAULT_MESH_POLICY, ...opts.policy },
|
|
2771
|
+
coordinator: opts.coordinator || {},
|
|
2772
|
+
nodes: [],
|
|
2773
|
+
createdAt: now,
|
|
2774
|
+
updatedAt: now
|
|
2775
|
+
};
|
|
2776
|
+
config2.meshes.push(mesh);
|
|
2777
|
+
saveMeshConfig(config2);
|
|
2778
|
+
return mesh;
|
|
2779
|
+
}
|
|
2780
|
+
function updateMesh(meshId, opts) {
|
|
2781
|
+
const config2 = loadMeshConfig();
|
|
2782
|
+
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
2783
|
+
if (!mesh) return void 0;
|
|
2784
|
+
if (opts.name !== void 0) mesh.name = opts.name.trim().slice(0, 100);
|
|
2785
|
+
if (opts.defaultBranch !== void 0) mesh.defaultBranch = opts.defaultBranch;
|
|
2786
|
+
if (opts.policy) mesh.policy = { ...mesh.policy, ...opts.policy };
|
|
2787
|
+
if (opts.coordinator) mesh.coordinator = opts.coordinator;
|
|
2788
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2789
|
+
saveMeshConfig(config2);
|
|
2790
|
+
return mesh;
|
|
2791
|
+
}
|
|
2792
|
+
function deleteMesh(meshId) {
|
|
2793
|
+
const config2 = loadMeshConfig();
|
|
2794
|
+
const idx = config2.meshes.findIndex((m) => m.id === meshId);
|
|
2795
|
+
if (idx === -1) return false;
|
|
2796
|
+
config2.meshes.splice(idx, 1);
|
|
2797
|
+
saveMeshConfig(config2);
|
|
2798
|
+
return true;
|
|
2799
|
+
}
|
|
2800
|
+
function addNode(meshId, opts) {
|
|
2801
|
+
const config2 = loadMeshConfig();
|
|
2802
|
+
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
2803
|
+
if (!mesh) return void 0;
|
|
2804
|
+
if (mesh.nodes.length >= 10) {
|
|
2805
|
+
throw new Error("Maximum 10 nodes per mesh");
|
|
2806
|
+
}
|
|
2807
|
+
if (mesh.nodes.some((n) => n.workspace === opts.workspace)) {
|
|
2808
|
+
throw new Error("This workspace is already in the mesh");
|
|
2809
|
+
}
|
|
2810
|
+
const node = {
|
|
2811
|
+
id: `node_${(0, import_crypto3.randomUUID)().replace(/-/g, "")}`,
|
|
2812
|
+
workspace: opts.workspace.trim(),
|
|
2813
|
+
repoRoot: opts.repoRoot,
|
|
2814
|
+
userOverrides: opts.userOverrides || {},
|
|
2815
|
+
policy: opts.policy || {},
|
|
2816
|
+
isLocalWorktree: opts.isLocalWorktree
|
|
2817
|
+
};
|
|
2818
|
+
mesh.nodes.push(node);
|
|
2819
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2820
|
+
saveMeshConfig(config2);
|
|
2821
|
+
return node;
|
|
2822
|
+
}
|
|
2823
|
+
function removeNode(meshId, nodeId) {
|
|
2824
|
+
const config2 = loadMeshConfig();
|
|
2825
|
+
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
2826
|
+
if (!mesh) return false;
|
|
2827
|
+
const idx = mesh.nodes.findIndex((n) => n.id === nodeId);
|
|
2828
|
+
if (idx === -1) return false;
|
|
2829
|
+
mesh.nodes.splice(idx, 1);
|
|
2830
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2831
|
+
saveMeshConfig(config2);
|
|
2832
|
+
return true;
|
|
2833
|
+
}
|
|
2834
|
+
function updateNode(meshId, nodeId, opts) {
|
|
2835
|
+
const config2 = loadMeshConfig();
|
|
2836
|
+
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
2837
|
+
if (!mesh) return void 0;
|
|
2838
|
+
const node = mesh.nodes.find((n) => n.id === nodeId);
|
|
2839
|
+
if (!node) return void 0;
|
|
2840
|
+
if (opts.userOverrides) node.userOverrides = { ...node.userOverrides, ...opts.userOverrides };
|
|
2841
|
+
if (opts.policy) node.policy = { ...node.policy, ...opts.policy };
|
|
2842
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2843
|
+
saveMeshConfig(config2);
|
|
2844
|
+
return node;
|
|
2845
|
+
}
|
|
2846
|
+
var import_fs2, import_path2, import_crypto3;
|
|
2847
|
+
var init_mesh_config = __esm({
|
|
2848
|
+
"../../oss/packages/daemon-core/src/config/mesh-config.ts"() {
|
|
2849
|
+
"use strict";
|
|
2850
|
+
import_fs2 = require("fs");
|
|
2851
|
+
import_path2 = require("path");
|
|
2852
|
+
import_crypto3 = require("crypto");
|
|
2853
|
+
init_config();
|
|
2854
|
+
init_repo_mesh_types();
|
|
2855
|
+
}
|
|
2856
|
+
});
|
|
2857
|
+
|
|
2858
|
+
// ../../oss/packages/daemon-core/src/mesh/coordinator-prompt.ts
|
|
2859
|
+
var coordinator_prompt_exports = {};
|
|
2860
|
+
__export(coordinator_prompt_exports, {
|
|
2861
|
+
buildCoordinatorSystemPrompt: () => buildCoordinatorSystemPrompt
|
|
2862
|
+
});
|
|
2863
|
+
function buildCoordinatorSystemPrompt(ctx) {
|
|
2864
|
+
const { mesh, status, userInstruction } = ctx;
|
|
2865
|
+
const sections = [];
|
|
2866
|
+
sections.push(`You are a **Repo Mesh Coordinator** \u2014 a technical team lead who orchestrates work across multiple agent sessions on a shared Git repository.
|
|
2867
|
+
|
|
2868
|
+
Your mesh: **${mesh.name}**
|
|
2869
|
+
Repository: \`${mesh.repoIdentity}\`${mesh.defaultBranch ? `
|
|
2870
|
+
Default branch: \`${mesh.defaultBranch}\`` : ""}`);
|
|
2871
|
+
if (status?.nodes?.length) {
|
|
2872
|
+
sections.push(buildNodeStatusSection(status.nodes));
|
|
2873
|
+
} else if (mesh.nodes.length) {
|
|
2874
|
+
sections.push(buildNodeConfigSection(mesh));
|
|
2875
|
+
} else {
|
|
2876
|
+
sections.push("## Nodes\nNo nodes configured yet. Ask the user to add nodes with `adhdev mesh add-node`.");
|
|
2877
|
+
}
|
|
2878
|
+
sections.push(buildPolicySection(mesh.policy));
|
|
2879
|
+
sections.push(TOOLS_SECTION);
|
|
2880
|
+
sections.push(WORKFLOW_SECTION);
|
|
2881
|
+
sections.push(RULES_SECTION);
|
|
2882
|
+
if (userInstruction) {
|
|
2883
|
+
sections.push(`## Additional Context
|
|
2884
|
+
${userInstruction}`);
|
|
2885
|
+
}
|
|
2886
|
+
if (mesh.coordinator.systemPromptSuffix) {
|
|
2887
|
+
sections.push(mesh.coordinator.systemPromptSuffix);
|
|
2888
|
+
}
|
|
2889
|
+
return sections.join("\n\n");
|
|
2890
|
+
}
|
|
2891
|
+
function buildNodeStatusSection(nodes) {
|
|
2892
|
+
const lines = ["## Current Node Status", ""];
|
|
2893
|
+
for (const n of nodes) {
|
|
2894
|
+
const healthIcon = n.health === "online" ? "\u{1F7E2}" : n.health === "dirty" ? "\u{1F7E1}" : n.health === "offline" ? "\u26AB" : "\u{1F534}";
|
|
2895
|
+
const sessions = n.activeSessions.length > 0 ? `sessions: ${n.activeSessions.join(", ")}` : "no active sessions";
|
|
2896
|
+
const branch = n.git?.branch ? `branch: \`${n.git.branch}\`` : "";
|
|
2897
|
+
lines.push(`- ${healthIcon} **${n.machineLabel}** (${n.nodeId})`);
|
|
2898
|
+
lines.push(` workspace: \`${n.workspace}\` | ${branch} | ${sessions}`);
|
|
2899
|
+
if (n.error) lines.push(` \u26A0\uFE0F ${n.error}`);
|
|
2900
|
+
}
|
|
2901
|
+
return lines.join("\n");
|
|
2902
|
+
}
|
|
2903
|
+
function buildNodeConfigSection(mesh) {
|
|
2904
|
+
const lines = ["## Configured Nodes", ""];
|
|
2905
|
+
for (const n of mesh.nodes) {
|
|
2906
|
+
const labels = [];
|
|
2907
|
+
if (n.isLocalWorktree) labels.push("worktree");
|
|
2908
|
+
if (n.policy.readOnly) labels.push("read-only");
|
|
2909
|
+
const suffix = labels.length ? ` [${labels.join(", ")}]` : "";
|
|
2910
|
+
lines.push(`- **${n.workspace}** (${n.id})${suffix}`);
|
|
2911
|
+
}
|
|
2912
|
+
lines.push("", "_Use `mesh_status` to probe live health before delegating work._");
|
|
2913
|
+
return lines.join("\n");
|
|
2914
|
+
}
|
|
2915
|
+
function buildPolicySection(policy) {
|
|
2916
|
+
const rules = [];
|
|
2917
|
+
if (policy.requirePreTaskCheckpoint) rules.push("- Create a git checkpoint **before** starting each task");
|
|
2918
|
+
if (policy.requirePostTaskCheckpoint) rules.push("- Create a git checkpoint **after** each task completes");
|
|
2919
|
+
if (policy.requireApprovalForPush) rules.push("- **Ask for user approval** before pushing to remote");
|
|
2920
|
+
if (policy.requireApprovalForDestructiveGit) rules.push("- **Ask for user approval** before destructive git operations (force push, reset, etc.)");
|
|
2921
|
+
const dirtyBehavior = {
|
|
2922
|
+
block: "- **Do not** send tasks to nodes with dirty workspaces",
|
|
2923
|
+
warn: "- Warn the user if a node has uncommitted changes before sending a task",
|
|
2924
|
+
checkpoint_then_continue: "- Auto-checkpoint dirty nodes before sending tasks"
|
|
2925
|
+
}[policy.dirtyWorkspaceBehavior] || "";
|
|
2926
|
+
if (dirtyBehavior) rules.push(dirtyBehavior);
|
|
2927
|
+
rules.push(`- Maximum **${policy.maxParallelTasks}** tasks running in parallel`);
|
|
2928
|
+
return `## Policy
|
|
2929
|
+
${rules.join("\n")}`;
|
|
2930
|
+
}
|
|
2931
|
+
var TOOLS_SECTION, WORKFLOW_SECTION, RULES_SECTION;
|
|
2932
|
+
var init_coordinator_prompt = __esm({
|
|
2933
|
+
"../../oss/packages/daemon-core/src/mesh/coordinator-prompt.ts"() {
|
|
2934
|
+
"use strict";
|
|
2935
|
+
TOOLS_SECTION = `## Available Tools
|
|
2936
|
+
|
|
2937
|
+
| Tool | Purpose |
|
|
2938
|
+
|------|---------|
|
|
2939
|
+
| \`mesh_status\` | Check all nodes' health, git state, and active sessions |
|
|
2940
|
+
| \`mesh_list_nodes\` | List nodes with workspace paths |
|
|
2941
|
+
| \`mesh_launch_session\` | Start a new agent session on a node |
|
|
2942
|
+
| \`mesh_send_task\` | Send a task (natural language) to a running agent |
|
|
2943
|
+
| \`mesh_read_chat\` | Read an agent's recent messages to check progress |
|
|
2944
|
+
| \`mesh_git_status\` | Check git status on a specific node |
|
|
2945
|
+
| \`mesh_checkpoint\` | Create a git checkpoint on a node |
|
|
2946
|
+
| \`mesh_approve\` | Approve/reject a pending agent action |`;
|
|
2947
|
+
WORKFLOW_SECTION = `## Orchestration Workflow
|
|
2948
|
+
|
|
2949
|
+
1. **Assess** \u2014 Call \`mesh_status\` to see which nodes are healthy and available.
|
|
2950
|
+
2. **Plan** \u2014 Decompose the user's request into independent tasks for parallel execution, or sequential tasks when dependencies exist.
|
|
2951
|
+
3. **Delegate** \u2014 For each task:
|
|
2952
|
+
a. Pick the best node (consider: health, dirty state, current workload).
|
|
2953
|
+
b. If no session exists, call \`mesh_launch_session\` to start one.
|
|
2954
|
+
c. Call \`mesh_send_task\` with a clear, self-contained natural-language instruction.
|
|
2955
|
+
4. **Monitor** \u2014 Periodically call \`mesh_read_chat\` to check progress. Handle approvals via \`mesh_approve\`.
|
|
2956
|
+
5. **Verify** \u2014 When a task reports completion, call \`mesh_git_status\` to verify changes were made.
|
|
2957
|
+
6. **Checkpoint** \u2014 Call \`mesh_checkpoint\` to save the work.
|
|
2958
|
+
7. **Report** \u2014 Summarize what was done, what changed, and any issues.`;
|
|
2959
|
+
RULES_SECTION = `## Rules
|
|
2960
|
+
|
|
2961
|
+
- **Be conversational.** Delegate work the way a tech lead would \u2014 clear, specific instructions in natural language.
|
|
2962
|
+
- **Don't inspect code.** Trust the agent's output. Verify via git diff/status, not by reading source files.
|
|
2963
|
+
- **Don't over-parallelize.** Start with 1-2 concurrent tasks. Scale up if they succeed.
|
|
2964
|
+
- **Handle failures gracefully.** If a task fails, read the chat to understand why, then retry or reassign.
|
|
2965
|
+
- **Keep the user informed.** Report progress after each delegation round.
|
|
2966
|
+
- **Respect node capabilities.** Don't send build tasks to read-only nodes. Don't push from nodes that aren't allowed to.
|
|
2967
|
+
- **Never fabricate tool results.** Always call the actual tool; never pretend you did.`;
|
|
2968
|
+
}
|
|
2969
|
+
});
|
|
2970
|
+
|
|
2971
|
+
// ../../oss/packages/daemon-core/src/mesh/mesh-sync.ts
|
|
2972
|
+
async function syncMeshes(transport) {
|
|
2973
|
+
const result = { pushed: 0, pulled: 0, deleted: 0, errors: [] };
|
|
2974
|
+
let remoteMeshes;
|
|
2975
|
+
try {
|
|
2976
|
+
const res = await transport.listRemoteMeshes();
|
|
2977
|
+
remoteMeshes = res.meshes;
|
|
2978
|
+
} catch (e) {
|
|
2979
|
+
result.errors.push(`Failed to list remote meshes: ${e.message}`);
|
|
2980
|
+
return result;
|
|
2981
|
+
}
|
|
2982
|
+
const localMeshes = listMeshes();
|
|
2983
|
+
const remoteByIdentity = new Map(remoteMeshes.map((m) => [m.repo_identity, m]));
|
|
2984
|
+
const localByIdentity = new Map(localMeshes.map((m) => [m.repoIdentity, m]));
|
|
2985
|
+
for (const local of localMeshes) {
|
|
2986
|
+
if (!remoteByIdentity.has(local.repoIdentity)) {
|
|
2987
|
+
try {
|
|
2988
|
+
await transport.createRemoteMesh({
|
|
2989
|
+
name: local.name,
|
|
2990
|
+
repo_identity: local.repoIdentity,
|
|
2991
|
+
repo_remote_url: local.repoRemoteUrl,
|
|
2992
|
+
default_branch: local.defaultBranch,
|
|
2993
|
+
policy: JSON.stringify(local.policy)
|
|
2994
|
+
});
|
|
2995
|
+
result.pushed++;
|
|
2996
|
+
} catch (e) {
|
|
2997
|
+
result.errors.push(`Push failed for "${local.name}": ${e.message}`);
|
|
2998
|
+
}
|
|
2999
|
+
}
|
|
3000
|
+
}
|
|
3001
|
+
for (const remote of remoteMeshes) {
|
|
3002
|
+
if (!localByIdentity.has(remote.repo_identity)) {
|
|
3003
|
+
try {
|
|
3004
|
+
let policy;
|
|
3005
|
+
try {
|
|
3006
|
+
policy = JSON.parse(remote.policy);
|
|
3007
|
+
} catch {
|
|
3008
|
+
policy = void 0;
|
|
3009
|
+
}
|
|
3010
|
+
createMesh({
|
|
3011
|
+
name: remote.name,
|
|
3012
|
+
repoIdentity: remote.repo_identity,
|
|
3013
|
+
repoRemoteUrl: remote.repo_remote_url || void 0,
|
|
3014
|
+
defaultBranch: remote.default_branch || void 0,
|
|
3015
|
+
policy
|
|
3016
|
+
});
|
|
3017
|
+
result.pulled++;
|
|
3018
|
+
} catch (e) {
|
|
3019
|
+
result.errors.push(`Pull failed for "${remote.name}": ${e.message}`);
|
|
3020
|
+
}
|
|
3021
|
+
}
|
|
3022
|
+
}
|
|
3023
|
+
return result;
|
|
3024
|
+
}
|
|
3025
|
+
var init_mesh_sync = __esm({
|
|
3026
|
+
"../../oss/packages/daemon-core/src/mesh/mesh-sync.ts"() {
|
|
3027
|
+
"use strict";
|
|
3028
|
+
init_mesh_config();
|
|
3029
|
+
}
|
|
3030
|
+
});
|
|
3031
|
+
|
|
2685
3032
|
// ../../oss/packages/daemon-core/src/config/state-store.ts
|
|
2686
3033
|
function isPlainObject2(value) {
|
|
2687
3034
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
2688
3035
|
}
|
|
2689
3036
|
function getStatePath() {
|
|
2690
|
-
return (0,
|
|
3037
|
+
return (0, import_path3.join)(getConfigDir(), "state.json");
|
|
2691
3038
|
}
|
|
2692
3039
|
function normalizeState(raw) {
|
|
2693
3040
|
const parsed = isPlainObject2(raw) ? raw : {};
|
|
@@ -2723,11 +3070,11 @@ function normalizeState(raw) {
|
|
|
2723
3070
|
}
|
|
2724
3071
|
function loadState() {
|
|
2725
3072
|
const statePath = getStatePath();
|
|
2726
|
-
if (!(0,
|
|
3073
|
+
if (!(0, import_fs3.existsSync)(statePath)) {
|
|
2727
3074
|
return { ...DEFAULT_STATE };
|
|
2728
3075
|
}
|
|
2729
3076
|
try {
|
|
2730
|
-
const raw = (0,
|
|
3077
|
+
const raw = (0, import_fs3.readFileSync)(statePath, "utf-8");
|
|
2731
3078
|
return normalizeState(JSON.parse(raw));
|
|
2732
3079
|
} catch {
|
|
2733
3080
|
return { ...DEFAULT_STATE };
|
|
@@ -2736,17 +3083,17 @@ function loadState() {
|
|
|
2736
3083
|
function saveState(state) {
|
|
2737
3084
|
const statePath = getStatePath();
|
|
2738
3085
|
const normalized = normalizeState(state);
|
|
2739
|
-
(0,
|
|
3086
|
+
(0, import_fs3.writeFileSync)(statePath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
|
|
2740
3087
|
}
|
|
2741
3088
|
function resetState() {
|
|
2742
3089
|
saveState({ ...DEFAULT_STATE });
|
|
2743
3090
|
}
|
|
2744
|
-
var
|
|
3091
|
+
var import_fs3, import_path3, DEFAULT_STATE;
|
|
2745
3092
|
var init_state_store = __esm({
|
|
2746
3093
|
"../../oss/packages/daemon-core/src/config/state-store.ts"() {
|
|
2747
3094
|
"use strict";
|
|
2748
|
-
|
|
2749
|
-
|
|
3095
|
+
import_fs3 = require("fs");
|
|
3096
|
+
import_path3 = require("path");
|
|
2750
3097
|
init_config();
|
|
2751
3098
|
DEFAULT_STATE = {
|
|
2752
3099
|
recentActivity: [],
|
|
@@ -2779,7 +3126,7 @@ function findCliCommand(command) {
|
|
|
2779
3126
|
if (path7.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
|
|
2780
3127
|
const candidate = trimmed.startsWith("~") ? path7.join((0, import_os2.homedir)(), trimmed.slice(1)) : trimmed;
|
|
2781
3128
|
const resolved = path7.isAbsolute(candidate) ? candidate : path7.resolve(candidate);
|
|
2782
|
-
return (0,
|
|
3129
|
+
return (0, import_fs4.existsSync)(resolved) ? resolved : null;
|
|
2783
3130
|
}
|
|
2784
3131
|
try {
|
|
2785
3132
|
const result = (0, import_child_process.execSync)(
|
|
@@ -2810,9 +3157,9 @@ function checkPathExists(paths) {
|
|
|
2810
3157
|
if (normalized.includes("*")) {
|
|
2811
3158
|
const username = home.split(/[\\/]/).pop() || "";
|
|
2812
3159
|
const resolved = normalized.replace("*", username);
|
|
2813
|
-
if ((0,
|
|
3160
|
+
if ((0, import_fs4.existsSync)(resolved)) return resolved;
|
|
2814
3161
|
} else {
|
|
2815
|
-
if ((0,
|
|
3162
|
+
if ((0, import_fs4.existsSync)(normalized)) return normalized;
|
|
2816
3163
|
}
|
|
2817
3164
|
}
|
|
2818
3165
|
return null;
|
|
@@ -2826,7 +3173,7 @@ async function detectIDEs(providerLoader) {
|
|
|
2826
3173
|
let resolvedCli = cliPath;
|
|
2827
3174
|
if (!resolvedCli && appPath && os31 === "darwin") {
|
|
2828
3175
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
2829
|
-
if ((0,
|
|
3176
|
+
if ((0, import_fs4.existsSync)(bundledCli)) resolvedCli = bundledCli;
|
|
2830
3177
|
}
|
|
2831
3178
|
if (!resolvedCli && appPath && os31 === "win32") {
|
|
2832
3179
|
const { dirname: dirname11 } = await import("path");
|
|
@@ -2839,7 +3186,7 @@ async function detectIDEs(providerLoader) {
|
|
|
2839
3186
|
`${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
|
|
2840
3187
|
];
|
|
2841
3188
|
for (const c of candidates) {
|
|
2842
|
-
if ((0,
|
|
3189
|
+
if ((0, import_fs4.existsSync)(c)) {
|
|
2843
3190
|
resolvedCli = c;
|
|
2844
3191
|
break;
|
|
2845
3192
|
}
|
|
@@ -2860,12 +3207,12 @@ async function detectIDEs(providerLoader) {
|
|
|
2860
3207
|
}
|
|
2861
3208
|
return results;
|
|
2862
3209
|
}
|
|
2863
|
-
var import_child_process,
|
|
3210
|
+
var import_child_process, import_fs4, import_os2, path7, BUILTIN_IDE_DEFINITIONS, registeredIDEs;
|
|
2864
3211
|
var init_ide_detector = __esm({
|
|
2865
3212
|
"../../oss/packages/daemon-core/src/detection/ide-detector.ts"() {
|
|
2866
3213
|
"use strict";
|
|
2867
3214
|
import_child_process = require("child_process");
|
|
2868
|
-
|
|
3215
|
+
import_fs4 = require("fs");
|
|
2869
3216
|
import_os2 = require("os");
|
|
2870
3217
|
path7 = __toESM(require("path"));
|
|
2871
3218
|
BUILTIN_IDE_DEFINITIONS = [];
|
|
@@ -2897,7 +3244,7 @@ function resolveCommandPath(command) {
|
|
|
2897
3244
|
if (isExplicitCommandPath(trimmed)) {
|
|
2898
3245
|
const expanded = expandHome(trimmed);
|
|
2899
3246
|
const candidate = path8.isAbsolute(expanded) ? expanded : path8.resolve(expanded);
|
|
2900
|
-
return (0,
|
|
3247
|
+
return (0, import_fs5.existsSync)(candidate) ? candidate : null;
|
|
2901
3248
|
}
|
|
2902
3249
|
return null;
|
|
2903
3250
|
}
|
|
@@ -2997,14 +3344,14 @@ async function detectCLI(cliId, providerLoader, options) {
|
|
|
2997
3344
|
const all = await detectCLIs(providerLoader, options);
|
|
2998
3345
|
return all.find((c) => c.id === resolvedId && c.installed) || null;
|
|
2999
3346
|
}
|
|
3000
|
-
var import_child_process2, os3, path8,
|
|
3347
|
+
var import_child_process2, os3, path8, import_fs5;
|
|
3001
3348
|
var init_cli_detector = __esm({
|
|
3002
3349
|
"../../oss/packages/daemon-core/src/detection/cli-detector.ts"() {
|
|
3003
3350
|
"use strict";
|
|
3004
3351
|
import_child_process2 = require("child_process");
|
|
3005
3352
|
os3 = __toESM(require("os"));
|
|
3006
3353
|
path8 = __toESM(require("path"));
|
|
3007
|
-
|
|
3354
|
+
import_fs5 = require("fs");
|
|
3008
3355
|
}
|
|
3009
3356
|
});
|
|
3010
3357
|
|
|
@@ -13173,16 +13520,16 @@ function ensureNodePtySpawnHelperPermissions(logFn) {
|
|
|
13173
13520
|
} catch {
|
|
13174
13521
|
}
|
|
13175
13522
|
}
|
|
13176
|
-
var
|
|
13523
|
+
var import_crypto4, path13, os10, path22, net, import_crypto5, os22, path32, __require, DEFAULT_SESSION_RING_BUFFER_MAX_BYTES, SessionRingBuffer, DEFAULT_SESSION_HOST_COLS, DEFAULT_SESSION_HOST_ROWS, LIVE_LIFECYCLES2, SessionHostRegistry, SessionHostClient;
|
|
13177
13524
|
var init_dist = __esm({
|
|
13178
13525
|
"../../oss/packages/session-host-core/dist/index.mjs"() {
|
|
13179
13526
|
"use strict";
|
|
13180
|
-
|
|
13527
|
+
import_crypto4 = require("crypto");
|
|
13181
13528
|
path13 = __toESM(require("path"), 1);
|
|
13182
13529
|
os10 = __toESM(require("os"), 1);
|
|
13183
13530
|
path22 = __toESM(require("path"), 1);
|
|
13184
13531
|
net = __toESM(require("net"), 1);
|
|
13185
|
-
|
|
13532
|
+
import_crypto5 = require("crypto");
|
|
13186
13533
|
os22 = __toESM(require("os"), 1);
|
|
13187
13534
|
path32 = __toESM(require("path"), 1);
|
|
13188
13535
|
__require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
@@ -13258,7 +13605,7 @@ var init_dist = __esm({
|
|
|
13258
13605
|
SessionHostRegistry = class {
|
|
13259
13606
|
sessions = /* @__PURE__ */ new Map();
|
|
13260
13607
|
createSession(payload) {
|
|
13261
|
-
const sessionId = payload.sessionId || (0,
|
|
13608
|
+
const sessionId = payload.sessionId || (0, import_crypto4.randomUUID)();
|
|
13262
13609
|
if (this.sessions.has(sessionId)) {
|
|
13263
13610
|
throw new Error(`Session already exists: ${sessionId}`);
|
|
13264
13611
|
}
|
|
@@ -13529,7 +13876,7 @@ var init_dist = __esm({
|
|
|
13529
13876
|
async request(request) {
|
|
13530
13877
|
await this.connect();
|
|
13531
13878
|
if (!this.socket) throw new Error("Session host socket unavailable");
|
|
13532
|
-
const requestId = (0,
|
|
13879
|
+
const requestId = (0, import_crypto5.randomUUID)();
|
|
13533
13880
|
const envelope = {
|
|
13534
13881
|
kind: "request",
|
|
13535
13882
|
requestId,
|
|
@@ -34565,7 +34912,7 @@ function commandExists(command) {
|
|
|
34565
34912
|
const trimmed = command.trim();
|
|
34566
34913
|
if (!trimmed) return false;
|
|
34567
34914
|
if (isExplicitCommand(trimmed)) {
|
|
34568
|
-
return (0,
|
|
34915
|
+
return (0, import_fs6.existsSync)(expandExecutable(trimmed));
|
|
34569
34916
|
}
|
|
34570
34917
|
try {
|
|
34571
34918
|
(0, import_child_process6.execFileSync)(process.platform === "win32" ? "where" : "which", [trimmed], {
|
|
@@ -34696,14 +35043,14 @@ function resolveCliSessionBinding(provider, normalizedType, cliArgs, requestedRe
|
|
|
34696
35043
|
launchMode: "new"
|
|
34697
35044
|
};
|
|
34698
35045
|
}
|
|
34699
|
-
var os16, path17, crypto4,
|
|
35046
|
+
var os16, path17, crypto4, import_fs6, import_child_process6, chalkModule, chalkApi, DaemonCliManager;
|
|
34700
35047
|
var init_cli_manager = __esm({
|
|
34701
35048
|
"../../oss/packages/daemon-core/src/commands/cli-manager.ts"() {
|
|
34702
35049
|
"use strict";
|
|
34703
35050
|
os16 = __toESM(require("os"));
|
|
34704
35051
|
path17 = __toESM(require("path"));
|
|
34705
35052
|
crypto4 = __toESM(require("crypto"));
|
|
34706
|
-
|
|
35053
|
+
import_fs6 = require("fs");
|
|
34707
35054
|
import_child_process6 = require("child_process");
|
|
34708
35055
|
init_source2();
|
|
34709
35056
|
init_provider_cli_adapter();
|
|
@@ -38271,7 +38618,7 @@ var init_provider_loader = __esm({
|
|
|
38271
38618
|
return { updated: false };
|
|
38272
38619
|
}
|
|
38273
38620
|
const https = require("https");
|
|
38274
|
-
const { execSync:
|
|
38621
|
+
const { execSync: execSync9 } = require("child_process");
|
|
38275
38622
|
const metaPath = path18.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
38276
38623
|
let prevEtag = "";
|
|
38277
38624
|
let prevTimestamp = 0;
|
|
@@ -38336,7 +38683,7 @@ var init_provider_loader = __esm({
|
|
|
38336
38683
|
const tmpExtract = path18.join(os17.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
|
|
38337
38684
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
38338
38685
|
fs7.mkdirSync(tmpExtract, { recursive: true });
|
|
38339
|
-
|
|
38686
|
+
execSync9(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
38340
38687
|
const extracted = fs7.readdirSync(tmpExtract);
|
|
38341
38688
|
const rootDir = extracted.find(
|
|
38342
38689
|
(d) => fs7.statSync(path18.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
|
|
@@ -40921,6 +41268,142 @@ var init_router = __esm({
|
|
|
40921
41268
|
updateConfig({ machineNickname: nickname || null });
|
|
40922
41269
|
return { success: true };
|
|
40923
41270
|
}
|
|
41271
|
+
// ─── Mesh CRUD (local meshes.json) ───
|
|
41272
|
+
case "list_meshes": {
|
|
41273
|
+
try {
|
|
41274
|
+
const { listMeshes: listMeshes2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
41275
|
+
return { success: true, meshes: listMeshes2() };
|
|
41276
|
+
} catch (e) {
|
|
41277
|
+
return { success: false, error: e.message };
|
|
41278
|
+
}
|
|
41279
|
+
}
|
|
41280
|
+
case "get_mesh": {
|
|
41281
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
41282
|
+
if (!meshId) return { success: false, error: "meshId required" };
|
|
41283
|
+
try {
|
|
41284
|
+
const { getMesh: getMesh3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
41285
|
+
const mesh = getMesh3(meshId);
|
|
41286
|
+
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
41287
|
+
return { success: true, mesh };
|
|
41288
|
+
} catch (e) {
|
|
41289
|
+
return { success: false, error: e.message };
|
|
41290
|
+
}
|
|
41291
|
+
}
|
|
41292
|
+
case "create_mesh": {
|
|
41293
|
+
const name = typeof args?.name === "string" ? args.name.trim() : "";
|
|
41294
|
+
const repoIdentity = typeof args?.repoIdentity === "string" ? args.repoIdentity.trim() : "";
|
|
41295
|
+
const repoRemoteUrl = typeof args?.repoRemoteUrl === "string" ? args.repoRemoteUrl.trim() : void 0;
|
|
41296
|
+
const defaultBranch = typeof args?.defaultBranch === "string" ? args.defaultBranch.trim() : void 0;
|
|
41297
|
+
if (!name) return { success: false, error: "name required" };
|
|
41298
|
+
try {
|
|
41299
|
+
const { createMesh: createMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
41300
|
+
const mesh = createMesh2({ name, repoIdentity, repoRemoteUrl, defaultBranch });
|
|
41301
|
+
return { success: true, mesh };
|
|
41302
|
+
} catch (e) {
|
|
41303
|
+
return { success: false, error: e.message };
|
|
41304
|
+
}
|
|
41305
|
+
}
|
|
41306
|
+
case "delete_mesh": {
|
|
41307
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
41308
|
+
if (!meshId) return { success: false, error: "meshId required" };
|
|
41309
|
+
try {
|
|
41310
|
+
const { deleteMesh: deleteMesh3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
41311
|
+
const deleted = deleteMesh3(meshId);
|
|
41312
|
+
return { success: true, deleted };
|
|
41313
|
+
} catch (e) {
|
|
41314
|
+
return { success: false, error: e.message };
|
|
41315
|
+
}
|
|
41316
|
+
}
|
|
41317
|
+
case "add_mesh_node": {
|
|
41318
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
41319
|
+
const workspace = typeof args?.workspace === "string" ? args.workspace.trim() : "";
|
|
41320
|
+
if (!meshId) return { success: false, error: "meshId required" };
|
|
41321
|
+
if (!workspace) return { success: false, error: "workspace required" };
|
|
41322
|
+
try {
|
|
41323
|
+
const { addNode: addNode3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
41324
|
+
const node = addNode3(meshId, { workspace });
|
|
41325
|
+
if (!node) return { success: false, error: "Mesh not found" };
|
|
41326
|
+
return { success: true, node };
|
|
41327
|
+
} catch (e) {
|
|
41328
|
+
return { success: false, error: e.message };
|
|
41329
|
+
}
|
|
41330
|
+
}
|
|
41331
|
+
case "remove_mesh_node": {
|
|
41332
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
41333
|
+
const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
|
|
41334
|
+
if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
|
|
41335
|
+
try {
|
|
41336
|
+
const { removeNode: removeNode3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
41337
|
+
const removed = removeNode3(meshId, nodeId);
|
|
41338
|
+
return { success: true, removed };
|
|
41339
|
+
} catch (e) {
|
|
41340
|
+
return { success: false, error: e.message };
|
|
41341
|
+
}
|
|
41342
|
+
}
|
|
41343
|
+
// ─── Mesh Coordinator Launch ───
|
|
41344
|
+
case "launch_mesh_coordinator": {
|
|
41345
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
41346
|
+
const cliType = typeof args?.cliType === "string" ? args.cliType.trim() : "claude-cli";
|
|
41347
|
+
if (!meshId) return { success: false, error: "meshId required" };
|
|
41348
|
+
try {
|
|
41349
|
+
const { getMesh: getMesh3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
41350
|
+
const { buildCoordinatorSystemPrompt: buildCoordinatorSystemPrompt2 } = await Promise.resolve().then(() => (init_coordinator_prompt(), coordinator_prompt_exports));
|
|
41351
|
+
const mesh = getMesh3(meshId);
|
|
41352
|
+
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
41353
|
+
if (mesh.nodes.length === 0) return { success: false, error: "No nodes in mesh" };
|
|
41354
|
+
const workspace = mesh.nodes[0].workspace;
|
|
41355
|
+
const { existsSync: existsSync28, readFileSync: readFileSync21, writeFileSync: writeFileSync15, copyFileSync: copyFileSync4 } = await import("fs");
|
|
41356
|
+
const { join: join35 } = await import("path");
|
|
41357
|
+
const mcpConfigPath = join35(workspace, ".mcp.json");
|
|
41358
|
+
const hadExistingMcpConfig = existsSync28(mcpConfigPath);
|
|
41359
|
+
let existingMcpConfig = {};
|
|
41360
|
+
if (hadExistingMcpConfig) {
|
|
41361
|
+
try {
|
|
41362
|
+
existingMcpConfig = JSON.parse(readFileSync21(mcpConfigPath, "utf-8"));
|
|
41363
|
+
copyFileSync4(mcpConfigPath, mcpConfigPath + ".backup");
|
|
41364
|
+
} catch {
|
|
41365
|
+
}
|
|
41366
|
+
}
|
|
41367
|
+
const mcpConfig = {
|
|
41368
|
+
...existingMcpConfig,
|
|
41369
|
+
mcpServers: {
|
|
41370
|
+
...existingMcpConfig.mcpServers || {},
|
|
41371
|
+
"adhdev-mesh": {
|
|
41372
|
+
command: "adhdev-mcp",
|
|
41373
|
+
args: ["--repo-mesh", meshId]
|
|
41374
|
+
}
|
|
41375
|
+
}
|
|
41376
|
+
};
|
|
41377
|
+
writeFileSync15(mcpConfigPath, JSON.stringify(mcpConfig, null, 2), "utf-8");
|
|
41378
|
+
LOG.info("MeshCoordinator", `Wrote .mcp.json to ${workspace} with adhdev-mesh server`);
|
|
41379
|
+
let systemPrompt = "";
|
|
41380
|
+
try {
|
|
41381
|
+
systemPrompt = buildCoordinatorSystemPrompt2({ mesh });
|
|
41382
|
+
} catch {
|
|
41383
|
+
systemPrompt = `You are a Repo Mesh Coordinator for "${mesh.name}". Use the adhdev-mesh MCP tools (mesh_status, mesh_list_nodes, mesh_send_task, mesh_read_chat, mesh_launch_session, etc.) to orchestrate work across ${mesh.nodes.length} node(s).`;
|
|
41384
|
+
}
|
|
41385
|
+
const launchResult = await this.deps.cliManager.handleCliCommand("launch_cli", {
|
|
41386
|
+
cliType,
|
|
41387
|
+
dir: workspace,
|
|
41388
|
+
initialPrompt: systemPrompt
|
|
41389
|
+
});
|
|
41390
|
+
if (!launchResult?.success) {
|
|
41391
|
+
return { success: false, error: launchResult?.error || "Failed to launch CLI session" };
|
|
41392
|
+
}
|
|
41393
|
+
LOG.info("MeshCoordinator", `Launched ${cliType} coordinator for mesh ${meshId} in ${workspace}`);
|
|
41394
|
+
return {
|
|
41395
|
+
success: true,
|
|
41396
|
+
meshId,
|
|
41397
|
+
cliType,
|
|
41398
|
+
workspace,
|
|
41399
|
+
sessionId: launchResult.sessionId || launchResult.id,
|
|
41400
|
+
mcpConfigWritten: true
|
|
41401
|
+
};
|
|
41402
|
+
} catch (e) {
|
|
41403
|
+
LOG.error("MeshCoordinator", `Failed: ${e.message}`);
|
|
41404
|
+
return { success: false, error: e.message };
|
|
41405
|
+
}
|
|
41406
|
+
}
|
|
40924
41407
|
default:
|
|
40925
41408
|
break;
|
|
40926
41409
|
}
|
|
@@ -49059,6 +49542,7 @@ __export(src_exports, {
|
|
|
49059
49542
|
DEFAULT_DAEMON_PORT: () => DEFAULT_DAEMON_PORT,
|
|
49060
49543
|
DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS: () => DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS,
|
|
49061
49544
|
DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS: () => DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS,
|
|
49545
|
+
DEFAULT_MESH_POLICY: () => DEFAULT_MESH_POLICY,
|
|
49062
49546
|
DEFAULT_SESSION_HOST_APP_NAME: () => DEFAULT_SESSION_HOST_APP_NAME,
|
|
49063
49547
|
DEFAULT_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS: () => DEFAULT_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS,
|
|
49064
49548
|
DEFAULT_SESSION_HOST_READY_TIMEOUT_MS: () => DEFAULT_SESSION_HOST_READY_TIMEOUT_MS,
|
|
@@ -49092,11 +49576,13 @@ __export(src_exports, {
|
|
|
49092
49576
|
SessionHostPtyTransportFactory: () => SessionHostPtyTransportFactory,
|
|
49093
49577
|
TurnSnapshotTracker: () => TurnSnapshotTracker,
|
|
49094
49578
|
VersionArchive: () => VersionArchive,
|
|
49579
|
+
addNode: () => addNode,
|
|
49095
49580
|
appendRecentActivity: () => appendRecentActivity,
|
|
49096
49581
|
buildAssistantChatMessage: () => buildAssistantChatMessage,
|
|
49097
49582
|
buildChatMessage: () => buildChatMessage,
|
|
49098
49583
|
buildChatMessageSignature: () => buildChatMessageSignature,
|
|
49099
49584
|
buildChatTailDeliverySignature: () => buildChatTailDeliverySignature,
|
|
49585
|
+
buildCoordinatorSystemPrompt: () => buildCoordinatorSystemPrompt,
|
|
49100
49586
|
buildMachineInfo: () => buildMachineInfo,
|
|
49101
49587
|
buildPinnedGlobalInstallCommand: () => buildPinnedGlobalInstallCommand,
|
|
49102
49588
|
buildRuntimeSystemChatMessage: () => buildRuntimeSystemChatMessage,
|
|
@@ -49119,6 +49605,8 @@ __export(src_exports, {
|
|
|
49119
49605
|
createGitSnapshotStore: () => createGitSnapshotStore,
|
|
49120
49606
|
createGitWorkspaceMonitor: () => createGitWorkspaceMonitor,
|
|
49121
49607
|
createInteractionId: () => createInteractionId,
|
|
49608
|
+
createMesh: () => createMesh,
|
|
49609
|
+
deleteMesh: () => deleteMesh,
|
|
49122
49610
|
detectAllVersions: () => detectAllVersions,
|
|
49123
49611
|
detectCLIs: () => detectCLIs,
|
|
49124
49612
|
detectIDEs: () => detectIDEs,
|
|
@@ -49137,6 +49625,8 @@ __export(src_exports, {
|
|
|
49137
49625
|
getGitRepoStatus: () => getGitRepoStatus,
|
|
49138
49626
|
getHostMemorySnapshot: () => getHostMemorySnapshot,
|
|
49139
49627
|
getLogLevel: () => getLogLevel,
|
|
49628
|
+
getMesh: () => getMesh,
|
|
49629
|
+
getMeshByRepo: () => getMeshByRepo,
|
|
49140
49630
|
getNpmExecOptions: () => getNpmExecOptions,
|
|
49141
49631
|
getRecentActivity: () => getRecentActivity,
|
|
49142
49632
|
getRecentCommands: () => getRecentCommands,
|
|
@@ -49167,6 +49657,7 @@ __export(src_exports, {
|
|
|
49167
49657
|
launchIDE: () => launchIDE,
|
|
49168
49658
|
launchWithCdp: () => launchWithCdp,
|
|
49169
49659
|
listHostedCliRuntimes: () => listHostedCliRuntimes,
|
|
49660
|
+
listMeshes: () => listMeshes,
|
|
49170
49661
|
loadConfig: () => loadConfig,
|
|
49171
49662
|
loadState: () => loadState,
|
|
49172
49663
|
logCommand: () => logCommand,
|
|
@@ -49182,6 +49673,7 @@ __export(src_exports, {
|
|
|
49182
49673
|
normalizeInputEnvelope: () => normalizeInputEnvelope,
|
|
49183
49674
|
normalizeManagedStatus: () => normalizeManagedStatus,
|
|
49184
49675
|
normalizeMessageParts: () => normalizeMessageParts,
|
|
49676
|
+
normalizeRepoIdentity: () => normalizeRepoIdentity,
|
|
49185
49677
|
normalizeSessionModalFields: () => normalizeSessionModalFields,
|
|
49186
49678
|
parsePorcelainV2Status: () => parsePorcelainV2Status,
|
|
49187
49679
|
parseProviderSourceConfigUpdate: () => parseProviderSourceConfigUpdate,
|
|
@@ -49193,6 +49685,7 @@ __export(src_exports, {
|
|
|
49193
49685
|
readChatHistory: () => readChatHistory,
|
|
49194
49686
|
recordDebugTrace: () => recordDebugTrace,
|
|
49195
49687
|
registerExtensionProviders: () => registerExtensionProviders,
|
|
49688
|
+
removeNode: () => removeNode,
|
|
49196
49689
|
resetConfig: () => resetConfig,
|
|
49197
49690
|
resetDebugRuntimeConfig: () => resetDebugRuntimeConfig,
|
|
49198
49691
|
resetState: () => resetState,
|
|
@@ -49215,17 +49708,24 @@ __export(src_exports, {
|
|
|
49215
49708
|
spawnDetachedDaemonUpgradeHelper: () => spawnDetachedDaemonUpgradeHelper,
|
|
49216
49709
|
startDaemonDevSupport: () => startDaemonDevSupport,
|
|
49217
49710
|
summarizeGitStatus: () => summarizeGitStatus,
|
|
49711
|
+
syncMeshes: () => syncMeshes,
|
|
49218
49712
|
updateConfig: () => updateConfig,
|
|
49713
|
+
updateMesh: () => updateMesh,
|
|
49714
|
+
updateNode: () => updateNode,
|
|
49219
49715
|
upsertSavedProviderSession: () => upsertSavedProviderSession
|
|
49220
49716
|
});
|
|
49221
49717
|
var init_src = __esm({
|
|
49222
49718
|
"../../oss/packages/daemon-core/src/index.ts"() {
|
|
49223
49719
|
"use strict";
|
|
49720
|
+
init_repo_mesh_types();
|
|
49224
49721
|
init_git();
|
|
49225
49722
|
init_config();
|
|
49226
49723
|
init_workspaces();
|
|
49227
49724
|
init_recent_activity();
|
|
49228
49725
|
init_saved_sessions();
|
|
49726
|
+
init_mesh_config();
|
|
49727
|
+
init_coordinator_prompt();
|
|
49728
|
+
init_mesh_sync();
|
|
49229
49729
|
init_state_store();
|
|
49230
49730
|
init_ide_detector();
|
|
49231
49731
|
init_cli_detector();
|
|
@@ -64071,7 +64571,7 @@ var require_buffer_list = __commonJS({
|
|
|
64071
64571
|
}
|
|
64072
64572
|
}, {
|
|
64073
64573
|
key: "join",
|
|
64074
|
-
value: function
|
|
64574
|
+
value: function join35(s) {
|
|
64075
64575
|
if (this.length === 0) return "";
|
|
64076
64576
|
var p = this.head;
|
|
64077
64577
|
var ret = "" + p.data;
|
|
@@ -78130,13 +78630,13 @@ function splitStringBySpace(str) {
|
|
|
78130
78630
|
}
|
|
78131
78631
|
return pieces;
|
|
78132
78632
|
}
|
|
78133
|
-
var import_chardet, import_child_process12,
|
|
78633
|
+
var import_chardet, import_child_process12, import_fs7, import_node_path2, import_node_os4, import_node_crypto2, import_iconv_lite, ExternalEditor;
|
|
78134
78634
|
var init_esm2 = __esm({
|
|
78135
78635
|
"../../node_modules/@inquirer/external-editor/dist/esm/index.js"() {
|
|
78136
78636
|
"use strict";
|
|
78137
78637
|
import_chardet = __toESM(require_lib(), 1);
|
|
78138
78638
|
import_child_process12 = require("child_process");
|
|
78139
|
-
|
|
78639
|
+
import_fs7 = require("fs");
|
|
78140
78640
|
import_node_path2 = __toESM(require("path"), 1);
|
|
78141
78641
|
import_node_os4 = __toESM(require("os"), 1);
|
|
78142
78642
|
import_node_crypto2 = require("crypto");
|
|
@@ -78212,14 +78712,14 @@ var init_esm2 = __esm({
|
|
|
78212
78712
|
if (Object.prototype.hasOwnProperty.call(this.fileOptions, "mode")) {
|
|
78213
78713
|
opt.mode = this.fileOptions.mode;
|
|
78214
78714
|
}
|
|
78215
|
-
(0,
|
|
78715
|
+
(0, import_fs7.writeFileSync)(this.tempFile, this.text, opt);
|
|
78216
78716
|
} catch (createFileError) {
|
|
78217
78717
|
throw new CreateFileError(createFileError);
|
|
78218
78718
|
}
|
|
78219
78719
|
}
|
|
78220
78720
|
readTemporaryFile() {
|
|
78221
78721
|
try {
|
|
78222
|
-
const tempFileBuffer = (0,
|
|
78722
|
+
const tempFileBuffer = (0, import_fs7.readFileSync)(this.tempFile);
|
|
78223
78723
|
if (tempFileBuffer.length === 0) {
|
|
78224
78724
|
this.text = "";
|
|
78225
78725
|
} else {
|
|
@@ -78235,7 +78735,7 @@ var init_esm2 = __esm({
|
|
|
78235
78735
|
}
|
|
78236
78736
|
removeTemporaryFile() {
|
|
78237
78737
|
try {
|
|
78238
|
-
(0,
|
|
78738
|
+
(0, import_fs7.unlinkSync)(this.tempFile);
|
|
78239
78739
|
} catch (removeFileError) {
|
|
78240
78740
|
throw new RemoveFileError(removeFileError);
|
|
78241
78741
|
}
|
|
@@ -79937,25 +80437,25 @@ function resolvePackageVersion(options) {
|
|
|
79937
80437
|
const injectedVersion = options?.injectedVersion || "unknown";
|
|
79938
80438
|
const dir = options?.dirname || __dirname;
|
|
79939
80439
|
const possiblePaths = [
|
|
79940
|
-
(0,
|
|
79941
|
-
(0,
|
|
79942
|
-
(0,
|
|
80440
|
+
(0, import_path4.join)(dir, "..", "..", "package.json"),
|
|
80441
|
+
(0, import_path4.join)(dir, "..", "package.json"),
|
|
80442
|
+
(0, import_path4.join)(dir, "package.json")
|
|
79943
80443
|
];
|
|
79944
80444
|
for (const p of possiblePaths) {
|
|
79945
80445
|
try {
|
|
79946
|
-
const data = JSON.parse((0,
|
|
80446
|
+
const data = JSON.parse((0, import_fs8.readFileSync)(p, "utf-8"));
|
|
79947
80447
|
if (data.version) return data.version;
|
|
79948
80448
|
} catch {
|
|
79949
80449
|
}
|
|
79950
80450
|
}
|
|
79951
80451
|
return injectedVersion;
|
|
79952
80452
|
}
|
|
79953
|
-
var
|
|
80453
|
+
var import_fs8, import_path4;
|
|
79954
80454
|
var init_version = __esm({
|
|
79955
80455
|
"src/version.ts"() {
|
|
79956
80456
|
"use strict";
|
|
79957
|
-
|
|
79958
|
-
|
|
80457
|
+
import_fs8 = require("fs");
|
|
80458
|
+
import_path4 = require("path");
|
|
79959
80459
|
}
|
|
79960
80460
|
});
|
|
79961
80461
|
|
|
@@ -81873,7 +82373,7 @@ var require_filesystem = __commonJS({
|
|
|
81873
82373
|
var LDD_PATH = "/usr/bin/ldd";
|
|
81874
82374
|
var SELF_PATH = "/proc/self/exe";
|
|
81875
82375
|
var MAX_LENGTH = 2048;
|
|
81876
|
-
var
|
|
82376
|
+
var readFileSync21 = (path40) => {
|
|
81877
82377
|
const fd = fs24.openSync(path40, "r");
|
|
81878
82378
|
const buffer = Buffer.alloc(MAX_LENGTH);
|
|
81879
82379
|
const bytesRead = fs24.readSync(fd, buffer, 0, MAX_LENGTH, 0);
|
|
@@ -81898,7 +82398,7 @@ var require_filesystem = __commonJS({
|
|
|
81898
82398
|
module2.exports = {
|
|
81899
82399
|
LDD_PATH,
|
|
81900
82400
|
SELF_PATH,
|
|
81901
|
-
readFileSync:
|
|
82401
|
+
readFileSync: readFileSync21,
|
|
81902
82402
|
readFile: readFile2
|
|
81903
82403
|
};
|
|
81904
82404
|
}
|
|
@@ -81947,7 +82447,7 @@ var require_detect_libc = __commonJS({
|
|
|
81947
82447
|
"use strict";
|
|
81948
82448
|
var childProcess = require("child_process");
|
|
81949
82449
|
var { isLinux: isLinux2, getReport } = require_process();
|
|
81950
|
-
var { LDD_PATH, SELF_PATH, readFile: readFile2, readFileSync:
|
|
82450
|
+
var { LDD_PATH, SELF_PATH, readFile: readFile2, readFileSync: readFileSync21 } = require_filesystem();
|
|
81951
82451
|
var { interpreterPath } = require_elf();
|
|
81952
82452
|
var cachedFamilyInterpreter;
|
|
81953
82453
|
var cachedFamilyFilesystem;
|
|
@@ -82039,7 +82539,7 @@ var require_detect_libc = __commonJS({
|
|
|
82039
82539
|
}
|
|
82040
82540
|
cachedFamilyFilesystem = null;
|
|
82041
82541
|
try {
|
|
82042
|
-
const lddContent =
|
|
82542
|
+
const lddContent = readFileSync21(LDD_PATH);
|
|
82043
82543
|
cachedFamilyFilesystem = getFamilyFromLddContent(lddContent);
|
|
82044
82544
|
} catch (e) {
|
|
82045
82545
|
}
|
|
@@ -82064,7 +82564,7 @@ var require_detect_libc = __commonJS({
|
|
|
82064
82564
|
}
|
|
82065
82565
|
cachedFamilyInterpreter = null;
|
|
82066
82566
|
try {
|
|
82067
|
-
const selfContent =
|
|
82567
|
+
const selfContent = readFileSync21(SELF_PATH);
|
|
82068
82568
|
const path40 = interpreterPath(selfContent);
|
|
82069
82569
|
cachedFamilyInterpreter = familyFromInterpreterPath(path40);
|
|
82070
82570
|
} catch (e) {
|
|
@@ -82128,7 +82628,7 @@ var require_detect_libc = __commonJS({
|
|
|
82128
82628
|
}
|
|
82129
82629
|
cachedVersionFilesystem = null;
|
|
82130
82630
|
try {
|
|
82131
|
-
const lddContent =
|
|
82631
|
+
const lddContent = readFileSync21(LDD_PATH);
|
|
82132
82632
|
const versionMatch = lddContent.match(RE_GLIBC_VERSION);
|
|
82133
82633
|
if (versionMatch) {
|
|
82134
82634
|
cachedVersionFilesystem = versionMatch[1];
|
|
@@ -89392,7 +89892,7 @@ var init_adhdev_daemon = __esm({
|
|
|
89392
89892
|
init_version();
|
|
89393
89893
|
init_src();
|
|
89394
89894
|
init_runtime_defaults();
|
|
89395
|
-
pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.
|
|
89895
|
+
pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.68" });
|
|
89396
89896
|
AdhdevDaemon = class _AdhdevDaemon {
|
|
89397
89897
|
localHttpServer = null;
|
|
89398
89898
|
localWss = null;
|
|
@@ -90884,20 +91384,20 @@ async function startDaemonFlow() {
|
|
|
90884
91384
|
try {
|
|
90885
91385
|
const { AdhdevDaemon: AdhdevDaemon2 } = await Promise.resolve().then(() => (init_adhdev_daemon(), adhdev_daemon_exports));
|
|
90886
91386
|
const daemon = new AdhdevDaemon2();
|
|
90887
|
-
const { execSync:
|
|
91387
|
+
const { execSync: execSync9 } = await import("child_process");
|
|
90888
91388
|
const { getCurrentDaemonLogPath: getCurrentDaemonLogPath2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
90889
91389
|
const logPath = getCurrentDaemonLogPath2();
|
|
90890
91390
|
const os31 = await import("os");
|
|
90891
91391
|
const platform12 = os31.platform();
|
|
90892
91392
|
try {
|
|
90893
91393
|
if (platform12 === "win32") {
|
|
90894
|
-
|
|
91394
|
+
execSync9("start /B adhdev daemon >NUL 2>&1", {
|
|
90895
91395
|
timeout: 3e3,
|
|
90896
91396
|
stdio: "ignore",
|
|
90897
91397
|
shell: "cmd.exe"
|
|
90898
91398
|
});
|
|
90899
91399
|
} else {
|
|
90900
|
-
|
|
91400
|
+
execSync9("nohup adhdev daemon >/dev/null 2>&1 &", {
|
|
90901
91401
|
timeout: 3e3,
|
|
90902
91402
|
stdio: "ignore"
|
|
90903
91403
|
});
|
|
@@ -93336,7 +93836,7 @@ async function handleTraceCommand(options) {
|
|
|
93336
93836
|
async function runDaemonUpgrade(options, pkgVersion3) {
|
|
93337
93837
|
const { isDaemonRunning: isDaemonRunning2, stopDaemon: stopDaemon2 } = await Promise.resolve().then(() => (init_adhdev_daemon(), adhdev_daemon_exports));
|
|
93338
93838
|
const { stopManagedSessionHostProcess: stopManagedSessionHostProcess2 } = await Promise.resolve().then(() => (init_session_host(), session_host_exports));
|
|
93339
|
-
const { execSync:
|
|
93839
|
+
const { execSync: execSync9, spawn: spawn7 } = await import("child_process");
|
|
93340
93840
|
const fsMod = await import("fs");
|
|
93341
93841
|
const pathMod = await import("path");
|
|
93342
93842
|
console.log(source_default.bold("\n \u{1F504} ADHDev Upgrade\n"));
|
|
@@ -93356,10 +93856,10 @@ async function runDaemonUpgrade(options, pkgVersion3) {
|
|
|
93356
93856
|
while (!fsMod.existsSync(pathMod.join(gitRoot, ".git")) && gitRoot !== "/") {
|
|
93357
93857
|
gitRoot = pathMod.dirname(gitRoot);
|
|
93358
93858
|
}
|
|
93359
|
-
|
|
93859
|
+
execSync9("git pull --rebase", { cwd: gitRoot, stdio: "inherit" });
|
|
93360
93860
|
console.log(source_default.cyan("\n Building..."));
|
|
93361
|
-
|
|
93362
|
-
|
|
93861
|
+
execSync9("npm run build", { cwd: launcherDir, stdio: "inherit" });
|
|
93862
|
+
execSync9("npm link", { cwd: launcherDir, stdio: "inherit" });
|
|
93363
93863
|
console.log(source_default.green("\n \u2713 Build complete"));
|
|
93364
93864
|
} catch (e) {
|
|
93365
93865
|
console.log(source_default.red(`
|
|
@@ -93467,7 +93967,7 @@ function registerDaemonCommands(program2, pkgVersion3) {
|
|
|
93467
93967
|
}
|
|
93468
93968
|
});
|
|
93469
93969
|
program2.command("standalone").description("\u{1F5A5}\uFE0F Start ADHDev Standalone Server (Local Dashboard & Embedded Daemon)").option("-p, --port <port>", "Local HTTP/WS server port", "3847").option("--host <host>", "Bind to specific host (use 0.0.0.0 for LAN access)").option("--no-open", "Prevent opening browser automatically").option("--token <token>", "Require token authentication").option("--dev", "Enable Dev Mode").action(async (options) => {
|
|
93470
|
-
const { spawn: spawn7, execSync:
|
|
93970
|
+
const { spawn: spawn7, execSync: execSync9 } = await import("child_process");
|
|
93471
93971
|
const { DEFAULT_STANDALONE_SESSION_HOST_APP_NAME: DEFAULT_STANDALONE_SESSION_HOST_APP_NAME2, resolveSessionHostAppNameResolution: resolveSessionHostAppNameResolution2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
93472
93972
|
console.log(source_default.cyan("\n Starting ADHDev Standalone Server..."));
|
|
93473
93973
|
const args = [];
|
|
@@ -93485,7 +93985,7 @@ function registerDaemonCommands(program2, pkgVersion3) {
|
|
|
93485
93985
|
let bin = "npx";
|
|
93486
93986
|
const npxArgs = ["-y", "@adhdev/daemon-standalone@latest", ...args];
|
|
93487
93987
|
try {
|
|
93488
|
-
|
|
93988
|
+
execSync9("adhdev-standalone --help", { stdio: "ignore" });
|
|
93489
93989
|
bin = "adhdev-standalone";
|
|
93490
93990
|
} catch {
|
|
93491
93991
|
console.log(source_default.gray(" Standalone server package not found locally."));
|
|
@@ -95993,7 +96493,7 @@ var import_node_module3 = require("module");
|
|
|
95993
96493
|
var path39 = __toESM(require("path"));
|
|
95994
96494
|
init_source();
|
|
95995
96495
|
function registerMcpCommands(program2) {
|
|
95996
|
-
program2.command("mcp").description("Start an MCP server to expose IDE agents as tools (for Claude Desktop, etc.)").option("--api-key <key>", "ADHDev cloud API key (switches to cloud mode)").option("--port <n>", "Standalone daemon port (default: 3847)", "3847").option("--password <pass>", "Standalone daemon password (if set)").option("--base-url <url>", "Override cloud API base URL").addHelpText("after", `
|
|
96496
|
+
program2.command("mcp").description("Start an MCP server to expose IDE agents as tools (for Claude Desktop, etc.)").option("--api-key <key>", "ADHDev cloud API key (switches to cloud mode)").option("--port <n>", "Standalone daemon port (default: 3847)", "3847").option("--password <pass>", "Standalone daemon password (if set)").option("--base-url <url>", "Override cloud API base URL").option("--repo-mesh <mesh_id>", "Start in mesh mode (coordinator-scoped tools)").addHelpText("after", `
|
|
95997
96497
|
Examples:
|
|
95998
96498
|
adhdev mcp Local mode (requires: adhdev standalone)
|
|
95999
96499
|
adhdev mcp --api-key adk_xxx Cloud mode (no local daemon needed)
|
|
@@ -96021,6 +96521,7 @@ Tools available (cloud): list_daemons, list_sessions, launch_session, stop_sess
|
|
|
96021
96521
|
if (opts.port && opts.port !== "3847") args.push("--port", opts.port);
|
|
96022
96522
|
if (opts.password) args.push("--password", opts.password);
|
|
96023
96523
|
if (opts.baseUrl) args.push("--base-url", opts.baseUrl);
|
|
96524
|
+
if (opts.repoMesh) args.push("--repo-mesh", opts.repoMesh);
|
|
96024
96525
|
const env3 = { ...process.env };
|
|
96025
96526
|
if (opts.apiKey) env3.ADHDEV_API_KEY = opts.apiKey;
|
|
96026
96527
|
if (opts.password) env3.ADHDEV_PASSWORD = opts.password;
|
|
@@ -96055,6 +96556,283 @@ function resolveMcpBin() {
|
|
|
96055
96556
|
}
|
|
96056
96557
|
}
|
|
96057
96558
|
|
|
96559
|
+
// src/cli/mesh-commands.ts
|
|
96560
|
+
init_source();
|
|
96561
|
+
var import_node_child_process4 = require("child_process");
|
|
96562
|
+
init_src();
|
|
96563
|
+
function registerMeshCommands(program2) {
|
|
96564
|
+
const mesh = program2.command("mesh").description("Manage Repo Meshes \u2014 repo-scoped execution environments");
|
|
96565
|
+
mesh.command("list").description("List all configured meshes").action(() => {
|
|
96566
|
+
const meshes = listMeshes();
|
|
96567
|
+
if (meshes.length === 0) {
|
|
96568
|
+
console.log(source_default.gray("No meshes configured. Create one with: adhdev mesh create <name>"));
|
|
96569
|
+
return;
|
|
96570
|
+
}
|
|
96571
|
+
console.log(source_default.bold(`
|
|
96572
|
+
Repo Meshes (${meshes.length})
|
|
96573
|
+
`));
|
|
96574
|
+
for (const m of meshes) {
|
|
96575
|
+
const nodeCount = m.nodes.length;
|
|
96576
|
+
const statusIcon = nodeCount > 0 ? source_default.green("\u25CF") : source_default.yellow("\u25CB");
|
|
96577
|
+
console.log(` ${statusIcon} ${source_default.bold(m.name)} ${source_default.gray(m.id)}`);
|
|
96578
|
+
console.log(` ${source_default.gray("repo:")} ${m.repoIdentity}`);
|
|
96579
|
+
console.log(` ${source_default.gray("nodes:")} ${nodeCount} ${source_default.gray("created:")} ${m.createdAt.split("T")[0]}`);
|
|
96580
|
+
console.log();
|
|
96581
|
+
}
|
|
96582
|
+
});
|
|
96583
|
+
mesh.command("create <name>").description("Create a new mesh for the current Git repository").option("--remote-url <url>", "Git remote URL (auto-detected from current directory)").option("--identity <identity>", "Repo identity override (e.g. github.com/user/repo)").option("--branch <branch>", "Default branch (e.g. main)").option("--add-current", "Also add current workspace as the first node", false).action(async (name, opts) => {
|
|
96584
|
+
let repoRemoteUrl = opts.remoteUrl;
|
|
96585
|
+
let repoIdentity = opts.identity;
|
|
96586
|
+
let defaultBranch = opts.branch;
|
|
96587
|
+
if (!repoRemoteUrl && !repoIdentity) {
|
|
96588
|
+
try {
|
|
96589
|
+
repoRemoteUrl = (0, import_node_child_process4.execSync)("git remote get-url origin", {
|
|
96590
|
+
encoding: "utf-8",
|
|
96591
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
96592
|
+
}).trim();
|
|
96593
|
+
console.log(source_default.gray(` Detected remote: ${repoRemoteUrl}`));
|
|
96594
|
+
} catch {
|
|
96595
|
+
console.error(source_default.red("\u2717 Could not detect Git remote. Use --remote-url or --identity."));
|
|
96596
|
+
process.exit(1);
|
|
96597
|
+
}
|
|
96598
|
+
}
|
|
96599
|
+
if (!defaultBranch) {
|
|
96600
|
+
try {
|
|
96601
|
+
defaultBranch = (0, import_node_child_process4.execSync)("git symbolic-ref refs/remotes/origin/HEAD", {
|
|
96602
|
+
encoding: "utf-8",
|
|
96603
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
96604
|
+
}).trim().replace("refs/remotes/origin/", "");
|
|
96605
|
+
} catch {
|
|
96606
|
+
try {
|
|
96607
|
+
defaultBranch = (0, import_node_child_process4.execSync)("git branch --show-current", {
|
|
96608
|
+
encoding: "utf-8",
|
|
96609
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
96610
|
+
}).trim();
|
|
96611
|
+
} catch {
|
|
96612
|
+
defaultBranch = "main";
|
|
96613
|
+
}
|
|
96614
|
+
}
|
|
96615
|
+
}
|
|
96616
|
+
try {
|
|
96617
|
+
const mesh2 = createMesh({
|
|
96618
|
+
name,
|
|
96619
|
+
repoRemoteUrl,
|
|
96620
|
+
repoIdentity,
|
|
96621
|
+
defaultBranch
|
|
96622
|
+
});
|
|
96623
|
+
console.log(source_default.green(`
|
|
96624
|
+
\u2713 Mesh created: ${source_default.bold(mesh2.name)}`));
|
|
96625
|
+
console.log(source_default.gray(` ID: ${mesh2.id}`));
|
|
96626
|
+
console.log(source_default.gray(` Repo: ${mesh2.repoIdentity}`));
|
|
96627
|
+
console.log(source_default.gray(` Branch: ${mesh2.defaultBranch || "auto"}`));
|
|
96628
|
+
if (opts.addCurrent) {
|
|
96629
|
+
const cwd = process.cwd();
|
|
96630
|
+
try {
|
|
96631
|
+
const node = addNode(mesh2.id, { workspace: cwd });
|
|
96632
|
+
if (node) {
|
|
96633
|
+
console.log(source_default.green(` \u2713 Added current workspace as node: ${source_default.gray(cwd)}`));
|
|
96634
|
+
console.log(source_default.gray(` Node ID: ${node.id}`));
|
|
96635
|
+
}
|
|
96636
|
+
} catch (e) {
|
|
96637
|
+
console.error(source_default.yellow(` \u26A0 Could not add current workspace: ${e.message}`));
|
|
96638
|
+
}
|
|
96639
|
+
}
|
|
96640
|
+
console.log();
|
|
96641
|
+
console.log(source_default.gray(" Next steps:"));
|
|
96642
|
+
console.log(source_default.gray(` adhdev mesh add-node ${mesh2.id} \u2014 Add a workspace to this mesh`));
|
|
96643
|
+
console.log(source_default.gray(` adhdev mcp --repo-mesh ${mesh2.id} \u2014 Start MCP server in mesh mode`));
|
|
96644
|
+
console.log();
|
|
96645
|
+
} catch (e) {
|
|
96646
|
+
console.error(source_default.red(`\u2717 ${e.message}`));
|
|
96647
|
+
process.exit(1);
|
|
96648
|
+
}
|
|
96649
|
+
});
|
|
96650
|
+
mesh.command("show <mesh_id>").description("Show mesh details and nodes").action((meshId) => {
|
|
96651
|
+
const m = getMesh(meshId);
|
|
96652
|
+
if (!m) {
|
|
96653
|
+
console.error(source_default.red(`\u2717 Mesh not found: ${meshId}`));
|
|
96654
|
+
process.exit(1);
|
|
96655
|
+
}
|
|
96656
|
+
console.log(source_default.bold(`
|
|
96657
|
+
${m.name} ${source_default.gray(m.id)}`));
|
|
96658
|
+
console.log(` ${source_default.gray("repo:")} ${m.repoIdentity}`);
|
|
96659
|
+
if (m.repoRemoteUrl) console.log(` ${source_default.gray("remote:")} ${m.repoRemoteUrl}`);
|
|
96660
|
+
if (m.defaultBranch) console.log(` ${source_default.gray("branch:")} ${m.defaultBranch}`);
|
|
96661
|
+
console.log(` ${source_default.gray("created:")} ${m.createdAt}`);
|
|
96662
|
+
console.log(` ${source_default.gray("updated:")} ${m.updatedAt}`);
|
|
96663
|
+
console.log(source_default.bold("\n Policy"));
|
|
96664
|
+
console.log(` ${source_default.gray("checkpoint after task:")} ${m.policy.requirePostTaskCheckpoint ? "yes" : "no"}`);
|
|
96665
|
+
console.log(` ${source_default.gray("push requires approval:")} ${m.policy.requireApprovalForPush ? "yes" : "no"}`);
|
|
96666
|
+
console.log(` ${source_default.gray("dirty workspace:")} ${m.policy.dirtyWorkspaceBehavior}`);
|
|
96667
|
+
console.log(` ${source_default.gray("max parallel tasks:")} ${m.policy.maxParallelTasks}`);
|
|
96668
|
+
console.log(source_default.bold(`
|
|
96669
|
+
Nodes (${m.nodes.length})`));
|
|
96670
|
+
if (m.nodes.length === 0) {
|
|
96671
|
+
console.log(source_default.gray(" No nodes. Add one with: adhdev mesh add-node " + meshId));
|
|
96672
|
+
} else {
|
|
96673
|
+
for (const n of m.nodes) {
|
|
96674
|
+
const label = n.isLocalWorktree ? source_default.cyan("[worktree]") : "";
|
|
96675
|
+
console.log(` ${source_default.gray("\u25CF")} ${n.workspace} ${label} ${source_default.gray(n.id)}`);
|
|
96676
|
+
if (n.policy.readOnly) console.log(` ${source_default.yellow("read-only")}`);
|
|
96677
|
+
if (Object.keys(n.userOverrides).length > 0) {
|
|
96678
|
+
console.log(` ${source_default.gray("overrides:")} ${JSON.stringify(n.userOverrides)}`);
|
|
96679
|
+
}
|
|
96680
|
+
}
|
|
96681
|
+
}
|
|
96682
|
+
console.log();
|
|
96683
|
+
});
|
|
96684
|
+
mesh.command("delete <mesh_id>").description("Delete a mesh").action((meshId) => {
|
|
96685
|
+
const m = getMesh(meshId);
|
|
96686
|
+
if (!m) {
|
|
96687
|
+
console.error(source_default.red(`\u2717 Mesh not found: ${meshId}`));
|
|
96688
|
+
process.exit(1);
|
|
96689
|
+
}
|
|
96690
|
+
const ok = deleteMesh(meshId);
|
|
96691
|
+
if (ok) {
|
|
96692
|
+
console.log(source_default.green(` \u2713 Deleted mesh: ${m.name} (${meshId})`));
|
|
96693
|
+
} else {
|
|
96694
|
+
console.error(source_default.red(`\u2717 Failed to delete mesh: ${meshId}`));
|
|
96695
|
+
process.exit(1);
|
|
96696
|
+
}
|
|
96697
|
+
});
|
|
96698
|
+
mesh.command("add-node <mesh_id>").description("Add a workspace as a node to the mesh").option("--workspace <path>", "Workspace path (default: current directory)").option("--worktree", "Mark as a local Git worktree", false).option("--read-only", "Mark this node as read-only", false).action((meshId, opts) => {
|
|
96699
|
+
const m = getMesh(meshId);
|
|
96700
|
+
if (!m) {
|
|
96701
|
+
console.error(source_default.red(`\u2717 Mesh not found: ${meshId}`));
|
|
96702
|
+
process.exit(1);
|
|
96703
|
+
}
|
|
96704
|
+
const workspace = opts.workspace || process.cwd();
|
|
96705
|
+
try {
|
|
96706
|
+
const node = addNode(meshId, {
|
|
96707
|
+
workspace,
|
|
96708
|
+
isLocalWorktree: opts.worktree,
|
|
96709
|
+
policy: opts.readOnly ? { readOnly: true } : {}
|
|
96710
|
+
});
|
|
96711
|
+
if (node) {
|
|
96712
|
+
console.log(source_default.green(` \u2713 Node added to ${m.name}`));
|
|
96713
|
+
console.log(source_default.gray(` ID: ${node.id}`));
|
|
96714
|
+
console.log(source_default.gray(` Workspace: ${workspace}`));
|
|
96715
|
+
if (opts.worktree) console.log(source_default.gray(` Type: local worktree`));
|
|
96716
|
+
if (opts.readOnly) console.log(source_default.gray(` Policy: read-only`));
|
|
96717
|
+
} else {
|
|
96718
|
+
console.error(source_default.red(`\u2717 Mesh not found`));
|
|
96719
|
+
process.exit(1);
|
|
96720
|
+
}
|
|
96721
|
+
} catch (e) {
|
|
96722
|
+
console.error(source_default.red(`\u2717 ${e.message}`));
|
|
96723
|
+
process.exit(1);
|
|
96724
|
+
}
|
|
96725
|
+
});
|
|
96726
|
+
mesh.command("remove-node <mesh_id> <node_id>").description("Remove a node from the mesh").action((meshId, nodeId) => {
|
|
96727
|
+
const ok = removeNode(meshId, nodeId);
|
|
96728
|
+
if (ok) {
|
|
96729
|
+
console.log(source_default.green(` \u2713 Node removed: ${nodeId}`));
|
|
96730
|
+
} else {
|
|
96731
|
+
console.error(source_default.red(`\u2717 Node or mesh not found`));
|
|
96732
|
+
process.exit(1);
|
|
96733
|
+
}
|
|
96734
|
+
});
|
|
96735
|
+
mesh.command("status <mesh_id>").description("Probe all mesh nodes and show health").action(async (meshId) => {
|
|
96736
|
+
const m = getMesh(meshId);
|
|
96737
|
+
if (!m) {
|
|
96738
|
+
console.error(source_default.red(`\u2717 Mesh not found: ${meshId}`));
|
|
96739
|
+
process.exit(1);
|
|
96740
|
+
}
|
|
96741
|
+
console.log(source_default.bold(`
|
|
96742
|
+
${m.name} \u2014 Node Status
|
|
96743
|
+
`));
|
|
96744
|
+
if (m.nodes.length === 0) {
|
|
96745
|
+
console.log(source_default.gray(" No nodes configured."));
|
|
96746
|
+
return;
|
|
96747
|
+
}
|
|
96748
|
+
for (const node of m.nodes) {
|
|
96749
|
+
let gitInfo = "";
|
|
96750
|
+
let healthIcon = source_default.gray("?");
|
|
96751
|
+
let health = "unknown";
|
|
96752
|
+
try {
|
|
96753
|
+
const branch = (0, import_node_child_process4.execSync)(`git -C "${node.workspace}" branch --show-current`, {
|
|
96754
|
+
encoding: "utf-8",
|
|
96755
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
96756
|
+
}).trim();
|
|
96757
|
+
const status = (0, import_node_child_process4.execSync)(`git -C "${node.workspace}" status --porcelain`, {
|
|
96758
|
+
encoding: "utf-8",
|
|
96759
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
96760
|
+
}).trim();
|
|
96761
|
+
const isDirty = status.length > 0;
|
|
96762
|
+
const changedFiles = isDirty ? status.split("\n").length : 0;
|
|
96763
|
+
if (isDirty) {
|
|
96764
|
+
health = "dirty";
|
|
96765
|
+
healthIcon = source_default.yellow("\u25CF");
|
|
96766
|
+
gitInfo = `${source_default.cyan(branch)} ${source_default.yellow(`(${changedFiles} changed)`)}`;
|
|
96767
|
+
} else {
|
|
96768
|
+
health = "clean";
|
|
96769
|
+
healthIcon = source_default.green("\u25CF");
|
|
96770
|
+
gitInfo = `${source_default.cyan(branch)} ${source_default.green("clean")}`;
|
|
96771
|
+
}
|
|
96772
|
+
} catch {
|
|
96773
|
+
health = "error";
|
|
96774
|
+
healthIcon = source_default.red("\u2717");
|
|
96775
|
+
gitInfo = source_default.red("git probe failed");
|
|
96776
|
+
}
|
|
96777
|
+
const label = node.isLocalWorktree ? source_default.gray(" [worktree]") : "";
|
|
96778
|
+
console.log(` ${healthIcon} ${node.workspace}${label} ${source_default.gray(node.id.slice(0, 12))}`);
|
|
96779
|
+
console.log(` ${gitInfo}`);
|
|
96780
|
+
if (node.policy.readOnly) console.log(` ${source_default.yellow("read-only")}`);
|
|
96781
|
+
console.log();
|
|
96782
|
+
}
|
|
96783
|
+
});
|
|
96784
|
+
mesh.command("sync").description("Sync local mesh config with cloud (push/pull)").action(async () => {
|
|
96785
|
+
try {
|
|
96786
|
+
const { syncMeshes: syncMeshes2, loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
96787
|
+
const config2 = loadConfig2();
|
|
96788
|
+
const apiKey = process.env.ADHDEV_API_KEY;
|
|
96789
|
+
if (!apiKey) {
|
|
96790
|
+
console.error(source_default.red("\u2717 No API key set. Export ADHDEV_API_KEY or use: adhdev setup"));
|
|
96791
|
+
process.exit(1);
|
|
96792
|
+
}
|
|
96793
|
+
const baseUrl = config2.serverUrl || "https://api.adhf.dev";
|
|
96794
|
+
const transport = {
|
|
96795
|
+
async listRemoteMeshes() {
|
|
96796
|
+
const res = await fetch(`${baseUrl}/api/v1/repo-meshes`, {
|
|
96797
|
+
headers: { "Authorization": `Bearer ${apiKey}`, "Content-Type": "application/json" }
|
|
96798
|
+
});
|
|
96799
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
96800
|
+
return res.json();
|
|
96801
|
+
},
|
|
96802
|
+
async createRemoteMesh(data) {
|
|
96803
|
+
const res = await fetch(`${baseUrl}/api/v1/repo-meshes`, {
|
|
96804
|
+
method: "POST",
|
|
96805
|
+
headers: { "Authorization": `Bearer ${apiKey}`, "Content-Type": "application/json" },
|
|
96806
|
+
body: JSON.stringify(data)
|
|
96807
|
+
});
|
|
96808
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
96809
|
+
return res.json();
|
|
96810
|
+
},
|
|
96811
|
+
async deleteRemoteMesh(meshId) {
|
|
96812
|
+
const res = await fetch(`${baseUrl}/api/v1/repo-meshes/${meshId}`, {
|
|
96813
|
+
method: "DELETE",
|
|
96814
|
+
headers: { "Authorization": `Bearer ${apiKey}` }
|
|
96815
|
+
});
|
|
96816
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
96817
|
+
}
|
|
96818
|
+
};
|
|
96819
|
+
console.log(source_default.gray(" Syncing with cloud..."));
|
|
96820
|
+
const result = await syncMeshes2(transport);
|
|
96821
|
+
if (result.pushed > 0) console.log(source_default.green(` \u2713 Pushed ${result.pushed} mesh${result.pushed > 1 ? "es" : ""} to cloud`));
|
|
96822
|
+
if (result.pulled > 0) console.log(source_default.green(` \u2713 Pulled ${result.pulled} mesh${result.pulled > 1 ? "es" : ""} from cloud`));
|
|
96823
|
+
if (result.pushed === 0 && result.pulled === 0 && result.errors.length === 0) {
|
|
96824
|
+
console.log(source_default.gray(" Already in sync."));
|
|
96825
|
+
}
|
|
96826
|
+
for (const err of result.errors) {
|
|
96827
|
+
console.error(source_default.yellow(` \u26A0 ${err}`));
|
|
96828
|
+
}
|
|
96829
|
+
} catch (e) {
|
|
96830
|
+
console.error(source_default.red(`\u2717 Sync failed: ${e.message}`));
|
|
96831
|
+
process.exit(1);
|
|
96832
|
+
}
|
|
96833
|
+
});
|
|
96834
|
+
}
|
|
96835
|
+
|
|
96058
96836
|
// src/cli/index.ts
|
|
96059
96837
|
init_version();
|
|
96060
96838
|
var pkgVersion2 = resolvePackageVersion();
|
|
@@ -96075,6 +96853,7 @@ registerProviderCommands(program);
|
|
|
96075
96853
|
registerCdpCommands(program);
|
|
96076
96854
|
registerServiceCommands(program);
|
|
96077
96855
|
registerMcpCommands(program);
|
|
96856
|
+
registerMeshCommands(program);
|
|
96078
96857
|
void (async () => {
|
|
96079
96858
|
const helperMode = await maybeRunDaemonUpgradeHelperFromEnv();
|
|
96080
96859
|
if (helperMode) {
|
|
@@ -96102,6 +96881,8 @@ void (async () => {
|
|
|
96102
96881
|
console.log(source_default.gray(" adhdev trace --category session_host \u2014 Inspect structured daemon trace"));
|
|
96103
96882
|
console.log(source_default.gray(" adhdev service \u2014 Manage OS background auto-start service"));
|
|
96104
96883
|
console.log(source_default.gray(" adhdev mcp \u2014 Start MCP server (expose agents to Claude Desktop, etc.)"));
|
|
96884
|
+
console.log(source_default.gray(" adhdev mesh list \u2014 List configured Repo Meshes"));
|
|
96885
|
+
console.log(source_default.gray(" adhdev mesh create myapp \u2014 Create a mesh for the current Git repo"));
|
|
96105
96886
|
console.log(source_default.gray(" adhdev provider ... \u2014 Provider development commands"));
|
|
96106
96887
|
console.log(source_default.gray(" adhdev cdp ... \u2014 CDP debugging tools"));
|
|
96107
96888
|
console.log();
|