@adhdev/daemon-standalone 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/index.js +506 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/public/assets/index-BZheomX7.css +1 -0
- package/public/assets/index-CxWt41PK.js +101 -0
- package/public/index.html +2 -2
- package/public/assets/index-Xf0Kv1tq.js +0 -94
- package/public/assets/index-uPjAf7pw.css +0 -1
package/dist/index.js
CHANGED
|
@@ -27884,6 +27884,20 @@ var require_dist2 = __commonJS({
|
|
|
27884
27884
|
mod
|
|
27885
27885
|
));
|
|
27886
27886
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
27887
|
+
var DEFAULT_MESH_POLICY;
|
|
27888
|
+
var init_repo_mesh_types = __esm2({
|
|
27889
|
+
"src/repo-mesh-types.ts"() {
|
|
27890
|
+
"use strict";
|
|
27891
|
+
DEFAULT_MESH_POLICY = {
|
|
27892
|
+
requirePreTaskCheckpoint: false,
|
|
27893
|
+
requirePostTaskCheckpoint: true,
|
|
27894
|
+
requireApprovalForPush: true,
|
|
27895
|
+
requireApprovalForDestructiveGit: true,
|
|
27896
|
+
dirtyWorkspaceBehavior: "warn",
|
|
27897
|
+
maxParallelTasks: 2
|
|
27898
|
+
};
|
|
27899
|
+
}
|
|
27900
|
+
});
|
|
27887
27901
|
var config_exports = {};
|
|
27888
27902
|
__export2(config_exports, {
|
|
27889
27903
|
generateMachineId: () => generateMachineId,
|
|
@@ -28125,6 +28139,276 @@ var require_dist2 = __commonJS({
|
|
|
28125
28139
|
MACHINE_ID_PREFIX = "mach_";
|
|
28126
28140
|
}
|
|
28127
28141
|
});
|
|
28142
|
+
var mesh_config_exports = {};
|
|
28143
|
+
__export2(mesh_config_exports, {
|
|
28144
|
+
addNode: () => addNode,
|
|
28145
|
+
createMesh: () => createMesh,
|
|
28146
|
+
deleteMesh: () => deleteMesh,
|
|
28147
|
+
getMesh: () => getMesh,
|
|
28148
|
+
getMeshByRepo: () => getMeshByRepo,
|
|
28149
|
+
listMeshes: () => listMeshes,
|
|
28150
|
+
normalizeRepoIdentity: () => normalizeRepoIdentity,
|
|
28151
|
+
removeNode: () => removeNode,
|
|
28152
|
+
updateMesh: () => updateMesh,
|
|
28153
|
+
updateNode: () => updateNode
|
|
28154
|
+
});
|
|
28155
|
+
function getMeshConfigPath() {
|
|
28156
|
+
return (0, import_path22.join)(getConfigDir(), "meshes.json");
|
|
28157
|
+
}
|
|
28158
|
+
function loadMeshConfig() {
|
|
28159
|
+
const path26 = getMeshConfigPath();
|
|
28160
|
+
if (!(0, import_fs2.existsSync)(path26)) return { meshes: [] };
|
|
28161
|
+
try {
|
|
28162
|
+
const raw = JSON.parse((0, import_fs2.readFileSync)(path26, "utf-8"));
|
|
28163
|
+
if (!raw || !Array.isArray(raw.meshes)) return { meshes: [] };
|
|
28164
|
+
return raw;
|
|
28165
|
+
} catch {
|
|
28166
|
+
return { meshes: [] };
|
|
28167
|
+
}
|
|
28168
|
+
}
|
|
28169
|
+
function saveMeshConfig(config2) {
|
|
28170
|
+
const path26 = getMeshConfigPath();
|
|
28171
|
+
(0, import_fs2.writeFileSync)(path26, JSON.stringify(config2, null, 2), { encoding: "utf-8", mode: 384 });
|
|
28172
|
+
}
|
|
28173
|
+
function normalizeRepoIdentity(remoteUrl) {
|
|
28174
|
+
let identity = remoteUrl.trim();
|
|
28175
|
+
if (identity.startsWith("http://") || identity.startsWith("https://")) {
|
|
28176
|
+
try {
|
|
28177
|
+
const url2 = new URL(identity);
|
|
28178
|
+
const path26 = url2.pathname.replace(/^\//, "").replace(/\.git$/, "");
|
|
28179
|
+
return `${url2.hostname}/${path26}`;
|
|
28180
|
+
} catch {
|
|
28181
|
+
}
|
|
28182
|
+
}
|
|
28183
|
+
const sshMatch = identity.match(/^(?:ssh:\/\/)?[\w.-]+@([\w.-]+)[:/]([\w.\-/]+?)(?:\.git)?$/);
|
|
28184
|
+
if (sshMatch) return `${sshMatch[1]}/${sshMatch[2]}`;
|
|
28185
|
+
return identity;
|
|
28186
|
+
}
|
|
28187
|
+
function listMeshes() {
|
|
28188
|
+
return loadMeshConfig().meshes;
|
|
28189
|
+
}
|
|
28190
|
+
function getMesh(meshId) {
|
|
28191
|
+
return loadMeshConfig().meshes.find((m) => m.id === meshId);
|
|
28192
|
+
}
|
|
28193
|
+
function getMeshByRepo(repoIdentity) {
|
|
28194
|
+
return loadMeshConfig().meshes.find((m) => m.repoIdentity === repoIdentity);
|
|
28195
|
+
}
|
|
28196
|
+
function createMesh(opts) {
|
|
28197
|
+
const config2 = loadMeshConfig();
|
|
28198
|
+
if (config2.meshes.length >= 20) {
|
|
28199
|
+
throw new Error("Maximum 20 meshes allowed");
|
|
28200
|
+
}
|
|
28201
|
+
const repoIdentity = opts.repoIdentity || (opts.repoRemoteUrl ? normalizeRepoIdentity(opts.repoRemoteUrl) : "");
|
|
28202
|
+
if (!repoIdentity) throw new Error("Either repoRemoteUrl or repoIdentity is required");
|
|
28203
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
28204
|
+
const mesh = {
|
|
28205
|
+
id: `mesh_${(0, import_crypto32.randomUUID)().replace(/-/g, "")}`,
|
|
28206
|
+
name: opts.name.trim().slice(0, 100),
|
|
28207
|
+
repoIdentity,
|
|
28208
|
+
repoRemoteUrl: opts.repoRemoteUrl,
|
|
28209
|
+
defaultBranch: opts.defaultBranch,
|
|
28210
|
+
policy: { ...DEFAULT_MESH_POLICY, ...opts.policy },
|
|
28211
|
+
coordinator: opts.coordinator || {},
|
|
28212
|
+
nodes: [],
|
|
28213
|
+
createdAt: now,
|
|
28214
|
+
updatedAt: now
|
|
28215
|
+
};
|
|
28216
|
+
config2.meshes.push(mesh);
|
|
28217
|
+
saveMeshConfig(config2);
|
|
28218
|
+
return mesh;
|
|
28219
|
+
}
|
|
28220
|
+
function updateMesh(meshId, opts) {
|
|
28221
|
+
const config2 = loadMeshConfig();
|
|
28222
|
+
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
28223
|
+
if (!mesh) return void 0;
|
|
28224
|
+
if (opts.name !== void 0) mesh.name = opts.name.trim().slice(0, 100);
|
|
28225
|
+
if (opts.defaultBranch !== void 0) mesh.defaultBranch = opts.defaultBranch;
|
|
28226
|
+
if (opts.policy) mesh.policy = { ...mesh.policy, ...opts.policy };
|
|
28227
|
+
if (opts.coordinator) mesh.coordinator = opts.coordinator;
|
|
28228
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
28229
|
+
saveMeshConfig(config2);
|
|
28230
|
+
return mesh;
|
|
28231
|
+
}
|
|
28232
|
+
function deleteMesh(meshId) {
|
|
28233
|
+
const config2 = loadMeshConfig();
|
|
28234
|
+
const idx = config2.meshes.findIndex((m) => m.id === meshId);
|
|
28235
|
+
if (idx === -1) return false;
|
|
28236
|
+
config2.meshes.splice(idx, 1);
|
|
28237
|
+
saveMeshConfig(config2);
|
|
28238
|
+
return true;
|
|
28239
|
+
}
|
|
28240
|
+
function addNode(meshId, opts) {
|
|
28241
|
+
const config2 = loadMeshConfig();
|
|
28242
|
+
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
28243
|
+
if (!mesh) return void 0;
|
|
28244
|
+
if (mesh.nodes.length >= 10) {
|
|
28245
|
+
throw new Error("Maximum 10 nodes per mesh");
|
|
28246
|
+
}
|
|
28247
|
+
if (mesh.nodes.some((n) => n.workspace === opts.workspace)) {
|
|
28248
|
+
throw new Error("This workspace is already in the mesh");
|
|
28249
|
+
}
|
|
28250
|
+
const node = {
|
|
28251
|
+
id: `node_${(0, import_crypto32.randomUUID)().replace(/-/g, "")}`,
|
|
28252
|
+
workspace: opts.workspace.trim(),
|
|
28253
|
+
repoRoot: opts.repoRoot,
|
|
28254
|
+
userOverrides: opts.userOverrides || {},
|
|
28255
|
+
policy: opts.policy || {},
|
|
28256
|
+
isLocalWorktree: opts.isLocalWorktree
|
|
28257
|
+
};
|
|
28258
|
+
mesh.nodes.push(node);
|
|
28259
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
28260
|
+
saveMeshConfig(config2);
|
|
28261
|
+
return node;
|
|
28262
|
+
}
|
|
28263
|
+
function removeNode(meshId, nodeId) {
|
|
28264
|
+
const config2 = loadMeshConfig();
|
|
28265
|
+
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
28266
|
+
if (!mesh) return false;
|
|
28267
|
+
const idx = mesh.nodes.findIndex((n) => n.id === nodeId);
|
|
28268
|
+
if (idx === -1) return false;
|
|
28269
|
+
mesh.nodes.splice(idx, 1);
|
|
28270
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
28271
|
+
saveMeshConfig(config2);
|
|
28272
|
+
return true;
|
|
28273
|
+
}
|
|
28274
|
+
function updateNode(meshId, nodeId, opts) {
|
|
28275
|
+
const config2 = loadMeshConfig();
|
|
28276
|
+
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
28277
|
+
if (!mesh) return void 0;
|
|
28278
|
+
const node = mesh.nodes.find((n) => n.id === nodeId);
|
|
28279
|
+
if (!node) return void 0;
|
|
28280
|
+
if (opts.userOverrides) node.userOverrides = { ...node.userOverrides, ...opts.userOverrides };
|
|
28281
|
+
if (opts.policy) node.policy = { ...node.policy, ...opts.policy };
|
|
28282
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
28283
|
+
saveMeshConfig(config2);
|
|
28284
|
+
return node;
|
|
28285
|
+
}
|
|
28286
|
+
var import_fs2;
|
|
28287
|
+
var import_path22;
|
|
28288
|
+
var import_crypto32;
|
|
28289
|
+
var init_mesh_config = __esm2({
|
|
28290
|
+
"src/config/mesh-config.ts"() {
|
|
28291
|
+
"use strict";
|
|
28292
|
+
import_fs2 = require("fs");
|
|
28293
|
+
import_path22 = require("path");
|
|
28294
|
+
import_crypto32 = require("crypto");
|
|
28295
|
+
init_config();
|
|
28296
|
+
init_repo_mesh_types();
|
|
28297
|
+
}
|
|
28298
|
+
});
|
|
28299
|
+
var coordinator_prompt_exports = {};
|
|
28300
|
+
__export2(coordinator_prompt_exports, {
|
|
28301
|
+
buildCoordinatorSystemPrompt: () => buildCoordinatorSystemPrompt
|
|
28302
|
+
});
|
|
28303
|
+
function buildCoordinatorSystemPrompt(ctx) {
|
|
28304
|
+
const { mesh, status, userInstruction } = ctx;
|
|
28305
|
+
const sections = [];
|
|
28306
|
+
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.
|
|
28307
|
+
|
|
28308
|
+
Your mesh: **${mesh.name}**
|
|
28309
|
+
Repository: \`${mesh.repoIdentity}\`${mesh.defaultBranch ? `
|
|
28310
|
+
Default branch: \`${mesh.defaultBranch}\`` : ""}`);
|
|
28311
|
+
if (status?.nodes?.length) {
|
|
28312
|
+
sections.push(buildNodeStatusSection(status.nodes));
|
|
28313
|
+
} else if (mesh.nodes.length) {
|
|
28314
|
+
sections.push(buildNodeConfigSection(mesh));
|
|
28315
|
+
} else {
|
|
28316
|
+
sections.push("## Nodes\nNo nodes configured yet. Ask the user to add nodes with `adhdev mesh add-node`.");
|
|
28317
|
+
}
|
|
28318
|
+
sections.push(buildPolicySection(mesh.policy));
|
|
28319
|
+
sections.push(TOOLS_SECTION);
|
|
28320
|
+
sections.push(WORKFLOW_SECTION);
|
|
28321
|
+
sections.push(RULES_SECTION);
|
|
28322
|
+
if (userInstruction) {
|
|
28323
|
+
sections.push(`## Additional Context
|
|
28324
|
+
${userInstruction}`);
|
|
28325
|
+
}
|
|
28326
|
+
if (mesh.coordinator.systemPromptSuffix) {
|
|
28327
|
+
sections.push(mesh.coordinator.systemPromptSuffix);
|
|
28328
|
+
}
|
|
28329
|
+
return sections.join("\n\n");
|
|
28330
|
+
}
|
|
28331
|
+
function buildNodeStatusSection(nodes) {
|
|
28332
|
+
const lines = ["## Current Node Status", ""];
|
|
28333
|
+
for (const n of nodes) {
|
|
28334
|
+
const healthIcon = n.health === "online" ? "\u{1F7E2}" : n.health === "dirty" ? "\u{1F7E1}" : n.health === "offline" ? "\u26AB" : "\u{1F534}";
|
|
28335
|
+
const sessions = n.activeSessions.length > 0 ? `sessions: ${n.activeSessions.join(", ")}` : "no active sessions";
|
|
28336
|
+
const branch = n.git?.branch ? `branch: \`${n.git.branch}\`` : "";
|
|
28337
|
+
lines.push(`- ${healthIcon} **${n.machineLabel}** (${n.nodeId})`);
|
|
28338
|
+
lines.push(` workspace: \`${n.workspace}\` | ${branch} | ${sessions}`);
|
|
28339
|
+
if (n.error) lines.push(` \u26A0\uFE0F ${n.error}`);
|
|
28340
|
+
}
|
|
28341
|
+
return lines.join("\n");
|
|
28342
|
+
}
|
|
28343
|
+
function buildNodeConfigSection(mesh) {
|
|
28344
|
+
const lines = ["## Configured Nodes", ""];
|
|
28345
|
+
for (const n of mesh.nodes) {
|
|
28346
|
+
const labels = [];
|
|
28347
|
+
if (n.isLocalWorktree) labels.push("worktree");
|
|
28348
|
+
if (n.policy.readOnly) labels.push("read-only");
|
|
28349
|
+
const suffix = labels.length ? ` [${labels.join(", ")}]` : "";
|
|
28350
|
+
lines.push(`- **${n.workspace}** (${n.id})${suffix}`);
|
|
28351
|
+
}
|
|
28352
|
+
lines.push("", "_Use `mesh_status` to probe live health before delegating work._");
|
|
28353
|
+
return lines.join("\n");
|
|
28354
|
+
}
|
|
28355
|
+
function buildPolicySection(policy) {
|
|
28356
|
+
const rules = [];
|
|
28357
|
+
if (policy.requirePreTaskCheckpoint) rules.push("- Create a git checkpoint **before** starting each task");
|
|
28358
|
+
if (policy.requirePostTaskCheckpoint) rules.push("- Create a git checkpoint **after** each task completes");
|
|
28359
|
+
if (policy.requireApprovalForPush) rules.push("- **Ask for user approval** before pushing to remote");
|
|
28360
|
+
if (policy.requireApprovalForDestructiveGit) rules.push("- **Ask for user approval** before destructive git operations (force push, reset, etc.)");
|
|
28361
|
+
const dirtyBehavior = {
|
|
28362
|
+
block: "- **Do not** send tasks to nodes with dirty workspaces",
|
|
28363
|
+
warn: "- Warn the user if a node has uncommitted changes before sending a task",
|
|
28364
|
+
checkpoint_then_continue: "- Auto-checkpoint dirty nodes before sending tasks"
|
|
28365
|
+
}[policy.dirtyWorkspaceBehavior] || "";
|
|
28366
|
+
if (dirtyBehavior) rules.push(dirtyBehavior);
|
|
28367
|
+
rules.push(`- Maximum **${policy.maxParallelTasks}** tasks running in parallel`);
|
|
28368
|
+
return `## Policy
|
|
28369
|
+
${rules.join("\n")}`;
|
|
28370
|
+
}
|
|
28371
|
+
var TOOLS_SECTION;
|
|
28372
|
+
var WORKFLOW_SECTION;
|
|
28373
|
+
var RULES_SECTION;
|
|
28374
|
+
var init_coordinator_prompt = __esm2({
|
|
28375
|
+
"src/mesh/coordinator-prompt.ts"() {
|
|
28376
|
+
"use strict";
|
|
28377
|
+
TOOLS_SECTION = `## Available Tools
|
|
28378
|
+
|
|
28379
|
+
| Tool | Purpose |
|
|
28380
|
+
|------|---------|
|
|
28381
|
+
| \`mesh_status\` | Check all nodes' health, git state, and active sessions |
|
|
28382
|
+
| \`mesh_list_nodes\` | List nodes with workspace paths |
|
|
28383
|
+
| \`mesh_launch_session\` | Start a new agent session on a node |
|
|
28384
|
+
| \`mesh_send_task\` | Send a task (natural language) to a running agent |
|
|
28385
|
+
| \`mesh_read_chat\` | Read an agent's recent messages to check progress |
|
|
28386
|
+
| \`mesh_git_status\` | Check git status on a specific node |
|
|
28387
|
+
| \`mesh_checkpoint\` | Create a git checkpoint on a node |
|
|
28388
|
+
| \`mesh_approve\` | Approve/reject a pending agent action |`;
|
|
28389
|
+
WORKFLOW_SECTION = `## Orchestration Workflow
|
|
28390
|
+
|
|
28391
|
+
1. **Assess** \u2014 Call \`mesh_status\` to see which nodes are healthy and available.
|
|
28392
|
+
2. **Plan** \u2014 Decompose the user's request into independent tasks for parallel execution, or sequential tasks when dependencies exist.
|
|
28393
|
+
3. **Delegate** \u2014 For each task:
|
|
28394
|
+
a. Pick the best node (consider: health, dirty state, current workload).
|
|
28395
|
+
b. If no session exists, call \`mesh_launch_session\` to start one.
|
|
28396
|
+
c. Call \`mesh_send_task\` with a clear, self-contained natural-language instruction.
|
|
28397
|
+
4. **Monitor** \u2014 Periodically call \`mesh_read_chat\` to check progress. Handle approvals via \`mesh_approve\`.
|
|
28398
|
+
5. **Verify** \u2014 When a task reports completion, call \`mesh_git_status\` to verify changes were made.
|
|
28399
|
+
6. **Checkpoint** \u2014 Call \`mesh_checkpoint\` to save the work.
|
|
28400
|
+
7. **Report** \u2014 Summarize what was done, what changed, and any issues.`;
|
|
28401
|
+
RULES_SECTION = `## Rules
|
|
28402
|
+
|
|
28403
|
+
- **Be conversational.** Delegate work the way a tech lead would \u2014 clear, specific instructions in natural language.
|
|
28404
|
+
- **Don't inspect code.** Trust the agent's output. Verify via git diff/status, not by reading source files.
|
|
28405
|
+
- **Don't over-parallelize.** Start with 1-2 concurrent tasks. Scale up if they succeed.
|
|
28406
|
+
- **Handle failures gracefully.** If a task fails, read the chat to understand why, then retry or reassign.
|
|
28407
|
+
- **Keep the user informed.** Report progress after each delegation round.
|
|
28408
|
+
- **Respect node capabilities.** Don't send build tasks to read-only nodes. Don't push from nodes that aren't allowed to.
|
|
28409
|
+
- **Never fabricate tool results.** Always call the actual tool; never pretend you did.`;
|
|
28410
|
+
}
|
|
28411
|
+
});
|
|
28128
28412
|
function setLogLevel(level) {
|
|
28129
28413
|
currentLevel = level;
|
|
28130
28414
|
daemonLog("Logger", `Log level set to: ${level}`, "info");
|
|
@@ -31208,6 +31492,7 @@ var require_dist2 = __commonJS({
|
|
|
31208
31492
|
DEFAULT_DAEMON_PORT: () => DEFAULT_DAEMON_PORT,
|
|
31209
31493
|
DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS: () => DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS,
|
|
31210
31494
|
DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS: () => DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS2,
|
|
31495
|
+
DEFAULT_MESH_POLICY: () => DEFAULT_MESH_POLICY,
|
|
31211
31496
|
DEFAULT_SESSION_HOST_APP_NAME: () => DEFAULT_SESSION_HOST_APP_NAME,
|
|
31212
31497
|
DEFAULT_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS: () => DEFAULT_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS2,
|
|
31213
31498
|
DEFAULT_SESSION_HOST_READY_TIMEOUT_MS: () => DEFAULT_SESSION_HOST_READY_TIMEOUT_MS2,
|
|
@@ -31241,11 +31526,13 @@ var require_dist2 = __commonJS({
|
|
|
31241
31526
|
SessionHostPtyTransportFactory: () => SessionHostPtyTransportFactory2,
|
|
31242
31527
|
TurnSnapshotTracker: () => TurnSnapshotTracker,
|
|
31243
31528
|
VersionArchive: () => VersionArchive,
|
|
31529
|
+
addNode: () => addNode,
|
|
31244
31530
|
appendRecentActivity: () => appendRecentActivity,
|
|
31245
31531
|
buildAssistantChatMessage: () => buildAssistantChatMessage,
|
|
31246
31532
|
buildChatMessage: () => buildChatMessage,
|
|
31247
31533
|
buildChatMessageSignature: () => buildChatMessageSignature,
|
|
31248
31534
|
buildChatTailDeliverySignature: () => buildChatTailDeliverySignature,
|
|
31535
|
+
buildCoordinatorSystemPrompt: () => buildCoordinatorSystemPrompt,
|
|
31249
31536
|
buildMachineInfo: () => buildMachineInfo2,
|
|
31250
31537
|
buildPinnedGlobalInstallCommand: () => buildPinnedGlobalInstallCommand,
|
|
31251
31538
|
buildRuntimeSystemChatMessage: () => buildRuntimeSystemChatMessage,
|
|
@@ -31268,6 +31555,8 @@ var require_dist2 = __commonJS({
|
|
|
31268
31555
|
createGitSnapshotStore: () => createGitSnapshotStore,
|
|
31269
31556
|
createGitWorkspaceMonitor: () => createGitWorkspaceMonitor2,
|
|
31270
31557
|
createInteractionId: () => createInteractionId,
|
|
31558
|
+
createMesh: () => createMesh,
|
|
31559
|
+
deleteMesh: () => deleteMesh,
|
|
31271
31560
|
detectAllVersions: () => detectAllVersions,
|
|
31272
31561
|
detectCLIs: () => detectCLIs,
|
|
31273
31562
|
detectIDEs: () => detectIDEs,
|
|
@@ -31286,6 +31575,8 @@ var require_dist2 = __commonJS({
|
|
|
31286
31575
|
getGitRepoStatus: () => getGitRepoStatus,
|
|
31287
31576
|
getHostMemorySnapshot: () => getHostMemorySnapshot,
|
|
31288
31577
|
getLogLevel: () => getLogLevel,
|
|
31578
|
+
getMesh: () => getMesh,
|
|
31579
|
+
getMeshByRepo: () => getMeshByRepo,
|
|
31289
31580
|
getNpmExecOptions: () => getNpmExecOptions,
|
|
31290
31581
|
getRecentActivity: () => getRecentActivity,
|
|
31291
31582
|
getRecentCommands: () => getRecentCommands,
|
|
@@ -31316,6 +31607,7 @@ var require_dist2 = __commonJS({
|
|
|
31316
31607
|
launchIDE: () => launchIDE,
|
|
31317
31608
|
launchWithCdp: () => launchWithCdp,
|
|
31318
31609
|
listHostedCliRuntimes: () => listHostedCliRuntimes2,
|
|
31610
|
+
listMeshes: () => listMeshes,
|
|
31319
31611
|
loadConfig: () => loadConfig2,
|
|
31320
31612
|
loadState: () => loadState,
|
|
31321
31613
|
logCommand: () => logCommand,
|
|
@@ -31331,6 +31623,7 @@ var require_dist2 = __commonJS({
|
|
|
31331
31623
|
normalizeInputEnvelope: () => normalizeInputEnvelope,
|
|
31332
31624
|
normalizeManagedStatus: () => normalizeManagedStatus,
|
|
31333
31625
|
normalizeMessageParts: () => normalizeMessageParts,
|
|
31626
|
+
normalizeRepoIdentity: () => normalizeRepoIdentity,
|
|
31334
31627
|
normalizeSessionModalFields: () => normalizeSessionModalFields,
|
|
31335
31628
|
parsePorcelainV2Status: () => parsePorcelainV2Status,
|
|
31336
31629
|
parseProviderSourceConfigUpdate: () => parseProviderSourceConfigUpdate,
|
|
@@ -31342,6 +31635,7 @@ var require_dist2 = __commonJS({
|
|
|
31342
31635
|
readChatHistory: () => readChatHistory,
|
|
31343
31636
|
recordDebugTrace: () => recordDebugTrace,
|
|
31344
31637
|
registerExtensionProviders: () => registerExtensionProviders,
|
|
31638
|
+
removeNode: () => removeNode,
|
|
31345
31639
|
resetConfig: () => resetConfig,
|
|
31346
31640
|
resetDebugRuntimeConfig: () => resetDebugRuntimeConfig,
|
|
31347
31641
|
resetState: () => resetState,
|
|
@@ -31364,10 +31658,14 @@ var require_dist2 = __commonJS({
|
|
|
31364
31658
|
spawnDetachedDaemonUpgradeHelper: () => spawnDetachedDaemonUpgradeHelper,
|
|
31365
31659
|
startDaemonDevSupport: () => startDaemonDevSupport2,
|
|
31366
31660
|
summarizeGitStatus: () => summarizeGitStatus,
|
|
31661
|
+
syncMeshes: () => syncMeshes,
|
|
31367
31662
|
updateConfig: () => updateConfig,
|
|
31663
|
+
updateMesh: () => updateMesh,
|
|
31664
|
+
updateNode: () => updateNode,
|
|
31368
31665
|
upsertSavedProviderSession: () => upsertSavedProviderSession
|
|
31369
31666
|
});
|
|
31370
31667
|
module2.exports = __toCommonJS2(index_exports);
|
|
31668
|
+
init_repo_mesh_types();
|
|
31371
31669
|
var import_node_child_process = require("child_process");
|
|
31372
31670
|
var import_node_fs3 = require("fs");
|
|
31373
31671
|
var import_promises4 = require("fs/promises");
|
|
@@ -33137,8 +33435,64 @@ var require_dist2 = __commonJS({
|
|
|
33137
33435
|
})
|
|
33138
33436
|
})).sort((a, b2) => b2.lastUsedAt - a.lastUsedAt);
|
|
33139
33437
|
}
|
|
33140
|
-
|
|
33141
|
-
|
|
33438
|
+
init_mesh_config();
|
|
33439
|
+
init_coordinator_prompt();
|
|
33440
|
+
init_mesh_config();
|
|
33441
|
+
async function syncMeshes(transport) {
|
|
33442
|
+
const result = { pushed: 0, pulled: 0, deleted: 0, errors: [] };
|
|
33443
|
+
let remoteMeshes;
|
|
33444
|
+
try {
|
|
33445
|
+
const res = await transport.listRemoteMeshes();
|
|
33446
|
+
remoteMeshes = res.meshes;
|
|
33447
|
+
} catch (e) {
|
|
33448
|
+
result.errors.push(`Failed to list remote meshes: ${e.message}`);
|
|
33449
|
+
return result;
|
|
33450
|
+
}
|
|
33451
|
+
const localMeshes = listMeshes();
|
|
33452
|
+
const remoteByIdentity = new Map(remoteMeshes.map((m) => [m.repo_identity, m]));
|
|
33453
|
+
const localByIdentity = new Map(localMeshes.map((m) => [m.repoIdentity, m]));
|
|
33454
|
+
for (const local of localMeshes) {
|
|
33455
|
+
if (!remoteByIdentity.has(local.repoIdentity)) {
|
|
33456
|
+
try {
|
|
33457
|
+
await transport.createRemoteMesh({
|
|
33458
|
+
name: local.name,
|
|
33459
|
+
repo_identity: local.repoIdentity,
|
|
33460
|
+
repo_remote_url: local.repoRemoteUrl,
|
|
33461
|
+
default_branch: local.defaultBranch,
|
|
33462
|
+
policy: JSON.stringify(local.policy)
|
|
33463
|
+
});
|
|
33464
|
+
result.pushed++;
|
|
33465
|
+
} catch (e) {
|
|
33466
|
+
result.errors.push(`Push failed for "${local.name}": ${e.message}`);
|
|
33467
|
+
}
|
|
33468
|
+
}
|
|
33469
|
+
}
|
|
33470
|
+
for (const remote of remoteMeshes) {
|
|
33471
|
+
if (!localByIdentity.has(remote.repo_identity)) {
|
|
33472
|
+
try {
|
|
33473
|
+
let policy;
|
|
33474
|
+
try {
|
|
33475
|
+
policy = JSON.parse(remote.policy);
|
|
33476
|
+
} catch {
|
|
33477
|
+
policy = void 0;
|
|
33478
|
+
}
|
|
33479
|
+
createMesh({
|
|
33480
|
+
name: remote.name,
|
|
33481
|
+
repoIdentity: remote.repo_identity,
|
|
33482
|
+
repoRemoteUrl: remote.repo_remote_url || void 0,
|
|
33483
|
+
defaultBranch: remote.default_branch || void 0,
|
|
33484
|
+
policy
|
|
33485
|
+
});
|
|
33486
|
+
result.pulled++;
|
|
33487
|
+
} catch (e) {
|
|
33488
|
+
result.errors.push(`Pull failed for "${remote.name}": ${e.message}`);
|
|
33489
|
+
}
|
|
33490
|
+
}
|
|
33491
|
+
}
|
|
33492
|
+
return result;
|
|
33493
|
+
}
|
|
33494
|
+
var import_fs3 = require("fs");
|
|
33495
|
+
var import_path3 = require("path");
|
|
33142
33496
|
init_config();
|
|
33143
33497
|
var DEFAULT_STATE = {
|
|
33144
33498
|
recentActivity: [],
|
|
@@ -33152,7 +33506,7 @@ var require_dist2 = __commonJS({
|
|
|
33152
33506
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
33153
33507
|
}
|
|
33154
33508
|
function getStatePath() {
|
|
33155
|
-
return (0,
|
|
33509
|
+
return (0, import_path3.join)(getConfigDir(), "state.json");
|
|
33156
33510
|
}
|
|
33157
33511
|
function normalizeState(raw) {
|
|
33158
33512
|
const parsed = isPlainObject22(raw) ? raw : {};
|
|
@@ -33188,11 +33542,11 @@ var require_dist2 = __commonJS({
|
|
|
33188
33542
|
}
|
|
33189
33543
|
function loadState() {
|
|
33190
33544
|
const statePath = getStatePath();
|
|
33191
|
-
if (!(0,
|
|
33545
|
+
if (!(0, import_fs3.existsSync)(statePath)) {
|
|
33192
33546
|
return { ...DEFAULT_STATE };
|
|
33193
33547
|
}
|
|
33194
33548
|
try {
|
|
33195
|
-
const raw = (0,
|
|
33549
|
+
const raw = (0, import_fs3.readFileSync)(statePath, "utf-8");
|
|
33196
33550
|
return normalizeState(JSON.parse(raw));
|
|
33197
33551
|
} catch {
|
|
33198
33552
|
return { ...DEFAULT_STATE };
|
|
@@ -33201,13 +33555,13 @@ var require_dist2 = __commonJS({
|
|
|
33201
33555
|
function saveState(state) {
|
|
33202
33556
|
const statePath = getStatePath();
|
|
33203
33557
|
const normalized = normalizeState(state);
|
|
33204
|
-
(0,
|
|
33558
|
+
(0, import_fs3.writeFileSync)(statePath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
|
|
33205
33559
|
}
|
|
33206
33560
|
function resetState() {
|
|
33207
33561
|
saveState({ ...DEFAULT_STATE });
|
|
33208
33562
|
}
|
|
33209
33563
|
var import_child_process = require("child_process");
|
|
33210
|
-
var
|
|
33564
|
+
var import_fs4 = require("fs");
|
|
33211
33565
|
var import_os22 = require("os");
|
|
33212
33566
|
var path7 = __toESM2(require("path"));
|
|
33213
33567
|
var BUILTIN_IDE_DEFINITIONS = [];
|
|
@@ -33231,7 +33585,7 @@ var require_dist2 = __commonJS({
|
|
|
33231
33585
|
if (path7.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
|
|
33232
33586
|
const candidate = trimmed.startsWith("~") ? path7.join((0, import_os22.homedir)(), trimmed.slice(1)) : trimmed;
|
|
33233
33587
|
const resolved = path7.isAbsolute(candidate) ? candidate : path7.resolve(candidate);
|
|
33234
|
-
return (0,
|
|
33588
|
+
return (0, import_fs4.existsSync)(resolved) ? resolved : null;
|
|
33235
33589
|
}
|
|
33236
33590
|
try {
|
|
33237
33591
|
const result = (0, import_child_process.execSync)(
|
|
@@ -33262,9 +33616,9 @@ var require_dist2 = __commonJS({
|
|
|
33262
33616
|
if (normalized.includes("*")) {
|
|
33263
33617
|
const username = home.split(/[\\/]/).pop() || "";
|
|
33264
33618
|
const resolved = normalized.replace("*", username);
|
|
33265
|
-
if ((0,
|
|
33619
|
+
if ((0, import_fs4.existsSync)(resolved)) return resolved;
|
|
33266
33620
|
} else {
|
|
33267
|
-
if ((0,
|
|
33621
|
+
if ((0, import_fs4.existsSync)(normalized)) return normalized;
|
|
33268
33622
|
}
|
|
33269
33623
|
}
|
|
33270
33624
|
return null;
|
|
@@ -33278,7 +33632,7 @@ var require_dist2 = __commonJS({
|
|
|
33278
33632
|
let resolvedCli = cliPath;
|
|
33279
33633
|
if (!resolvedCli && appPath && os21 === "darwin") {
|
|
33280
33634
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
33281
|
-
if ((0,
|
|
33635
|
+
if ((0, import_fs4.existsSync)(bundledCli)) resolvedCli = bundledCli;
|
|
33282
33636
|
}
|
|
33283
33637
|
if (!resolvedCli && appPath && os21 === "win32") {
|
|
33284
33638
|
const { dirname: dirname7 } = await import("path");
|
|
@@ -33291,7 +33645,7 @@ var require_dist2 = __commonJS({
|
|
|
33291
33645
|
`${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
|
|
33292
33646
|
];
|
|
33293
33647
|
for (const c of candidates) {
|
|
33294
|
-
if ((0,
|
|
33648
|
+
if ((0, import_fs4.existsSync)(c)) {
|
|
33295
33649
|
resolvedCli = c;
|
|
33296
33650
|
break;
|
|
33297
33651
|
}
|
|
@@ -33315,7 +33669,7 @@ var require_dist2 = __commonJS({
|
|
|
33315
33669
|
var import_child_process2 = require("child_process");
|
|
33316
33670
|
var os22 = __toESM2(require("os"));
|
|
33317
33671
|
var path8 = __toESM2(require("path"));
|
|
33318
|
-
var
|
|
33672
|
+
var import_fs5 = require("fs");
|
|
33319
33673
|
function parseVersion(raw) {
|
|
33320
33674
|
const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
|
|
33321
33675
|
return match ? match[1] : raw.split("\n")[0].slice(0, 100);
|
|
@@ -33339,7 +33693,7 @@ var require_dist2 = __commonJS({
|
|
|
33339
33693
|
if (isExplicitCommandPath(trimmed)) {
|
|
33340
33694
|
const expanded = expandHome(trimmed);
|
|
33341
33695
|
const candidate = path8.isAbsolute(expanded) ? expanded : path8.resolve(expanded);
|
|
33342
|
-
return (0,
|
|
33696
|
+
return (0, import_fs5.existsSync)(candidate) ? candidate : null;
|
|
33343
33697
|
}
|
|
33344
33698
|
return null;
|
|
33345
33699
|
}
|
|
@@ -41991,7 +42345,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41991
42345
|
var os13 = __toESM2(require("os"));
|
|
41992
42346
|
var path16 = __toESM2(require("path"));
|
|
41993
42347
|
var crypto4 = __toESM2(require("crypto"));
|
|
41994
|
-
var
|
|
42348
|
+
var import_fs6 = require("fs");
|
|
41995
42349
|
var import_child_process6 = require("child_process");
|
|
41996
42350
|
var import_chalk = __toESM2(require("chalk"));
|
|
41997
42351
|
init_provider_cli_adapter();
|
|
@@ -44115,7 +44469,7 @@ ${rawInput}` : rawInput;
|
|
|
44115
44469
|
const trimmed = command.trim();
|
|
44116
44470
|
if (!trimmed) return false;
|
|
44117
44471
|
if (isExplicitCommand(trimmed)) {
|
|
44118
|
-
return (0,
|
|
44472
|
+
return (0, import_fs6.existsSync)(expandExecutable(trimmed));
|
|
44119
44473
|
}
|
|
44120
44474
|
try {
|
|
44121
44475
|
(0, import_child_process6.execFileSync)(process.platform === "win32" ? "where" : "which", [trimmed], {
|
|
@@ -48604,6 +48958,142 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
48604
48958
|
updateConfig({ machineNickname: nickname || null });
|
|
48605
48959
|
return { success: true };
|
|
48606
48960
|
}
|
|
48961
|
+
// ─── Mesh CRUD (local meshes.json) ───
|
|
48962
|
+
case "list_meshes": {
|
|
48963
|
+
try {
|
|
48964
|
+
const { listMeshes: listMeshes2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
48965
|
+
return { success: true, meshes: listMeshes2() };
|
|
48966
|
+
} catch (e) {
|
|
48967
|
+
return { success: false, error: e.message };
|
|
48968
|
+
}
|
|
48969
|
+
}
|
|
48970
|
+
case "get_mesh": {
|
|
48971
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
48972
|
+
if (!meshId) return { success: false, error: "meshId required" };
|
|
48973
|
+
try {
|
|
48974
|
+
const { getMesh: getMesh3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
48975
|
+
const mesh = getMesh3(meshId);
|
|
48976
|
+
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
48977
|
+
return { success: true, mesh };
|
|
48978
|
+
} catch (e) {
|
|
48979
|
+
return { success: false, error: e.message };
|
|
48980
|
+
}
|
|
48981
|
+
}
|
|
48982
|
+
case "create_mesh": {
|
|
48983
|
+
const name = typeof args?.name === "string" ? args.name.trim() : "";
|
|
48984
|
+
const repoIdentity = typeof args?.repoIdentity === "string" ? args.repoIdentity.trim() : "";
|
|
48985
|
+
const repoRemoteUrl = typeof args?.repoRemoteUrl === "string" ? args.repoRemoteUrl.trim() : void 0;
|
|
48986
|
+
const defaultBranch = typeof args?.defaultBranch === "string" ? args.defaultBranch.trim() : void 0;
|
|
48987
|
+
if (!name) return { success: false, error: "name required" };
|
|
48988
|
+
try {
|
|
48989
|
+
const { createMesh: createMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
48990
|
+
const mesh = createMesh2({ name, repoIdentity, repoRemoteUrl, defaultBranch });
|
|
48991
|
+
return { success: true, mesh };
|
|
48992
|
+
} catch (e) {
|
|
48993
|
+
return { success: false, error: e.message };
|
|
48994
|
+
}
|
|
48995
|
+
}
|
|
48996
|
+
case "delete_mesh": {
|
|
48997
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
48998
|
+
if (!meshId) return { success: false, error: "meshId required" };
|
|
48999
|
+
try {
|
|
49000
|
+
const { deleteMesh: deleteMesh3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
49001
|
+
const deleted = deleteMesh3(meshId);
|
|
49002
|
+
return { success: true, deleted };
|
|
49003
|
+
} catch (e) {
|
|
49004
|
+
return { success: false, error: e.message };
|
|
49005
|
+
}
|
|
49006
|
+
}
|
|
49007
|
+
case "add_mesh_node": {
|
|
49008
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
49009
|
+
const workspace = typeof args?.workspace === "string" ? args.workspace.trim() : "";
|
|
49010
|
+
if (!meshId) return { success: false, error: "meshId required" };
|
|
49011
|
+
if (!workspace) return { success: false, error: "workspace required" };
|
|
49012
|
+
try {
|
|
49013
|
+
const { addNode: addNode3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
49014
|
+
const node = addNode3(meshId, { workspace });
|
|
49015
|
+
if (!node) return { success: false, error: "Mesh not found" };
|
|
49016
|
+
return { success: true, node };
|
|
49017
|
+
} catch (e) {
|
|
49018
|
+
return { success: false, error: e.message };
|
|
49019
|
+
}
|
|
49020
|
+
}
|
|
49021
|
+
case "remove_mesh_node": {
|
|
49022
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
49023
|
+
const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
|
|
49024
|
+
if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
|
|
49025
|
+
try {
|
|
49026
|
+
const { removeNode: removeNode3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
49027
|
+
const removed = removeNode3(meshId, nodeId);
|
|
49028
|
+
return { success: true, removed };
|
|
49029
|
+
} catch (e) {
|
|
49030
|
+
return { success: false, error: e.message };
|
|
49031
|
+
}
|
|
49032
|
+
}
|
|
49033
|
+
// ─── Mesh Coordinator Launch ───
|
|
49034
|
+
case "launch_mesh_coordinator": {
|
|
49035
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
49036
|
+
const cliType = typeof args?.cliType === "string" ? args.cliType.trim() : "claude-cli";
|
|
49037
|
+
if (!meshId) return { success: false, error: "meshId required" };
|
|
49038
|
+
try {
|
|
49039
|
+
const { getMesh: getMesh3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
49040
|
+
const { buildCoordinatorSystemPrompt: buildCoordinatorSystemPrompt2 } = await Promise.resolve().then(() => (init_coordinator_prompt(), coordinator_prompt_exports));
|
|
49041
|
+
const mesh = getMesh3(meshId);
|
|
49042
|
+
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
49043
|
+
if (mesh.nodes.length === 0) return { success: false, error: "No nodes in mesh" };
|
|
49044
|
+
const workspace = mesh.nodes[0].workspace;
|
|
49045
|
+
const { existsSync: existsSync21, readFileSync: readFileSync15, writeFileSync: writeFileSync12, copyFileSync: copyFileSync3 } = await import("fs");
|
|
49046
|
+
const { join: join23 } = await import("path");
|
|
49047
|
+
const mcpConfigPath = join23(workspace, ".mcp.json");
|
|
49048
|
+
const hadExistingMcpConfig = existsSync21(mcpConfigPath);
|
|
49049
|
+
let existingMcpConfig = {};
|
|
49050
|
+
if (hadExistingMcpConfig) {
|
|
49051
|
+
try {
|
|
49052
|
+
existingMcpConfig = JSON.parse(readFileSync15(mcpConfigPath, "utf-8"));
|
|
49053
|
+
copyFileSync3(mcpConfigPath, mcpConfigPath + ".backup");
|
|
49054
|
+
} catch {
|
|
49055
|
+
}
|
|
49056
|
+
}
|
|
49057
|
+
const mcpConfig = {
|
|
49058
|
+
...existingMcpConfig,
|
|
49059
|
+
mcpServers: {
|
|
49060
|
+
...existingMcpConfig.mcpServers || {},
|
|
49061
|
+
"adhdev-mesh": {
|
|
49062
|
+
command: "adhdev-mcp",
|
|
49063
|
+
args: ["--repo-mesh", meshId]
|
|
49064
|
+
}
|
|
49065
|
+
}
|
|
49066
|
+
};
|
|
49067
|
+
writeFileSync12(mcpConfigPath, JSON.stringify(mcpConfig, null, 2), "utf-8");
|
|
49068
|
+
LOG2.info("MeshCoordinator", `Wrote .mcp.json to ${workspace} with adhdev-mesh server`);
|
|
49069
|
+
let systemPrompt = "";
|
|
49070
|
+
try {
|
|
49071
|
+
systemPrompt = buildCoordinatorSystemPrompt2({ mesh });
|
|
49072
|
+
} catch {
|
|
49073
|
+
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).`;
|
|
49074
|
+
}
|
|
49075
|
+
const launchResult = await this.deps.cliManager.handleCliCommand("launch_cli", {
|
|
49076
|
+
cliType,
|
|
49077
|
+
dir: workspace,
|
|
49078
|
+
initialPrompt: systemPrompt
|
|
49079
|
+
});
|
|
49080
|
+
if (!launchResult?.success) {
|
|
49081
|
+
return { success: false, error: launchResult?.error || "Failed to launch CLI session" };
|
|
49082
|
+
}
|
|
49083
|
+
LOG2.info("MeshCoordinator", `Launched ${cliType} coordinator for mesh ${meshId} in ${workspace}`);
|
|
49084
|
+
return {
|
|
49085
|
+
success: true,
|
|
49086
|
+
meshId,
|
|
49087
|
+
cliType,
|
|
49088
|
+
workspace,
|
|
49089
|
+
sessionId: launchResult.sessionId || launchResult.id,
|
|
49090
|
+
mcpConfigWritten: true
|
|
49091
|
+
};
|
|
49092
|
+
} catch (e) {
|
|
49093
|
+
LOG2.error("MeshCoordinator", `Failed: ${e.message}`);
|
|
49094
|
+
return { success: false, error: e.message };
|
|
49095
|
+
}
|
|
49096
|
+
}
|
|
48607
49097
|
default:
|
|
48608
49098
|
break;
|
|
48609
49099
|
}
|