@adhdev/daemon-core 0.9.82-rc.115 → 0.9.82-rc.117
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 +132 -42
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +132 -42
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/commands/chat-commands.ts +29 -2
- package/src/commands/router.ts +106 -39
- package/src/providers/approval-utils.ts +12 -5
package/dist/index.js
CHANGED
|
@@ -14843,6 +14843,10 @@ var DEFAULT_APPROVAL_POSITIVE_HINTS = [
|
|
|
14843
14843
|
function normalizeApprovalLabel(value) {
|
|
14844
14844
|
return String(value || "").toLowerCase().replace(/^[\s\[(<{]*\d+(?:\s*[.)\]}>:-]|\s)+/, "").replace(/[^\p{L}\p{N}]+/gu, " ").trim();
|
|
14845
14845
|
}
|
|
14846
|
+
function isNegativeApprovalLabel(value) {
|
|
14847
|
+
const label = normalizeApprovalLabel(value);
|
|
14848
|
+
return /^(no|deny|reject|cancel|skip|exit|stop)\b/.test(label) || /\bwithout\b/.test(label) || /\bdo not\b/.test(label);
|
|
14849
|
+
}
|
|
14846
14850
|
function getApprovalPositiveHints(provider) {
|
|
14847
14851
|
const customHints = Array.isArray(provider?.approvalPositiveHints) ? provider.approvalPositiveHints.map((hint) => normalizeApprovalLabel(String(hint || ""))).filter(Boolean) : [];
|
|
14848
14852
|
return customHints.length > 0 ? customHints : DEFAULT_APPROVAL_POSITIVE_HINTS;
|
|
@@ -14850,19 +14854,19 @@ function getApprovalPositiveHints(provider) {
|
|
|
14850
14854
|
function pickApprovalButton(buttons, provider) {
|
|
14851
14855
|
const labels = (buttons || []).map((button) => String(button || "").trim()).filter(Boolean);
|
|
14852
14856
|
if (labels.length === 0) {
|
|
14853
|
-
return { index:
|
|
14857
|
+
return { index: -1, label: "" };
|
|
14854
14858
|
}
|
|
14855
14859
|
const normalizedButtons = labels.map((label) => normalizeApprovalLabel(label));
|
|
14856
14860
|
const hints = getApprovalPositiveHints(provider);
|
|
14857
14861
|
for (const hint of hints) {
|
|
14858
|
-
const exactIndex = normalizedButtons.findIndex((label) => label === hint);
|
|
14862
|
+
const exactIndex = normalizedButtons.findIndex((label, index) => label === hint && !isNegativeApprovalLabel(labels[index]));
|
|
14859
14863
|
if (exactIndex >= 0) return { index: exactIndex, label: labels[exactIndex] };
|
|
14860
|
-
const prefixIndex = normalizedButtons.findIndex((label) => label.startsWith(hint));
|
|
14864
|
+
const prefixIndex = normalizedButtons.findIndex((label, index) => label.startsWith(hint) && !isNegativeApprovalLabel(labels[index]));
|
|
14861
14865
|
if (prefixIndex >= 0) return { index: prefixIndex, label: labels[prefixIndex] };
|
|
14862
|
-
const includeIndex = normalizedButtons.findIndex((label) => label.includes(hint));
|
|
14866
|
+
const includeIndex = normalizedButtons.findIndex((label, index) => label.includes(hint) && !isNegativeApprovalLabel(labels[index]));
|
|
14863
14867
|
if (includeIndex >= 0) return { index: includeIndex, label: labels[includeIndex] };
|
|
14864
14868
|
}
|
|
14865
|
-
return { index:
|
|
14869
|
+
return { index: -1, label: "" };
|
|
14866
14870
|
}
|
|
14867
14871
|
function formatAutoApprovalMessage(modalMessage, buttonLabel) {
|
|
14868
14872
|
const lines = [`Auto-approved${buttonLabel ? `: ${buttonLabel}` : ""}`];
|
|
@@ -16953,16 +16957,39 @@ function hasOverlappingVisibleConversationText(nativeMessages, ptyMessages) {
|
|
|
16953
16957
|
return false;
|
|
16954
16958
|
}
|
|
16955
16959
|
function hasSafeNativeHistoryMapping(args) {
|
|
16960
|
+
const isCoordinatorTranscript = args.nativeMessages.some((m) => {
|
|
16961
|
+
const text = typeof m?.content === "string" ? m.content : JSON.stringify(m?.content || "");
|
|
16962
|
+
return text.includes("mesh_send_task") || text.includes("mesh_status") || text.includes("mesh_read_chat") || text.includes("mesh_launch_session");
|
|
16963
|
+
});
|
|
16956
16964
|
const explicitSessionId = String(args.historySessionId || args.providerSessionId || "").trim();
|
|
16957
16965
|
if (explicitSessionId) {
|
|
16958
16966
|
const messageSessionIds = args.nativeMessages.map((message) => typeof message?.historySessionId === "string" ? message.historySessionId.trim() : "").filter(Boolean);
|
|
16959
|
-
if (messageSessionIds.length
|
|
16960
|
-
|
|
16967
|
+
if (messageSessionIds.length > 0) {
|
|
16968
|
+
return messageSessionIds.some((id) => id === explicitSessionId);
|
|
16969
|
+
}
|
|
16970
|
+
if (isCoordinatorTranscript && args.ptyMessages && args.ptyMessages.length > 0) {
|
|
16971
|
+
const ptyHasCoordinator = args.ptyMessages.some((m) => {
|
|
16972
|
+
const text = typeof m?.content === "string" ? m.content : JSON.stringify(m?.content || "");
|
|
16973
|
+
return text.includes("mesh_send_task") || text.includes("mesh_status") || text.includes("mesh_read_chat");
|
|
16974
|
+
});
|
|
16975
|
+
if (!ptyHasCoordinator) {
|
|
16976
|
+
return false;
|
|
16977
|
+
}
|
|
16978
|
+
}
|
|
16961
16979
|
}
|
|
16962
16980
|
const workspace = String(args.workspace || "").trim();
|
|
16963
16981
|
if (!workspace) return false;
|
|
16964
16982
|
const workspaceMatches = args.nativeMessages.some((message) => String(message?.workspace || "").trim() === workspace);
|
|
16965
16983
|
if (!workspaceMatches) return false;
|
|
16984
|
+
if (isCoordinatorTranscript && args.ptyMessages && args.ptyMessages.length > 0) {
|
|
16985
|
+
const ptyHasCoordinator = args.ptyMessages.some((m) => {
|
|
16986
|
+
const text = typeof m?.content === "string" ? m.content : JSON.stringify(m?.content || "");
|
|
16987
|
+
return text.includes("mesh_send_task") || text.includes("mesh_status") || text.includes("mesh_read_chat");
|
|
16988
|
+
});
|
|
16989
|
+
if (!ptyHasCoordinator) {
|
|
16990
|
+
return false;
|
|
16991
|
+
}
|
|
16992
|
+
}
|
|
16966
16993
|
if (!args.requireWorkspaceContentOverlap) return true;
|
|
16967
16994
|
return hasOverlappingVisibleConversationText(args.nativeMessages, args.ptyMessages || []);
|
|
16968
16995
|
}
|
|
@@ -27842,6 +27869,12 @@ function finalizeMeshNodeStatus(args) {
|
|
|
27842
27869
|
status.launchBlockedMessage = readStringValue(bootstrap.error) || "Required worktree bootstrap failed; resolve it before launching an agent into this node.";
|
|
27843
27870
|
return;
|
|
27844
27871
|
}
|
|
27872
|
+
if (bootstrap.status === "running" && bootstrap.required !== false) {
|
|
27873
|
+
status.launchReady = false;
|
|
27874
|
+
status.launchBlockedReason = "worktree_bootstrap_running";
|
|
27875
|
+
status.launchBlockedMessage = "Required worktree bootstrap is still running; wait for it to finish before launching an agent into this node.";
|
|
27876
|
+
return;
|
|
27877
|
+
}
|
|
27845
27878
|
}
|
|
27846
27879
|
const connectionState = readStringValue(readObjectRecord(status.connection).state);
|
|
27847
27880
|
status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || connectionState === "connected" || isSelfNode);
|
|
@@ -31191,56 +31224,113 @@ var DaemonCommandRouter = class {
|
|
|
31191
31224
|
if (!node) return { success: false, error: "Failed to register worktree node" };
|
|
31192
31225
|
this.invalidateAggregateMeshStatus(meshId);
|
|
31193
31226
|
}
|
|
31194
|
-
const
|
|
31195
|
-
|
|
31196
|
-
|
|
31197
|
-
|
|
31198
|
-
|
|
31199
|
-
{ workspace: result.worktreePath, repoRoot: result.worktreePath, isGitRepo: true },
|
|
31200
|
-
["submodule", "update", "--init", "--recursive"],
|
|
31201
|
-
{ timeoutMs: 12e4 }
|
|
31202
|
-
);
|
|
31203
|
-
} catch (subErr) {
|
|
31204
|
-
console.warn("[mesh] Submodule init failed for worktree:", subErr.message);
|
|
31227
|
+
const persistWorktreeSetupState = async (bootstrapState2) => {
|
|
31228
|
+
node.worktreeBootstrap = bootstrapState2;
|
|
31229
|
+
if (meshRecord.inline) {
|
|
31230
|
+
this.updateInlineMeshNode(meshId, mesh, node);
|
|
31231
|
+
return;
|
|
31205
31232
|
}
|
|
31206
|
-
}
|
|
31207
|
-
const bootstrapState = await runMeshWorktreeBootstrap(mesh, result.worktreePath);
|
|
31208
|
-
node.worktreeBootstrap = bootstrapState;
|
|
31209
|
-
if (!meshRecord.inline) {
|
|
31210
31233
|
try {
|
|
31211
31234
|
const { updateNode: updateNode2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
31212
|
-
updateNode2(meshId, node.id, { worktreeBootstrap:
|
|
31235
|
+
updateNode2(meshId, node.id, { worktreeBootstrap: bootstrapState2 });
|
|
31213
31236
|
this.invalidateAggregateMeshStatus(meshId);
|
|
31214
31237
|
} catch {
|
|
31215
31238
|
}
|
|
31216
|
-
}
|
|
31217
|
-
|
|
31218
|
-
|
|
31219
|
-
|
|
31220
|
-
|
|
31221
|
-
|
|
31222
|
-
|
|
31223
|
-
|
|
31224
|
-
|
|
31225
|
-
|
|
31226
|
-
|
|
31227
|
-
|
|
31228
|
-
|
|
31229
|
-
|
|
31230
|
-
|
|
31231
|
-
|
|
31232
|
-
|
|
31233
|
-
|
|
31239
|
+
};
|
|
31240
|
+
const appendCloneLedger = async (initSubmodules2, bootstrapState2) => {
|
|
31241
|
+
try {
|
|
31242
|
+
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
31243
|
+
appendLedgerEntry2(meshId, {
|
|
31244
|
+
kind: "node_cloned",
|
|
31245
|
+
nodeId: node.id,
|
|
31246
|
+
payload: {
|
|
31247
|
+
sourceNodeId,
|
|
31248
|
+
branch: result.branch,
|
|
31249
|
+
worktreePath: result.worktreePath,
|
|
31250
|
+
submodulesInitialized: initSubmodules2,
|
|
31251
|
+
worktreeBootstrap: {
|
|
31252
|
+
status: bootstrapState2.status,
|
|
31253
|
+
required: bootstrapState2.required,
|
|
31254
|
+
configSource: bootstrapState2.configSource,
|
|
31255
|
+
configSourceType: bootstrapState2.configSourceType,
|
|
31256
|
+
lastCommand: bootstrapState2.lastCommand,
|
|
31257
|
+
exitCode: bootstrapState2.exitCode
|
|
31258
|
+
}
|
|
31234
31259
|
}
|
|
31260
|
+
});
|
|
31261
|
+
} catch {
|
|
31262
|
+
}
|
|
31263
|
+
};
|
|
31264
|
+
const initSubmodules = sourceNode.policy?.initSubmodulesOnClone !== false;
|
|
31265
|
+
const loadedBootstrap = loadMeshWorktreeBootstrapConfig(mesh, result.worktreePath);
|
|
31266
|
+
const runningBootstrapState = {
|
|
31267
|
+
status: "running",
|
|
31268
|
+
required: loadedBootstrap.config?.required !== false,
|
|
31269
|
+
configSource: loadedBootstrap.path || loadedBootstrap.source,
|
|
31270
|
+
configSourceType: loadedBootstrap.sourceType,
|
|
31271
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
31272
|
+
};
|
|
31273
|
+
await persistWorktreeSetupState(runningBootstrapState);
|
|
31274
|
+
const finishWorktreeSetup = async () => {
|
|
31275
|
+
let submodulesInitialized2 = false;
|
|
31276
|
+
if (initSubmodules) {
|
|
31277
|
+
try {
|
|
31278
|
+
const { runGit: runGit3 } = await Promise.resolve().then(() => (init_git_executor(), git_executor_exports));
|
|
31279
|
+
await runGit3(
|
|
31280
|
+
{ workspace: result.worktreePath, repoRoot: result.worktreePath, isGitRepo: true },
|
|
31281
|
+
["submodule", "update", "--init", "--recursive"],
|
|
31282
|
+
{ timeoutMs: 12e4 }
|
|
31283
|
+
);
|
|
31284
|
+
submodulesInitialized2 = true;
|
|
31285
|
+
} catch (subErr) {
|
|
31286
|
+
console.warn("[mesh] Submodule init failed for worktree:", subErr.message);
|
|
31235
31287
|
}
|
|
31288
|
+
}
|
|
31289
|
+
const bootstrapState2 = await runMeshWorktreeBootstrap(mesh, result.worktreePath);
|
|
31290
|
+
await persistWorktreeSetupState(bootstrapState2);
|
|
31291
|
+
await appendCloneLedger(submodulesInitialized2, bootstrapState2);
|
|
31292
|
+
return { submodulesInitialized: submodulesInitialized2, bootstrapState: bootstrapState2 };
|
|
31293
|
+
};
|
|
31294
|
+
const requestedSetupWaitMs = Number(args?.setupWaitMs ?? args?.bootstrapWaitMs ?? 8e3);
|
|
31295
|
+
const setupWaitMs = Number.isFinite(requestedSetupWaitMs) ? Math.min(Math.max(requestedSetupWaitMs, 0), 14e3) : 8e3;
|
|
31296
|
+
const setupPromise = finishWorktreeSetup();
|
|
31297
|
+
const setupResult = await Promise.race([
|
|
31298
|
+
setupPromise.then((value) => ({ completed: true, value })),
|
|
31299
|
+
new Promise((resolve17) => setTimeout(() => resolve17({ completed: false }), setupWaitMs))
|
|
31300
|
+
]);
|
|
31301
|
+
if (!setupResult.completed) {
|
|
31302
|
+
setupPromise.catch((error) => {
|
|
31303
|
+
const failedState = {
|
|
31304
|
+
...runningBootstrapState,
|
|
31305
|
+
status: "failed",
|
|
31306
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
31307
|
+
error: error?.message || String(error)
|
|
31308
|
+
};
|
|
31309
|
+
void persistWorktreeSetupState(failedState);
|
|
31310
|
+
void appendCloneLedger(false, failedState);
|
|
31236
31311
|
});
|
|
31237
|
-
|
|
31312
|
+
return {
|
|
31313
|
+
success: true,
|
|
31314
|
+
async: true,
|
|
31315
|
+
status: "accepted",
|
|
31316
|
+
node,
|
|
31317
|
+
worktreePath: result.worktreePath,
|
|
31318
|
+
branch: result.branch,
|
|
31319
|
+
worktreeBootstrap: runningBootstrapState,
|
|
31320
|
+
worktreeSetup: {
|
|
31321
|
+
status: "running",
|
|
31322
|
+
setupWaitMs,
|
|
31323
|
+
message: "Worktree node is registered; submodule/bootstrap setup is continuing in the background."
|
|
31324
|
+
}
|
|
31325
|
+
};
|
|
31238
31326
|
}
|
|
31327
|
+
const { submodulesInitialized, bootstrapState } = setupResult.value;
|
|
31239
31328
|
return {
|
|
31240
31329
|
success: true,
|
|
31241
31330
|
node,
|
|
31242
31331
|
worktreePath: result.worktreePath,
|
|
31243
31332
|
branch: result.branch,
|
|
31333
|
+
submodulesInitialized,
|
|
31244
31334
|
worktreeBootstrap: bootstrapState
|
|
31245
31335
|
};
|
|
31246
31336
|
} catch (e) {
|