adhdev 0.9.66 → 0.9.67
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 +685 -57
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +390 -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,326 @@ var init_saved_sessions = __esm({
|
|
|
2682
2698
|
}
|
|
2683
2699
|
});
|
|
2684
2700
|
|
|
2701
|
+
// ../../oss/packages/daemon-core/src/config/mesh-config.ts
|
|
2702
|
+
function getMeshConfigPath() {
|
|
2703
|
+
return (0, import_path2.join)(getConfigDir(), "meshes.json");
|
|
2704
|
+
}
|
|
2705
|
+
function loadMeshConfig() {
|
|
2706
|
+
const path40 = getMeshConfigPath();
|
|
2707
|
+
if (!(0, import_fs2.existsSync)(path40)) return { meshes: [] };
|
|
2708
|
+
try {
|
|
2709
|
+
const raw = JSON.parse((0, import_fs2.readFileSync)(path40, "utf-8"));
|
|
2710
|
+
if (!raw || !Array.isArray(raw.meshes)) return { meshes: [] };
|
|
2711
|
+
return raw;
|
|
2712
|
+
} catch {
|
|
2713
|
+
return { meshes: [] };
|
|
2714
|
+
}
|
|
2715
|
+
}
|
|
2716
|
+
function saveMeshConfig(config2) {
|
|
2717
|
+
const path40 = getMeshConfigPath();
|
|
2718
|
+
(0, import_fs2.writeFileSync)(path40, JSON.stringify(config2, null, 2), { encoding: "utf-8", mode: 384 });
|
|
2719
|
+
}
|
|
2720
|
+
function normalizeRepoIdentity(remoteUrl) {
|
|
2721
|
+
let identity = remoteUrl.trim();
|
|
2722
|
+
if (identity.startsWith("http://") || identity.startsWith("https://")) {
|
|
2723
|
+
try {
|
|
2724
|
+
const url2 = new URL(identity);
|
|
2725
|
+
const path40 = url2.pathname.replace(/^\//, "").replace(/\.git$/, "");
|
|
2726
|
+
return `${url2.hostname}/${path40}`;
|
|
2727
|
+
} catch {
|
|
2728
|
+
}
|
|
2729
|
+
}
|
|
2730
|
+
const sshMatch = identity.match(/^(?:ssh:\/\/)?[\w.-]+@([\w.-]+)[:/]([\w.\-/]+?)(?:\.git)?$/);
|
|
2731
|
+
if (sshMatch) return `${sshMatch[1]}/${sshMatch[2]}`;
|
|
2732
|
+
return identity;
|
|
2733
|
+
}
|
|
2734
|
+
function listMeshes() {
|
|
2735
|
+
return loadMeshConfig().meshes;
|
|
2736
|
+
}
|
|
2737
|
+
function getMesh(meshId) {
|
|
2738
|
+
return loadMeshConfig().meshes.find((m) => m.id === meshId);
|
|
2739
|
+
}
|
|
2740
|
+
function getMeshByRepo(repoIdentity) {
|
|
2741
|
+
return loadMeshConfig().meshes.find((m) => m.repoIdentity === repoIdentity);
|
|
2742
|
+
}
|
|
2743
|
+
function createMesh(opts) {
|
|
2744
|
+
const config2 = loadMeshConfig();
|
|
2745
|
+
if (config2.meshes.length >= 20) {
|
|
2746
|
+
throw new Error("Maximum 20 meshes allowed");
|
|
2747
|
+
}
|
|
2748
|
+
const repoIdentity = opts.repoIdentity || (opts.repoRemoteUrl ? normalizeRepoIdentity(opts.repoRemoteUrl) : "");
|
|
2749
|
+
if (!repoIdentity) throw new Error("Either repoRemoteUrl or repoIdentity is required");
|
|
2750
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2751
|
+
const mesh = {
|
|
2752
|
+
id: `mesh_${(0, import_crypto3.randomUUID)().replace(/-/g, "")}`,
|
|
2753
|
+
name: opts.name.trim().slice(0, 100),
|
|
2754
|
+
repoIdentity,
|
|
2755
|
+
repoRemoteUrl: opts.repoRemoteUrl,
|
|
2756
|
+
defaultBranch: opts.defaultBranch,
|
|
2757
|
+
policy: { ...DEFAULT_MESH_POLICY, ...opts.policy },
|
|
2758
|
+
coordinator: opts.coordinator || {},
|
|
2759
|
+
nodes: [],
|
|
2760
|
+
createdAt: now,
|
|
2761
|
+
updatedAt: now
|
|
2762
|
+
};
|
|
2763
|
+
config2.meshes.push(mesh);
|
|
2764
|
+
saveMeshConfig(config2);
|
|
2765
|
+
return mesh;
|
|
2766
|
+
}
|
|
2767
|
+
function updateMesh(meshId, opts) {
|
|
2768
|
+
const config2 = loadMeshConfig();
|
|
2769
|
+
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
2770
|
+
if (!mesh) return void 0;
|
|
2771
|
+
if (opts.name !== void 0) mesh.name = opts.name.trim().slice(0, 100);
|
|
2772
|
+
if (opts.defaultBranch !== void 0) mesh.defaultBranch = opts.defaultBranch;
|
|
2773
|
+
if (opts.policy) mesh.policy = { ...mesh.policy, ...opts.policy };
|
|
2774
|
+
if (opts.coordinator) mesh.coordinator = opts.coordinator;
|
|
2775
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2776
|
+
saveMeshConfig(config2);
|
|
2777
|
+
return mesh;
|
|
2778
|
+
}
|
|
2779
|
+
function deleteMesh(meshId) {
|
|
2780
|
+
const config2 = loadMeshConfig();
|
|
2781
|
+
const idx = config2.meshes.findIndex((m) => m.id === meshId);
|
|
2782
|
+
if (idx === -1) return false;
|
|
2783
|
+
config2.meshes.splice(idx, 1);
|
|
2784
|
+
saveMeshConfig(config2);
|
|
2785
|
+
return true;
|
|
2786
|
+
}
|
|
2787
|
+
function addNode(meshId, opts) {
|
|
2788
|
+
const config2 = loadMeshConfig();
|
|
2789
|
+
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
2790
|
+
if (!mesh) return void 0;
|
|
2791
|
+
if (mesh.nodes.length >= 10) {
|
|
2792
|
+
throw new Error("Maximum 10 nodes per mesh");
|
|
2793
|
+
}
|
|
2794
|
+
if (mesh.nodes.some((n) => n.workspace === opts.workspace)) {
|
|
2795
|
+
throw new Error("This workspace is already in the mesh");
|
|
2796
|
+
}
|
|
2797
|
+
const node = {
|
|
2798
|
+
id: `node_${(0, import_crypto3.randomUUID)().replace(/-/g, "")}`,
|
|
2799
|
+
workspace: opts.workspace.trim(),
|
|
2800
|
+
repoRoot: opts.repoRoot,
|
|
2801
|
+
userOverrides: opts.userOverrides || {},
|
|
2802
|
+
policy: opts.policy || {},
|
|
2803
|
+
isLocalWorktree: opts.isLocalWorktree
|
|
2804
|
+
};
|
|
2805
|
+
mesh.nodes.push(node);
|
|
2806
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2807
|
+
saveMeshConfig(config2);
|
|
2808
|
+
return node;
|
|
2809
|
+
}
|
|
2810
|
+
function removeNode(meshId, nodeId) {
|
|
2811
|
+
const config2 = loadMeshConfig();
|
|
2812
|
+
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
2813
|
+
if (!mesh) return false;
|
|
2814
|
+
const idx = mesh.nodes.findIndex((n) => n.id === nodeId);
|
|
2815
|
+
if (idx === -1) return false;
|
|
2816
|
+
mesh.nodes.splice(idx, 1);
|
|
2817
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2818
|
+
saveMeshConfig(config2);
|
|
2819
|
+
return true;
|
|
2820
|
+
}
|
|
2821
|
+
function updateNode(meshId, nodeId, opts) {
|
|
2822
|
+
const config2 = loadMeshConfig();
|
|
2823
|
+
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
2824
|
+
if (!mesh) return void 0;
|
|
2825
|
+
const node = mesh.nodes.find((n) => n.id === nodeId);
|
|
2826
|
+
if (!node) return void 0;
|
|
2827
|
+
if (opts.userOverrides) node.userOverrides = { ...node.userOverrides, ...opts.userOverrides };
|
|
2828
|
+
if (opts.policy) node.policy = { ...node.policy, ...opts.policy };
|
|
2829
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2830
|
+
saveMeshConfig(config2);
|
|
2831
|
+
return node;
|
|
2832
|
+
}
|
|
2833
|
+
var import_fs2, import_path2, import_crypto3;
|
|
2834
|
+
var init_mesh_config = __esm({
|
|
2835
|
+
"../../oss/packages/daemon-core/src/config/mesh-config.ts"() {
|
|
2836
|
+
"use strict";
|
|
2837
|
+
import_fs2 = require("fs");
|
|
2838
|
+
import_path2 = require("path");
|
|
2839
|
+
import_crypto3 = require("crypto");
|
|
2840
|
+
init_config();
|
|
2841
|
+
init_repo_mesh_types();
|
|
2842
|
+
}
|
|
2843
|
+
});
|
|
2844
|
+
|
|
2845
|
+
// ../../oss/packages/daemon-core/src/mesh/coordinator-prompt.ts
|
|
2846
|
+
function buildCoordinatorSystemPrompt(ctx) {
|
|
2847
|
+
const { mesh, status, userInstruction } = ctx;
|
|
2848
|
+
const sections = [];
|
|
2849
|
+
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.
|
|
2850
|
+
|
|
2851
|
+
Your mesh: **${mesh.name}**
|
|
2852
|
+
Repository: \`${mesh.repoIdentity}\`${mesh.defaultBranch ? `
|
|
2853
|
+
Default branch: \`${mesh.defaultBranch}\`` : ""}`);
|
|
2854
|
+
if (status?.nodes?.length) {
|
|
2855
|
+
sections.push(buildNodeStatusSection(status.nodes));
|
|
2856
|
+
} else if (mesh.nodes.length) {
|
|
2857
|
+
sections.push(buildNodeConfigSection(mesh));
|
|
2858
|
+
} else {
|
|
2859
|
+
sections.push("## Nodes\nNo nodes configured yet. Ask the user to add nodes with `adhdev mesh add-node`.");
|
|
2860
|
+
}
|
|
2861
|
+
sections.push(buildPolicySection(mesh.policy));
|
|
2862
|
+
sections.push(TOOLS_SECTION);
|
|
2863
|
+
sections.push(WORKFLOW_SECTION);
|
|
2864
|
+
sections.push(RULES_SECTION);
|
|
2865
|
+
if (userInstruction) {
|
|
2866
|
+
sections.push(`## Additional Context
|
|
2867
|
+
${userInstruction}`);
|
|
2868
|
+
}
|
|
2869
|
+
if (mesh.coordinator.systemPromptSuffix) {
|
|
2870
|
+
sections.push(mesh.coordinator.systemPromptSuffix);
|
|
2871
|
+
}
|
|
2872
|
+
return sections.join("\n\n");
|
|
2873
|
+
}
|
|
2874
|
+
function buildNodeStatusSection(nodes) {
|
|
2875
|
+
const lines = ["## Current Node Status", ""];
|
|
2876
|
+
for (const n of nodes) {
|
|
2877
|
+
const healthIcon = n.health === "online" ? "\u{1F7E2}" : n.health === "dirty" ? "\u{1F7E1}" : n.health === "offline" ? "\u26AB" : "\u{1F534}";
|
|
2878
|
+
const sessions = n.activeSessions.length > 0 ? `sessions: ${n.activeSessions.join(", ")}` : "no active sessions";
|
|
2879
|
+
const branch = n.git?.branch ? `branch: \`${n.git.branch}\`` : "";
|
|
2880
|
+
lines.push(`- ${healthIcon} **${n.machineLabel}** (${n.nodeId})`);
|
|
2881
|
+
lines.push(` workspace: \`${n.workspace}\` | ${branch} | ${sessions}`);
|
|
2882
|
+
if (n.error) lines.push(` \u26A0\uFE0F ${n.error}`);
|
|
2883
|
+
}
|
|
2884
|
+
return lines.join("\n");
|
|
2885
|
+
}
|
|
2886
|
+
function buildNodeConfigSection(mesh) {
|
|
2887
|
+
const lines = ["## Configured Nodes", ""];
|
|
2888
|
+
for (const n of mesh.nodes) {
|
|
2889
|
+
const labels = [];
|
|
2890
|
+
if (n.isLocalWorktree) labels.push("worktree");
|
|
2891
|
+
if (n.policy.readOnly) labels.push("read-only");
|
|
2892
|
+
const suffix = labels.length ? ` [${labels.join(", ")}]` : "";
|
|
2893
|
+
lines.push(`- **${n.workspace}** (${n.id})${suffix}`);
|
|
2894
|
+
}
|
|
2895
|
+
lines.push("", "_Use `mesh_status` to probe live health before delegating work._");
|
|
2896
|
+
return lines.join("\n");
|
|
2897
|
+
}
|
|
2898
|
+
function buildPolicySection(policy) {
|
|
2899
|
+
const rules = [];
|
|
2900
|
+
if (policy.requirePreTaskCheckpoint) rules.push("- Create a git checkpoint **before** starting each task");
|
|
2901
|
+
if (policy.requirePostTaskCheckpoint) rules.push("- Create a git checkpoint **after** each task completes");
|
|
2902
|
+
if (policy.requireApprovalForPush) rules.push("- **Ask for user approval** before pushing to remote");
|
|
2903
|
+
if (policy.requireApprovalForDestructiveGit) rules.push("- **Ask for user approval** before destructive git operations (force push, reset, etc.)");
|
|
2904
|
+
const dirtyBehavior = {
|
|
2905
|
+
block: "- **Do not** send tasks to nodes with dirty workspaces",
|
|
2906
|
+
warn: "- Warn the user if a node has uncommitted changes before sending a task",
|
|
2907
|
+
checkpoint_then_continue: "- Auto-checkpoint dirty nodes before sending tasks"
|
|
2908
|
+
}[policy.dirtyWorkspaceBehavior] || "";
|
|
2909
|
+
if (dirtyBehavior) rules.push(dirtyBehavior);
|
|
2910
|
+
rules.push(`- Maximum **${policy.maxParallelTasks}** tasks running in parallel`);
|
|
2911
|
+
return `## Policy
|
|
2912
|
+
${rules.join("\n")}`;
|
|
2913
|
+
}
|
|
2914
|
+
var TOOLS_SECTION, WORKFLOW_SECTION, RULES_SECTION;
|
|
2915
|
+
var init_coordinator_prompt = __esm({
|
|
2916
|
+
"../../oss/packages/daemon-core/src/mesh/coordinator-prompt.ts"() {
|
|
2917
|
+
"use strict";
|
|
2918
|
+
TOOLS_SECTION = `## Available Tools
|
|
2919
|
+
|
|
2920
|
+
| Tool | Purpose |
|
|
2921
|
+
|------|---------|
|
|
2922
|
+
| \`mesh_status\` | Check all nodes' health, git state, and active sessions |
|
|
2923
|
+
| \`mesh_list_nodes\` | List nodes with workspace paths |
|
|
2924
|
+
| \`mesh_launch_session\` | Start a new agent session on a node |
|
|
2925
|
+
| \`mesh_send_task\` | Send a task (natural language) to a running agent |
|
|
2926
|
+
| \`mesh_read_chat\` | Read an agent's recent messages to check progress |
|
|
2927
|
+
| \`mesh_git_status\` | Check git status on a specific node |
|
|
2928
|
+
| \`mesh_checkpoint\` | Create a git checkpoint on a node |
|
|
2929
|
+
| \`mesh_approve\` | Approve/reject a pending agent action |`;
|
|
2930
|
+
WORKFLOW_SECTION = `## Orchestration Workflow
|
|
2931
|
+
|
|
2932
|
+
1. **Assess** \u2014 Call \`mesh_status\` to see which nodes are healthy and available.
|
|
2933
|
+
2. **Plan** \u2014 Decompose the user's request into independent tasks for parallel execution, or sequential tasks when dependencies exist.
|
|
2934
|
+
3. **Delegate** \u2014 For each task:
|
|
2935
|
+
a. Pick the best node (consider: health, dirty state, current workload).
|
|
2936
|
+
b. If no session exists, call \`mesh_launch_session\` to start one.
|
|
2937
|
+
c. Call \`mesh_send_task\` with a clear, self-contained natural-language instruction.
|
|
2938
|
+
4. **Monitor** \u2014 Periodically call \`mesh_read_chat\` to check progress. Handle approvals via \`mesh_approve\`.
|
|
2939
|
+
5. **Verify** \u2014 When a task reports completion, call \`mesh_git_status\` to verify changes were made.
|
|
2940
|
+
6. **Checkpoint** \u2014 Call \`mesh_checkpoint\` to save the work.
|
|
2941
|
+
7. **Report** \u2014 Summarize what was done, what changed, and any issues.`;
|
|
2942
|
+
RULES_SECTION = `## Rules
|
|
2943
|
+
|
|
2944
|
+
- **Be conversational.** Delegate work the way a tech lead would \u2014 clear, specific instructions in natural language.
|
|
2945
|
+
- **Don't inspect code.** Trust the agent's output. Verify via git diff/status, not by reading source files.
|
|
2946
|
+
- **Don't over-parallelize.** Start with 1-2 concurrent tasks. Scale up if they succeed.
|
|
2947
|
+
- **Handle failures gracefully.** If a task fails, read the chat to understand why, then retry or reassign.
|
|
2948
|
+
- **Keep the user informed.** Report progress after each delegation round.
|
|
2949
|
+
- **Respect node capabilities.** Don't send build tasks to read-only nodes. Don't push from nodes that aren't allowed to.
|
|
2950
|
+
- **Never fabricate tool results.** Always call the actual tool; never pretend you did.`;
|
|
2951
|
+
}
|
|
2952
|
+
});
|
|
2953
|
+
|
|
2954
|
+
// ../../oss/packages/daemon-core/src/mesh/mesh-sync.ts
|
|
2955
|
+
async function syncMeshes(transport) {
|
|
2956
|
+
const result = { pushed: 0, pulled: 0, deleted: 0, errors: [] };
|
|
2957
|
+
let remoteMeshes;
|
|
2958
|
+
try {
|
|
2959
|
+
const res = await transport.listRemoteMeshes();
|
|
2960
|
+
remoteMeshes = res.meshes;
|
|
2961
|
+
} catch (e) {
|
|
2962
|
+
result.errors.push(`Failed to list remote meshes: ${e.message}`);
|
|
2963
|
+
return result;
|
|
2964
|
+
}
|
|
2965
|
+
const localMeshes = listMeshes();
|
|
2966
|
+
const remoteByIdentity = new Map(remoteMeshes.map((m) => [m.repo_identity, m]));
|
|
2967
|
+
const localByIdentity = new Map(localMeshes.map((m) => [m.repoIdentity, m]));
|
|
2968
|
+
for (const local of localMeshes) {
|
|
2969
|
+
if (!remoteByIdentity.has(local.repoIdentity)) {
|
|
2970
|
+
try {
|
|
2971
|
+
await transport.createRemoteMesh({
|
|
2972
|
+
name: local.name,
|
|
2973
|
+
repo_identity: local.repoIdentity,
|
|
2974
|
+
repo_remote_url: local.repoRemoteUrl,
|
|
2975
|
+
default_branch: local.defaultBranch,
|
|
2976
|
+
policy: JSON.stringify(local.policy)
|
|
2977
|
+
});
|
|
2978
|
+
result.pushed++;
|
|
2979
|
+
} catch (e) {
|
|
2980
|
+
result.errors.push(`Push failed for "${local.name}": ${e.message}`);
|
|
2981
|
+
}
|
|
2982
|
+
}
|
|
2983
|
+
}
|
|
2984
|
+
for (const remote of remoteMeshes) {
|
|
2985
|
+
if (!localByIdentity.has(remote.repo_identity)) {
|
|
2986
|
+
try {
|
|
2987
|
+
let policy;
|
|
2988
|
+
try {
|
|
2989
|
+
policy = JSON.parse(remote.policy);
|
|
2990
|
+
} catch {
|
|
2991
|
+
policy = void 0;
|
|
2992
|
+
}
|
|
2993
|
+
createMesh({
|
|
2994
|
+
name: remote.name,
|
|
2995
|
+
repoIdentity: remote.repo_identity,
|
|
2996
|
+
repoRemoteUrl: remote.repo_remote_url || void 0,
|
|
2997
|
+
defaultBranch: remote.default_branch || void 0,
|
|
2998
|
+
policy
|
|
2999
|
+
});
|
|
3000
|
+
result.pulled++;
|
|
3001
|
+
} catch (e) {
|
|
3002
|
+
result.errors.push(`Pull failed for "${remote.name}": ${e.message}`);
|
|
3003
|
+
}
|
|
3004
|
+
}
|
|
3005
|
+
}
|
|
3006
|
+
return result;
|
|
3007
|
+
}
|
|
3008
|
+
var init_mesh_sync = __esm({
|
|
3009
|
+
"../../oss/packages/daemon-core/src/mesh/mesh-sync.ts"() {
|
|
3010
|
+
"use strict";
|
|
3011
|
+
init_mesh_config();
|
|
3012
|
+
}
|
|
3013
|
+
});
|
|
3014
|
+
|
|
2685
3015
|
// ../../oss/packages/daemon-core/src/config/state-store.ts
|
|
2686
3016
|
function isPlainObject2(value) {
|
|
2687
3017
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
2688
3018
|
}
|
|
2689
3019
|
function getStatePath() {
|
|
2690
|
-
return (0,
|
|
3020
|
+
return (0, import_path3.join)(getConfigDir(), "state.json");
|
|
2691
3021
|
}
|
|
2692
3022
|
function normalizeState(raw) {
|
|
2693
3023
|
const parsed = isPlainObject2(raw) ? raw : {};
|
|
@@ -2723,11 +3053,11 @@ function normalizeState(raw) {
|
|
|
2723
3053
|
}
|
|
2724
3054
|
function loadState() {
|
|
2725
3055
|
const statePath = getStatePath();
|
|
2726
|
-
if (!(0,
|
|
3056
|
+
if (!(0, import_fs3.existsSync)(statePath)) {
|
|
2727
3057
|
return { ...DEFAULT_STATE };
|
|
2728
3058
|
}
|
|
2729
3059
|
try {
|
|
2730
|
-
const raw = (0,
|
|
3060
|
+
const raw = (0, import_fs3.readFileSync)(statePath, "utf-8");
|
|
2731
3061
|
return normalizeState(JSON.parse(raw));
|
|
2732
3062
|
} catch {
|
|
2733
3063
|
return { ...DEFAULT_STATE };
|
|
@@ -2736,17 +3066,17 @@ function loadState() {
|
|
|
2736
3066
|
function saveState(state) {
|
|
2737
3067
|
const statePath = getStatePath();
|
|
2738
3068
|
const normalized = normalizeState(state);
|
|
2739
|
-
(0,
|
|
3069
|
+
(0, import_fs3.writeFileSync)(statePath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
|
|
2740
3070
|
}
|
|
2741
3071
|
function resetState() {
|
|
2742
3072
|
saveState({ ...DEFAULT_STATE });
|
|
2743
3073
|
}
|
|
2744
|
-
var
|
|
3074
|
+
var import_fs3, import_path3, DEFAULT_STATE;
|
|
2745
3075
|
var init_state_store = __esm({
|
|
2746
3076
|
"../../oss/packages/daemon-core/src/config/state-store.ts"() {
|
|
2747
3077
|
"use strict";
|
|
2748
|
-
|
|
2749
|
-
|
|
3078
|
+
import_fs3 = require("fs");
|
|
3079
|
+
import_path3 = require("path");
|
|
2750
3080
|
init_config();
|
|
2751
3081
|
DEFAULT_STATE = {
|
|
2752
3082
|
recentActivity: [],
|
|
@@ -2779,7 +3109,7 @@ function findCliCommand(command) {
|
|
|
2779
3109
|
if (path7.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
|
|
2780
3110
|
const candidate = trimmed.startsWith("~") ? path7.join((0, import_os2.homedir)(), trimmed.slice(1)) : trimmed;
|
|
2781
3111
|
const resolved = path7.isAbsolute(candidate) ? candidate : path7.resolve(candidate);
|
|
2782
|
-
return (0,
|
|
3112
|
+
return (0, import_fs4.existsSync)(resolved) ? resolved : null;
|
|
2783
3113
|
}
|
|
2784
3114
|
try {
|
|
2785
3115
|
const result = (0, import_child_process.execSync)(
|
|
@@ -2810,9 +3140,9 @@ function checkPathExists(paths) {
|
|
|
2810
3140
|
if (normalized.includes("*")) {
|
|
2811
3141
|
const username = home.split(/[\\/]/).pop() || "";
|
|
2812
3142
|
const resolved = normalized.replace("*", username);
|
|
2813
|
-
if ((0,
|
|
3143
|
+
if ((0, import_fs4.existsSync)(resolved)) return resolved;
|
|
2814
3144
|
} else {
|
|
2815
|
-
if ((0,
|
|
3145
|
+
if ((0, import_fs4.existsSync)(normalized)) return normalized;
|
|
2816
3146
|
}
|
|
2817
3147
|
}
|
|
2818
3148
|
return null;
|
|
@@ -2826,7 +3156,7 @@ async function detectIDEs(providerLoader) {
|
|
|
2826
3156
|
let resolvedCli = cliPath;
|
|
2827
3157
|
if (!resolvedCli && appPath && os31 === "darwin") {
|
|
2828
3158
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
2829
|
-
if ((0,
|
|
3159
|
+
if ((0, import_fs4.existsSync)(bundledCli)) resolvedCli = bundledCli;
|
|
2830
3160
|
}
|
|
2831
3161
|
if (!resolvedCli && appPath && os31 === "win32") {
|
|
2832
3162
|
const { dirname: dirname11 } = await import("path");
|
|
@@ -2839,7 +3169,7 @@ async function detectIDEs(providerLoader) {
|
|
|
2839
3169
|
`${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
|
|
2840
3170
|
];
|
|
2841
3171
|
for (const c of candidates) {
|
|
2842
|
-
if ((0,
|
|
3172
|
+
if ((0, import_fs4.existsSync)(c)) {
|
|
2843
3173
|
resolvedCli = c;
|
|
2844
3174
|
break;
|
|
2845
3175
|
}
|
|
@@ -2860,12 +3190,12 @@ async function detectIDEs(providerLoader) {
|
|
|
2860
3190
|
}
|
|
2861
3191
|
return results;
|
|
2862
3192
|
}
|
|
2863
|
-
var import_child_process,
|
|
3193
|
+
var import_child_process, import_fs4, import_os2, path7, BUILTIN_IDE_DEFINITIONS, registeredIDEs;
|
|
2864
3194
|
var init_ide_detector = __esm({
|
|
2865
3195
|
"../../oss/packages/daemon-core/src/detection/ide-detector.ts"() {
|
|
2866
3196
|
"use strict";
|
|
2867
3197
|
import_child_process = require("child_process");
|
|
2868
|
-
|
|
3198
|
+
import_fs4 = require("fs");
|
|
2869
3199
|
import_os2 = require("os");
|
|
2870
3200
|
path7 = __toESM(require("path"));
|
|
2871
3201
|
BUILTIN_IDE_DEFINITIONS = [];
|
|
@@ -2897,7 +3227,7 @@ function resolveCommandPath(command) {
|
|
|
2897
3227
|
if (isExplicitCommandPath(trimmed)) {
|
|
2898
3228
|
const expanded = expandHome(trimmed);
|
|
2899
3229
|
const candidate = path8.isAbsolute(expanded) ? expanded : path8.resolve(expanded);
|
|
2900
|
-
return (0,
|
|
3230
|
+
return (0, import_fs5.existsSync)(candidate) ? candidate : null;
|
|
2901
3231
|
}
|
|
2902
3232
|
return null;
|
|
2903
3233
|
}
|
|
@@ -2997,14 +3327,14 @@ async function detectCLI(cliId, providerLoader, options) {
|
|
|
2997
3327
|
const all = await detectCLIs(providerLoader, options);
|
|
2998
3328
|
return all.find((c) => c.id === resolvedId && c.installed) || null;
|
|
2999
3329
|
}
|
|
3000
|
-
var import_child_process2, os3, path8,
|
|
3330
|
+
var import_child_process2, os3, path8, import_fs5;
|
|
3001
3331
|
var init_cli_detector = __esm({
|
|
3002
3332
|
"../../oss/packages/daemon-core/src/detection/cli-detector.ts"() {
|
|
3003
3333
|
"use strict";
|
|
3004
3334
|
import_child_process2 = require("child_process");
|
|
3005
3335
|
os3 = __toESM(require("os"));
|
|
3006
3336
|
path8 = __toESM(require("path"));
|
|
3007
|
-
|
|
3337
|
+
import_fs5 = require("fs");
|
|
3008
3338
|
}
|
|
3009
3339
|
});
|
|
3010
3340
|
|
|
@@ -13173,16 +13503,16 @@ function ensureNodePtySpawnHelperPermissions(logFn) {
|
|
|
13173
13503
|
} catch {
|
|
13174
13504
|
}
|
|
13175
13505
|
}
|
|
13176
|
-
var
|
|
13506
|
+
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
13507
|
var init_dist = __esm({
|
|
13178
13508
|
"../../oss/packages/session-host-core/dist/index.mjs"() {
|
|
13179
13509
|
"use strict";
|
|
13180
|
-
|
|
13510
|
+
import_crypto4 = require("crypto");
|
|
13181
13511
|
path13 = __toESM(require("path"), 1);
|
|
13182
13512
|
os10 = __toESM(require("os"), 1);
|
|
13183
13513
|
path22 = __toESM(require("path"), 1);
|
|
13184
13514
|
net = __toESM(require("net"), 1);
|
|
13185
|
-
|
|
13515
|
+
import_crypto5 = require("crypto");
|
|
13186
13516
|
os22 = __toESM(require("os"), 1);
|
|
13187
13517
|
path32 = __toESM(require("path"), 1);
|
|
13188
13518
|
__require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
@@ -13258,7 +13588,7 @@ var init_dist = __esm({
|
|
|
13258
13588
|
SessionHostRegistry = class {
|
|
13259
13589
|
sessions = /* @__PURE__ */ new Map();
|
|
13260
13590
|
createSession(payload) {
|
|
13261
|
-
const sessionId = payload.sessionId || (0,
|
|
13591
|
+
const sessionId = payload.sessionId || (0, import_crypto4.randomUUID)();
|
|
13262
13592
|
if (this.sessions.has(sessionId)) {
|
|
13263
13593
|
throw new Error(`Session already exists: ${sessionId}`);
|
|
13264
13594
|
}
|
|
@@ -13529,7 +13859,7 @@ var init_dist = __esm({
|
|
|
13529
13859
|
async request(request) {
|
|
13530
13860
|
await this.connect();
|
|
13531
13861
|
if (!this.socket) throw new Error("Session host socket unavailable");
|
|
13532
|
-
const requestId = (0,
|
|
13862
|
+
const requestId = (0, import_crypto5.randomUUID)();
|
|
13533
13863
|
const envelope = {
|
|
13534
13864
|
kind: "request",
|
|
13535
13865
|
requestId,
|
|
@@ -34565,7 +34895,7 @@ function commandExists(command) {
|
|
|
34565
34895
|
const trimmed = command.trim();
|
|
34566
34896
|
if (!trimmed) return false;
|
|
34567
34897
|
if (isExplicitCommand(trimmed)) {
|
|
34568
|
-
return (0,
|
|
34898
|
+
return (0, import_fs6.existsSync)(expandExecutable(trimmed));
|
|
34569
34899
|
}
|
|
34570
34900
|
try {
|
|
34571
34901
|
(0, import_child_process6.execFileSync)(process.platform === "win32" ? "where" : "which", [trimmed], {
|
|
@@ -34696,14 +35026,14 @@ function resolveCliSessionBinding(provider, normalizedType, cliArgs, requestedRe
|
|
|
34696
35026
|
launchMode: "new"
|
|
34697
35027
|
};
|
|
34698
35028
|
}
|
|
34699
|
-
var os16, path17, crypto4,
|
|
35029
|
+
var os16, path17, crypto4, import_fs6, import_child_process6, chalkModule, chalkApi, DaemonCliManager;
|
|
34700
35030
|
var init_cli_manager = __esm({
|
|
34701
35031
|
"../../oss/packages/daemon-core/src/commands/cli-manager.ts"() {
|
|
34702
35032
|
"use strict";
|
|
34703
35033
|
os16 = __toESM(require("os"));
|
|
34704
35034
|
path17 = __toESM(require("path"));
|
|
34705
35035
|
crypto4 = __toESM(require("crypto"));
|
|
34706
|
-
|
|
35036
|
+
import_fs6 = require("fs");
|
|
34707
35037
|
import_child_process6 = require("child_process");
|
|
34708
35038
|
init_source2();
|
|
34709
35039
|
init_provider_cli_adapter();
|
|
@@ -38271,7 +38601,7 @@ var init_provider_loader = __esm({
|
|
|
38271
38601
|
return { updated: false };
|
|
38272
38602
|
}
|
|
38273
38603
|
const https = require("https");
|
|
38274
|
-
const { execSync:
|
|
38604
|
+
const { execSync: execSync9 } = require("child_process");
|
|
38275
38605
|
const metaPath = path18.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
38276
38606
|
let prevEtag = "";
|
|
38277
38607
|
let prevTimestamp = 0;
|
|
@@ -38336,7 +38666,7 @@ var init_provider_loader = __esm({
|
|
|
38336
38666
|
const tmpExtract = path18.join(os17.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
|
|
38337
38667
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
38338
38668
|
fs7.mkdirSync(tmpExtract, { recursive: true });
|
|
38339
|
-
|
|
38669
|
+
execSync9(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
38340
38670
|
const extracted = fs7.readdirSync(tmpExtract);
|
|
38341
38671
|
const rootDir = extracted.find(
|
|
38342
38672
|
(d) => fs7.statSync(path18.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
|
|
@@ -49059,6 +49389,7 @@ __export(src_exports, {
|
|
|
49059
49389
|
DEFAULT_DAEMON_PORT: () => DEFAULT_DAEMON_PORT,
|
|
49060
49390
|
DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS: () => DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS,
|
|
49061
49391
|
DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS: () => DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS,
|
|
49392
|
+
DEFAULT_MESH_POLICY: () => DEFAULT_MESH_POLICY,
|
|
49062
49393
|
DEFAULT_SESSION_HOST_APP_NAME: () => DEFAULT_SESSION_HOST_APP_NAME,
|
|
49063
49394
|
DEFAULT_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS: () => DEFAULT_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS,
|
|
49064
49395
|
DEFAULT_SESSION_HOST_READY_TIMEOUT_MS: () => DEFAULT_SESSION_HOST_READY_TIMEOUT_MS,
|
|
@@ -49092,11 +49423,13 @@ __export(src_exports, {
|
|
|
49092
49423
|
SessionHostPtyTransportFactory: () => SessionHostPtyTransportFactory,
|
|
49093
49424
|
TurnSnapshotTracker: () => TurnSnapshotTracker,
|
|
49094
49425
|
VersionArchive: () => VersionArchive,
|
|
49426
|
+
addNode: () => addNode,
|
|
49095
49427
|
appendRecentActivity: () => appendRecentActivity,
|
|
49096
49428
|
buildAssistantChatMessage: () => buildAssistantChatMessage,
|
|
49097
49429
|
buildChatMessage: () => buildChatMessage,
|
|
49098
49430
|
buildChatMessageSignature: () => buildChatMessageSignature,
|
|
49099
49431
|
buildChatTailDeliverySignature: () => buildChatTailDeliverySignature,
|
|
49432
|
+
buildCoordinatorSystemPrompt: () => buildCoordinatorSystemPrompt,
|
|
49100
49433
|
buildMachineInfo: () => buildMachineInfo,
|
|
49101
49434
|
buildPinnedGlobalInstallCommand: () => buildPinnedGlobalInstallCommand,
|
|
49102
49435
|
buildRuntimeSystemChatMessage: () => buildRuntimeSystemChatMessage,
|
|
@@ -49119,6 +49452,8 @@ __export(src_exports, {
|
|
|
49119
49452
|
createGitSnapshotStore: () => createGitSnapshotStore,
|
|
49120
49453
|
createGitWorkspaceMonitor: () => createGitWorkspaceMonitor,
|
|
49121
49454
|
createInteractionId: () => createInteractionId,
|
|
49455
|
+
createMesh: () => createMesh,
|
|
49456
|
+
deleteMesh: () => deleteMesh,
|
|
49122
49457
|
detectAllVersions: () => detectAllVersions,
|
|
49123
49458
|
detectCLIs: () => detectCLIs,
|
|
49124
49459
|
detectIDEs: () => detectIDEs,
|
|
@@ -49137,6 +49472,8 @@ __export(src_exports, {
|
|
|
49137
49472
|
getGitRepoStatus: () => getGitRepoStatus,
|
|
49138
49473
|
getHostMemorySnapshot: () => getHostMemorySnapshot,
|
|
49139
49474
|
getLogLevel: () => getLogLevel,
|
|
49475
|
+
getMesh: () => getMesh,
|
|
49476
|
+
getMeshByRepo: () => getMeshByRepo,
|
|
49140
49477
|
getNpmExecOptions: () => getNpmExecOptions,
|
|
49141
49478
|
getRecentActivity: () => getRecentActivity,
|
|
49142
49479
|
getRecentCommands: () => getRecentCommands,
|
|
@@ -49167,6 +49504,7 @@ __export(src_exports, {
|
|
|
49167
49504
|
launchIDE: () => launchIDE,
|
|
49168
49505
|
launchWithCdp: () => launchWithCdp,
|
|
49169
49506
|
listHostedCliRuntimes: () => listHostedCliRuntimes,
|
|
49507
|
+
listMeshes: () => listMeshes,
|
|
49170
49508
|
loadConfig: () => loadConfig,
|
|
49171
49509
|
loadState: () => loadState,
|
|
49172
49510
|
logCommand: () => logCommand,
|
|
@@ -49182,6 +49520,7 @@ __export(src_exports, {
|
|
|
49182
49520
|
normalizeInputEnvelope: () => normalizeInputEnvelope,
|
|
49183
49521
|
normalizeManagedStatus: () => normalizeManagedStatus,
|
|
49184
49522
|
normalizeMessageParts: () => normalizeMessageParts,
|
|
49523
|
+
normalizeRepoIdentity: () => normalizeRepoIdentity,
|
|
49185
49524
|
normalizeSessionModalFields: () => normalizeSessionModalFields,
|
|
49186
49525
|
parsePorcelainV2Status: () => parsePorcelainV2Status,
|
|
49187
49526
|
parseProviderSourceConfigUpdate: () => parseProviderSourceConfigUpdate,
|
|
@@ -49193,6 +49532,7 @@ __export(src_exports, {
|
|
|
49193
49532
|
readChatHistory: () => readChatHistory,
|
|
49194
49533
|
recordDebugTrace: () => recordDebugTrace,
|
|
49195
49534
|
registerExtensionProviders: () => registerExtensionProviders,
|
|
49535
|
+
removeNode: () => removeNode,
|
|
49196
49536
|
resetConfig: () => resetConfig,
|
|
49197
49537
|
resetDebugRuntimeConfig: () => resetDebugRuntimeConfig,
|
|
49198
49538
|
resetState: () => resetState,
|
|
@@ -49215,17 +49555,24 @@ __export(src_exports, {
|
|
|
49215
49555
|
spawnDetachedDaemonUpgradeHelper: () => spawnDetachedDaemonUpgradeHelper,
|
|
49216
49556
|
startDaemonDevSupport: () => startDaemonDevSupport,
|
|
49217
49557
|
summarizeGitStatus: () => summarizeGitStatus,
|
|
49558
|
+
syncMeshes: () => syncMeshes,
|
|
49218
49559
|
updateConfig: () => updateConfig,
|
|
49560
|
+
updateMesh: () => updateMesh,
|
|
49561
|
+
updateNode: () => updateNode,
|
|
49219
49562
|
upsertSavedProviderSession: () => upsertSavedProviderSession
|
|
49220
49563
|
});
|
|
49221
49564
|
var init_src = __esm({
|
|
49222
49565
|
"../../oss/packages/daemon-core/src/index.ts"() {
|
|
49223
49566
|
"use strict";
|
|
49567
|
+
init_repo_mesh_types();
|
|
49224
49568
|
init_git();
|
|
49225
49569
|
init_config();
|
|
49226
49570
|
init_workspaces();
|
|
49227
49571
|
init_recent_activity();
|
|
49228
49572
|
init_saved_sessions();
|
|
49573
|
+
init_mesh_config();
|
|
49574
|
+
init_coordinator_prompt();
|
|
49575
|
+
init_mesh_sync();
|
|
49229
49576
|
init_state_store();
|
|
49230
49577
|
init_ide_detector();
|
|
49231
49578
|
init_cli_detector();
|
|
@@ -64071,7 +64418,7 @@ var require_buffer_list = __commonJS({
|
|
|
64071
64418
|
}
|
|
64072
64419
|
}, {
|
|
64073
64420
|
key: "join",
|
|
64074
|
-
value: function
|
|
64421
|
+
value: function join35(s) {
|
|
64075
64422
|
if (this.length === 0) return "";
|
|
64076
64423
|
var p = this.head;
|
|
64077
64424
|
var ret = "" + p.data;
|
|
@@ -78130,13 +78477,13 @@ function splitStringBySpace(str) {
|
|
|
78130
78477
|
}
|
|
78131
78478
|
return pieces;
|
|
78132
78479
|
}
|
|
78133
|
-
var import_chardet, import_child_process12,
|
|
78480
|
+
var import_chardet, import_child_process12, import_fs7, import_node_path2, import_node_os4, import_node_crypto2, import_iconv_lite, ExternalEditor;
|
|
78134
78481
|
var init_esm2 = __esm({
|
|
78135
78482
|
"../../node_modules/@inquirer/external-editor/dist/esm/index.js"() {
|
|
78136
78483
|
"use strict";
|
|
78137
78484
|
import_chardet = __toESM(require_lib(), 1);
|
|
78138
78485
|
import_child_process12 = require("child_process");
|
|
78139
|
-
|
|
78486
|
+
import_fs7 = require("fs");
|
|
78140
78487
|
import_node_path2 = __toESM(require("path"), 1);
|
|
78141
78488
|
import_node_os4 = __toESM(require("os"), 1);
|
|
78142
78489
|
import_node_crypto2 = require("crypto");
|
|
@@ -78212,14 +78559,14 @@ var init_esm2 = __esm({
|
|
|
78212
78559
|
if (Object.prototype.hasOwnProperty.call(this.fileOptions, "mode")) {
|
|
78213
78560
|
opt.mode = this.fileOptions.mode;
|
|
78214
78561
|
}
|
|
78215
|
-
(0,
|
|
78562
|
+
(0, import_fs7.writeFileSync)(this.tempFile, this.text, opt);
|
|
78216
78563
|
} catch (createFileError) {
|
|
78217
78564
|
throw new CreateFileError(createFileError);
|
|
78218
78565
|
}
|
|
78219
78566
|
}
|
|
78220
78567
|
readTemporaryFile() {
|
|
78221
78568
|
try {
|
|
78222
|
-
const tempFileBuffer = (0,
|
|
78569
|
+
const tempFileBuffer = (0, import_fs7.readFileSync)(this.tempFile);
|
|
78223
78570
|
if (tempFileBuffer.length === 0) {
|
|
78224
78571
|
this.text = "";
|
|
78225
78572
|
} else {
|
|
@@ -78235,7 +78582,7 @@ var init_esm2 = __esm({
|
|
|
78235
78582
|
}
|
|
78236
78583
|
removeTemporaryFile() {
|
|
78237
78584
|
try {
|
|
78238
|
-
(0,
|
|
78585
|
+
(0, import_fs7.unlinkSync)(this.tempFile);
|
|
78239
78586
|
} catch (removeFileError) {
|
|
78240
78587
|
throw new RemoveFileError(removeFileError);
|
|
78241
78588
|
}
|
|
@@ -79937,25 +80284,25 @@ function resolvePackageVersion(options) {
|
|
|
79937
80284
|
const injectedVersion = options?.injectedVersion || "unknown";
|
|
79938
80285
|
const dir = options?.dirname || __dirname;
|
|
79939
80286
|
const possiblePaths = [
|
|
79940
|
-
(0,
|
|
79941
|
-
(0,
|
|
79942
|
-
(0,
|
|
80287
|
+
(0, import_path4.join)(dir, "..", "..", "package.json"),
|
|
80288
|
+
(0, import_path4.join)(dir, "..", "package.json"),
|
|
80289
|
+
(0, import_path4.join)(dir, "package.json")
|
|
79943
80290
|
];
|
|
79944
80291
|
for (const p of possiblePaths) {
|
|
79945
80292
|
try {
|
|
79946
|
-
const data = JSON.parse((0,
|
|
80293
|
+
const data = JSON.parse((0, import_fs8.readFileSync)(p, "utf-8"));
|
|
79947
80294
|
if (data.version) return data.version;
|
|
79948
80295
|
} catch {
|
|
79949
80296
|
}
|
|
79950
80297
|
}
|
|
79951
80298
|
return injectedVersion;
|
|
79952
80299
|
}
|
|
79953
|
-
var
|
|
80300
|
+
var import_fs8, import_path4;
|
|
79954
80301
|
var init_version = __esm({
|
|
79955
80302
|
"src/version.ts"() {
|
|
79956
80303
|
"use strict";
|
|
79957
|
-
|
|
79958
|
-
|
|
80304
|
+
import_fs8 = require("fs");
|
|
80305
|
+
import_path4 = require("path");
|
|
79959
80306
|
}
|
|
79960
80307
|
});
|
|
79961
80308
|
|
|
@@ -81873,7 +82220,7 @@ var require_filesystem = __commonJS({
|
|
|
81873
82220
|
var LDD_PATH = "/usr/bin/ldd";
|
|
81874
82221
|
var SELF_PATH = "/proc/self/exe";
|
|
81875
82222
|
var MAX_LENGTH = 2048;
|
|
81876
|
-
var
|
|
82223
|
+
var readFileSync21 = (path40) => {
|
|
81877
82224
|
const fd = fs24.openSync(path40, "r");
|
|
81878
82225
|
const buffer = Buffer.alloc(MAX_LENGTH);
|
|
81879
82226
|
const bytesRead = fs24.readSync(fd, buffer, 0, MAX_LENGTH, 0);
|
|
@@ -81898,7 +82245,7 @@ var require_filesystem = __commonJS({
|
|
|
81898
82245
|
module2.exports = {
|
|
81899
82246
|
LDD_PATH,
|
|
81900
82247
|
SELF_PATH,
|
|
81901
|
-
readFileSync:
|
|
82248
|
+
readFileSync: readFileSync21,
|
|
81902
82249
|
readFile: readFile2
|
|
81903
82250
|
};
|
|
81904
82251
|
}
|
|
@@ -81947,7 +82294,7 @@ var require_detect_libc = __commonJS({
|
|
|
81947
82294
|
"use strict";
|
|
81948
82295
|
var childProcess = require("child_process");
|
|
81949
82296
|
var { isLinux: isLinux2, getReport } = require_process();
|
|
81950
|
-
var { LDD_PATH, SELF_PATH, readFile: readFile2, readFileSync:
|
|
82297
|
+
var { LDD_PATH, SELF_PATH, readFile: readFile2, readFileSync: readFileSync21 } = require_filesystem();
|
|
81951
82298
|
var { interpreterPath } = require_elf();
|
|
81952
82299
|
var cachedFamilyInterpreter;
|
|
81953
82300
|
var cachedFamilyFilesystem;
|
|
@@ -82039,7 +82386,7 @@ var require_detect_libc = __commonJS({
|
|
|
82039
82386
|
}
|
|
82040
82387
|
cachedFamilyFilesystem = null;
|
|
82041
82388
|
try {
|
|
82042
|
-
const lddContent =
|
|
82389
|
+
const lddContent = readFileSync21(LDD_PATH);
|
|
82043
82390
|
cachedFamilyFilesystem = getFamilyFromLddContent(lddContent);
|
|
82044
82391
|
} catch (e) {
|
|
82045
82392
|
}
|
|
@@ -82064,7 +82411,7 @@ var require_detect_libc = __commonJS({
|
|
|
82064
82411
|
}
|
|
82065
82412
|
cachedFamilyInterpreter = null;
|
|
82066
82413
|
try {
|
|
82067
|
-
const selfContent =
|
|
82414
|
+
const selfContent = readFileSync21(SELF_PATH);
|
|
82068
82415
|
const path40 = interpreterPath(selfContent);
|
|
82069
82416
|
cachedFamilyInterpreter = familyFromInterpreterPath(path40);
|
|
82070
82417
|
} catch (e) {
|
|
@@ -82128,7 +82475,7 @@ var require_detect_libc = __commonJS({
|
|
|
82128
82475
|
}
|
|
82129
82476
|
cachedVersionFilesystem = null;
|
|
82130
82477
|
try {
|
|
82131
|
-
const lddContent =
|
|
82478
|
+
const lddContent = readFileSync21(LDD_PATH);
|
|
82132
82479
|
const versionMatch = lddContent.match(RE_GLIBC_VERSION);
|
|
82133
82480
|
if (versionMatch) {
|
|
82134
82481
|
cachedVersionFilesystem = versionMatch[1];
|
|
@@ -89392,7 +89739,7 @@ var init_adhdev_daemon = __esm({
|
|
|
89392
89739
|
init_version();
|
|
89393
89740
|
init_src();
|
|
89394
89741
|
init_runtime_defaults();
|
|
89395
|
-
pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.
|
|
89742
|
+
pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.67" });
|
|
89396
89743
|
AdhdevDaemon = class _AdhdevDaemon {
|
|
89397
89744
|
localHttpServer = null;
|
|
89398
89745
|
localWss = null;
|
|
@@ -90884,20 +91231,20 @@ async function startDaemonFlow() {
|
|
|
90884
91231
|
try {
|
|
90885
91232
|
const { AdhdevDaemon: AdhdevDaemon2 } = await Promise.resolve().then(() => (init_adhdev_daemon(), adhdev_daemon_exports));
|
|
90886
91233
|
const daemon = new AdhdevDaemon2();
|
|
90887
|
-
const { execSync:
|
|
91234
|
+
const { execSync: execSync9 } = await import("child_process");
|
|
90888
91235
|
const { getCurrentDaemonLogPath: getCurrentDaemonLogPath2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
90889
91236
|
const logPath = getCurrentDaemonLogPath2();
|
|
90890
91237
|
const os31 = await import("os");
|
|
90891
91238
|
const platform12 = os31.platform();
|
|
90892
91239
|
try {
|
|
90893
91240
|
if (platform12 === "win32") {
|
|
90894
|
-
|
|
91241
|
+
execSync9("start /B adhdev daemon >NUL 2>&1", {
|
|
90895
91242
|
timeout: 3e3,
|
|
90896
91243
|
stdio: "ignore",
|
|
90897
91244
|
shell: "cmd.exe"
|
|
90898
91245
|
});
|
|
90899
91246
|
} else {
|
|
90900
|
-
|
|
91247
|
+
execSync9("nohup adhdev daemon >/dev/null 2>&1 &", {
|
|
90901
91248
|
timeout: 3e3,
|
|
90902
91249
|
stdio: "ignore"
|
|
90903
91250
|
});
|
|
@@ -93336,7 +93683,7 @@ async function handleTraceCommand(options) {
|
|
|
93336
93683
|
async function runDaemonUpgrade(options, pkgVersion3) {
|
|
93337
93684
|
const { isDaemonRunning: isDaemonRunning2, stopDaemon: stopDaemon2 } = await Promise.resolve().then(() => (init_adhdev_daemon(), adhdev_daemon_exports));
|
|
93338
93685
|
const { stopManagedSessionHostProcess: stopManagedSessionHostProcess2 } = await Promise.resolve().then(() => (init_session_host(), session_host_exports));
|
|
93339
|
-
const { execSync:
|
|
93686
|
+
const { execSync: execSync9, spawn: spawn7 } = await import("child_process");
|
|
93340
93687
|
const fsMod = await import("fs");
|
|
93341
93688
|
const pathMod = await import("path");
|
|
93342
93689
|
console.log(source_default.bold("\n \u{1F504} ADHDev Upgrade\n"));
|
|
@@ -93356,10 +93703,10 @@ async function runDaemonUpgrade(options, pkgVersion3) {
|
|
|
93356
93703
|
while (!fsMod.existsSync(pathMod.join(gitRoot, ".git")) && gitRoot !== "/") {
|
|
93357
93704
|
gitRoot = pathMod.dirname(gitRoot);
|
|
93358
93705
|
}
|
|
93359
|
-
|
|
93706
|
+
execSync9("git pull --rebase", { cwd: gitRoot, stdio: "inherit" });
|
|
93360
93707
|
console.log(source_default.cyan("\n Building..."));
|
|
93361
|
-
|
|
93362
|
-
|
|
93708
|
+
execSync9("npm run build", { cwd: launcherDir, stdio: "inherit" });
|
|
93709
|
+
execSync9("npm link", { cwd: launcherDir, stdio: "inherit" });
|
|
93363
93710
|
console.log(source_default.green("\n \u2713 Build complete"));
|
|
93364
93711
|
} catch (e) {
|
|
93365
93712
|
console.log(source_default.red(`
|
|
@@ -93467,7 +93814,7 @@ function registerDaemonCommands(program2, pkgVersion3) {
|
|
|
93467
93814
|
}
|
|
93468
93815
|
});
|
|
93469
93816
|
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:
|
|
93817
|
+
const { spawn: spawn7, execSync: execSync9 } = await import("child_process");
|
|
93471
93818
|
const { DEFAULT_STANDALONE_SESSION_HOST_APP_NAME: DEFAULT_STANDALONE_SESSION_HOST_APP_NAME2, resolveSessionHostAppNameResolution: resolveSessionHostAppNameResolution2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
93472
93819
|
console.log(source_default.cyan("\n Starting ADHDev Standalone Server..."));
|
|
93473
93820
|
const args = [];
|
|
@@ -93485,7 +93832,7 @@ function registerDaemonCommands(program2, pkgVersion3) {
|
|
|
93485
93832
|
let bin = "npx";
|
|
93486
93833
|
const npxArgs = ["-y", "@adhdev/daemon-standalone@latest", ...args];
|
|
93487
93834
|
try {
|
|
93488
|
-
|
|
93835
|
+
execSync9("adhdev-standalone --help", { stdio: "ignore" });
|
|
93489
93836
|
bin = "adhdev-standalone";
|
|
93490
93837
|
} catch {
|
|
93491
93838
|
console.log(source_default.gray(" Standalone server package not found locally."));
|
|
@@ -95993,7 +96340,7 @@ var import_node_module3 = require("module");
|
|
|
95993
96340
|
var path39 = __toESM(require("path"));
|
|
95994
96341
|
init_source();
|
|
95995
96342
|
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", `
|
|
96343
|
+
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
96344
|
Examples:
|
|
95998
96345
|
adhdev mcp Local mode (requires: adhdev standalone)
|
|
95999
96346
|
adhdev mcp --api-key adk_xxx Cloud mode (no local daemon needed)
|
|
@@ -96021,6 +96368,7 @@ Tools available (cloud): list_daemons, list_sessions, launch_session, stop_sess
|
|
|
96021
96368
|
if (opts.port && opts.port !== "3847") args.push("--port", opts.port);
|
|
96022
96369
|
if (opts.password) args.push("--password", opts.password);
|
|
96023
96370
|
if (opts.baseUrl) args.push("--base-url", opts.baseUrl);
|
|
96371
|
+
if (opts.repoMesh) args.push("--repo-mesh", opts.repoMesh);
|
|
96024
96372
|
const env3 = { ...process.env };
|
|
96025
96373
|
if (opts.apiKey) env3.ADHDEV_API_KEY = opts.apiKey;
|
|
96026
96374
|
if (opts.password) env3.ADHDEV_PASSWORD = opts.password;
|
|
@@ -96055,6 +96403,283 @@ function resolveMcpBin() {
|
|
|
96055
96403
|
}
|
|
96056
96404
|
}
|
|
96057
96405
|
|
|
96406
|
+
// src/cli/mesh-commands.ts
|
|
96407
|
+
init_source();
|
|
96408
|
+
var import_node_child_process4 = require("child_process");
|
|
96409
|
+
init_src();
|
|
96410
|
+
function registerMeshCommands(program2) {
|
|
96411
|
+
const mesh = program2.command("mesh").description("Manage Repo Meshes \u2014 repo-scoped execution environments");
|
|
96412
|
+
mesh.command("list").description("List all configured meshes").action(() => {
|
|
96413
|
+
const meshes = listMeshes();
|
|
96414
|
+
if (meshes.length === 0) {
|
|
96415
|
+
console.log(source_default.gray("No meshes configured. Create one with: adhdev mesh create <name>"));
|
|
96416
|
+
return;
|
|
96417
|
+
}
|
|
96418
|
+
console.log(source_default.bold(`
|
|
96419
|
+
Repo Meshes (${meshes.length})
|
|
96420
|
+
`));
|
|
96421
|
+
for (const m of meshes) {
|
|
96422
|
+
const nodeCount = m.nodes.length;
|
|
96423
|
+
const statusIcon = nodeCount > 0 ? source_default.green("\u25CF") : source_default.yellow("\u25CB");
|
|
96424
|
+
console.log(` ${statusIcon} ${source_default.bold(m.name)} ${source_default.gray(m.id)}`);
|
|
96425
|
+
console.log(` ${source_default.gray("repo:")} ${m.repoIdentity}`);
|
|
96426
|
+
console.log(` ${source_default.gray("nodes:")} ${nodeCount} ${source_default.gray("created:")} ${m.createdAt.split("T")[0]}`);
|
|
96427
|
+
console.log();
|
|
96428
|
+
}
|
|
96429
|
+
});
|
|
96430
|
+
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) => {
|
|
96431
|
+
let repoRemoteUrl = opts.remoteUrl;
|
|
96432
|
+
let repoIdentity = opts.identity;
|
|
96433
|
+
let defaultBranch = opts.branch;
|
|
96434
|
+
if (!repoRemoteUrl && !repoIdentity) {
|
|
96435
|
+
try {
|
|
96436
|
+
repoRemoteUrl = (0, import_node_child_process4.execSync)("git remote get-url origin", {
|
|
96437
|
+
encoding: "utf-8",
|
|
96438
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
96439
|
+
}).trim();
|
|
96440
|
+
console.log(source_default.gray(` Detected remote: ${repoRemoteUrl}`));
|
|
96441
|
+
} catch {
|
|
96442
|
+
console.error(source_default.red("\u2717 Could not detect Git remote. Use --remote-url or --identity."));
|
|
96443
|
+
process.exit(1);
|
|
96444
|
+
}
|
|
96445
|
+
}
|
|
96446
|
+
if (!defaultBranch) {
|
|
96447
|
+
try {
|
|
96448
|
+
defaultBranch = (0, import_node_child_process4.execSync)("git symbolic-ref refs/remotes/origin/HEAD", {
|
|
96449
|
+
encoding: "utf-8",
|
|
96450
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
96451
|
+
}).trim().replace("refs/remotes/origin/", "");
|
|
96452
|
+
} catch {
|
|
96453
|
+
try {
|
|
96454
|
+
defaultBranch = (0, import_node_child_process4.execSync)("git branch --show-current", {
|
|
96455
|
+
encoding: "utf-8",
|
|
96456
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
96457
|
+
}).trim();
|
|
96458
|
+
} catch {
|
|
96459
|
+
defaultBranch = "main";
|
|
96460
|
+
}
|
|
96461
|
+
}
|
|
96462
|
+
}
|
|
96463
|
+
try {
|
|
96464
|
+
const mesh2 = createMesh({
|
|
96465
|
+
name,
|
|
96466
|
+
repoRemoteUrl,
|
|
96467
|
+
repoIdentity,
|
|
96468
|
+
defaultBranch
|
|
96469
|
+
});
|
|
96470
|
+
console.log(source_default.green(`
|
|
96471
|
+
\u2713 Mesh created: ${source_default.bold(mesh2.name)}`));
|
|
96472
|
+
console.log(source_default.gray(` ID: ${mesh2.id}`));
|
|
96473
|
+
console.log(source_default.gray(` Repo: ${mesh2.repoIdentity}`));
|
|
96474
|
+
console.log(source_default.gray(` Branch: ${mesh2.defaultBranch || "auto"}`));
|
|
96475
|
+
if (opts.addCurrent) {
|
|
96476
|
+
const cwd = process.cwd();
|
|
96477
|
+
try {
|
|
96478
|
+
const node = addNode(mesh2.id, { workspace: cwd });
|
|
96479
|
+
if (node) {
|
|
96480
|
+
console.log(source_default.green(` \u2713 Added current workspace as node: ${source_default.gray(cwd)}`));
|
|
96481
|
+
console.log(source_default.gray(` Node ID: ${node.id}`));
|
|
96482
|
+
}
|
|
96483
|
+
} catch (e) {
|
|
96484
|
+
console.error(source_default.yellow(` \u26A0 Could not add current workspace: ${e.message}`));
|
|
96485
|
+
}
|
|
96486
|
+
}
|
|
96487
|
+
console.log();
|
|
96488
|
+
console.log(source_default.gray(" Next steps:"));
|
|
96489
|
+
console.log(source_default.gray(` adhdev mesh add-node ${mesh2.id} \u2014 Add a workspace to this mesh`));
|
|
96490
|
+
console.log(source_default.gray(` adhdev mcp --repo-mesh ${mesh2.id} \u2014 Start MCP server in mesh mode`));
|
|
96491
|
+
console.log();
|
|
96492
|
+
} catch (e) {
|
|
96493
|
+
console.error(source_default.red(`\u2717 ${e.message}`));
|
|
96494
|
+
process.exit(1);
|
|
96495
|
+
}
|
|
96496
|
+
});
|
|
96497
|
+
mesh.command("show <mesh_id>").description("Show mesh details and nodes").action((meshId) => {
|
|
96498
|
+
const m = getMesh(meshId);
|
|
96499
|
+
if (!m) {
|
|
96500
|
+
console.error(source_default.red(`\u2717 Mesh not found: ${meshId}`));
|
|
96501
|
+
process.exit(1);
|
|
96502
|
+
}
|
|
96503
|
+
console.log(source_default.bold(`
|
|
96504
|
+
${m.name} ${source_default.gray(m.id)}`));
|
|
96505
|
+
console.log(` ${source_default.gray("repo:")} ${m.repoIdentity}`);
|
|
96506
|
+
if (m.repoRemoteUrl) console.log(` ${source_default.gray("remote:")} ${m.repoRemoteUrl}`);
|
|
96507
|
+
if (m.defaultBranch) console.log(` ${source_default.gray("branch:")} ${m.defaultBranch}`);
|
|
96508
|
+
console.log(` ${source_default.gray("created:")} ${m.createdAt}`);
|
|
96509
|
+
console.log(` ${source_default.gray("updated:")} ${m.updatedAt}`);
|
|
96510
|
+
console.log(source_default.bold("\n Policy"));
|
|
96511
|
+
console.log(` ${source_default.gray("checkpoint after task:")} ${m.policy.requirePostTaskCheckpoint ? "yes" : "no"}`);
|
|
96512
|
+
console.log(` ${source_default.gray("push requires approval:")} ${m.policy.requireApprovalForPush ? "yes" : "no"}`);
|
|
96513
|
+
console.log(` ${source_default.gray("dirty workspace:")} ${m.policy.dirtyWorkspaceBehavior}`);
|
|
96514
|
+
console.log(` ${source_default.gray("max parallel tasks:")} ${m.policy.maxParallelTasks}`);
|
|
96515
|
+
console.log(source_default.bold(`
|
|
96516
|
+
Nodes (${m.nodes.length})`));
|
|
96517
|
+
if (m.nodes.length === 0) {
|
|
96518
|
+
console.log(source_default.gray(" No nodes. Add one with: adhdev mesh add-node " + meshId));
|
|
96519
|
+
} else {
|
|
96520
|
+
for (const n of m.nodes) {
|
|
96521
|
+
const label = n.isLocalWorktree ? source_default.cyan("[worktree]") : "";
|
|
96522
|
+
console.log(` ${source_default.gray("\u25CF")} ${n.workspace} ${label} ${source_default.gray(n.id)}`);
|
|
96523
|
+
if (n.policy.readOnly) console.log(` ${source_default.yellow("read-only")}`);
|
|
96524
|
+
if (Object.keys(n.userOverrides).length > 0) {
|
|
96525
|
+
console.log(` ${source_default.gray("overrides:")} ${JSON.stringify(n.userOverrides)}`);
|
|
96526
|
+
}
|
|
96527
|
+
}
|
|
96528
|
+
}
|
|
96529
|
+
console.log();
|
|
96530
|
+
});
|
|
96531
|
+
mesh.command("delete <mesh_id>").description("Delete a mesh").action((meshId) => {
|
|
96532
|
+
const m = getMesh(meshId);
|
|
96533
|
+
if (!m) {
|
|
96534
|
+
console.error(source_default.red(`\u2717 Mesh not found: ${meshId}`));
|
|
96535
|
+
process.exit(1);
|
|
96536
|
+
}
|
|
96537
|
+
const ok = deleteMesh(meshId);
|
|
96538
|
+
if (ok) {
|
|
96539
|
+
console.log(source_default.green(` \u2713 Deleted mesh: ${m.name} (${meshId})`));
|
|
96540
|
+
} else {
|
|
96541
|
+
console.error(source_default.red(`\u2717 Failed to delete mesh: ${meshId}`));
|
|
96542
|
+
process.exit(1);
|
|
96543
|
+
}
|
|
96544
|
+
});
|
|
96545
|
+
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) => {
|
|
96546
|
+
const m = getMesh(meshId);
|
|
96547
|
+
if (!m) {
|
|
96548
|
+
console.error(source_default.red(`\u2717 Mesh not found: ${meshId}`));
|
|
96549
|
+
process.exit(1);
|
|
96550
|
+
}
|
|
96551
|
+
const workspace = opts.workspace || process.cwd();
|
|
96552
|
+
try {
|
|
96553
|
+
const node = addNode(meshId, {
|
|
96554
|
+
workspace,
|
|
96555
|
+
isLocalWorktree: opts.worktree,
|
|
96556
|
+
policy: opts.readOnly ? { readOnly: true } : {}
|
|
96557
|
+
});
|
|
96558
|
+
if (node) {
|
|
96559
|
+
console.log(source_default.green(` \u2713 Node added to ${m.name}`));
|
|
96560
|
+
console.log(source_default.gray(` ID: ${node.id}`));
|
|
96561
|
+
console.log(source_default.gray(` Workspace: ${workspace}`));
|
|
96562
|
+
if (opts.worktree) console.log(source_default.gray(` Type: local worktree`));
|
|
96563
|
+
if (opts.readOnly) console.log(source_default.gray(` Policy: read-only`));
|
|
96564
|
+
} else {
|
|
96565
|
+
console.error(source_default.red(`\u2717 Mesh not found`));
|
|
96566
|
+
process.exit(1);
|
|
96567
|
+
}
|
|
96568
|
+
} catch (e) {
|
|
96569
|
+
console.error(source_default.red(`\u2717 ${e.message}`));
|
|
96570
|
+
process.exit(1);
|
|
96571
|
+
}
|
|
96572
|
+
});
|
|
96573
|
+
mesh.command("remove-node <mesh_id> <node_id>").description("Remove a node from the mesh").action((meshId, nodeId) => {
|
|
96574
|
+
const ok = removeNode(meshId, nodeId);
|
|
96575
|
+
if (ok) {
|
|
96576
|
+
console.log(source_default.green(` \u2713 Node removed: ${nodeId}`));
|
|
96577
|
+
} else {
|
|
96578
|
+
console.error(source_default.red(`\u2717 Node or mesh not found`));
|
|
96579
|
+
process.exit(1);
|
|
96580
|
+
}
|
|
96581
|
+
});
|
|
96582
|
+
mesh.command("status <mesh_id>").description("Probe all mesh nodes and show health").action(async (meshId) => {
|
|
96583
|
+
const m = getMesh(meshId);
|
|
96584
|
+
if (!m) {
|
|
96585
|
+
console.error(source_default.red(`\u2717 Mesh not found: ${meshId}`));
|
|
96586
|
+
process.exit(1);
|
|
96587
|
+
}
|
|
96588
|
+
console.log(source_default.bold(`
|
|
96589
|
+
${m.name} \u2014 Node Status
|
|
96590
|
+
`));
|
|
96591
|
+
if (m.nodes.length === 0) {
|
|
96592
|
+
console.log(source_default.gray(" No nodes configured."));
|
|
96593
|
+
return;
|
|
96594
|
+
}
|
|
96595
|
+
for (const node of m.nodes) {
|
|
96596
|
+
let gitInfo = "";
|
|
96597
|
+
let healthIcon = source_default.gray("?");
|
|
96598
|
+
let health = "unknown";
|
|
96599
|
+
try {
|
|
96600
|
+
const branch = (0, import_node_child_process4.execSync)(`git -C "${node.workspace}" branch --show-current`, {
|
|
96601
|
+
encoding: "utf-8",
|
|
96602
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
96603
|
+
}).trim();
|
|
96604
|
+
const status = (0, import_node_child_process4.execSync)(`git -C "${node.workspace}" status --porcelain`, {
|
|
96605
|
+
encoding: "utf-8",
|
|
96606
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
96607
|
+
}).trim();
|
|
96608
|
+
const isDirty = status.length > 0;
|
|
96609
|
+
const changedFiles = isDirty ? status.split("\n").length : 0;
|
|
96610
|
+
if (isDirty) {
|
|
96611
|
+
health = "dirty";
|
|
96612
|
+
healthIcon = source_default.yellow("\u25CF");
|
|
96613
|
+
gitInfo = `${source_default.cyan(branch)} ${source_default.yellow(`(${changedFiles} changed)`)}`;
|
|
96614
|
+
} else {
|
|
96615
|
+
health = "clean";
|
|
96616
|
+
healthIcon = source_default.green("\u25CF");
|
|
96617
|
+
gitInfo = `${source_default.cyan(branch)} ${source_default.green("clean")}`;
|
|
96618
|
+
}
|
|
96619
|
+
} catch {
|
|
96620
|
+
health = "error";
|
|
96621
|
+
healthIcon = source_default.red("\u2717");
|
|
96622
|
+
gitInfo = source_default.red("git probe failed");
|
|
96623
|
+
}
|
|
96624
|
+
const label = node.isLocalWorktree ? source_default.gray(" [worktree]") : "";
|
|
96625
|
+
console.log(` ${healthIcon} ${node.workspace}${label} ${source_default.gray(node.id.slice(0, 12))}`);
|
|
96626
|
+
console.log(` ${gitInfo}`);
|
|
96627
|
+
if (node.policy.readOnly) console.log(` ${source_default.yellow("read-only")}`);
|
|
96628
|
+
console.log();
|
|
96629
|
+
}
|
|
96630
|
+
});
|
|
96631
|
+
mesh.command("sync").description("Sync local mesh config with cloud (push/pull)").action(async () => {
|
|
96632
|
+
try {
|
|
96633
|
+
const { syncMeshes: syncMeshes2, loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
96634
|
+
const config2 = loadConfig2();
|
|
96635
|
+
const apiKey = process.env.ADHDEV_API_KEY;
|
|
96636
|
+
if (!apiKey) {
|
|
96637
|
+
console.error(source_default.red("\u2717 No API key set. Export ADHDEV_API_KEY or use: adhdev setup"));
|
|
96638
|
+
process.exit(1);
|
|
96639
|
+
}
|
|
96640
|
+
const baseUrl = config2.serverUrl || "https://api.adhf.dev";
|
|
96641
|
+
const transport = {
|
|
96642
|
+
async listRemoteMeshes() {
|
|
96643
|
+
const res = await fetch(`${baseUrl}/api/v1/repo-meshes`, {
|
|
96644
|
+
headers: { "Authorization": `Bearer ${apiKey}`, "Content-Type": "application/json" }
|
|
96645
|
+
});
|
|
96646
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
96647
|
+
return res.json();
|
|
96648
|
+
},
|
|
96649
|
+
async createRemoteMesh(data) {
|
|
96650
|
+
const res = await fetch(`${baseUrl}/api/v1/repo-meshes`, {
|
|
96651
|
+
method: "POST",
|
|
96652
|
+
headers: { "Authorization": `Bearer ${apiKey}`, "Content-Type": "application/json" },
|
|
96653
|
+
body: JSON.stringify(data)
|
|
96654
|
+
});
|
|
96655
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
96656
|
+
return res.json();
|
|
96657
|
+
},
|
|
96658
|
+
async deleteRemoteMesh(meshId) {
|
|
96659
|
+
const res = await fetch(`${baseUrl}/api/v1/repo-meshes/${meshId}`, {
|
|
96660
|
+
method: "DELETE",
|
|
96661
|
+
headers: { "Authorization": `Bearer ${apiKey}` }
|
|
96662
|
+
});
|
|
96663
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
96664
|
+
}
|
|
96665
|
+
};
|
|
96666
|
+
console.log(source_default.gray(" Syncing with cloud..."));
|
|
96667
|
+
const result = await syncMeshes2(transport);
|
|
96668
|
+
if (result.pushed > 0) console.log(source_default.green(` \u2713 Pushed ${result.pushed} mesh${result.pushed > 1 ? "es" : ""} to cloud`));
|
|
96669
|
+
if (result.pulled > 0) console.log(source_default.green(` \u2713 Pulled ${result.pulled} mesh${result.pulled > 1 ? "es" : ""} from cloud`));
|
|
96670
|
+
if (result.pushed === 0 && result.pulled === 0 && result.errors.length === 0) {
|
|
96671
|
+
console.log(source_default.gray(" Already in sync."));
|
|
96672
|
+
}
|
|
96673
|
+
for (const err of result.errors) {
|
|
96674
|
+
console.error(source_default.yellow(` \u26A0 ${err}`));
|
|
96675
|
+
}
|
|
96676
|
+
} catch (e) {
|
|
96677
|
+
console.error(source_default.red(`\u2717 Sync failed: ${e.message}`));
|
|
96678
|
+
process.exit(1);
|
|
96679
|
+
}
|
|
96680
|
+
});
|
|
96681
|
+
}
|
|
96682
|
+
|
|
96058
96683
|
// src/cli/index.ts
|
|
96059
96684
|
init_version();
|
|
96060
96685
|
var pkgVersion2 = resolvePackageVersion();
|
|
@@ -96075,6 +96700,7 @@ registerProviderCommands(program);
|
|
|
96075
96700
|
registerCdpCommands(program);
|
|
96076
96701
|
registerServiceCommands(program);
|
|
96077
96702
|
registerMcpCommands(program);
|
|
96703
|
+
registerMeshCommands(program);
|
|
96078
96704
|
void (async () => {
|
|
96079
96705
|
const helperMode = await maybeRunDaemonUpgradeHelperFromEnv();
|
|
96080
96706
|
if (helperMode) {
|
|
@@ -96102,6 +96728,8 @@ void (async () => {
|
|
|
96102
96728
|
console.log(source_default.gray(" adhdev trace --category session_host \u2014 Inspect structured daemon trace"));
|
|
96103
96729
|
console.log(source_default.gray(" adhdev service \u2014 Manage OS background auto-start service"));
|
|
96104
96730
|
console.log(source_default.gray(" adhdev mcp \u2014 Start MCP server (expose agents to Claude Desktop, etc.)"));
|
|
96731
|
+
console.log(source_default.gray(" adhdev mesh list \u2014 List configured Repo Meshes"));
|
|
96732
|
+
console.log(source_default.gray(" adhdev mesh create myapp \u2014 Create a mesh for the current Git repo"));
|
|
96105
96733
|
console.log(source_default.gray(" adhdev provider ... \u2014 Provider development commands"));
|
|
96106
96734
|
console.log(source_default.gray(" adhdev cdp ... \u2014 CDP debugging tools"));
|
|
96107
96735
|
console.log();
|