@adhdev/daemon-core 0.9.77-rc.2 → 0.9.77-rc.20
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/cli-adapters/provider-cli-adapter.d.ts +2 -0
- package/dist/cli-adapters/provider-cli-shared.d.ts +14 -4
- package/dist/commands/mesh-coordinator.d.ts +8 -0
- package/dist/index.js +128 -15
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +128 -15
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/cli-adapters/provider-cli-adapter.ts +10 -4
- package/src/cli-adapters/provider-cli-shared.ts +14 -4
- package/src/commands/cli-manager.ts +0 -4
- package/src/commands/mesh-coordinator.ts +28 -6
- package/src/commands/router.ts +99 -0
- package/src/commands/stream-commands.ts +8 -1
- package/src/mesh/mesh-events.ts +12 -1
- package/src/providers/cli-provider-instance.ts +2 -0
|
@@ -77,6 +77,8 @@ export declare class ProviderCliAdapter implements CliAdapter {
|
|
|
77
77
|
private resizeSuppressUntil;
|
|
78
78
|
private statusHistory;
|
|
79
79
|
private cliScripts;
|
|
80
|
+
/** Per-session opaque state object created by cliScripts.createState(), reset on stop. */
|
|
81
|
+
private scriptState;
|
|
80
82
|
private runtimeSettings;
|
|
81
83
|
/** Full accumulated rendered PTY transcript for parser/readback use */
|
|
82
84
|
private accumulatedBuffer;
|
|
@@ -63,17 +63,27 @@ export interface ParsedSession {
|
|
|
63
63
|
coverage?: 'full' | 'tail' | 'current-turn';
|
|
64
64
|
}
|
|
65
65
|
export interface CliScripts {
|
|
66
|
-
|
|
66
|
+
/**
|
|
67
|
+
* Optional state factory. Called once per CLI session start (or script reload).
|
|
68
|
+
* The returned object is passed as the first argument to detectStatus, parseApproval,
|
|
69
|
+
* and parseSession on every invocation, allowing scripts to maintain per-session state
|
|
70
|
+
* (e.g. last-seen status, approval fingerprints, stability counters).
|
|
71
|
+
*
|
|
72
|
+
* Scripts that don't define createState() receive null as the state argument,
|
|
73
|
+
* making this change fully backward compatible.
|
|
74
|
+
*/
|
|
75
|
+
createState?: () => unknown;
|
|
76
|
+
parseSession?: (state: unknown, input: CliScriptInput & {
|
|
67
77
|
tail?: string;
|
|
68
78
|
tailScreen?: CliScreenSnapshot;
|
|
69
79
|
}) => ParsedSession | null;
|
|
70
|
-
detectStatus?: (input: CliStatusInput) => string | null;
|
|
71
|
-
parseApproval?: (input: CliApprovalInput) => {
|
|
80
|
+
detectStatus?: (state: unknown, input: CliStatusInput) => string | null;
|
|
81
|
+
parseApproval?: (state: unknown, input: CliApprovalInput) => {
|
|
72
82
|
message: string;
|
|
73
83
|
buttons: string[];
|
|
74
84
|
} | null;
|
|
75
85
|
resolveAction?: (data: any) => string;
|
|
76
|
-
[name: string]: ((input: any) => any) | undefined;
|
|
86
|
+
[name: string]: ((state: unknown, input: any) => any) | ((data: any) => any) | (() => unknown) | undefined;
|
|
77
87
|
}
|
|
78
88
|
export interface CliScreenLine {
|
|
79
89
|
index: number;
|
|
@@ -17,6 +17,14 @@ export type MeshCoordinatorSetup = {
|
|
|
17
17
|
requiresRestart: boolean;
|
|
18
18
|
instructions: string;
|
|
19
19
|
template: string;
|
|
20
|
+
} | {
|
|
21
|
+
/** Provider registers MCP via its own CLI command (e.g. `codex mcp add` / `gemini mcp add`). */
|
|
22
|
+
kind: 'cli_command';
|
|
23
|
+
serverName: string;
|
|
24
|
+
/** The rendered shell command to execute before launching the coordinator session. */
|
|
25
|
+
command: string;
|
|
26
|
+
requiresRestart: boolean;
|
|
27
|
+
instructions: string;
|
|
20
28
|
} | {
|
|
21
29
|
kind: 'unsupported';
|
|
22
30
|
reason: string;
|
package/dist/index.js
CHANGED
|
@@ -1323,7 +1323,7 @@ function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType)
|
|
|
1323
1323
|
targetSessionId: sessionId,
|
|
1324
1324
|
cliType: providerType,
|
|
1325
1325
|
action: "send_chat",
|
|
1326
|
-
|
|
1326
|
+
message: task.message
|
|
1327
1327
|
}).catch((e) => {
|
|
1328
1328
|
LOG.error("MeshQueue", `Failed to dispatch task to node ${nodeId}: ${e?.message}`);
|
|
1329
1329
|
});
|
|
@@ -1405,6 +1405,15 @@ function injectMeshSystemMessage(components, args) {
|
|
|
1405
1405
|
}, 500);
|
|
1406
1406
|
}
|
|
1407
1407
|
}
|
|
1408
|
+
} else if (args.event === "agent:ready") {
|
|
1409
|
+
const sessionId = readNonEmptyString(args.metadataEvent.targetSessionId);
|
|
1410
|
+
const nodeId = readNonEmptyString(args.metadataEvent.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId);
|
|
1411
|
+
const providerType = readNonEmptyString(args.metadataEvent.providerType);
|
|
1412
|
+
if (sessionId && nodeId && providerType) {
|
|
1413
|
+
setTimeout(() => {
|
|
1414
|
+
tryAssignQueueTask(components, args.meshId, nodeId, sessionId, providerType);
|
|
1415
|
+
}, 500);
|
|
1416
|
+
}
|
|
1408
1417
|
} else if (args.event === "agent:stopped") {
|
|
1409
1418
|
const sessionId = readNonEmptyString(args.metadataEvent.targetSessionId);
|
|
1410
1419
|
if (sessionId) {
|
|
@@ -1584,6 +1593,7 @@ var init_mesh_events = __esm({
|
|
|
1584
1593
|
"agent:generating_completed",
|
|
1585
1594
|
"agent:waiting_approval",
|
|
1586
1595
|
"agent:stopped",
|
|
1596
|
+
"agent:ready",
|
|
1587
1597
|
"monitor:long_generating"
|
|
1588
1598
|
]);
|
|
1589
1599
|
EVENT_TO_LEDGER_KIND = {
|
|
@@ -2699,6 +2709,8 @@ var init_provider_cli_adapter = __esm({
|
|
|
2699
2709
|
statusHistory = [];
|
|
2700
2710
|
// ─── CLI Scripts (script-based parsing) ───
|
|
2701
2711
|
cliScripts;
|
|
2712
|
+
/** Per-session opaque state object created by cliScripts.createState(), reset on stop. */
|
|
2713
|
+
scriptState = null;
|
|
2702
2714
|
runtimeSettings = {};
|
|
2703
2715
|
/** Full accumulated rendered PTY transcript for parser/readback use */
|
|
2704
2716
|
accumulatedBuffer = "";
|
|
@@ -2880,6 +2892,7 @@ ${lastSnapshot}`;
|
|
|
2880
2892
|
this.cliScripts = scripts;
|
|
2881
2893
|
this.parsedStatusCache = null;
|
|
2882
2894
|
this.parseErrorMessage = null;
|
|
2895
|
+
this.scriptState = typeof scripts.createState === "function" ? scripts.createState() : null;
|
|
2883
2896
|
const scriptNames = listCliScriptNames(scripts);
|
|
2884
2897
|
LOG.info("CLI", `[${this.cliType}] CLI scripts injected: [${scriptNames.join(", ")}]`);
|
|
2885
2898
|
}
|
|
@@ -2997,6 +3010,7 @@ ${lastSnapshot}`;
|
|
|
2997
3010
|
this.ready = false;
|
|
2998
3011
|
this.startupParseGate = false;
|
|
2999
3012
|
this.spawnAt = 0;
|
|
3013
|
+
this.scriptState = null;
|
|
3000
3014
|
this.onStatusChange?.();
|
|
3001
3015
|
});
|
|
3002
3016
|
this.spawnAt = Date.now();
|
|
@@ -3770,7 +3784,7 @@ ${lastSnapshot}`;
|
|
|
3770
3784
|
scope: this.currentTurnScope,
|
|
3771
3785
|
runtimeSettings: this.runtimeSettings
|
|
3772
3786
|
});
|
|
3773
|
-
const session = this.cliScripts.parseSession({ ...input, tail, tailScreen: buildCliScreenSnapshot(tail) });
|
|
3787
|
+
const session = this.cliScripts.parseSession(this.scriptState, { ...input, tail, tailScreen: buildCliScreenSnapshot(tail) });
|
|
3774
3788
|
this.parseErrorMessage = null;
|
|
3775
3789
|
return session && typeof session === "object" ? session : null;
|
|
3776
3790
|
} catch (e) {
|
|
@@ -3784,7 +3798,7 @@ ${lastSnapshot}`;
|
|
|
3784
3798
|
if (!this.cliScripts?.detectStatus) return null;
|
|
3785
3799
|
try {
|
|
3786
3800
|
const screenText = this.terminalScreen.getText();
|
|
3787
|
-
const status = this.cliScripts.detectStatus({
|
|
3801
|
+
const status = this.cliScripts.detectStatus(this.scriptState, {
|
|
3788
3802
|
tail: text.slice(-500),
|
|
3789
3803
|
screenText,
|
|
3790
3804
|
rawBuffer: this.accumulatedRawBuffer,
|
|
@@ -3803,7 +3817,7 @@ ${lastSnapshot}`;
|
|
|
3803
3817
|
try {
|
|
3804
3818
|
const screenText = this.terminalScreen.getText();
|
|
3805
3819
|
const buffer = screenText || this.accumulatedBuffer;
|
|
3806
|
-
return this.cliScripts.parseApproval({
|
|
3820
|
+
return this.cliScripts.parseApproval(this.scriptState, {
|
|
3807
3821
|
buffer,
|
|
3808
3822
|
screenText,
|
|
3809
3823
|
rawBuffer: this.accumulatedRawBuffer,
|
|
@@ -3911,7 +3925,7 @@ ${lastSnapshot}`;
|
|
|
3911
3925
|
scope: this.currentTurnScope,
|
|
3912
3926
|
runtimeSettings: this.runtimeSettings
|
|
3913
3927
|
});
|
|
3914
|
-
return await Promise.resolve(fn({
|
|
3928
|
+
return await Promise.resolve(fn(this.scriptState, {
|
|
3915
3929
|
...input,
|
|
3916
3930
|
args: args && typeof args === "object" ? { ...args } : {}
|
|
3917
3931
|
}));
|
|
@@ -15205,11 +15219,13 @@ async function handleOpenPanel(h, args) {
|
|
|
15205
15219
|
async function handlePtyInput(h, args) {
|
|
15206
15220
|
const { cliType, data, targetSessionId } = args || {};
|
|
15207
15221
|
if (!data) return { success: false, error: "data required" };
|
|
15222
|
+
const cleanData = typeof data === "string" ? data.replace(/\x1b\[[?>][0-9;]*c/g, "") : data;
|
|
15223
|
+
if (!cleanData) return { success: true };
|
|
15208
15224
|
const adapter = h.getCliAdapter(targetSessionId || cliType);
|
|
15209
15225
|
if (!adapter || typeof adapter.writeRaw !== "function") {
|
|
15210
15226
|
return { success: false, error: `CLI adapter not found: ${targetSessionId || cliType || "unknown"}` };
|
|
15211
15227
|
}
|
|
15212
|
-
await adapter.writeRaw(
|
|
15228
|
+
await adapter.writeRaw(cleanData);
|
|
15213
15229
|
return { success: true };
|
|
15214
15230
|
}
|
|
15215
15231
|
function handlePtyResize(_h, args) {
|
|
@@ -16839,6 +16855,8 @@ var CliProviderInstance = class {
|
|
|
16839
16855
|
this.completedDebounceTimer = null;
|
|
16840
16856
|
}, 3e3);
|
|
16841
16857
|
}
|
|
16858
|
+
} else if (newStatus === "idle" && this.lastStatus === "starting") {
|
|
16859
|
+
this.pushEvent({ event: "agent:ready", chatTitle, timestamp: now });
|
|
16842
16860
|
} else if (newStatus === "stopped") {
|
|
16843
16861
|
if (this.generatingDebounceTimer) {
|
|
16844
16862
|
clearTimeout(this.generatingDebounceTimer);
|
|
@@ -18582,9 +18600,6 @@ function buildCoordinatorDelegatedCliLaunchOptions(input) {
|
|
|
18582
18600
|
const cliType = String(input.cliType || "").trim();
|
|
18583
18601
|
const cliArgs = Array.isArray(input.cliArgs) ? [...input.cliArgs] : [];
|
|
18584
18602
|
const env = { ...input.env || {}, ...COORDINATOR_DELEGATED_ENV_UNSETS };
|
|
18585
|
-
if (cliType === "hermes-cli" && !hasCliArg(cliArgs, "--ignore-user-config")) {
|
|
18586
|
-
cliArgs.unshift("--ignore-user-config");
|
|
18587
|
-
}
|
|
18588
18603
|
if (cliType === "claude-cli" && !hasCliArg(cliArgs, "--mcp-config")) {
|
|
18589
18604
|
cliArgs.unshift("--mcp-config", ensureEmptyDelegatedMcpConfig(input.workspace));
|
|
18590
18605
|
}
|
|
@@ -21919,6 +21934,22 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
21919
21934
|
if (!instructions || !template?.trim()) {
|
|
21920
21935
|
return { kind: "unsupported", reason: "Provider manual MCP setup is missing instructions or template" };
|
|
21921
21936
|
}
|
|
21937
|
+
const renderedTemplate = renderMeshCoordinatorTemplate(template, {
|
|
21938
|
+
meshId,
|
|
21939
|
+
workspace,
|
|
21940
|
+
serverName,
|
|
21941
|
+
adhdevMcpCommand: options.adhdevMcpCommand || DEFAULT_ADHDEV_MCP_COMMAND
|
|
21942
|
+
});
|
|
21943
|
+
const isCliCommand = !renderedTemplate.trim().includes("\n") && !renderedTemplate.trim().startsWith("{");
|
|
21944
|
+
if (isCliCommand) {
|
|
21945
|
+
return {
|
|
21946
|
+
kind: "cli_command",
|
|
21947
|
+
serverName,
|
|
21948
|
+
command: renderedTemplate.trim(),
|
|
21949
|
+
requiresRestart: mcpConfig.requiresRestart === true,
|
|
21950
|
+
instructions
|
|
21951
|
+
};
|
|
21952
|
+
}
|
|
21922
21953
|
return {
|
|
21923
21954
|
kind: "manual",
|
|
21924
21955
|
serverName,
|
|
@@ -21926,12 +21957,7 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
21926
21957
|
configPathCommand: mcpConfig.configPathCommand,
|
|
21927
21958
|
requiresRestart: mcpConfig.requiresRestart === true,
|
|
21928
21959
|
instructions,
|
|
21929
|
-
template:
|
|
21930
|
-
meshId,
|
|
21931
|
-
workspace,
|
|
21932
|
-
serverName,
|
|
21933
|
-
adhdevMcpCommand: options.adhdevMcpCommand || DEFAULT_ADHDEV_MCP_COMMAND
|
|
21934
|
-
})
|
|
21960
|
+
template: renderedTemplate
|
|
21935
21961
|
};
|
|
21936
21962
|
}
|
|
21937
21963
|
return {
|
|
@@ -24113,6 +24139,93 @@ var DaemonCommandRouter = class {
|
|
|
24113
24139
|
meshCoordinatorSetup: coordinatorSetup
|
|
24114
24140
|
};
|
|
24115
24141
|
}
|
|
24142
|
+
if (coordinatorSetup.kind === "cli_command") {
|
|
24143
|
+
let cliCmdSystemPrompt = "";
|
|
24144
|
+
try {
|
|
24145
|
+
cliCmdSystemPrompt = buildCoordinatorSystemPrompt2({ mesh, coordinatorCliType: cliType });
|
|
24146
|
+
} catch (error) {
|
|
24147
|
+
const message = error?.message || String(error);
|
|
24148
|
+
LOG.error("MeshCoordinator", `Failed to build coordinator prompt: ${message}`);
|
|
24149
|
+
return {
|
|
24150
|
+
success: false,
|
|
24151
|
+
code: "mesh_coordinator_prompt_failed",
|
|
24152
|
+
error: `Failed to build Repo Mesh coordinator prompt: ${message}`,
|
|
24153
|
+
meshId,
|
|
24154
|
+
cliType,
|
|
24155
|
+
workspace
|
|
24156
|
+
};
|
|
24157
|
+
}
|
|
24158
|
+
try {
|
|
24159
|
+
const { execFileSync: execCmdSync } = await import("child_process");
|
|
24160
|
+
const cmdParts = coordinatorSetup.command.trim().split(/\s+/);
|
|
24161
|
+
const [regCmd, ...regArgs] = cmdParts;
|
|
24162
|
+
LOG.info("MeshCoordinator", `Running MCP registration: ${coordinatorSetup.command}`);
|
|
24163
|
+
execCmdSync(regCmd, regArgs, { stdio: "pipe", timeout: 15e3 });
|
|
24164
|
+
} catch (error) {
|
|
24165
|
+
LOG.warn("MeshCoordinator", `MCP registration command failed (may be pre-registered): ${error?.message || error}`);
|
|
24166
|
+
}
|
|
24167
|
+
const cliCmdArgs = [];
|
|
24168
|
+
const cliCmdEnv = {};
|
|
24169
|
+
if (cliCmdSystemPrompt) {
|
|
24170
|
+
if (cliType === "codex-cli") {
|
|
24171
|
+
cliCmdArgs.push("-c", `developer_instructions=${JSON.stringify(cliCmdSystemPrompt)}`);
|
|
24172
|
+
} else if (cliType === "gemini-cli") {
|
|
24173
|
+
try {
|
|
24174
|
+
const { writeFileSync: wfs, existsSync: efs, readFileSync: rfs } = await import("fs");
|
|
24175
|
+
const geminiMdPath = `${workspace}/GEMINI.md`;
|
|
24176
|
+
const marker = "<!-- adhdev-mesh-coordinator-prompt -->";
|
|
24177
|
+
const markerEnd = "<!-- /adhdev-mesh-coordinator-prompt -->";
|
|
24178
|
+
const block = `${marker}
|
|
24179
|
+
${cliCmdSystemPrompt}
|
|
24180
|
+
${markerEnd}`;
|
|
24181
|
+
if (efs(geminiMdPath)) {
|
|
24182
|
+
const existing = rfs(geminiMdPath, "utf-8");
|
|
24183
|
+
const replaced = existing.replace(
|
|
24184
|
+
new RegExp(`${marker}[\\s\\S]*?${markerEnd}`, "g"),
|
|
24185
|
+
block
|
|
24186
|
+
);
|
|
24187
|
+
wfs(geminiMdPath, replaced.includes(marker) ? replaced : `${existing}
|
|
24188
|
+
|
|
24189
|
+
${block}`);
|
|
24190
|
+
} else {
|
|
24191
|
+
wfs(geminiMdPath, block);
|
|
24192
|
+
}
|
|
24193
|
+
LOG.info("MeshCoordinator", `Wrote coordinator prompt to ${workspace}/GEMINI.md`);
|
|
24194
|
+
} catch (e) {
|
|
24195
|
+
LOG.warn("MeshCoordinator", `Could not write GEMINI.md: ${e?.message || e}`);
|
|
24196
|
+
}
|
|
24197
|
+
}
|
|
24198
|
+
}
|
|
24199
|
+
const cliCmdLaunch = await this.deps.cliManager.handleCliCommand("launch_cli", {
|
|
24200
|
+
cliType,
|
|
24201
|
+
dir: workspace,
|
|
24202
|
+
cliArgs: cliCmdArgs.length > 0 ? cliCmdArgs : void 0,
|
|
24203
|
+
env: Object.keys(cliCmdEnv).length > 0 ? cliCmdEnv : void 0,
|
|
24204
|
+
settings: { meshCoordinatorFor: meshId }
|
|
24205
|
+
});
|
|
24206
|
+
if (!cliCmdLaunch?.success) {
|
|
24207
|
+
return { success: false, error: cliCmdLaunch?.error || "Failed to launch CLI session" };
|
|
24208
|
+
}
|
|
24209
|
+
LOG.info("MeshCoordinator", `Launched ${cliType} coordinator (cli_command) for mesh ${meshId}`);
|
|
24210
|
+
try {
|
|
24211
|
+
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
24212
|
+
appendLedgerEntry2(meshId, {
|
|
24213
|
+
kind: "coordinator_started",
|
|
24214
|
+
sessionId: cliCmdLaunch.sessionId || cliCmdLaunch.id,
|
|
24215
|
+
providerType: cliType,
|
|
24216
|
+
payload: { workspace }
|
|
24217
|
+
});
|
|
24218
|
+
} catch {
|
|
24219
|
+
}
|
|
24220
|
+
return {
|
|
24221
|
+
success: true,
|
|
24222
|
+
meshId,
|
|
24223
|
+
cliType,
|
|
24224
|
+
workspace,
|
|
24225
|
+
sessionId: cliCmdLaunch.sessionId || cliCmdLaunch.id,
|
|
24226
|
+
mcpRegistered: true
|
|
24227
|
+
};
|
|
24228
|
+
}
|
|
24116
24229
|
const configFormat = coordinatorSetup.configFormat;
|
|
24117
24230
|
if (configFormat !== "claude_mcp_json" && configFormat !== "hermes_config_yaml") {
|
|
24118
24231
|
return {
|