@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.mjs
CHANGED
|
@@ -14577,6 +14577,10 @@ var DEFAULT_APPROVAL_POSITIVE_HINTS = [
|
|
|
14577
14577
|
function normalizeApprovalLabel(value) {
|
|
14578
14578
|
return String(value || "").toLowerCase().replace(/^[\s\[(<{]*\d+(?:\s*[.)\]}>:-]|\s)+/, "").replace(/[^\p{L}\p{N}]+/gu, " ").trim();
|
|
14579
14579
|
}
|
|
14580
|
+
function isNegativeApprovalLabel(value) {
|
|
14581
|
+
const label = normalizeApprovalLabel(value);
|
|
14582
|
+
return /^(no|deny|reject|cancel|skip|exit|stop)\b/.test(label) || /\bwithout\b/.test(label) || /\bdo not\b/.test(label);
|
|
14583
|
+
}
|
|
14580
14584
|
function getApprovalPositiveHints(provider) {
|
|
14581
14585
|
const customHints = Array.isArray(provider?.approvalPositiveHints) ? provider.approvalPositiveHints.map((hint) => normalizeApprovalLabel(String(hint || ""))).filter(Boolean) : [];
|
|
14582
14586
|
return customHints.length > 0 ? customHints : DEFAULT_APPROVAL_POSITIVE_HINTS;
|
|
@@ -14584,19 +14588,19 @@ function getApprovalPositiveHints(provider) {
|
|
|
14584
14588
|
function pickApprovalButton(buttons, provider) {
|
|
14585
14589
|
const labels = (buttons || []).map((button) => String(button || "").trim()).filter(Boolean);
|
|
14586
14590
|
if (labels.length === 0) {
|
|
14587
|
-
return { index:
|
|
14591
|
+
return { index: -1, label: "" };
|
|
14588
14592
|
}
|
|
14589
14593
|
const normalizedButtons = labels.map((label) => normalizeApprovalLabel(label));
|
|
14590
14594
|
const hints = getApprovalPositiveHints(provider);
|
|
14591
14595
|
for (const hint of hints) {
|
|
14592
|
-
const exactIndex = normalizedButtons.findIndex((label) => label === hint);
|
|
14596
|
+
const exactIndex = normalizedButtons.findIndex((label, index) => label === hint && !isNegativeApprovalLabel(labels[index]));
|
|
14593
14597
|
if (exactIndex >= 0) return { index: exactIndex, label: labels[exactIndex] };
|
|
14594
|
-
const prefixIndex = normalizedButtons.findIndex((label) => label.startsWith(hint));
|
|
14598
|
+
const prefixIndex = normalizedButtons.findIndex((label, index) => label.startsWith(hint) && !isNegativeApprovalLabel(labels[index]));
|
|
14595
14599
|
if (prefixIndex >= 0) return { index: prefixIndex, label: labels[prefixIndex] };
|
|
14596
|
-
const includeIndex = normalizedButtons.findIndex((label) => label.includes(hint));
|
|
14600
|
+
const includeIndex = normalizedButtons.findIndex((label, index) => label.includes(hint) && !isNegativeApprovalLabel(labels[index]));
|
|
14597
14601
|
if (includeIndex >= 0) return { index: includeIndex, label: labels[includeIndex] };
|
|
14598
14602
|
}
|
|
14599
|
-
return { index:
|
|
14603
|
+
return { index: -1, label: "" };
|
|
14600
14604
|
}
|
|
14601
14605
|
function formatAutoApprovalMessage(modalMessage, buttonLabel) {
|
|
14602
14606
|
const lines = [`Auto-approved${buttonLabel ? `: ${buttonLabel}` : ""}`];
|
|
@@ -16687,16 +16691,39 @@ function hasOverlappingVisibleConversationText(nativeMessages, ptyMessages) {
|
|
|
16687
16691
|
return false;
|
|
16688
16692
|
}
|
|
16689
16693
|
function hasSafeNativeHistoryMapping(args) {
|
|
16694
|
+
const isCoordinatorTranscript = args.nativeMessages.some((m) => {
|
|
16695
|
+
const text = typeof m?.content === "string" ? m.content : JSON.stringify(m?.content || "");
|
|
16696
|
+
return text.includes("mesh_send_task") || text.includes("mesh_status") || text.includes("mesh_read_chat") || text.includes("mesh_launch_session");
|
|
16697
|
+
});
|
|
16690
16698
|
const explicitSessionId = String(args.historySessionId || args.providerSessionId || "").trim();
|
|
16691
16699
|
if (explicitSessionId) {
|
|
16692
16700
|
const messageSessionIds = args.nativeMessages.map((message) => typeof message?.historySessionId === "string" ? message.historySessionId.trim() : "").filter(Boolean);
|
|
16693
|
-
if (messageSessionIds.length
|
|
16694
|
-
|
|
16701
|
+
if (messageSessionIds.length > 0) {
|
|
16702
|
+
return messageSessionIds.some((id) => id === explicitSessionId);
|
|
16703
|
+
}
|
|
16704
|
+
if (isCoordinatorTranscript && args.ptyMessages && args.ptyMessages.length > 0) {
|
|
16705
|
+
const ptyHasCoordinator = args.ptyMessages.some((m) => {
|
|
16706
|
+
const text = typeof m?.content === "string" ? m.content : JSON.stringify(m?.content || "");
|
|
16707
|
+
return text.includes("mesh_send_task") || text.includes("mesh_status") || text.includes("mesh_read_chat");
|
|
16708
|
+
});
|
|
16709
|
+
if (!ptyHasCoordinator) {
|
|
16710
|
+
return false;
|
|
16711
|
+
}
|
|
16712
|
+
}
|
|
16695
16713
|
}
|
|
16696
16714
|
const workspace = String(args.workspace || "").trim();
|
|
16697
16715
|
if (!workspace) return false;
|
|
16698
16716
|
const workspaceMatches = args.nativeMessages.some((message) => String(message?.workspace || "").trim() === workspace);
|
|
16699
16717
|
if (!workspaceMatches) return false;
|
|
16718
|
+
if (isCoordinatorTranscript && args.ptyMessages && args.ptyMessages.length > 0) {
|
|
16719
|
+
const ptyHasCoordinator = args.ptyMessages.some((m) => {
|
|
16720
|
+
const text = typeof m?.content === "string" ? m.content : JSON.stringify(m?.content || "");
|
|
16721
|
+
return text.includes("mesh_send_task") || text.includes("mesh_status") || text.includes("mesh_read_chat");
|
|
16722
|
+
});
|
|
16723
|
+
if (!ptyHasCoordinator) {
|
|
16724
|
+
return false;
|
|
16725
|
+
}
|
|
16726
|
+
}
|
|
16700
16727
|
if (!args.requireWorkspaceContentOverlap) return true;
|
|
16701
16728
|
return hasOverlappingVisibleConversationText(args.nativeMessages, args.ptyMessages || []);
|
|
16702
16729
|
}
|
|
@@ -27581,6 +27608,12 @@ function finalizeMeshNodeStatus(args) {
|
|
|
27581
27608
|
status.launchBlockedMessage = readStringValue(bootstrap.error) || "Required worktree bootstrap failed; resolve it before launching an agent into this node.";
|
|
27582
27609
|
return;
|
|
27583
27610
|
}
|
|
27611
|
+
if (bootstrap.status === "running" && bootstrap.required !== false) {
|
|
27612
|
+
status.launchReady = false;
|
|
27613
|
+
status.launchBlockedReason = "worktree_bootstrap_running";
|
|
27614
|
+
status.launchBlockedMessage = "Required worktree bootstrap is still running; wait for it to finish before launching an agent into this node.";
|
|
27615
|
+
return;
|
|
27616
|
+
}
|
|
27584
27617
|
}
|
|
27585
27618
|
const connectionState = readStringValue(readObjectRecord(status.connection).state);
|
|
27586
27619
|
status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || connectionState === "connected" || isSelfNode);
|
|
@@ -30930,56 +30963,113 @@ var DaemonCommandRouter = class {
|
|
|
30930
30963
|
if (!node) return { success: false, error: "Failed to register worktree node" };
|
|
30931
30964
|
this.invalidateAggregateMeshStatus(meshId);
|
|
30932
30965
|
}
|
|
30933
|
-
const
|
|
30934
|
-
|
|
30935
|
-
|
|
30936
|
-
|
|
30937
|
-
|
|
30938
|
-
{ workspace: result.worktreePath, repoRoot: result.worktreePath, isGitRepo: true },
|
|
30939
|
-
["submodule", "update", "--init", "--recursive"],
|
|
30940
|
-
{ timeoutMs: 12e4 }
|
|
30941
|
-
);
|
|
30942
|
-
} catch (subErr) {
|
|
30943
|
-
console.warn("[mesh] Submodule init failed for worktree:", subErr.message);
|
|
30966
|
+
const persistWorktreeSetupState = async (bootstrapState2) => {
|
|
30967
|
+
node.worktreeBootstrap = bootstrapState2;
|
|
30968
|
+
if (meshRecord.inline) {
|
|
30969
|
+
this.updateInlineMeshNode(meshId, mesh, node);
|
|
30970
|
+
return;
|
|
30944
30971
|
}
|
|
30945
|
-
}
|
|
30946
|
-
const bootstrapState = await runMeshWorktreeBootstrap(mesh, result.worktreePath);
|
|
30947
|
-
node.worktreeBootstrap = bootstrapState;
|
|
30948
|
-
if (!meshRecord.inline) {
|
|
30949
30972
|
try {
|
|
30950
30973
|
const { updateNode: updateNode2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
30951
|
-
updateNode2(meshId, node.id, { worktreeBootstrap:
|
|
30974
|
+
updateNode2(meshId, node.id, { worktreeBootstrap: bootstrapState2 });
|
|
30952
30975
|
this.invalidateAggregateMeshStatus(meshId);
|
|
30953
30976
|
} catch {
|
|
30954
30977
|
}
|
|
30955
|
-
}
|
|
30956
|
-
|
|
30957
|
-
|
|
30958
|
-
|
|
30959
|
-
|
|
30960
|
-
|
|
30961
|
-
|
|
30962
|
-
|
|
30963
|
-
|
|
30964
|
-
|
|
30965
|
-
|
|
30966
|
-
|
|
30967
|
-
|
|
30968
|
-
|
|
30969
|
-
|
|
30970
|
-
|
|
30971
|
-
|
|
30972
|
-
|
|
30978
|
+
};
|
|
30979
|
+
const appendCloneLedger = async (initSubmodules2, bootstrapState2) => {
|
|
30980
|
+
try {
|
|
30981
|
+
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
30982
|
+
appendLedgerEntry2(meshId, {
|
|
30983
|
+
kind: "node_cloned",
|
|
30984
|
+
nodeId: node.id,
|
|
30985
|
+
payload: {
|
|
30986
|
+
sourceNodeId,
|
|
30987
|
+
branch: result.branch,
|
|
30988
|
+
worktreePath: result.worktreePath,
|
|
30989
|
+
submodulesInitialized: initSubmodules2,
|
|
30990
|
+
worktreeBootstrap: {
|
|
30991
|
+
status: bootstrapState2.status,
|
|
30992
|
+
required: bootstrapState2.required,
|
|
30993
|
+
configSource: bootstrapState2.configSource,
|
|
30994
|
+
configSourceType: bootstrapState2.configSourceType,
|
|
30995
|
+
lastCommand: bootstrapState2.lastCommand,
|
|
30996
|
+
exitCode: bootstrapState2.exitCode
|
|
30997
|
+
}
|
|
30973
30998
|
}
|
|
30999
|
+
});
|
|
31000
|
+
} catch {
|
|
31001
|
+
}
|
|
31002
|
+
};
|
|
31003
|
+
const initSubmodules = sourceNode.policy?.initSubmodulesOnClone !== false;
|
|
31004
|
+
const loadedBootstrap = loadMeshWorktreeBootstrapConfig(mesh, result.worktreePath);
|
|
31005
|
+
const runningBootstrapState = {
|
|
31006
|
+
status: "running",
|
|
31007
|
+
required: loadedBootstrap.config?.required !== false,
|
|
31008
|
+
configSource: loadedBootstrap.path || loadedBootstrap.source,
|
|
31009
|
+
configSourceType: loadedBootstrap.sourceType,
|
|
31010
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
31011
|
+
};
|
|
31012
|
+
await persistWorktreeSetupState(runningBootstrapState);
|
|
31013
|
+
const finishWorktreeSetup = async () => {
|
|
31014
|
+
let submodulesInitialized2 = false;
|
|
31015
|
+
if (initSubmodules) {
|
|
31016
|
+
try {
|
|
31017
|
+
const { runGit: runGit3 } = await Promise.resolve().then(() => (init_git_executor(), git_executor_exports));
|
|
31018
|
+
await runGit3(
|
|
31019
|
+
{ workspace: result.worktreePath, repoRoot: result.worktreePath, isGitRepo: true },
|
|
31020
|
+
["submodule", "update", "--init", "--recursive"],
|
|
31021
|
+
{ timeoutMs: 12e4 }
|
|
31022
|
+
);
|
|
31023
|
+
submodulesInitialized2 = true;
|
|
31024
|
+
} catch (subErr) {
|
|
31025
|
+
console.warn("[mesh] Submodule init failed for worktree:", subErr.message);
|
|
30974
31026
|
}
|
|
31027
|
+
}
|
|
31028
|
+
const bootstrapState2 = await runMeshWorktreeBootstrap(mesh, result.worktreePath);
|
|
31029
|
+
await persistWorktreeSetupState(bootstrapState2);
|
|
31030
|
+
await appendCloneLedger(submodulesInitialized2, bootstrapState2);
|
|
31031
|
+
return { submodulesInitialized: submodulesInitialized2, bootstrapState: bootstrapState2 };
|
|
31032
|
+
};
|
|
31033
|
+
const requestedSetupWaitMs = Number(args?.setupWaitMs ?? args?.bootstrapWaitMs ?? 8e3);
|
|
31034
|
+
const setupWaitMs = Number.isFinite(requestedSetupWaitMs) ? Math.min(Math.max(requestedSetupWaitMs, 0), 14e3) : 8e3;
|
|
31035
|
+
const setupPromise = finishWorktreeSetup();
|
|
31036
|
+
const setupResult = await Promise.race([
|
|
31037
|
+
setupPromise.then((value) => ({ completed: true, value })),
|
|
31038
|
+
new Promise((resolve17) => setTimeout(() => resolve17({ completed: false }), setupWaitMs))
|
|
31039
|
+
]);
|
|
31040
|
+
if (!setupResult.completed) {
|
|
31041
|
+
setupPromise.catch((error) => {
|
|
31042
|
+
const failedState = {
|
|
31043
|
+
...runningBootstrapState,
|
|
31044
|
+
status: "failed",
|
|
31045
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
31046
|
+
error: error?.message || String(error)
|
|
31047
|
+
};
|
|
31048
|
+
void persistWorktreeSetupState(failedState);
|
|
31049
|
+
void appendCloneLedger(false, failedState);
|
|
30975
31050
|
});
|
|
30976
|
-
|
|
31051
|
+
return {
|
|
31052
|
+
success: true,
|
|
31053
|
+
async: true,
|
|
31054
|
+
status: "accepted",
|
|
31055
|
+
node,
|
|
31056
|
+
worktreePath: result.worktreePath,
|
|
31057
|
+
branch: result.branch,
|
|
31058
|
+
worktreeBootstrap: runningBootstrapState,
|
|
31059
|
+
worktreeSetup: {
|
|
31060
|
+
status: "running",
|
|
31061
|
+
setupWaitMs,
|
|
31062
|
+
message: "Worktree node is registered; submodule/bootstrap setup is continuing in the background."
|
|
31063
|
+
}
|
|
31064
|
+
};
|
|
30977
31065
|
}
|
|
31066
|
+
const { submodulesInitialized, bootstrapState } = setupResult.value;
|
|
30978
31067
|
return {
|
|
30979
31068
|
success: true,
|
|
30980
31069
|
node,
|
|
30981
31070
|
worktreePath: result.worktreePath,
|
|
30982
31071
|
branch: result.branch,
|
|
31072
|
+
submodulesInitialized,
|
|
30983
31073
|
worktreeBootstrap: bootstrapState
|
|
30984
31074
|
};
|
|
30985
31075
|
} catch (e) {
|