@adhdev/daemon-standalone 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/index.js
CHANGED
|
@@ -31208,6 +31208,7 @@ var require_dist2 = __commonJS({
|
|
|
31208
31208
|
DEFAULT_DAEMON_PORT: () => DEFAULT_DAEMON_PORT,
|
|
31209
31209
|
DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS: () => DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS,
|
|
31210
31210
|
DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS: () => DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS2,
|
|
31211
|
+
DEFAULT_MESH_POLICY: () => DEFAULT_MESH_POLICY,
|
|
31211
31212
|
DEFAULT_SESSION_HOST_APP_NAME: () => DEFAULT_SESSION_HOST_APP_NAME,
|
|
31212
31213
|
DEFAULT_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS: () => DEFAULT_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS2,
|
|
31213
31214
|
DEFAULT_SESSION_HOST_READY_TIMEOUT_MS: () => DEFAULT_SESSION_HOST_READY_TIMEOUT_MS2,
|
|
@@ -31241,11 +31242,13 @@ var require_dist2 = __commonJS({
|
|
|
31241
31242
|
SessionHostPtyTransportFactory: () => SessionHostPtyTransportFactory2,
|
|
31242
31243
|
TurnSnapshotTracker: () => TurnSnapshotTracker,
|
|
31243
31244
|
VersionArchive: () => VersionArchive,
|
|
31245
|
+
addNode: () => addNode,
|
|
31244
31246
|
appendRecentActivity: () => appendRecentActivity,
|
|
31245
31247
|
buildAssistantChatMessage: () => buildAssistantChatMessage,
|
|
31246
31248
|
buildChatMessage: () => buildChatMessage,
|
|
31247
31249
|
buildChatMessageSignature: () => buildChatMessageSignature,
|
|
31248
31250
|
buildChatTailDeliverySignature: () => buildChatTailDeliverySignature,
|
|
31251
|
+
buildCoordinatorSystemPrompt: () => buildCoordinatorSystemPrompt,
|
|
31249
31252
|
buildMachineInfo: () => buildMachineInfo2,
|
|
31250
31253
|
buildPinnedGlobalInstallCommand: () => buildPinnedGlobalInstallCommand,
|
|
31251
31254
|
buildRuntimeSystemChatMessage: () => buildRuntimeSystemChatMessage,
|
|
@@ -31268,6 +31271,8 @@ var require_dist2 = __commonJS({
|
|
|
31268
31271
|
createGitSnapshotStore: () => createGitSnapshotStore,
|
|
31269
31272
|
createGitWorkspaceMonitor: () => createGitWorkspaceMonitor2,
|
|
31270
31273
|
createInteractionId: () => createInteractionId,
|
|
31274
|
+
createMesh: () => createMesh,
|
|
31275
|
+
deleteMesh: () => deleteMesh,
|
|
31271
31276
|
detectAllVersions: () => detectAllVersions,
|
|
31272
31277
|
detectCLIs: () => detectCLIs,
|
|
31273
31278
|
detectIDEs: () => detectIDEs,
|
|
@@ -31286,6 +31291,8 @@ var require_dist2 = __commonJS({
|
|
|
31286
31291
|
getGitRepoStatus: () => getGitRepoStatus,
|
|
31287
31292
|
getHostMemorySnapshot: () => getHostMemorySnapshot,
|
|
31288
31293
|
getLogLevel: () => getLogLevel,
|
|
31294
|
+
getMesh: () => getMesh,
|
|
31295
|
+
getMeshByRepo: () => getMeshByRepo,
|
|
31289
31296
|
getNpmExecOptions: () => getNpmExecOptions,
|
|
31290
31297
|
getRecentActivity: () => getRecentActivity,
|
|
31291
31298
|
getRecentCommands: () => getRecentCommands,
|
|
@@ -31316,6 +31323,7 @@ var require_dist2 = __commonJS({
|
|
|
31316
31323
|
launchIDE: () => launchIDE,
|
|
31317
31324
|
launchWithCdp: () => launchWithCdp,
|
|
31318
31325
|
listHostedCliRuntimes: () => listHostedCliRuntimes2,
|
|
31326
|
+
listMeshes: () => listMeshes,
|
|
31319
31327
|
loadConfig: () => loadConfig2,
|
|
31320
31328
|
loadState: () => loadState,
|
|
31321
31329
|
logCommand: () => logCommand,
|
|
@@ -31331,6 +31339,7 @@ var require_dist2 = __commonJS({
|
|
|
31331
31339
|
normalizeInputEnvelope: () => normalizeInputEnvelope,
|
|
31332
31340
|
normalizeManagedStatus: () => normalizeManagedStatus,
|
|
31333
31341
|
normalizeMessageParts: () => normalizeMessageParts,
|
|
31342
|
+
normalizeRepoIdentity: () => normalizeRepoIdentity,
|
|
31334
31343
|
normalizeSessionModalFields: () => normalizeSessionModalFields,
|
|
31335
31344
|
parsePorcelainV2Status: () => parsePorcelainV2Status,
|
|
31336
31345
|
parseProviderSourceConfigUpdate: () => parseProviderSourceConfigUpdate,
|
|
@@ -31342,6 +31351,7 @@ var require_dist2 = __commonJS({
|
|
|
31342
31351
|
readChatHistory: () => readChatHistory,
|
|
31343
31352
|
recordDebugTrace: () => recordDebugTrace,
|
|
31344
31353
|
registerExtensionProviders: () => registerExtensionProviders,
|
|
31354
|
+
removeNode: () => removeNode,
|
|
31345
31355
|
resetConfig: () => resetConfig,
|
|
31346
31356
|
resetDebugRuntimeConfig: () => resetDebugRuntimeConfig,
|
|
31347
31357
|
resetState: () => resetState,
|
|
@@ -31364,10 +31374,21 @@ var require_dist2 = __commonJS({
|
|
|
31364
31374
|
spawnDetachedDaemonUpgradeHelper: () => spawnDetachedDaemonUpgradeHelper,
|
|
31365
31375
|
startDaemonDevSupport: () => startDaemonDevSupport2,
|
|
31366
31376
|
summarizeGitStatus: () => summarizeGitStatus,
|
|
31377
|
+
syncMeshes: () => syncMeshes,
|
|
31367
31378
|
updateConfig: () => updateConfig,
|
|
31379
|
+
updateMesh: () => updateMesh,
|
|
31380
|
+
updateNode: () => updateNode,
|
|
31368
31381
|
upsertSavedProviderSession: () => upsertSavedProviderSession
|
|
31369
31382
|
});
|
|
31370
31383
|
module2.exports = __toCommonJS2(index_exports);
|
|
31384
|
+
var DEFAULT_MESH_POLICY = {
|
|
31385
|
+
requirePreTaskCheckpoint: false,
|
|
31386
|
+
requirePostTaskCheckpoint: true,
|
|
31387
|
+
requireApprovalForPush: true,
|
|
31388
|
+
requireApprovalForDestructiveGit: true,
|
|
31389
|
+
dirtyWorkspaceBehavior: "warn",
|
|
31390
|
+
maxParallelTasks: 2
|
|
31391
|
+
};
|
|
31371
31392
|
var import_node_child_process = require("child_process");
|
|
31372
31393
|
var import_node_fs3 = require("fs");
|
|
31373
31394
|
var import_promises4 = require("fs/promises");
|
|
@@ -33139,6 +33160,295 @@ var require_dist2 = __commonJS({
|
|
|
33139
33160
|
}
|
|
33140
33161
|
var import_fs2 = require("fs");
|
|
33141
33162
|
var import_path22 = require("path");
|
|
33163
|
+
var import_crypto32 = require("crypto");
|
|
33164
|
+
init_config();
|
|
33165
|
+
function getMeshConfigPath() {
|
|
33166
|
+
return (0, import_path22.join)(getConfigDir(), "meshes.json");
|
|
33167
|
+
}
|
|
33168
|
+
function loadMeshConfig() {
|
|
33169
|
+
const path26 = getMeshConfigPath();
|
|
33170
|
+
if (!(0, import_fs2.existsSync)(path26)) return { meshes: [] };
|
|
33171
|
+
try {
|
|
33172
|
+
const raw = JSON.parse((0, import_fs2.readFileSync)(path26, "utf-8"));
|
|
33173
|
+
if (!raw || !Array.isArray(raw.meshes)) return { meshes: [] };
|
|
33174
|
+
return raw;
|
|
33175
|
+
} catch {
|
|
33176
|
+
return { meshes: [] };
|
|
33177
|
+
}
|
|
33178
|
+
}
|
|
33179
|
+
function saveMeshConfig(config2) {
|
|
33180
|
+
const path26 = getMeshConfigPath();
|
|
33181
|
+
(0, import_fs2.writeFileSync)(path26, JSON.stringify(config2, null, 2), { encoding: "utf-8", mode: 384 });
|
|
33182
|
+
}
|
|
33183
|
+
function normalizeRepoIdentity(remoteUrl) {
|
|
33184
|
+
let identity = remoteUrl.trim();
|
|
33185
|
+
if (identity.startsWith("http://") || identity.startsWith("https://")) {
|
|
33186
|
+
try {
|
|
33187
|
+
const url2 = new URL(identity);
|
|
33188
|
+
const path26 = url2.pathname.replace(/^\//, "").replace(/\.git$/, "");
|
|
33189
|
+
return `${url2.hostname}/${path26}`;
|
|
33190
|
+
} catch {
|
|
33191
|
+
}
|
|
33192
|
+
}
|
|
33193
|
+
const sshMatch = identity.match(/^(?:ssh:\/\/)?[\w.-]+@([\w.-]+)[:/]([\w.\-/]+?)(?:\.git)?$/);
|
|
33194
|
+
if (sshMatch) return `${sshMatch[1]}/${sshMatch[2]}`;
|
|
33195
|
+
return identity;
|
|
33196
|
+
}
|
|
33197
|
+
function listMeshes() {
|
|
33198
|
+
return loadMeshConfig().meshes;
|
|
33199
|
+
}
|
|
33200
|
+
function getMesh(meshId) {
|
|
33201
|
+
return loadMeshConfig().meshes.find((m) => m.id === meshId);
|
|
33202
|
+
}
|
|
33203
|
+
function getMeshByRepo(repoIdentity) {
|
|
33204
|
+
return loadMeshConfig().meshes.find((m) => m.repoIdentity === repoIdentity);
|
|
33205
|
+
}
|
|
33206
|
+
function createMesh(opts) {
|
|
33207
|
+
const config2 = loadMeshConfig();
|
|
33208
|
+
if (config2.meshes.length >= 20) {
|
|
33209
|
+
throw new Error("Maximum 20 meshes allowed");
|
|
33210
|
+
}
|
|
33211
|
+
const repoIdentity = opts.repoIdentity || (opts.repoRemoteUrl ? normalizeRepoIdentity(opts.repoRemoteUrl) : "");
|
|
33212
|
+
if (!repoIdentity) throw new Error("Either repoRemoteUrl or repoIdentity is required");
|
|
33213
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
33214
|
+
const mesh = {
|
|
33215
|
+
id: `mesh_${(0, import_crypto32.randomUUID)().replace(/-/g, "")}`,
|
|
33216
|
+
name: opts.name.trim().slice(0, 100),
|
|
33217
|
+
repoIdentity,
|
|
33218
|
+
repoRemoteUrl: opts.repoRemoteUrl,
|
|
33219
|
+
defaultBranch: opts.defaultBranch,
|
|
33220
|
+
policy: { ...DEFAULT_MESH_POLICY, ...opts.policy },
|
|
33221
|
+
coordinator: opts.coordinator || {},
|
|
33222
|
+
nodes: [],
|
|
33223
|
+
createdAt: now,
|
|
33224
|
+
updatedAt: now
|
|
33225
|
+
};
|
|
33226
|
+
config2.meshes.push(mesh);
|
|
33227
|
+
saveMeshConfig(config2);
|
|
33228
|
+
return mesh;
|
|
33229
|
+
}
|
|
33230
|
+
function updateMesh(meshId, opts) {
|
|
33231
|
+
const config2 = loadMeshConfig();
|
|
33232
|
+
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
33233
|
+
if (!mesh) return void 0;
|
|
33234
|
+
if (opts.name !== void 0) mesh.name = opts.name.trim().slice(0, 100);
|
|
33235
|
+
if (opts.defaultBranch !== void 0) mesh.defaultBranch = opts.defaultBranch;
|
|
33236
|
+
if (opts.policy) mesh.policy = { ...mesh.policy, ...opts.policy };
|
|
33237
|
+
if (opts.coordinator) mesh.coordinator = opts.coordinator;
|
|
33238
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
33239
|
+
saveMeshConfig(config2);
|
|
33240
|
+
return mesh;
|
|
33241
|
+
}
|
|
33242
|
+
function deleteMesh(meshId) {
|
|
33243
|
+
const config2 = loadMeshConfig();
|
|
33244
|
+
const idx = config2.meshes.findIndex((m) => m.id === meshId);
|
|
33245
|
+
if (idx === -1) return false;
|
|
33246
|
+
config2.meshes.splice(idx, 1);
|
|
33247
|
+
saveMeshConfig(config2);
|
|
33248
|
+
return true;
|
|
33249
|
+
}
|
|
33250
|
+
function addNode(meshId, opts) {
|
|
33251
|
+
const config2 = loadMeshConfig();
|
|
33252
|
+
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
33253
|
+
if (!mesh) return void 0;
|
|
33254
|
+
if (mesh.nodes.length >= 10) {
|
|
33255
|
+
throw new Error("Maximum 10 nodes per mesh");
|
|
33256
|
+
}
|
|
33257
|
+
if (mesh.nodes.some((n) => n.workspace === opts.workspace)) {
|
|
33258
|
+
throw new Error("This workspace is already in the mesh");
|
|
33259
|
+
}
|
|
33260
|
+
const node = {
|
|
33261
|
+
id: `node_${(0, import_crypto32.randomUUID)().replace(/-/g, "")}`,
|
|
33262
|
+
workspace: opts.workspace.trim(),
|
|
33263
|
+
repoRoot: opts.repoRoot,
|
|
33264
|
+
userOverrides: opts.userOverrides || {},
|
|
33265
|
+
policy: opts.policy || {},
|
|
33266
|
+
isLocalWorktree: opts.isLocalWorktree
|
|
33267
|
+
};
|
|
33268
|
+
mesh.nodes.push(node);
|
|
33269
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
33270
|
+
saveMeshConfig(config2);
|
|
33271
|
+
return node;
|
|
33272
|
+
}
|
|
33273
|
+
function removeNode(meshId, nodeId) {
|
|
33274
|
+
const config2 = loadMeshConfig();
|
|
33275
|
+
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
33276
|
+
if (!mesh) return false;
|
|
33277
|
+
const idx = mesh.nodes.findIndex((n) => n.id === nodeId);
|
|
33278
|
+
if (idx === -1) return false;
|
|
33279
|
+
mesh.nodes.splice(idx, 1);
|
|
33280
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
33281
|
+
saveMeshConfig(config2);
|
|
33282
|
+
return true;
|
|
33283
|
+
}
|
|
33284
|
+
function updateNode(meshId, nodeId, opts) {
|
|
33285
|
+
const config2 = loadMeshConfig();
|
|
33286
|
+
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
33287
|
+
if (!mesh) return void 0;
|
|
33288
|
+
const node = mesh.nodes.find((n) => n.id === nodeId);
|
|
33289
|
+
if (!node) return void 0;
|
|
33290
|
+
if (opts.userOverrides) node.userOverrides = { ...node.userOverrides, ...opts.userOverrides };
|
|
33291
|
+
if (opts.policy) node.policy = { ...node.policy, ...opts.policy };
|
|
33292
|
+
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
33293
|
+
saveMeshConfig(config2);
|
|
33294
|
+
return node;
|
|
33295
|
+
}
|
|
33296
|
+
function buildCoordinatorSystemPrompt(ctx) {
|
|
33297
|
+
const { mesh, status, userInstruction } = ctx;
|
|
33298
|
+
const sections = [];
|
|
33299
|
+
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.
|
|
33300
|
+
|
|
33301
|
+
Your mesh: **${mesh.name}**
|
|
33302
|
+
Repository: \`${mesh.repoIdentity}\`${mesh.defaultBranch ? `
|
|
33303
|
+
Default branch: \`${mesh.defaultBranch}\`` : ""}`);
|
|
33304
|
+
if (status?.nodes?.length) {
|
|
33305
|
+
sections.push(buildNodeStatusSection(status.nodes));
|
|
33306
|
+
} else if (mesh.nodes.length) {
|
|
33307
|
+
sections.push(buildNodeConfigSection(mesh));
|
|
33308
|
+
} else {
|
|
33309
|
+
sections.push("## Nodes\nNo nodes configured yet. Ask the user to add nodes with `adhdev mesh add-node`.");
|
|
33310
|
+
}
|
|
33311
|
+
sections.push(buildPolicySection(mesh.policy));
|
|
33312
|
+
sections.push(TOOLS_SECTION);
|
|
33313
|
+
sections.push(WORKFLOW_SECTION);
|
|
33314
|
+
sections.push(RULES_SECTION);
|
|
33315
|
+
if (userInstruction) {
|
|
33316
|
+
sections.push(`## Additional Context
|
|
33317
|
+
${userInstruction}`);
|
|
33318
|
+
}
|
|
33319
|
+
if (mesh.coordinator.systemPromptSuffix) {
|
|
33320
|
+
sections.push(mesh.coordinator.systemPromptSuffix);
|
|
33321
|
+
}
|
|
33322
|
+
return sections.join("\n\n");
|
|
33323
|
+
}
|
|
33324
|
+
function buildNodeStatusSection(nodes) {
|
|
33325
|
+
const lines = ["## Current Node Status", ""];
|
|
33326
|
+
for (const n of nodes) {
|
|
33327
|
+
const healthIcon = n.health === "online" ? "\u{1F7E2}" : n.health === "dirty" ? "\u{1F7E1}" : n.health === "offline" ? "\u26AB" : "\u{1F534}";
|
|
33328
|
+
const sessions = n.activeSessions.length > 0 ? `sessions: ${n.activeSessions.join(", ")}` : "no active sessions";
|
|
33329
|
+
const branch = n.git?.branch ? `branch: \`${n.git.branch}\`` : "";
|
|
33330
|
+
lines.push(`- ${healthIcon} **${n.machineLabel}** (${n.nodeId})`);
|
|
33331
|
+
lines.push(` workspace: \`${n.workspace}\` | ${branch} | ${sessions}`);
|
|
33332
|
+
if (n.error) lines.push(` \u26A0\uFE0F ${n.error}`);
|
|
33333
|
+
}
|
|
33334
|
+
return lines.join("\n");
|
|
33335
|
+
}
|
|
33336
|
+
function buildNodeConfigSection(mesh) {
|
|
33337
|
+
const lines = ["## Configured Nodes", ""];
|
|
33338
|
+
for (const n of mesh.nodes) {
|
|
33339
|
+
const labels = [];
|
|
33340
|
+
if (n.isLocalWorktree) labels.push("worktree");
|
|
33341
|
+
if (n.policy.readOnly) labels.push("read-only");
|
|
33342
|
+
const suffix = labels.length ? ` [${labels.join(", ")}]` : "";
|
|
33343
|
+
lines.push(`- **${n.workspace}** (${n.id})${suffix}`);
|
|
33344
|
+
}
|
|
33345
|
+
lines.push("", "_Use `mesh_status` to probe live health before delegating work._");
|
|
33346
|
+
return lines.join("\n");
|
|
33347
|
+
}
|
|
33348
|
+
function buildPolicySection(policy) {
|
|
33349
|
+
const rules = [];
|
|
33350
|
+
if (policy.requirePreTaskCheckpoint) rules.push("- Create a git checkpoint **before** starting each task");
|
|
33351
|
+
if (policy.requirePostTaskCheckpoint) rules.push("- Create a git checkpoint **after** each task completes");
|
|
33352
|
+
if (policy.requireApprovalForPush) rules.push("- **Ask for user approval** before pushing to remote");
|
|
33353
|
+
if (policy.requireApprovalForDestructiveGit) rules.push("- **Ask for user approval** before destructive git operations (force push, reset, etc.)");
|
|
33354
|
+
const dirtyBehavior = {
|
|
33355
|
+
block: "- **Do not** send tasks to nodes with dirty workspaces",
|
|
33356
|
+
warn: "- Warn the user if a node has uncommitted changes before sending a task",
|
|
33357
|
+
checkpoint_then_continue: "- Auto-checkpoint dirty nodes before sending tasks"
|
|
33358
|
+
}[policy.dirtyWorkspaceBehavior] || "";
|
|
33359
|
+
if (dirtyBehavior) rules.push(dirtyBehavior);
|
|
33360
|
+
rules.push(`- Maximum **${policy.maxParallelTasks}** tasks running in parallel`);
|
|
33361
|
+
return `## Policy
|
|
33362
|
+
${rules.join("\n")}`;
|
|
33363
|
+
}
|
|
33364
|
+
var TOOLS_SECTION = `## Available Tools
|
|
33365
|
+
|
|
33366
|
+
| Tool | Purpose |
|
|
33367
|
+
|------|---------|
|
|
33368
|
+
| \`mesh_status\` | Check all nodes' health, git state, and active sessions |
|
|
33369
|
+
| \`mesh_list_nodes\` | List nodes with workspace paths |
|
|
33370
|
+
| \`mesh_launch_session\` | Start a new agent session on a node |
|
|
33371
|
+
| \`mesh_send_task\` | Send a task (natural language) to a running agent |
|
|
33372
|
+
| \`mesh_read_chat\` | Read an agent's recent messages to check progress |
|
|
33373
|
+
| \`mesh_git_status\` | Check git status on a specific node |
|
|
33374
|
+
| \`mesh_checkpoint\` | Create a git checkpoint on a node |
|
|
33375
|
+
| \`mesh_approve\` | Approve/reject a pending agent action |`;
|
|
33376
|
+
var WORKFLOW_SECTION = `## Orchestration Workflow
|
|
33377
|
+
|
|
33378
|
+
1. **Assess** \u2014 Call \`mesh_status\` to see which nodes are healthy and available.
|
|
33379
|
+
2. **Plan** \u2014 Decompose the user's request into independent tasks for parallel execution, or sequential tasks when dependencies exist.
|
|
33380
|
+
3. **Delegate** \u2014 For each task:
|
|
33381
|
+
a. Pick the best node (consider: health, dirty state, current workload).
|
|
33382
|
+
b. If no session exists, call \`mesh_launch_session\` to start one.
|
|
33383
|
+
c. Call \`mesh_send_task\` with a clear, self-contained natural-language instruction.
|
|
33384
|
+
4. **Monitor** \u2014 Periodically call \`mesh_read_chat\` to check progress. Handle approvals via \`mesh_approve\`.
|
|
33385
|
+
5. **Verify** \u2014 When a task reports completion, call \`mesh_git_status\` to verify changes were made.
|
|
33386
|
+
6. **Checkpoint** \u2014 Call \`mesh_checkpoint\` to save the work.
|
|
33387
|
+
7. **Report** \u2014 Summarize what was done, what changed, and any issues.`;
|
|
33388
|
+
var RULES_SECTION = `## Rules
|
|
33389
|
+
|
|
33390
|
+
- **Be conversational.** Delegate work the way a tech lead would \u2014 clear, specific instructions in natural language.
|
|
33391
|
+
- **Don't inspect code.** Trust the agent's output. Verify via git diff/status, not by reading source files.
|
|
33392
|
+
- **Don't over-parallelize.** Start with 1-2 concurrent tasks. Scale up if they succeed.
|
|
33393
|
+
- **Handle failures gracefully.** If a task fails, read the chat to understand why, then retry or reassign.
|
|
33394
|
+
- **Keep the user informed.** Report progress after each delegation round.
|
|
33395
|
+
- **Respect node capabilities.** Don't send build tasks to read-only nodes. Don't push from nodes that aren't allowed to.
|
|
33396
|
+
- **Never fabricate tool results.** Always call the actual tool; never pretend you did.`;
|
|
33397
|
+
async function syncMeshes(transport) {
|
|
33398
|
+
const result = { pushed: 0, pulled: 0, deleted: 0, errors: [] };
|
|
33399
|
+
let remoteMeshes;
|
|
33400
|
+
try {
|
|
33401
|
+
const res = await transport.listRemoteMeshes();
|
|
33402
|
+
remoteMeshes = res.meshes;
|
|
33403
|
+
} catch (e) {
|
|
33404
|
+
result.errors.push(`Failed to list remote meshes: ${e.message}`);
|
|
33405
|
+
return result;
|
|
33406
|
+
}
|
|
33407
|
+
const localMeshes = listMeshes();
|
|
33408
|
+
const remoteByIdentity = new Map(remoteMeshes.map((m) => [m.repo_identity, m]));
|
|
33409
|
+
const localByIdentity = new Map(localMeshes.map((m) => [m.repoIdentity, m]));
|
|
33410
|
+
for (const local of localMeshes) {
|
|
33411
|
+
if (!remoteByIdentity.has(local.repoIdentity)) {
|
|
33412
|
+
try {
|
|
33413
|
+
await transport.createRemoteMesh({
|
|
33414
|
+
name: local.name,
|
|
33415
|
+
repo_identity: local.repoIdentity,
|
|
33416
|
+
repo_remote_url: local.repoRemoteUrl,
|
|
33417
|
+
default_branch: local.defaultBranch,
|
|
33418
|
+
policy: JSON.stringify(local.policy)
|
|
33419
|
+
});
|
|
33420
|
+
result.pushed++;
|
|
33421
|
+
} catch (e) {
|
|
33422
|
+
result.errors.push(`Push failed for "${local.name}": ${e.message}`);
|
|
33423
|
+
}
|
|
33424
|
+
}
|
|
33425
|
+
}
|
|
33426
|
+
for (const remote of remoteMeshes) {
|
|
33427
|
+
if (!localByIdentity.has(remote.repo_identity)) {
|
|
33428
|
+
try {
|
|
33429
|
+
let policy;
|
|
33430
|
+
try {
|
|
33431
|
+
policy = JSON.parse(remote.policy);
|
|
33432
|
+
} catch {
|
|
33433
|
+
policy = void 0;
|
|
33434
|
+
}
|
|
33435
|
+
createMesh({
|
|
33436
|
+
name: remote.name,
|
|
33437
|
+
repoIdentity: remote.repo_identity,
|
|
33438
|
+
repoRemoteUrl: remote.repo_remote_url || void 0,
|
|
33439
|
+
defaultBranch: remote.default_branch || void 0,
|
|
33440
|
+
policy
|
|
33441
|
+
});
|
|
33442
|
+
result.pulled++;
|
|
33443
|
+
} catch (e) {
|
|
33444
|
+
result.errors.push(`Pull failed for "${remote.name}": ${e.message}`);
|
|
33445
|
+
}
|
|
33446
|
+
}
|
|
33447
|
+
}
|
|
33448
|
+
return result;
|
|
33449
|
+
}
|
|
33450
|
+
var import_fs3 = require("fs");
|
|
33451
|
+
var import_path3 = require("path");
|
|
33142
33452
|
init_config();
|
|
33143
33453
|
var DEFAULT_STATE = {
|
|
33144
33454
|
recentActivity: [],
|
|
@@ -33152,7 +33462,7 @@ var require_dist2 = __commonJS({
|
|
|
33152
33462
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
33153
33463
|
}
|
|
33154
33464
|
function getStatePath() {
|
|
33155
|
-
return (0,
|
|
33465
|
+
return (0, import_path3.join)(getConfigDir(), "state.json");
|
|
33156
33466
|
}
|
|
33157
33467
|
function normalizeState(raw) {
|
|
33158
33468
|
const parsed = isPlainObject22(raw) ? raw : {};
|
|
@@ -33188,11 +33498,11 @@ var require_dist2 = __commonJS({
|
|
|
33188
33498
|
}
|
|
33189
33499
|
function loadState() {
|
|
33190
33500
|
const statePath = getStatePath();
|
|
33191
|
-
if (!(0,
|
|
33501
|
+
if (!(0, import_fs3.existsSync)(statePath)) {
|
|
33192
33502
|
return { ...DEFAULT_STATE };
|
|
33193
33503
|
}
|
|
33194
33504
|
try {
|
|
33195
|
-
const raw = (0,
|
|
33505
|
+
const raw = (0, import_fs3.readFileSync)(statePath, "utf-8");
|
|
33196
33506
|
return normalizeState(JSON.parse(raw));
|
|
33197
33507
|
} catch {
|
|
33198
33508
|
return { ...DEFAULT_STATE };
|
|
@@ -33201,13 +33511,13 @@ var require_dist2 = __commonJS({
|
|
|
33201
33511
|
function saveState(state) {
|
|
33202
33512
|
const statePath = getStatePath();
|
|
33203
33513
|
const normalized = normalizeState(state);
|
|
33204
|
-
(0,
|
|
33514
|
+
(0, import_fs3.writeFileSync)(statePath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
|
|
33205
33515
|
}
|
|
33206
33516
|
function resetState() {
|
|
33207
33517
|
saveState({ ...DEFAULT_STATE });
|
|
33208
33518
|
}
|
|
33209
33519
|
var import_child_process = require("child_process");
|
|
33210
|
-
var
|
|
33520
|
+
var import_fs4 = require("fs");
|
|
33211
33521
|
var import_os22 = require("os");
|
|
33212
33522
|
var path7 = __toESM2(require("path"));
|
|
33213
33523
|
var BUILTIN_IDE_DEFINITIONS = [];
|
|
@@ -33231,7 +33541,7 @@ var require_dist2 = __commonJS({
|
|
|
33231
33541
|
if (path7.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
|
|
33232
33542
|
const candidate = trimmed.startsWith("~") ? path7.join((0, import_os22.homedir)(), trimmed.slice(1)) : trimmed;
|
|
33233
33543
|
const resolved = path7.isAbsolute(candidate) ? candidate : path7.resolve(candidate);
|
|
33234
|
-
return (0,
|
|
33544
|
+
return (0, import_fs4.existsSync)(resolved) ? resolved : null;
|
|
33235
33545
|
}
|
|
33236
33546
|
try {
|
|
33237
33547
|
const result = (0, import_child_process.execSync)(
|
|
@@ -33262,9 +33572,9 @@ var require_dist2 = __commonJS({
|
|
|
33262
33572
|
if (normalized.includes("*")) {
|
|
33263
33573
|
const username = home.split(/[\\/]/).pop() || "";
|
|
33264
33574
|
const resolved = normalized.replace("*", username);
|
|
33265
|
-
if ((0,
|
|
33575
|
+
if ((0, import_fs4.existsSync)(resolved)) return resolved;
|
|
33266
33576
|
} else {
|
|
33267
|
-
if ((0,
|
|
33577
|
+
if ((0, import_fs4.existsSync)(normalized)) return normalized;
|
|
33268
33578
|
}
|
|
33269
33579
|
}
|
|
33270
33580
|
return null;
|
|
@@ -33278,7 +33588,7 @@ var require_dist2 = __commonJS({
|
|
|
33278
33588
|
let resolvedCli = cliPath;
|
|
33279
33589
|
if (!resolvedCli && appPath && os21 === "darwin") {
|
|
33280
33590
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
33281
|
-
if ((0,
|
|
33591
|
+
if ((0, import_fs4.existsSync)(bundledCli)) resolvedCli = bundledCli;
|
|
33282
33592
|
}
|
|
33283
33593
|
if (!resolvedCli && appPath && os21 === "win32") {
|
|
33284
33594
|
const { dirname: dirname7 } = await import("path");
|
|
@@ -33291,7 +33601,7 @@ var require_dist2 = __commonJS({
|
|
|
33291
33601
|
`${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
|
|
33292
33602
|
];
|
|
33293
33603
|
for (const c of candidates) {
|
|
33294
|
-
if ((0,
|
|
33604
|
+
if ((0, import_fs4.existsSync)(c)) {
|
|
33295
33605
|
resolvedCli = c;
|
|
33296
33606
|
break;
|
|
33297
33607
|
}
|
|
@@ -33315,7 +33625,7 @@ var require_dist2 = __commonJS({
|
|
|
33315
33625
|
var import_child_process2 = require("child_process");
|
|
33316
33626
|
var os22 = __toESM2(require("os"));
|
|
33317
33627
|
var path8 = __toESM2(require("path"));
|
|
33318
|
-
var
|
|
33628
|
+
var import_fs5 = require("fs");
|
|
33319
33629
|
function parseVersion(raw) {
|
|
33320
33630
|
const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
|
|
33321
33631
|
return match ? match[1] : raw.split("\n")[0].slice(0, 100);
|
|
@@ -33339,7 +33649,7 @@ var require_dist2 = __commonJS({
|
|
|
33339
33649
|
if (isExplicitCommandPath(trimmed)) {
|
|
33340
33650
|
const expanded = expandHome(trimmed);
|
|
33341
33651
|
const candidate = path8.isAbsolute(expanded) ? expanded : path8.resolve(expanded);
|
|
33342
|
-
return (0,
|
|
33652
|
+
return (0, import_fs5.existsSync)(candidate) ? candidate : null;
|
|
33343
33653
|
}
|
|
33344
33654
|
return null;
|
|
33345
33655
|
}
|
|
@@ -41991,7 +42301,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41991
42301
|
var os13 = __toESM2(require("os"));
|
|
41992
42302
|
var path16 = __toESM2(require("path"));
|
|
41993
42303
|
var crypto4 = __toESM2(require("crypto"));
|
|
41994
|
-
var
|
|
42304
|
+
var import_fs6 = require("fs");
|
|
41995
42305
|
var import_child_process6 = require("child_process");
|
|
41996
42306
|
var import_chalk = __toESM2(require("chalk"));
|
|
41997
42307
|
init_provider_cli_adapter();
|
|
@@ -44115,7 +44425,7 @@ ${rawInput}` : rawInput;
|
|
|
44115
44425
|
const trimmed = command.trim();
|
|
44116
44426
|
if (!trimmed) return false;
|
|
44117
44427
|
if (isExplicitCommand(trimmed)) {
|
|
44118
|
-
return (0,
|
|
44428
|
+
return (0, import_fs6.existsSync)(expandExecutable(trimmed));
|
|
44119
44429
|
}
|
|
44120
44430
|
try {
|
|
44121
44431
|
(0, import_child_process6.execFileSync)(process.platform === "win32" ? "where" : "which", [trimmed], {
|