@adhdev/daemon-core 0.9.74 → 0.9.75
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 +1 -0
- package/dist/config/config.d.ts +3 -0
- package/dist/index.js +46 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +46 -14
- package/dist/index.mjs.map +1 -1
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/cli-adapters/provider-cli-adapter.ts +17 -4
- package/src/commands/mesh-coordinator.ts +5 -0
- package/src/commands/router.ts +40 -11
- package/src/config/config.ts +6 -0
package/package.json
CHANGED
|
@@ -262,6 +262,17 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
262
262
|
return screenText;
|
|
263
263
|
}
|
|
264
264
|
|
|
265
|
+
private getParseScreenText(screenText: string): string {
|
|
266
|
+
const currentSnapshot = normalizeScreenSnapshot(screenText);
|
|
267
|
+
const lastSnapshot = this.lastScreenSnapshot;
|
|
268
|
+
if (!lastSnapshot || lastSnapshot === currentSnapshot) return screenText;
|
|
269
|
+
// Terminal screen reads can miss a just-rendered completed Hermes box while
|
|
270
|
+
// the normalized snapshot captured during output still has it. Feed both
|
|
271
|
+
// views to provider parsers so flattened snapshot-only final bubbles do
|
|
272
|
+
// not disappear from read_chat/chat_tail.
|
|
273
|
+
return `${screenText}\n${lastSnapshot}`;
|
|
274
|
+
}
|
|
275
|
+
|
|
265
276
|
private shouldReadTerminalScreenSnapshot(now: number): boolean {
|
|
266
277
|
if (!this.lastScreenText) return true;
|
|
267
278
|
return (now - this.lastScreenSnapshotReadAt) >= ProviderCliAdapter.SCREEN_SNAPSHOT_MIN_INTERVAL_MS;
|
|
@@ -1424,12 +1435,13 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1424
1435
|
}
|
|
1425
1436
|
try {
|
|
1426
1437
|
const screenText = this.terminalScreen.getText();
|
|
1438
|
+
const parseScreenText = this.getParseScreenText(screenText);
|
|
1427
1439
|
const tail = this.recentOutputBuffer.slice(-500);
|
|
1428
1440
|
const input = buildCliParseInput({
|
|
1429
1441
|
accumulatedBuffer: this.accumulatedBuffer,
|
|
1430
1442
|
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
1431
1443
|
recentOutputBuffer: this.recentOutputBuffer,
|
|
1432
|
-
terminalScreenText:
|
|
1444
|
+
terminalScreenText: parseScreenText,
|
|
1433
1445
|
baseMessages: [],
|
|
1434
1446
|
partialResponse: this.responseBuffer,
|
|
1435
1447
|
isWaitingForResponse: this.isWaitingForResponse,
|
|
@@ -1534,6 +1546,7 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1534
1546
|
*/
|
|
1535
1547
|
getScriptParsedStatus(): any {
|
|
1536
1548
|
const screenText = this.readTerminalScreenText();
|
|
1549
|
+
const parseScreenText = this.getParseScreenText(screenText);
|
|
1537
1550
|
const cached = this.parsedStatusCache;
|
|
1538
1551
|
if (
|
|
1539
1552
|
cached
|
|
@@ -1541,7 +1554,7 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1541
1554
|
&& cached.currentTurnScope === this.currentTurnScope
|
|
1542
1555
|
&& cached.recentOutputBuffer === this.recentOutputBuffer
|
|
1543
1556
|
&& cached.accumulatedBuffer === this.accumulatedBuffer
|
|
1544
|
-
&& cached.screenText ===
|
|
1557
|
+
&& cached.screenText === parseScreenText
|
|
1545
1558
|
&& cached.currentStatus === this.currentStatus
|
|
1546
1559
|
&& cached.activeModal === this.activeModal
|
|
1547
1560
|
&& cached.cliName === this.cliName
|
|
@@ -1580,7 +1593,7 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1580
1593
|
currentTurnScope: this.currentTurnScope,
|
|
1581
1594
|
recentOutputBuffer: this.recentOutputBuffer,
|
|
1582
1595
|
accumulatedBuffer: this.accumulatedBuffer,
|
|
1583
|
-
screenText,
|
|
1596
|
+
screenText: parseScreenText,
|
|
1584
1597
|
currentStatus: this.currentStatus,
|
|
1585
1598
|
activeModal: this.activeModal,
|
|
1586
1599
|
cliName: this.cliName,
|
|
@@ -1598,7 +1611,7 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1598
1611
|
accumulatedBuffer: this.accumulatedBuffer,
|
|
1599
1612
|
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
1600
1613
|
recentOutputBuffer: this.recentOutputBuffer,
|
|
1601
|
-
terminalScreenText: this.terminalScreen.getText(),
|
|
1614
|
+
terminalScreenText: this.getParseScreenText(this.terminalScreen.getText()),
|
|
1602
1615
|
baseMessages: [],
|
|
1603
1616
|
partialResponse: this.responseBuffer,
|
|
1604
1617
|
isWaitingForResponse: this.isWaitingForResponse,
|
|
@@ -149,6 +149,11 @@ function resolveAdhdevMcpEntryPath(explicitPath?: string): string | null {
|
|
|
149
149
|
addCandidate(resolve(dir, '../vendor/mcp-server/index.js'))
|
|
150
150
|
addCandidate(resolve(dir, '../../vendor/mcp-server/index.js'))
|
|
151
151
|
addCandidate(resolve(dir, '../../../vendor/mcp-server/index.js'))
|
|
152
|
+
// Source checkout/dev mode does not vendor the MCP server into daemon-standalone.
|
|
153
|
+
// Resolve the sibling workspace build directly so Repo Mesh auto-import still
|
|
154
|
+
// writes an absolute Node entrypoint instead of falling back to a PATH bin shim.
|
|
155
|
+
addCandidate(resolve(dir, '../../mcp-server/dist/index.js'))
|
|
156
|
+
addCandidate(resolve(dir, '../../../mcp-server/dist/index.js'))
|
|
152
157
|
}
|
|
153
158
|
|
|
154
159
|
addPackagedCandidates(process.argv[1])
|
package/src/commands/router.ts
CHANGED
|
@@ -38,6 +38,25 @@ import { buildSessionEntries } from '../status/builders.js';
|
|
|
38
38
|
import { buildMachineInfo, buildStatusSnapshot } from '../status/snapshot.js';
|
|
39
39
|
import { getSessionCompletionMarker } from '../status/snapshot.js';
|
|
40
40
|
import { execNpmCommandSync, resolveCurrentGlobalInstallSurface, spawnDetachedDaemonUpgradeHelper } from './upgrade-helper.js';
|
|
41
|
+
|
|
42
|
+
type ReleaseChannel = 'stable' | 'preview';
|
|
43
|
+
const CHANNEL_NPM_TAG: Record<ReleaseChannel, 'latest' | 'next'> = { stable: 'latest', preview: 'next' };
|
|
44
|
+
|
|
45
|
+
function normalizeReleaseChannel(value: unknown): ReleaseChannel | null {
|
|
46
|
+
if (typeof value !== 'string') return null;
|
|
47
|
+
const normalized = value.trim().toLowerCase();
|
|
48
|
+
if (normalized === 'stable' || normalized === 'latest') return 'stable';
|
|
49
|
+
if (normalized === 'preview' || normalized === 'next') return 'preview';
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function resolveUpgradeChannel(args: any): ReleaseChannel {
|
|
54
|
+
return normalizeReleaseChannel(args?.channel)
|
|
55
|
+
|| normalizeReleaseChannel(args?.updatePolicy?.channel)
|
|
56
|
+
|| normalizeReleaseChannel(args?.npmTag)
|
|
57
|
+
|| normalizeReleaseChannel(loadConfig().updateChannel)
|
|
58
|
+
|| 'stable';
|
|
59
|
+
}
|
|
41
60
|
import * as fs from 'fs';
|
|
42
61
|
|
|
43
62
|
// ─── Types ───
|
|
@@ -867,10 +886,12 @@ export class DaemonCommandRouter {
|
|
|
867
886
|
|| process.argv[1]?.includes('daemon-standalone');
|
|
868
887
|
const pkgName = isStandalone ? '@adhdev/daemon-standalone' : 'adhdev';
|
|
869
888
|
const npmSurface = resolveCurrentGlobalInstallSurface({ packageName: pkgName });
|
|
889
|
+
const channel = resolveUpgradeChannel(args);
|
|
890
|
+
const npmTag = CHANNEL_NPM_TAG[channel];
|
|
870
891
|
|
|
871
|
-
// Check
|
|
872
|
-
const latest = String(execNpmCommandSync(['view', pkgName
|
|
873
|
-
LOG.info('Upgrade', `Latest ${pkgName}: v${latest}`);
|
|
892
|
+
// Check channel-pinned dist-tag and resolve it to a concrete install version.
|
|
893
|
+
const latest = String(execNpmCommandSync(['view', `${pkgName}@${npmTag}`, 'version'], { encoding: 'utf-8', timeout: 10000 }, npmSurface)).trim();
|
|
894
|
+
LOG.info('Upgrade', `Latest ${pkgName}@${npmTag}: v${latest}`);
|
|
874
895
|
let currentInstalled: string | null = null;
|
|
875
896
|
try {
|
|
876
897
|
const currentJson = String(execNpmCommandSync(['ls', '-g', pkgName, '--depth=0', '--json'], {
|
|
@@ -888,8 +909,8 @@ export class DaemonCommandRouter {
|
|
|
888
909
|
? this.deps.statusVersion.trim().replace(/^v/, '')
|
|
889
910
|
: null;
|
|
890
911
|
if (currentInstalled === latest && runningVersion === latest) {
|
|
891
|
-
LOG.info('Upgrade', `Already on
|
|
892
|
-
return { success: true, upgraded: false, alreadyLatest: true, version: latest };
|
|
912
|
+
LOG.info('Upgrade', `Already on ${channel} channel version v${latest}; skipping install`);
|
|
913
|
+
return { success: true, upgraded: false, alreadyLatest: true, version: latest, channel, npmTag };
|
|
893
914
|
}
|
|
894
915
|
if (currentInstalled === latest && runningVersion && runningVersion !== latest) {
|
|
895
916
|
LOG.info('Upgrade', `Installed package is v${latest}, but running daemon is v${runningVersion}; scheduling restart`);
|
|
@@ -903,7 +924,7 @@ export class DaemonCommandRouter {
|
|
|
903
924
|
cwd: process.cwd(),
|
|
904
925
|
sessionHostAppName: process.env.ADHDEV_SESSION_HOST_NAME || 'adhdev',
|
|
905
926
|
});
|
|
906
|
-
LOG.info('Upgrade', `Scheduled detached upgrade to v${latest}`);
|
|
927
|
+
LOG.info('Upgrade', `Scheduled detached ${channel} upgrade to v${latest}`);
|
|
907
928
|
|
|
908
929
|
// Exit after the command response has been sent so the helper can replace the package cleanly.
|
|
909
930
|
setTimeout(() => {
|
|
@@ -911,7 +932,7 @@ export class DaemonCommandRouter {
|
|
|
911
932
|
process.exit(0);
|
|
912
933
|
}, 3000);
|
|
913
934
|
|
|
914
|
-
return { success: true, upgraded: true, version: latest, restarting: true };
|
|
935
|
+
return { success: true, upgraded: true, version: latest, restarting: true, channel, npmTag };
|
|
915
936
|
} catch (e: any) {
|
|
916
937
|
LOG.error('Upgrade', `Failed: ${e.message}`);
|
|
917
938
|
return { success: false, error: e.message };
|
|
@@ -1101,14 +1122,22 @@ export class DaemonCommandRouter {
|
|
|
1101
1122
|
}
|
|
1102
1123
|
|
|
1103
1124
|
// Merge ADHDev mesh server into existing config.
|
|
1125
|
+
// Pass full mesh data as env var so the MCP server can bootstrap
|
|
1126
|
+
// without depending on meshes.json or a running daemon.
|
|
1127
|
+
const mcpServerEntry: Record<string, any> = {
|
|
1128
|
+
command: coordinatorSetup.mcpServer.command,
|
|
1129
|
+
args: coordinatorSetup.mcpServer.args,
|
|
1130
|
+
};
|
|
1131
|
+
if (args?.inlineMesh) {
|
|
1132
|
+
mcpServerEntry.env = {
|
|
1133
|
+
ADHDEV_INLINE_MESH: JSON.stringify(mesh),
|
|
1134
|
+
};
|
|
1135
|
+
}
|
|
1104
1136
|
const mcpConfig = {
|
|
1105
1137
|
...existingMcpConfig,
|
|
1106
1138
|
mcpServers: {
|
|
1107
1139
|
...(existingMcpConfig.mcpServers || {}),
|
|
1108
|
-
[coordinatorSetup.serverName]:
|
|
1109
|
-
command: coordinatorSetup.mcpServer.command,
|
|
1110
|
-
args: coordinatorSetup.mcpServer.args,
|
|
1111
|
-
},
|
|
1140
|
+
[coordinatorSetup.serverName]: mcpServerEntry,
|
|
1112
1141
|
},
|
|
1113
1142
|
};
|
|
1114
1143
|
writeFileSync(mcpConfigPath, JSON.stringify(mcpConfig, null, 2), 'utf-8');
|
package/src/config/config.ts
CHANGED
|
@@ -15,6 +15,7 @@ export type { SavedProviderSessionEntry } from './saved-sessions.js';
|
|
|
15
15
|
export type { DaemonState } from './state-store.js';
|
|
16
16
|
|
|
17
17
|
export type ProviderSourceMode = 'normal' | 'no-upstream';
|
|
18
|
+
export type ReleaseChannel = 'stable' | 'preview';
|
|
18
19
|
|
|
19
20
|
export function resolveProviderSourceMode(
|
|
20
21
|
providerSourceMode: unknown,
|
|
@@ -122,6 +123,9 @@ export interface ADHDevConfig {
|
|
|
122
123
|
// Optional explicit provider override root (for example a local adhdev-providers checkout)
|
|
123
124
|
providerDir?: string;
|
|
124
125
|
|
|
126
|
+
/** Preferred daemon update channel. Defaults to stable/latest. */
|
|
127
|
+
updateChannel?: ReleaseChannel;
|
|
128
|
+
|
|
125
129
|
/**
|
|
126
130
|
* Browser terminal sizing behavior for dashboard CLI panes.
|
|
127
131
|
* Default `measured` keeps terminal size daemon-authoritative.
|
|
@@ -151,6 +155,7 @@ const DEFAULT_CONFIG: ADHDevConfig = {
|
|
|
151
155
|
machineProviders: {},
|
|
152
156
|
ideSettings: {},
|
|
153
157
|
providerSourceMode: 'normal',
|
|
158
|
+
updateChannel: 'stable',
|
|
154
159
|
terminalSizingMode: 'measured',
|
|
155
160
|
};
|
|
156
161
|
|
|
@@ -228,6 +233,7 @@ function normalizeConfig(raw: unknown): ADHDevConfig & { activeWorkspaceId?: str
|
|
|
228
233
|
ideSettings: isPlainObject(parsed.ideSettings) ? parsed.ideSettings : {},
|
|
229
234
|
providerSourceMode: resolveProviderSourceMode(parsed.providerSourceMode, parsed.disableUpstream),
|
|
230
235
|
providerDir: asOptionalString(parsed.providerDir),
|
|
236
|
+
updateChannel: parsed.updateChannel === 'preview' ? 'preview' : 'stable',
|
|
231
237
|
terminalSizingMode: parsed.terminalSizingMode === 'fit' ? 'fit' : 'measured',
|
|
232
238
|
};
|
|
233
239
|
}
|