@adhdev/daemon-core 0.9.65 → 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/config/mesh-config.d.ts +47 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +346 -15
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +335 -17
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/coordinator-prompt.d.ts +18 -0
- package/dist/mesh/mesh-sync.d.ts +51 -0
- package/dist/repo-mesh-types.d.ts +168 -0
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/config/mesh-config.ts +228 -0
- package/src/index.ts +33 -0
- package/src/mesh/coordinator-prompt.ts +156 -0
- package/src/mesh/mesh-sync.ts +109 -0
- package/src/repo-mesh-types.ts +212 -0
package/dist/index.mjs
CHANGED
|
@@ -3320,6 +3320,16 @@ var init_provider_cli_adapter = __esm({
|
|
|
3320
3320
|
}
|
|
3321
3321
|
});
|
|
3322
3322
|
|
|
3323
|
+
// src/repo-mesh-types.ts
|
|
3324
|
+
var DEFAULT_MESH_POLICY = {
|
|
3325
|
+
requirePreTaskCheckpoint: false,
|
|
3326
|
+
requirePostTaskCheckpoint: true,
|
|
3327
|
+
requireApprovalForPush: true,
|
|
3328
|
+
requireApprovalForDestructiveGit: true,
|
|
3329
|
+
dirtyWorkspaceBehavior: "warn",
|
|
3330
|
+
maxParallelTasks: 2
|
|
3331
|
+
};
|
|
3332
|
+
|
|
3323
3333
|
// src/git/git-executor.ts
|
|
3324
3334
|
import { execFile } from "child_process";
|
|
3325
3335
|
import { constants } from "fs";
|
|
@@ -5117,10 +5127,305 @@ function getSavedProviderSessions(state, filters) {
|
|
|
5117
5127
|
})).sort((a, b) => b.lastUsedAt - a.lastUsedAt);
|
|
5118
5128
|
}
|
|
5119
5129
|
|
|
5120
|
-
// src/config/
|
|
5130
|
+
// src/config/mesh-config.ts
|
|
5121
5131
|
init_config();
|
|
5122
5132
|
import { existsSync as existsSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
5123
5133
|
import { join as join3 } from "path";
|
|
5134
|
+
import { randomUUID as randomUUID3 } from "crypto";
|
|
5135
|
+
function getMeshConfigPath() {
|
|
5136
|
+
return join3(getConfigDir(), "meshes.json");
|
|
5137
|
+
}
|
|
5138
|
+
function loadMeshConfig() {
|
|
5139
|
+
const path26 = getMeshConfigPath();
|
|
5140
|
+
if (!existsSync3(path26)) return { meshes: [] };
|
|
5141
|
+
try {
|
|
5142
|
+
const raw = JSON.parse(readFileSync2(path26, "utf-8"));
|
|
5143
|
+
if (!raw || !Array.isArray(raw.meshes)) return { meshes: [] };
|
|
5144
|
+
return raw;
|
|
5145
|
+
} catch {
|
|
5146
|
+
return { meshes: [] };
|
|
5147
|
+
}
|
|
5148
|
+
}
|
|
5149
|
+
function saveMeshConfig(config) {
|
|
5150
|
+
const path26 = getMeshConfigPath();
|
|
5151
|
+
writeFileSync2(path26, JSON.stringify(config, null, 2), { encoding: "utf-8", mode: 384 });
|
|
5152
|
+
}
|
|
5153
|
+
function normalizeRepoIdentity(remoteUrl) {
|
|
5154
|
+
let identity = remoteUrl.trim();
|
|
5155
|
+
if (identity.startsWith("http://") || identity.startsWith("https://")) {
|
|
5156
|
+
try {
|
|
5157
|
+
const url = new URL(identity);
|
|
5158
|
+
const path26 = url.pathname.replace(/^\//, "").replace(/\.git$/, "");
|
|
5159
|
+
return `${url.hostname}/${path26}`;
|
|
5160
|
+
} catch {
|
|
5161
|
+
}
|
|
5162
|
+
}
|
|
5163
|
+
const sshMatch = identity.match(/^(?:ssh:\/\/)?[\w.-]+@([\w.-]+)[:/]([\w.\-/]+?)(?:\.git)?$/);
|
|
5164
|
+
if (sshMatch) return `${sshMatch[1]}/${sshMatch[2]}`;
|
|
5165
|
+
return identity;
|
|
5166
|
+
}
|
|
5167
|
+
function listMeshes() {
|
|
5168
|
+
return loadMeshConfig().meshes;
|
|
5169
|
+
}
|
|
5170
|
+
function getMesh(meshId) {
|
|
5171
|
+
return loadMeshConfig().meshes.find((m) => m.id === meshId);
|
|
5172
|
+
}
|
|
5173
|
+
function getMeshByRepo(repoIdentity) {
|
|
5174
|
+
return loadMeshConfig().meshes.find((m) => m.repoIdentity === repoIdentity);
|
|
5175
|
+
}
|
|
5176
|
+
function createMesh(opts) {
|
|
5177
|
+
const config = loadMeshConfig();
|
|
5178
|
+
if (config.meshes.length >= 20) {
|
|
5179
|
+
throw new Error("Maximum 20 meshes allowed");
|
|
5180
|
+
}
|
|
5181
|
+
const repoIdentity = opts.repoIdentity || (opts.repoRemoteUrl ? normalizeRepoIdentity(opts.repoRemoteUrl) : "");
|
|
5182
|
+
if (!repoIdentity) throw new Error("Either repoRemoteUrl or repoIdentity is required");
|
|
5183
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
5184
|
+
const mesh = {
|
|
5185
|
+
id: `mesh_${randomUUID3().replace(/-/g, "")}`,
|
|
5186
|
+
name: opts.name.trim().slice(0, 100),
|
|
5187
|
+
repoIdentity,
|
|
5188
|
+
repoRemoteUrl: opts.repoRemoteUrl,
|
|
5189
|
+
defaultBranch: opts.defaultBranch,
|
|
5190
|
+
policy: { ...DEFAULT_MESH_POLICY, ...opts.policy },
|
|
5191
|
+
coordinator: opts.coordinator || {},
|
|
5192
|
+
nodes: [],
|
|
5193
|
+
createdAt: now,
|
|
5194
|
+
updatedAt: now
|
|
5195
|
+
};
|
|
5196
|
+
config.meshes.push(mesh);
|
|
5197
|
+
saveMeshConfig(config);
|
|
5198
|
+
return mesh;
|
|
5199
|
+
}
|
|
5200
|
+
function updateMesh(meshId, opts) {
|
|
5201
|
+
const config = loadMeshConfig();
|
|
5202
|
+
const mesh = config.meshes.find((m) => m.id === meshId);
|
|
5203
|
+
if (!mesh) return void 0;
|
|
5204
|
+
if (opts.name !== void 0) mesh.name = opts.name.trim().slice(0, 100);
|
|
5205
|
+
if (opts.defaultBranch !== void 0) mesh.defaultBranch = opts.defaultBranch;
|
|
5206
|
+
if (opts.policy) mesh.policy = { ...mesh.policy, ...opts.policy };
|
|
5207
|
+
if (opts.coordinator) mesh.coordinator = opts.coordinator;
|
|
5208
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
5209
|
+
saveMeshConfig(config);
|
|
5210
|
+
return mesh;
|
|
5211
|
+
}
|
|
5212
|
+
function deleteMesh(meshId) {
|
|
5213
|
+
const config = loadMeshConfig();
|
|
5214
|
+
const idx = config.meshes.findIndex((m) => m.id === meshId);
|
|
5215
|
+
if (idx === -1) return false;
|
|
5216
|
+
config.meshes.splice(idx, 1);
|
|
5217
|
+
saveMeshConfig(config);
|
|
5218
|
+
return true;
|
|
5219
|
+
}
|
|
5220
|
+
function addNode(meshId, opts) {
|
|
5221
|
+
const config = loadMeshConfig();
|
|
5222
|
+
const mesh = config.meshes.find((m) => m.id === meshId);
|
|
5223
|
+
if (!mesh) return void 0;
|
|
5224
|
+
if (mesh.nodes.length >= 10) {
|
|
5225
|
+
throw new Error("Maximum 10 nodes per mesh");
|
|
5226
|
+
}
|
|
5227
|
+
if (mesh.nodes.some((n) => n.workspace === opts.workspace)) {
|
|
5228
|
+
throw new Error("This workspace is already in the mesh");
|
|
5229
|
+
}
|
|
5230
|
+
const node = {
|
|
5231
|
+
id: `node_${randomUUID3().replace(/-/g, "")}`,
|
|
5232
|
+
workspace: opts.workspace.trim(),
|
|
5233
|
+
repoRoot: opts.repoRoot,
|
|
5234
|
+
userOverrides: opts.userOverrides || {},
|
|
5235
|
+
policy: opts.policy || {},
|
|
5236
|
+
isLocalWorktree: opts.isLocalWorktree
|
|
5237
|
+
};
|
|
5238
|
+
mesh.nodes.push(node);
|
|
5239
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
5240
|
+
saveMeshConfig(config);
|
|
5241
|
+
return node;
|
|
5242
|
+
}
|
|
5243
|
+
function removeNode(meshId, nodeId) {
|
|
5244
|
+
const config = loadMeshConfig();
|
|
5245
|
+
const mesh = config.meshes.find((m) => m.id === meshId);
|
|
5246
|
+
if (!mesh) return false;
|
|
5247
|
+
const idx = mesh.nodes.findIndex((n) => n.id === nodeId);
|
|
5248
|
+
if (idx === -1) return false;
|
|
5249
|
+
mesh.nodes.splice(idx, 1);
|
|
5250
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
5251
|
+
saveMeshConfig(config);
|
|
5252
|
+
return true;
|
|
5253
|
+
}
|
|
5254
|
+
function updateNode(meshId, nodeId, opts) {
|
|
5255
|
+
const config = loadMeshConfig();
|
|
5256
|
+
const mesh = config.meshes.find((m) => m.id === meshId);
|
|
5257
|
+
if (!mesh) return void 0;
|
|
5258
|
+
const node = mesh.nodes.find((n) => n.id === nodeId);
|
|
5259
|
+
if (!node) return void 0;
|
|
5260
|
+
if (opts.userOverrides) node.userOverrides = { ...node.userOverrides, ...opts.userOverrides };
|
|
5261
|
+
if (opts.policy) node.policy = { ...node.policy, ...opts.policy };
|
|
5262
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
5263
|
+
saveMeshConfig(config);
|
|
5264
|
+
return node;
|
|
5265
|
+
}
|
|
5266
|
+
|
|
5267
|
+
// src/mesh/coordinator-prompt.ts
|
|
5268
|
+
function buildCoordinatorSystemPrompt(ctx) {
|
|
5269
|
+
const { mesh, status, userInstruction } = ctx;
|
|
5270
|
+
const sections = [];
|
|
5271
|
+
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.
|
|
5272
|
+
|
|
5273
|
+
Your mesh: **${mesh.name}**
|
|
5274
|
+
Repository: \`${mesh.repoIdentity}\`${mesh.defaultBranch ? `
|
|
5275
|
+
Default branch: \`${mesh.defaultBranch}\`` : ""}`);
|
|
5276
|
+
if (status?.nodes?.length) {
|
|
5277
|
+
sections.push(buildNodeStatusSection(status.nodes));
|
|
5278
|
+
} else if (mesh.nodes.length) {
|
|
5279
|
+
sections.push(buildNodeConfigSection(mesh));
|
|
5280
|
+
} else {
|
|
5281
|
+
sections.push("## Nodes\nNo nodes configured yet. Ask the user to add nodes with `adhdev mesh add-node`.");
|
|
5282
|
+
}
|
|
5283
|
+
sections.push(buildPolicySection(mesh.policy));
|
|
5284
|
+
sections.push(TOOLS_SECTION);
|
|
5285
|
+
sections.push(WORKFLOW_SECTION);
|
|
5286
|
+
sections.push(RULES_SECTION);
|
|
5287
|
+
if (userInstruction) {
|
|
5288
|
+
sections.push(`## Additional Context
|
|
5289
|
+
${userInstruction}`);
|
|
5290
|
+
}
|
|
5291
|
+
if (mesh.coordinator.systemPromptSuffix) {
|
|
5292
|
+
sections.push(mesh.coordinator.systemPromptSuffix);
|
|
5293
|
+
}
|
|
5294
|
+
return sections.join("\n\n");
|
|
5295
|
+
}
|
|
5296
|
+
function buildNodeStatusSection(nodes) {
|
|
5297
|
+
const lines = ["## Current Node Status", ""];
|
|
5298
|
+
for (const n of nodes) {
|
|
5299
|
+
const healthIcon = n.health === "online" ? "\u{1F7E2}" : n.health === "dirty" ? "\u{1F7E1}" : n.health === "offline" ? "\u26AB" : "\u{1F534}";
|
|
5300
|
+
const sessions = n.activeSessions.length > 0 ? `sessions: ${n.activeSessions.join(", ")}` : "no active sessions";
|
|
5301
|
+
const branch = n.git?.branch ? `branch: \`${n.git.branch}\`` : "";
|
|
5302
|
+
lines.push(`- ${healthIcon} **${n.machineLabel}** (${n.nodeId})`);
|
|
5303
|
+
lines.push(` workspace: \`${n.workspace}\` | ${branch} | ${sessions}`);
|
|
5304
|
+
if (n.error) lines.push(` \u26A0\uFE0F ${n.error}`);
|
|
5305
|
+
}
|
|
5306
|
+
return lines.join("\n");
|
|
5307
|
+
}
|
|
5308
|
+
function buildNodeConfigSection(mesh) {
|
|
5309
|
+
const lines = ["## Configured Nodes", ""];
|
|
5310
|
+
for (const n of mesh.nodes) {
|
|
5311
|
+
const labels = [];
|
|
5312
|
+
if (n.isLocalWorktree) labels.push("worktree");
|
|
5313
|
+
if (n.policy.readOnly) labels.push("read-only");
|
|
5314
|
+
const suffix = labels.length ? ` [${labels.join(", ")}]` : "";
|
|
5315
|
+
lines.push(`- **${n.workspace}** (${n.id})${suffix}`);
|
|
5316
|
+
}
|
|
5317
|
+
lines.push("", "_Use `mesh_status` to probe live health before delegating work._");
|
|
5318
|
+
return lines.join("\n");
|
|
5319
|
+
}
|
|
5320
|
+
function buildPolicySection(policy) {
|
|
5321
|
+
const rules = [];
|
|
5322
|
+
if (policy.requirePreTaskCheckpoint) rules.push("- Create a git checkpoint **before** starting each task");
|
|
5323
|
+
if (policy.requirePostTaskCheckpoint) rules.push("- Create a git checkpoint **after** each task completes");
|
|
5324
|
+
if (policy.requireApprovalForPush) rules.push("- **Ask for user approval** before pushing to remote");
|
|
5325
|
+
if (policy.requireApprovalForDestructiveGit) rules.push("- **Ask for user approval** before destructive git operations (force push, reset, etc.)");
|
|
5326
|
+
const dirtyBehavior = {
|
|
5327
|
+
block: "- **Do not** send tasks to nodes with dirty workspaces",
|
|
5328
|
+
warn: "- Warn the user if a node has uncommitted changes before sending a task",
|
|
5329
|
+
checkpoint_then_continue: "- Auto-checkpoint dirty nodes before sending tasks"
|
|
5330
|
+
}[policy.dirtyWorkspaceBehavior] || "";
|
|
5331
|
+
if (dirtyBehavior) rules.push(dirtyBehavior);
|
|
5332
|
+
rules.push(`- Maximum **${policy.maxParallelTasks}** tasks running in parallel`);
|
|
5333
|
+
return `## Policy
|
|
5334
|
+
${rules.join("\n")}`;
|
|
5335
|
+
}
|
|
5336
|
+
var TOOLS_SECTION = `## Available Tools
|
|
5337
|
+
|
|
5338
|
+
| Tool | Purpose |
|
|
5339
|
+
|------|---------|
|
|
5340
|
+
| \`mesh_status\` | Check all nodes' health, git state, and active sessions |
|
|
5341
|
+
| \`mesh_list_nodes\` | List nodes with workspace paths |
|
|
5342
|
+
| \`mesh_launch_session\` | Start a new agent session on a node |
|
|
5343
|
+
| \`mesh_send_task\` | Send a task (natural language) to a running agent |
|
|
5344
|
+
| \`mesh_read_chat\` | Read an agent's recent messages to check progress |
|
|
5345
|
+
| \`mesh_git_status\` | Check git status on a specific node |
|
|
5346
|
+
| \`mesh_checkpoint\` | Create a git checkpoint on a node |
|
|
5347
|
+
| \`mesh_approve\` | Approve/reject a pending agent action |`;
|
|
5348
|
+
var WORKFLOW_SECTION = `## Orchestration Workflow
|
|
5349
|
+
|
|
5350
|
+
1. **Assess** \u2014 Call \`mesh_status\` to see which nodes are healthy and available.
|
|
5351
|
+
2. **Plan** \u2014 Decompose the user's request into independent tasks for parallel execution, or sequential tasks when dependencies exist.
|
|
5352
|
+
3. **Delegate** \u2014 For each task:
|
|
5353
|
+
a. Pick the best node (consider: health, dirty state, current workload).
|
|
5354
|
+
b. If no session exists, call \`mesh_launch_session\` to start one.
|
|
5355
|
+
c. Call \`mesh_send_task\` with a clear, self-contained natural-language instruction.
|
|
5356
|
+
4. **Monitor** \u2014 Periodically call \`mesh_read_chat\` to check progress. Handle approvals via \`mesh_approve\`.
|
|
5357
|
+
5. **Verify** \u2014 When a task reports completion, call \`mesh_git_status\` to verify changes were made.
|
|
5358
|
+
6. **Checkpoint** \u2014 Call \`mesh_checkpoint\` to save the work.
|
|
5359
|
+
7. **Report** \u2014 Summarize what was done, what changed, and any issues.`;
|
|
5360
|
+
var RULES_SECTION = `## Rules
|
|
5361
|
+
|
|
5362
|
+
- **Be conversational.** Delegate work the way a tech lead would \u2014 clear, specific instructions in natural language.
|
|
5363
|
+
- **Don't inspect code.** Trust the agent's output. Verify via git diff/status, not by reading source files.
|
|
5364
|
+
- **Don't over-parallelize.** Start with 1-2 concurrent tasks. Scale up if they succeed.
|
|
5365
|
+
- **Handle failures gracefully.** If a task fails, read the chat to understand why, then retry or reassign.
|
|
5366
|
+
- **Keep the user informed.** Report progress after each delegation round.
|
|
5367
|
+
- **Respect node capabilities.** Don't send build tasks to read-only nodes. Don't push from nodes that aren't allowed to.
|
|
5368
|
+
- **Never fabricate tool results.** Always call the actual tool; never pretend you did.`;
|
|
5369
|
+
|
|
5370
|
+
// src/mesh/mesh-sync.ts
|
|
5371
|
+
async function syncMeshes(transport) {
|
|
5372
|
+
const result = { pushed: 0, pulled: 0, deleted: 0, errors: [] };
|
|
5373
|
+
let remoteMeshes;
|
|
5374
|
+
try {
|
|
5375
|
+
const res = await transport.listRemoteMeshes();
|
|
5376
|
+
remoteMeshes = res.meshes;
|
|
5377
|
+
} catch (e) {
|
|
5378
|
+
result.errors.push(`Failed to list remote meshes: ${e.message}`);
|
|
5379
|
+
return result;
|
|
5380
|
+
}
|
|
5381
|
+
const localMeshes = listMeshes();
|
|
5382
|
+
const remoteByIdentity = new Map(remoteMeshes.map((m) => [m.repo_identity, m]));
|
|
5383
|
+
const localByIdentity = new Map(localMeshes.map((m) => [m.repoIdentity, m]));
|
|
5384
|
+
for (const local of localMeshes) {
|
|
5385
|
+
if (!remoteByIdentity.has(local.repoIdentity)) {
|
|
5386
|
+
try {
|
|
5387
|
+
await transport.createRemoteMesh({
|
|
5388
|
+
name: local.name,
|
|
5389
|
+
repo_identity: local.repoIdentity,
|
|
5390
|
+
repo_remote_url: local.repoRemoteUrl,
|
|
5391
|
+
default_branch: local.defaultBranch,
|
|
5392
|
+
policy: JSON.stringify(local.policy)
|
|
5393
|
+
});
|
|
5394
|
+
result.pushed++;
|
|
5395
|
+
} catch (e) {
|
|
5396
|
+
result.errors.push(`Push failed for "${local.name}": ${e.message}`);
|
|
5397
|
+
}
|
|
5398
|
+
}
|
|
5399
|
+
}
|
|
5400
|
+
for (const remote of remoteMeshes) {
|
|
5401
|
+
if (!localByIdentity.has(remote.repo_identity)) {
|
|
5402
|
+
try {
|
|
5403
|
+
let policy;
|
|
5404
|
+
try {
|
|
5405
|
+
policy = JSON.parse(remote.policy);
|
|
5406
|
+
} catch {
|
|
5407
|
+
policy = void 0;
|
|
5408
|
+
}
|
|
5409
|
+
createMesh({
|
|
5410
|
+
name: remote.name,
|
|
5411
|
+
repoIdentity: remote.repo_identity,
|
|
5412
|
+
repoRemoteUrl: remote.repo_remote_url || void 0,
|
|
5413
|
+
defaultBranch: remote.default_branch || void 0,
|
|
5414
|
+
policy
|
|
5415
|
+
});
|
|
5416
|
+
result.pulled++;
|
|
5417
|
+
} catch (e) {
|
|
5418
|
+
result.errors.push(`Pull failed for "${remote.name}": ${e.message}`);
|
|
5419
|
+
}
|
|
5420
|
+
}
|
|
5421
|
+
}
|
|
5422
|
+
return result;
|
|
5423
|
+
}
|
|
5424
|
+
|
|
5425
|
+
// src/config/state-store.ts
|
|
5426
|
+
init_config();
|
|
5427
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
5428
|
+
import { join as join4 } from "path";
|
|
5124
5429
|
var DEFAULT_STATE = {
|
|
5125
5430
|
recentActivity: [],
|
|
5126
5431
|
savedProviderSessions: [],
|
|
@@ -5133,7 +5438,7 @@ function isPlainObject2(value) {
|
|
|
5133
5438
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
5134
5439
|
}
|
|
5135
5440
|
function getStatePath() {
|
|
5136
|
-
return
|
|
5441
|
+
return join4(getConfigDir(), "state.json");
|
|
5137
5442
|
}
|
|
5138
5443
|
function normalizeState(raw) {
|
|
5139
5444
|
const parsed = isPlainObject2(raw) ? raw : {};
|
|
@@ -5169,11 +5474,11 @@ function normalizeState(raw) {
|
|
|
5169
5474
|
}
|
|
5170
5475
|
function loadState() {
|
|
5171
5476
|
const statePath = getStatePath();
|
|
5172
|
-
if (!
|
|
5477
|
+
if (!existsSync4(statePath)) {
|
|
5173
5478
|
return { ...DEFAULT_STATE };
|
|
5174
5479
|
}
|
|
5175
5480
|
try {
|
|
5176
|
-
const raw =
|
|
5481
|
+
const raw = readFileSync3(statePath, "utf-8");
|
|
5177
5482
|
return normalizeState(JSON.parse(raw));
|
|
5178
5483
|
} catch {
|
|
5179
5484
|
return { ...DEFAULT_STATE };
|
|
@@ -5182,7 +5487,7 @@ function loadState() {
|
|
|
5182
5487
|
function saveState(state) {
|
|
5183
5488
|
const statePath = getStatePath();
|
|
5184
5489
|
const normalized = normalizeState(state);
|
|
5185
|
-
|
|
5490
|
+
writeFileSync3(statePath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
|
|
5186
5491
|
}
|
|
5187
5492
|
function resetState() {
|
|
5188
5493
|
saveState({ ...DEFAULT_STATE });
|
|
@@ -5190,7 +5495,7 @@ function resetState() {
|
|
|
5190
5495
|
|
|
5191
5496
|
// src/detection/ide-detector.ts
|
|
5192
5497
|
import { execSync } from "child_process";
|
|
5193
|
-
import { existsSync as
|
|
5498
|
+
import { existsSync as existsSync5 } from "fs";
|
|
5194
5499
|
import { platform, homedir as homedir3 } from "os";
|
|
5195
5500
|
import * as path7 from "path";
|
|
5196
5501
|
var BUILTIN_IDE_DEFINITIONS = [];
|
|
@@ -5214,7 +5519,7 @@ function findCliCommand(command) {
|
|
|
5214
5519
|
if (path7.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
|
|
5215
5520
|
const candidate = trimmed.startsWith("~") ? path7.join(homedir3(), trimmed.slice(1)) : trimmed;
|
|
5216
5521
|
const resolved = path7.isAbsolute(candidate) ? candidate : path7.resolve(candidate);
|
|
5217
|
-
return
|
|
5522
|
+
return existsSync5(resolved) ? resolved : null;
|
|
5218
5523
|
}
|
|
5219
5524
|
try {
|
|
5220
5525
|
const result = execSync(
|
|
@@ -5245,9 +5550,9 @@ function checkPathExists(paths) {
|
|
|
5245
5550
|
if (normalized.includes("*")) {
|
|
5246
5551
|
const username = home.split(/[\\/]/).pop() || "";
|
|
5247
5552
|
const resolved = normalized.replace("*", username);
|
|
5248
|
-
if (
|
|
5553
|
+
if (existsSync5(resolved)) return resolved;
|
|
5249
5554
|
} else {
|
|
5250
|
-
if (
|
|
5555
|
+
if (existsSync5(normalized)) return normalized;
|
|
5251
5556
|
}
|
|
5252
5557
|
}
|
|
5253
5558
|
return null;
|
|
@@ -5261,7 +5566,7 @@ async function detectIDEs(providerLoader) {
|
|
|
5261
5566
|
let resolvedCli = cliPath;
|
|
5262
5567
|
if (!resolvedCli && appPath && os21 === "darwin") {
|
|
5263
5568
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
5264
|
-
if (
|
|
5569
|
+
if (existsSync5(bundledCli)) resolvedCli = bundledCli;
|
|
5265
5570
|
}
|
|
5266
5571
|
if (!resolvedCli && appPath && os21 === "win32") {
|
|
5267
5572
|
const { dirname: dirname7 } = await import("path");
|
|
@@ -5274,7 +5579,7 @@ async function detectIDEs(providerLoader) {
|
|
|
5274
5579
|
`${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
|
|
5275
5580
|
];
|
|
5276
5581
|
for (const c of candidates) {
|
|
5277
|
-
if (
|
|
5582
|
+
if (existsSync5(c)) {
|
|
5278
5583
|
resolvedCli = c;
|
|
5279
5584
|
break;
|
|
5280
5585
|
}
|
|
@@ -5300,7 +5605,7 @@ async function detectIDEs(providerLoader) {
|
|
|
5300
5605
|
import { exec } from "child_process";
|
|
5301
5606
|
import * as os2 from "os";
|
|
5302
5607
|
import * as path8 from "path";
|
|
5303
|
-
import { existsSync as
|
|
5608
|
+
import { existsSync as existsSync6 } from "fs";
|
|
5304
5609
|
function parseVersion(raw) {
|
|
5305
5610
|
const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
|
|
5306
5611
|
return match ? match[1] : raw.split("\n")[0].slice(0, 100);
|
|
@@ -5324,7 +5629,7 @@ function resolveCommandPath(command) {
|
|
|
5324
5629
|
if (isExplicitCommandPath(trimmed)) {
|
|
5325
5630
|
const expanded = expandHome(trimmed);
|
|
5326
5631
|
const candidate = path8.isAbsolute(expanded) ? expanded : path8.resolve(expanded);
|
|
5327
|
-
return
|
|
5632
|
+
return existsSync6(candidate) ? candidate : null;
|
|
5328
5633
|
}
|
|
5329
5634
|
return null;
|
|
5330
5635
|
}
|
|
@@ -10952,7 +11257,7 @@ function resolveLegacyProviderScript(fn, scriptName, params) {
|
|
|
10952
11257
|
import * as fs4 from "fs";
|
|
10953
11258
|
import * as os6 from "os";
|
|
10954
11259
|
import * as path11 from "path";
|
|
10955
|
-
import { randomUUID as
|
|
11260
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
10956
11261
|
|
|
10957
11262
|
// src/providers/provider-input-support.ts
|
|
10958
11263
|
var VALID_INPUT_MEDIA_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "resource"]);
|
|
@@ -11469,7 +11774,7 @@ function safeBundleIdSegment(value, fallback) {
|
|
|
11469
11774
|
function createChatDebugBundleId(targetSessionId) {
|
|
11470
11775
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[-:.]/g, "").replace("T", "T").replace("Z", "Z");
|
|
11471
11776
|
const sessionSegment = safeBundleIdSegment(targetSessionId, "unknown-session");
|
|
11472
|
-
return `chat-debug-${timestamp}-${sessionSegment}-${
|
|
11777
|
+
return `chat-debug-${timestamp}-${sessionSegment}-${randomUUID5().slice(0, 8)}`;
|
|
11473
11778
|
}
|
|
11474
11779
|
function buildChatDebugBundleSummary(bundle) {
|
|
11475
11780
|
const target = bundle.target && typeof bundle.target === "object" ? bundle.target : {};
|
|
@@ -14063,7 +14368,7 @@ init_provider_cli_adapter();
|
|
|
14063
14368
|
import * as os13 from "os";
|
|
14064
14369
|
import * as path16 from "path";
|
|
14065
14370
|
import * as crypto4 from "crypto";
|
|
14066
|
-
import { existsSync as
|
|
14371
|
+
import { existsSync as existsSync11 } from "fs";
|
|
14067
14372
|
import { execFileSync } from "child_process";
|
|
14068
14373
|
import chalk from "chalk";
|
|
14069
14374
|
init_config();
|
|
@@ -16205,7 +16510,7 @@ function commandExists(command) {
|
|
|
16205
16510
|
const trimmed = command.trim();
|
|
16206
16511
|
if (!trimmed) return false;
|
|
16207
16512
|
if (isExplicitCommand(trimmed)) {
|
|
16208
|
-
return
|
|
16513
|
+
return existsSync11(expandExecutable(trimmed));
|
|
16209
16514
|
}
|
|
16210
16515
|
try {
|
|
16211
16516
|
execFileSync(process.platform === "win32" ? "where" : "which", [trimmed], {
|
|
@@ -28683,6 +28988,7 @@ export {
|
|
|
28683
28988
|
DEFAULT_DAEMON_PORT,
|
|
28684
28989
|
DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS,
|
|
28685
28990
|
DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS,
|
|
28991
|
+
DEFAULT_MESH_POLICY,
|
|
28686
28992
|
DEFAULT_SESSION_HOST_APP_NAME,
|
|
28687
28993
|
DEFAULT_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS,
|
|
28688
28994
|
DEFAULT_SESSION_HOST_READY_TIMEOUT_MS,
|
|
@@ -28716,11 +29022,13 @@ export {
|
|
|
28716
29022
|
SessionHostPtyTransportFactory,
|
|
28717
29023
|
TurnSnapshotTracker,
|
|
28718
29024
|
VersionArchive,
|
|
29025
|
+
addNode,
|
|
28719
29026
|
appendRecentActivity,
|
|
28720
29027
|
buildAssistantChatMessage,
|
|
28721
29028
|
buildChatMessage,
|
|
28722
29029
|
buildChatMessageSignature,
|
|
28723
29030
|
buildChatTailDeliverySignature,
|
|
29031
|
+
buildCoordinatorSystemPrompt,
|
|
28724
29032
|
buildMachineInfo,
|
|
28725
29033
|
buildPinnedGlobalInstallCommand,
|
|
28726
29034
|
buildRuntimeSystemChatMessage,
|
|
@@ -28743,6 +29051,8 @@ export {
|
|
|
28743
29051
|
createGitSnapshotStore,
|
|
28744
29052
|
createGitWorkspaceMonitor,
|
|
28745
29053
|
createInteractionId,
|
|
29054
|
+
createMesh,
|
|
29055
|
+
deleteMesh,
|
|
28746
29056
|
detectAllVersions,
|
|
28747
29057
|
detectCLIs,
|
|
28748
29058
|
detectIDEs,
|
|
@@ -28761,6 +29071,8 @@ export {
|
|
|
28761
29071
|
getGitRepoStatus,
|
|
28762
29072
|
getHostMemorySnapshot,
|
|
28763
29073
|
getLogLevel,
|
|
29074
|
+
getMesh,
|
|
29075
|
+
getMeshByRepo,
|
|
28764
29076
|
getNpmExecOptions,
|
|
28765
29077
|
getRecentActivity,
|
|
28766
29078
|
getRecentCommands,
|
|
@@ -28791,6 +29103,7 @@ export {
|
|
|
28791
29103
|
launchIDE,
|
|
28792
29104
|
launchWithCdp,
|
|
28793
29105
|
listHostedCliRuntimes,
|
|
29106
|
+
listMeshes,
|
|
28794
29107
|
loadConfig,
|
|
28795
29108
|
loadState,
|
|
28796
29109
|
logCommand,
|
|
@@ -28806,6 +29119,7 @@ export {
|
|
|
28806
29119
|
normalizeInputEnvelope,
|
|
28807
29120
|
normalizeManagedStatus,
|
|
28808
29121
|
normalizeMessageParts,
|
|
29122
|
+
normalizeRepoIdentity,
|
|
28809
29123
|
normalizeSessionModalFields,
|
|
28810
29124
|
parsePorcelainV2Status,
|
|
28811
29125
|
parseProviderSourceConfigUpdate,
|
|
@@ -28817,6 +29131,7 @@ export {
|
|
|
28817
29131
|
readChatHistory,
|
|
28818
29132
|
recordDebugTrace,
|
|
28819
29133
|
registerExtensionProviders,
|
|
29134
|
+
removeNode,
|
|
28820
29135
|
resetConfig,
|
|
28821
29136
|
resetDebugRuntimeConfig,
|
|
28822
29137
|
resetState,
|
|
@@ -28839,7 +29154,10 @@ export {
|
|
|
28839
29154
|
spawnDetachedDaemonUpgradeHelper,
|
|
28840
29155
|
startDaemonDevSupport,
|
|
28841
29156
|
summarizeGitStatus,
|
|
29157
|
+
syncMeshes,
|
|
28842
29158
|
updateConfig,
|
|
29159
|
+
updateMesh,
|
|
29160
|
+
updateNode,
|
|
28843
29161
|
upsertSavedProviderSession
|
|
28844
29162
|
};
|
|
28845
29163
|
//# sourceMappingURL=index.mjs.map
|