@adhdev/daemon-core 0.9.77-rc.9 → 0.9.78
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/boot/daemon-lifecycle.d.ts +3 -0
- package/dist/cli-adapters/provider-cli-adapter.d.ts +2 -0
- package/dist/commands/mesh-coordinator.d.ts +10 -0
- package/dist/commands/router.d.ts +4 -1
- package/dist/config/mesh-config.d.ts +1 -0
- package/dist/git/git-worktree.d.ts +15 -2
- package/dist/index.d.ts +11 -6
- package/dist/index.js +2117 -300
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2102 -300
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-events.d.ts +14 -7
- package/dist/mesh/mesh-ledger-reconciliation.d.ts +55 -0
- package/dist/mesh/mesh-ledger.d.ts +84 -4
- package/dist/mesh/mesh-sync.d.ts +4 -12
- package/dist/mesh/mesh-visualization.d.ts +70 -0
- package/dist/mesh/mesh-work-queue.d.ts +58 -1
- package/dist/mesh/p2p-relay-failure.d.ts +35 -0
- package/dist/providers/chat-message-normalization.d.ts +1 -0
- package/dist/providers/cli-provider-instance.d.ts +6 -0
- package/dist/repo-mesh-types.d.ts +2 -0
- package/dist/shared-types.d.ts +38 -0
- package/package.json +1 -1
- package/src/boot/daemon-lifecycle.ts +5 -0
- package/src/cli-adapters/provider-cli-adapter.ts +30 -5
- package/src/commands/cli-manager.ts +0 -4
- package/src/commands/mesh-coordinator.ts +55 -7
- package/src/commands/router.ts +964 -26
- package/src/commands/stream-commands.ts +8 -1
- package/src/config/config.ts +2 -1
- package/src/config/mesh-config.ts +2 -0
- package/src/config/workspaces.ts +1 -1
- package/src/git/git-worktree.ts +56 -4
- package/src/index.d.ts +3 -0
- package/src/index.ts +30 -6
- package/src/mesh/coordinator-prompt.ts +21 -10
- package/src/mesh/mesh-events.ts +532 -22
- package/src/mesh/mesh-ledger-reconciliation.ts +115 -0
- package/src/mesh/mesh-ledger.ts +209 -8
- package/src/mesh/mesh-sync.ts +4 -34
- package/src/mesh/mesh-visualization.ts +341 -0
- package/src/mesh/mesh-work-queue.ts +183 -17
- package/src/mesh/p2p-relay-failure.ts +152 -0
- package/src/providers/acp-provider-instance.ts +2 -1
- package/src/providers/chat-message-normalization.ts +33 -1
- package/src/providers/cli-provider-instance.ts +155 -31
- package/src/providers/extension-provider-instance.ts +2 -1
- package/src/providers/ide-provider-instance.ts +2 -2
- package/src/repo-mesh-types.ts +2 -0
- package/src/shared-types.ts +38 -0
|
@@ -225,6 +225,7 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
225
225
|
currentTurnScope: TurnParseScope | null;
|
|
226
226
|
recentOutputBuffer: string;
|
|
227
227
|
accumulatedBuffer: string;
|
|
228
|
+
accumulatedRawBufferKey: string;
|
|
228
229
|
screenText: string;
|
|
229
230
|
currentStatus: CliSessionStatus['status'];
|
|
230
231
|
activeModal: { message: string; buttons: string[] } | null;
|
|
@@ -299,14 +300,23 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
299
300
|
this.lastScreenSnapshotReadAt = Number.NEGATIVE_INFINITY;
|
|
300
301
|
}
|
|
301
302
|
|
|
303
|
+
private getAccumulatedRawBufferCacheKey(): string {
|
|
304
|
+
return this.accumulatedRawBuffer
|
|
305
|
+
.replace(/\x1B\][^\x07]*(?:\x07|\x1B\\)/g, '')
|
|
306
|
+
.replace(/\x1B[P^_X][\s\S]*?(?:\x07|\x1B\\)/g, '')
|
|
307
|
+
.replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, '');
|
|
308
|
+
}
|
|
309
|
+
|
|
302
310
|
private getFreshParsedStatusCache(): any | null {
|
|
303
311
|
const cached = this.parsedStatusCache;
|
|
312
|
+
const accumulatedRawBufferKey = this.getAccumulatedRawBufferCacheKey();
|
|
304
313
|
if (
|
|
305
314
|
cached
|
|
306
315
|
&& cached.responseBuffer === this.responseBuffer
|
|
307
316
|
&& cached.currentTurnScope === this.currentTurnScope
|
|
308
317
|
&& cached.recentOutputBuffer === this.recentOutputBuffer
|
|
309
318
|
&& cached.accumulatedBuffer === this.accumulatedBuffer
|
|
319
|
+
&& cached.accumulatedRawBufferKey === accumulatedRawBufferKey
|
|
310
320
|
&& cached.screenText === this.lastScreenText
|
|
311
321
|
&& cached.currentStatus === this.currentStatus
|
|
312
322
|
&& cached.activeModal === this.activeModal
|
|
@@ -450,6 +460,7 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
450
460
|
|
|
451
461
|
// Scripts are required — loaded by ProviderLoader via compatibility array
|
|
452
462
|
this.cliScripts = provider.scripts || {};
|
|
463
|
+
this.scriptState = typeof this.cliScripts.createState === 'function' ? (this.cliScripts.createState() ?? null) : null;
|
|
453
464
|
const scriptNames = listCliScriptNames(this.cliScripts);
|
|
454
465
|
if (scriptNames.length > 0) {
|
|
455
466
|
LOG.info('CLI', `[${this.cliType}] CLI scripts: [${scriptNames.join(', ')}]`);
|
|
@@ -481,7 +492,7 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
481
492
|
this.parseErrorMessage = null;
|
|
482
493
|
// Initialize per-session state: createState() is called once here and on script reload.
|
|
483
494
|
// The returned object lives until the PTY exits (scriptState = null on exit).
|
|
484
|
-
this.scriptState = typeof scripts.createState === 'function' ? scripts.createState() : null;
|
|
495
|
+
this.scriptState = typeof scripts.createState === 'function' ? (scripts.createState() ?? null) : null;
|
|
485
496
|
const scriptNames = listCliScriptNames(scripts);
|
|
486
497
|
LOG.info('CLI', `[${this.cliType}] CLI scripts injected: [${scriptNames.join(', ')}]`);
|
|
487
498
|
}
|
|
@@ -1456,6 +1467,14 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1456
1467
|
|
|
1457
1468
|
// ─── Script Execution ──────────────────────────
|
|
1458
1469
|
|
|
1470
|
+
private invokeCliScript<T>(script: Function, input: any): T {
|
|
1471
|
+
const hasStateFactory = typeof this.cliScripts?.createState === 'function';
|
|
1472
|
+
const expectsStateArgument = hasStateFactory || this.scriptState !== null || script.length >= 2;
|
|
1473
|
+
return expectsStateArgument
|
|
1474
|
+
? script(this.scriptState, input)
|
|
1475
|
+
: script(input);
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1459
1478
|
private runParseSession(): ParsedSession | null {
|
|
1460
1479
|
if (typeof this.cliScripts?.parseSession !== 'function') {
|
|
1461
1480
|
this.parseErrorMessage = `${this.cliType} parseSession unavailable`;
|
|
@@ -1476,7 +1495,10 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1476
1495
|
scope: this.currentTurnScope,
|
|
1477
1496
|
runtimeSettings: this.runtimeSettings,
|
|
1478
1497
|
});
|
|
1479
|
-
const session = this.
|
|
1498
|
+
const session = this.invokeCliScript<ParsedSession | null>(
|
|
1499
|
+
this.cliScripts.parseSession,
|
|
1500
|
+
{ ...input, tail, tailScreen: buildCliScreenSnapshot(tail) },
|
|
1501
|
+
);
|
|
1480
1502
|
this.parseErrorMessage = null;
|
|
1481
1503
|
return session && typeof session === 'object' ? session : null;
|
|
1482
1504
|
} catch (e: any) {
|
|
@@ -1491,7 +1513,7 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1491
1513
|
if (!this.cliScripts?.detectStatus) return null;
|
|
1492
1514
|
try {
|
|
1493
1515
|
const screenText = this.terminalScreen.getText();
|
|
1494
|
-
const status = this.cliScripts.detectStatus
|
|
1516
|
+
const status = this.invokeCliScript<string | null>(this.cliScripts.detectStatus, {
|
|
1495
1517
|
tail: text.slice(-500),
|
|
1496
1518
|
screenText,
|
|
1497
1519
|
rawBuffer: this.accumulatedRawBuffer,
|
|
@@ -1511,7 +1533,7 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1511
1533
|
try {
|
|
1512
1534
|
const screenText = this.terminalScreen.getText();
|
|
1513
1535
|
const buffer = screenText || this.accumulatedBuffer;
|
|
1514
|
-
return this.cliScripts.parseApproval
|
|
1536
|
+
return this.invokeCliScript<{ message: string; buttons: string[] } | null>(this.cliScripts.parseApproval, {
|
|
1515
1537
|
buffer,
|
|
1516
1538
|
screenText,
|
|
1517
1539
|
rawBuffer: this.accumulatedRawBuffer,
|
|
@@ -1576,12 +1598,14 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1576
1598
|
const screenText = this.readTerminalScreenText();
|
|
1577
1599
|
const parseScreenText = this.getParseScreenText(screenText);
|
|
1578
1600
|
const cached = this.parsedStatusCache;
|
|
1601
|
+
const accumulatedRawBufferKey = this.getAccumulatedRawBufferCacheKey();
|
|
1579
1602
|
if (
|
|
1580
1603
|
cached
|
|
1581
1604
|
&& cached.responseBuffer === this.responseBuffer
|
|
1582
1605
|
&& cached.currentTurnScope === this.currentTurnScope
|
|
1583
1606
|
&& cached.recentOutputBuffer === this.recentOutputBuffer
|
|
1584
1607
|
&& cached.accumulatedBuffer === this.accumulatedBuffer
|
|
1608
|
+
&& cached.accumulatedRawBufferKey === accumulatedRawBufferKey
|
|
1585
1609
|
&& cached.screenText === parseScreenText
|
|
1586
1610
|
&& cached.currentStatus === this.currentStatus
|
|
1587
1611
|
&& cached.activeModal === this.activeModal
|
|
@@ -1621,6 +1645,7 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1621
1645
|
currentTurnScope: this.currentTurnScope,
|
|
1622
1646
|
recentOutputBuffer: this.recentOutputBuffer,
|
|
1623
1647
|
accumulatedBuffer: this.accumulatedBuffer,
|
|
1648
|
+
accumulatedRawBufferKey,
|
|
1624
1649
|
screenText: parseScreenText,
|
|
1625
1650
|
currentStatus: this.currentStatus,
|
|
1626
1651
|
activeModal: this.activeModal,
|
|
@@ -1646,7 +1671,7 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1646
1671
|
scope: this.currentTurnScope,
|
|
1647
1672
|
runtimeSettings: this.runtimeSettings,
|
|
1648
1673
|
});
|
|
1649
|
-
return await Promise.resolve(
|
|
1674
|
+
return await Promise.resolve(this.invokeCliScript(fn, {
|
|
1650
1675
|
...input,
|
|
1651
1676
|
args: args && typeof args === 'object' ? { ...args } : {},
|
|
1652
1677
|
}));
|
|
@@ -177,10 +177,6 @@ export function buildCoordinatorDelegatedCliLaunchOptions(
|
|
|
177
177
|
const cliArgs = Array.isArray(input.cliArgs) ? [...input.cliArgs] : [];
|
|
178
178
|
const env: Record<string, string> = { ...(input.env || {}), ...COORDINATOR_DELEGATED_ENV_UNSETS };
|
|
179
179
|
|
|
180
|
-
if (cliType === 'hermes-cli' && !hasCliArg(cliArgs, '--ignore-user-config')) {
|
|
181
|
-
cliArgs.unshift('--ignore-user-config');
|
|
182
|
-
}
|
|
183
|
-
|
|
184
180
|
if (cliType === 'claude-cli' && !hasCliArg(cliArgs, '--mcp-config')) {
|
|
185
181
|
cliArgs.unshift('--mcp-config', ensureEmptyDelegatedMcpConfig(input.workspace));
|
|
186
182
|
}
|
|
@@ -28,6 +28,15 @@ export type MeshCoordinatorSetup =
|
|
|
28
28
|
instructions: string
|
|
29
29
|
template: string
|
|
30
30
|
}
|
|
31
|
+
| {
|
|
32
|
+
/** Provider registers MCP via its own CLI command (e.g. `codex mcp add` / `gemini mcp add`). */
|
|
33
|
+
kind: 'cli_command'
|
|
34
|
+
serverName: string
|
|
35
|
+
/** The rendered shell command to execute before launching the coordinator session. */
|
|
36
|
+
command: string
|
|
37
|
+
requiresRestart: boolean
|
|
38
|
+
instructions: string
|
|
39
|
+
}
|
|
31
40
|
| {
|
|
32
41
|
kind: 'unsupported'
|
|
33
42
|
reason: string
|
|
@@ -41,6 +50,8 @@ export interface ResolveMeshCoordinatorSetupOptions {
|
|
|
41
50
|
adhdevMcpCommand?: string
|
|
42
51
|
adhdevMcpEntryPath?: string
|
|
43
52
|
nodeExecutable?: string
|
|
53
|
+
adhdevMcpTransport?: 'local' | 'ipc'
|
|
54
|
+
adhdevMcpPort?: number
|
|
44
55
|
}
|
|
45
56
|
|
|
46
57
|
const DEFAULT_SERVER_NAME = 'adhdev-mesh'
|
|
@@ -58,6 +69,8 @@ function resolveHermesMeshCoordinatorSetup(options: ResolveMeshCoordinatorSetupO
|
|
|
58
69
|
meshId: options.meshId,
|
|
59
70
|
nodeExecutable: options.nodeExecutable,
|
|
60
71
|
adhdevMcpEntryPath: options.adhdevMcpEntryPath,
|
|
72
|
+
adhdevMcpTransport: options.adhdevMcpTransport,
|
|
73
|
+
adhdevMcpPort: options.adhdevMcpPort,
|
|
61
74
|
})
|
|
62
75
|
if (!mcpServer) {
|
|
63
76
|
return {
|
|
@@ -130,6 +143,8 @@ export function resolveMeshCoordinatorSetup(options: ResolveMeshCoordinatorSetup
|
|
|
130
143
|
meshId,
|
|
131
144
|
nodeExecutable: options.nodeExecutable,
|
|
132
145
|
adhdevMcpEntryPath: options.adhdevMcpEntryPath,
|
|
146
|
+
adhdevMcpTransport: options.adhdevMcpTransport,
|
|
147
|
+
adhdevMcpPort: options.adhdevMcpPort,
|
|
133
148
|
})
|
|
134
149
|
if (!mcpServer) {
|
|
135
150
|
return {
|
|
@@ -152,6 +167,24 @@ export function resolveMeshCoordinatorSetup(options: ResolveMeshCoordinatorSetup
|
|
|
152
167
|
if (!instructions || !template?.trim()) {
|
|
153
168
|
return { kind: 'unsupported', reason: 'Provider manual MCP setup is missing instructions or template' }
|
|
154
169
|
}
|
|
170
|
+
const renderedTemplate = renderMeshCoordinatorTemplate(template, {
|
|
171
|
+
meshId,
|
|
172
|
+
workspace,
|
|
173
|
+
serverName,
|
|
174
|
+
adhdevMcpCommand: options.adhdevMcpCommand || DEFAULT_ADHDEV_MCP_COMMAND,
|
|
175
|
+
})
|
|
176
|
+
// Detect if the template is a runnable CLI command (single line, no YAML/JSON structure).
|
|
177
|
+
// If so, use cli_command kind so the daemon can execute it automatically.
|
|
178
|
+
const isCliCommand = !renderedTemplate.trim().includes('\n') && !renderedTemplate.trim().startsWith('{')
|
|
179
|
+
if (isCliCommand) {
|
|
180
|
+
return {
|
|
181
|
+
kind: 'cli_command',
|
|
182
|
+
serverName,
|
|
183
|
+
command: renderedTemplate.trim(),
|
|
184
|
+
requiresRestart: mcpConfig.requiresRestart === true,
|
|
185
|
+
instructions: instructions,
|
|
186
|
+
}
|
|
187
|
+
}
|
|
155
188
|
return {
|
|
156
189
|
kind: 'manual',
|
|
157
190
|
serverName,
|
|
@@ -159,12 +192,7 @@ export function resolveMeshCoordinatorSetup(options: ResolveMeshCoordinatorSetup
|
|
|
159
192
|
configPathCommand: mcpConfig.configPathCommand,
|
|
160
193
|
requiresRestart: mcpConfig.requiresRestart === true,
|
|
161
194
|
instructions,
|
|
162
|
-
template:
|
|
163
|
-
meshId,
|
|
164
|
-
workspace,
|
|
165
|
-
serverName,
|
|
166
|
-
adhdevMcpCommand: options.adhdevMcpCommand || DEFAULT_ADHDEV_MCP_COMMAND,
|
|
167
|
-
}),
|
|
195
|
+
template: renderedTemplate,
|
|
168
196
|
}
|
|
169
197
|
}
|
|
170
198
|
|
|
@@ -196,17 +224,37 @@ function resolveAdhdevMcpServerLaunch(options: {
|
|
|
196
224
|
meshId: string
|
|
197
225
|
nodeExecutable?: string
|
|
198
226
|
adhdevMcpEntryPath?: string
|
|
227
|
+
adhdevMcpTransport?: 'local' | 'ipc'
|
|
228
|
+
adhdevMcpPort?: number
|
|
199
229
|
}): MeshCoordinatorMcpServerLaunch | null {
|
|
200
230
|
const entryPath = resolveAdhdevMcpEntryPath(options.adhdevMcpEntryPath)
|
|
201
231
|
if (!entryPath) return null
|
|
202
232
|
const nodeExecutable = resolveMcpNodeExecutable(options.nodeExecutable)
|
|
203
233
|
if (!nodeExecutable) return null
|
|
234
|
+
const transport = resolveMcpTransport(options.adhdevMcpTransport)
|
|
235
|
+
const args = [entryPath, '--mode', transport, '--repo-mesh', options.meshId]
|
|
236
|
+
const port = resolveMcpPort(options.adhdevMcpPort)
|
|
237
|
+
if (port !== undefined) args.push('--port', String(port))
|
|
204
238
|
return {
|
|
205
239
|
command: nodeExecutable,
|
|
206
|
-
args
|
|
240
|
+
args,
|
|
207
241
|
}
|
|
208
242
|
}
|
|
209
243
|
|
|
244
|
+
function resolveMcpTransport(explicitTransport?: 'local' | 'ipc'): 'local' | 'ipc' {
|
|
245
|
+
if (explicitTransport === 'local' || explicitTransport === 'ipc') return explicitTransport
|
|
246
|
+
const envTransport = process.env.ADHDEV_COORDINATOR_MCP_TRANSPORT?.trim()
|
|
247
|
+
return envTransport === 'local' ? 'local' : 'ipc'
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function resolveMcpPort(explicitPort?: number): number | undefined {
|
|
251
|
+
if (typeof explicitPort === 'number' && Number.isInteger(explicitPort) && explicitPort > 0) return explicitPort
|
|
252
|
+
const raw = process.env.ADHDEV_COORDINATOR_MCP_PORT?.trim()
|
|
253
|
+
if (!raw) return undefined
|
|
254
|
+
const parsed = Number(raw)
|
|
255
|
+
return Number.isInteger(parsed) && parsed > 0 ? parsed : undefined
|
|
256
|
+
}
|
|
257
|
+
|
|
210
258
|
function resolveMcpNodeExecutable(explicitExecutable?: string): string | null {
|
|
211
259
|
const explicit = explicitExecutable?.trim()
|
|
212
260
|
if (explicit) return explicit
|