@adhdev/daemon-core 0.6.68 → 0.6.70
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.d.ts +50 -9
- package/dist/index.js +178 -59
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/src/agent-stream/forward.ts +29 -0
- package/src/cli-adapters/provider-cli-adapter.ts +34 -3
- package/src/config/config.ts +51 -16
- package/src/index.ts +3 -1
- package/src/status/reporter.ts +18 -48
- package/src/status/snapshot.ts +123 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adhdev/daemon-core",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.70",
|
|
4
4
|
"description": "ADHDev daemon core — CDP, IDE detection, providers, command execution",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
"@xterm/xterm": "^6.0.0",
|
|
35
35
|
"chalk": "^5.3.0",
|
|
36
36
|
"conf": "^13.0.0",
|
|
37
|
+
"node-pty": "^1.1.0",
|
|
37
38
|
"ws": "^8.19.0"
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helper for forwarding agent stream snapshots into the IDE instance.
|
|
3
|
+
*
|
|
4
|
+
* Both cloud and standalone daemons use the same InstanceManager wiring.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export function forwardAgentStreamsToIdeInstance(
|
|
8
|
+
instanceManager: { getInstance: (key: string) => any },
|
|
9
|
+
ideType: string,
|
|
10
|
+
streams: any[],
|
|
11
|
+
): void {
|
|
12
|
+
const ideInstance = instanceManager.getInstance(`ide:${ideType}`) as
|
|
13
|
+
| { onEvent?: (event: string, payload: Record<string, unknown>) => void }
|
|
14
|
+
| undefined;
|
|
15
|
+
|
|
16
|
+
if (!ideInstance?.onEvent) return;
|
|
17
|
+
|
|
18
|
+
for (const stream of streams) {
|
|
19
|
+
ideInstance.onEvent('stream_update', {
|
|
20
|
+
extensionType: stream.agentType,
|
|
21
|
+
streams: [stream],
|
|
22
|
+
messages: stream.messages || [],
|
|
23
|
+
status: stream.status || 'idle',
|
|
24
|
+
activeModal: stream.activeModal || null,
|
|
25
|
+
model: stream.model || undefined,
|
|
26
|
+
mode: stream.mode || undefined,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -654,6 +654,8 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
654
654
|
/Quick safety check/i,
|
|
655
655
|
/Is this a project/i,
|
|
656
656
|
/Enter to confirm/i,
|
|
657
|
+
/be able to read, edit, and execute/i,
|
|
658
|
+
/Security guide/i,
|
|
657
659
|
];
|
|
658
660
|
if (dialogPatterns.some(p => p.test(this.startupBuffer))) {
|
|
659
661
|
setTimeout(() => this.ptyProcess?.write('\r'), this.timeouts.dialogAccept);
|
|
@@ -721,17 +723,46 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
721
723
|
}
|
|
722
724
|
|
|
723
725
|
private evaluateSettled(): void {
|
|
724
|
-
|
|
725
|
-
if (this.responseSettleIgnoreUntil >
|
|
726
|
+
const now = Date.now();
|
|
727
|
+
if (this.submitPendingUntil > now || this.responseSettleIgnoreUntil > now) {
|
|
728
|
+
const delayTime = Math.max(this.submitPendingUntil - now, this.responseSettleIgnoreUntil - now) + 50;
|
|
729
|
+
if (this.settleTimer) clearTimeout(this.settleTimer);
|
|
730
|
+
this.settleTimer = setTimeout(() => {
|
|
731
|
+
this.settleTimer = null;
|
|
732
|
+
this.settledBuffer = this.recentOutputBuffer;
|
|
733
|
+
this.evaluateSettled();
|
|
734
|
+
}, delayTime);
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
726
737
|
const tail = this.settledBuffer;
|
|
727
738
|
const modal = this.runParseApproval(tail);
|
|
728
739
|
const rawScriptStatus = this.runDetectStatus(tail);
|
|
729
|
-
|
|
740
|
+
// detectStatus is the sole authority for status. parseApproval only enriches modal info.
|
|
741
|
+
const scriptStatus = rawScriptStatus;
|
|
730
742
|
if (!scriptStatus) return;
|
|
731
743
|
|
|
732
744
|
const prevStatus = this.currentStatus;
|
|
733
745
|
|
|
734
746
|
if (scriptStatus === 'waiting_approval') {
|
|
747
|
+
// Auto-accept startup safety dialogs (e.g., "Claude Code'll be able to read, edit, and execute")
|
|
748
|
+
const modalMessage = modal?.message || '';
|
|
749
|
+
const screenText = this.terminalScreen.getText() || this.accumulatedBuffer;
|
|
750
|
+
const autoAcceptPatterns = [
|
|
751
|
+
/be able to read, edit, and execute/i,
|
|
752
|
+
/Security guide/i,
|
|
753
|
+
/Enter to confirm/i,
|
|
754
|
+
/Quick safety check/i,
|
|
755
|
+
/Do you trust the files/i,
|
|
756
|
+
/Is this a project/i,
|
|
757
|
+
];
|
|
758
|
+
if (autoAcceptPatterns.some(p => p.test(modalMessage) || p.test(screenText))) {
|
|
759
|
+
LOG.info('CLI', `[${this.cliType}] Auto-accepting startup dialog: ${modalMessage.slice(0, 80)}`);
|
|
760
|
+
setTimeout(() => this.ptyProcess?.write('\r'), 200);
|
|
761
|
+
this.lastApprovalResolvedAt = Date.now();
|
|
762
|
+
this.activeModal = null;
|
|
763
|
+
return;
|
|
764
|
+
}
|
|
765
|
+
|
|
735
766
|
const inCooldown = this.lastApprovalResolvedAt && (Date.now() - this.lastApprovalResolvedAt) < this.timeouts.approvalCooldown;
|
|
736
767
|
if (!inCooldown) {
|
|
737
768
|
this.isWaitingForResponse = true;
|
package/src/config/config.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import { homedir } from 'os';
|
|
8
8
|
import { join } from 'path';
|
|
9
9
|
import { existsSync, mkdirSync, readFileSync, writeFileSync, chmodSync } from 'fs';
|
|
10
|
+
import { randomUUID } from 'crypto';
|
|
10
11
|
import { migrateWorkspacesFromRecent } from './workspaces.js';
|
|
11
12
|
import type { WorkspaceEntry } from './workspaces.js';
|
|
12
13
|
import type { WorkspaceActivityEntry } from './workspace-activity.js';
|
|
@@ -64,12 +65,15 @@ export interface ADHDevConfig {
|
|
|
64
65
|
// Machine nickname (user-customizable label for this machine)
|
|
65
66
|
machineNickname: string | null;
|
|
66
67
|
|
|
67
|
-
// Stable machine ID
|
|
68
|
+
// Stable local machine ID shared by standalone and cloud daemon modes
|
|
68
69
|
machineId?: string;
|
|
69
70
|
|
|
70
71
|
// Machine secret for server auth (replaces connectionToken)
|
|
71
72
|
machineSecret?: string | null;
|
|
72
73
|
|
|
74
|
+
// Account-scoped registered machine row ID (cloud-side)
|
|
75
|
+
registeredMachineId?: string;
|
|
76
|
+
|
|
73
77
|
// CLI launch history
|
|
74
78
|
cliHistory: CliHistoryEntry[];
|
|
75
79
|
|
|
@@ -123,12 +127,44 @@ const DEFAULT_CONFIG: ADHDevConfig = {
|
|
|
123
127
|
machineNickname: null,
|
|
124
128
|
machineId: undefined,
|
|
125
129
|
machineSecret: null,
|
|
130
|
+
registeredMachineId: undefined,
|
|
126
131
|
cliHistory: [],
|
|
127
132
|
providerSettings: {},
|
|
128
133
|
ideSettings: {},
|
|
129
134
|
disableUpstream: false,
|
|
130
135
|
};
|
|
131
136
|
|
|
137
|
+
const MACHINE_ID_PREFIX = 'mach_';
|
|
138
|
+
|
|
139
|
+
export function generateMachineId(): string {
|
|
140
|
+
return `${MACHINE_ID_PREFIX}${randomUUID().replace(/-/g, '')}`;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export function isStableMachineId(machineId?: string | null): boolean {
|
|
144
|
+
return typeof machineId === 'string' && machineId.startsWith(MACHINE_ID_PREFIX);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function ensureMachineId(config: ADHDevConfig): { config: ADHDevConfig; changed: boolean } {
|
|
148
|
+
if (isStableMachineId(config.machineId)) {
|
|
149
|
+
return { config, changed: false };
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// TODO(2026-04-06): Remove this legacy bridge after cloud clients have had
|
|
153
|
+
// time to persist registeredMachineId from the upgraded setup/login flow.
|
|
154
|
+
const legacyRegisteredMachineId = (!config.registeredMachineId && config.machineSecret && config.machineId)
|
|
155
|
+
? config.machineId
|
|
156
|
+
: config.registeredMachineId;
|
|
157
|
+
|
|
158
|
+
return {
|
|
159
|
+
config: {
|
|
160
|
+
...config,
|
|
161
|
+
machineId: generateMachineId(),
|
|
162
|
+
registeredMachineId: legacyRegisteredMachineId,
|
|
163
|
+
},
|
|
164
|
+
changed: true,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
132
168
|
/**
|
|
133
169
|
* Get the config directory path
|
|
134
170
|
*/
|
|
@@ -154,7 +190,11 @@ export function loadConfig(): ADHDevConfig {
|
|
|
154
190
|
const configPath = getConfigPath();
|
|
155
191
|
|
|
156
192
|
if (!existsSync(configPath)) {
|
|
157
|
-
|
|
193
|
+
const initialized = ensureMachineId({ ...DEFAULT_CONFIG });
|
|
194
|
+
try {
|
|
195
|
+
saveConfig(initialized.config);
|
|
196
|
+
} catch { /* ignore */ }
|
|
197
|
+
return initialized.config;
|
|
158
198
|
}
|
|
159
199
|
|
|
160
200
|
try {
|
|
@@ -166,30 +206,25 @@ export function loadConfig(): ADHDevConfig {
|
|
|
166
206
|
}
|
|
167
207
|
delete (merged as any).activeWorkspaceId;
|
|
168
208
|
const hadStoredWorkspaces = Array.isArray(parsed.workspaces) && parsed.workspaces.length > 0;
|
|
169
|
-
|
|
209
|
+
const ensured = ensureMachineId(merged);
|
|
210
|
+
const normalized = ensured.config as ADHDevConfig & { activeWorkspaceId?: string | null };
|
|
211
|
+
migrateWorkspacesFromRecent(normalized);
|
|
170
212
|
|
|
171
|
-
let configChanged =
|
|
172
|
-
if (!merged.machineId) {
|
|
173
|
-
const os = require('os');
|
|
174
|
-
const crypto = require('crypto');
|
|
175
|
-
const safeHostname = os.hostname().replace(/[^a-zA-Z0-9]/g, '_');
|
|
176
|
-
const machineHash = crypto.createHash('md5').update(os.hostname() + os.homedir()).digest('hex').slice(0, 8);
|
|
177
|
-
merged.machineId = `${safeHostname}_${machineHash}`;
|
|
178
|
-
configChanged = true;
|
|
179
|
-
}
|
|
213
|
+
let configChanged = ensured.changed;
|
|
180
214
|
|
|
181
|
-
if (!hadStoredWorkspaces && (
|
|
215
|
+
if (!hadStoredWorkspaces && (normalized.workspaces?.length || 0) > 0) {
|
|
182
216
|
configChanged = true;
|
|
183
217
|
}
|
|
184
218
|
|
|
185
219
|
if (configChanged) {
|
|
186
220
|
try {
|
|
187
|
-
saveConfig(
|
|
221
|
+
saveConfig(normalized);
|
|
188
222
|
} catch { /* ignore */ }
|
|
189
223
|
}
|
|
190
|
-
return
|
|
224
|
+
return normalized;
|
|
191
225
|
} catch {
|
|
192
|
-
|
|
226
|
+
const initialized = ensureMachineId({ ...DEFAULT_CONFIG });
|
|
227
|
+
return initialized.config;
|
|
193
228
|
}
|
|
194
229
|
}
|
|
195
230
|
|
package/src/index.ts
CHANGED
|
@@ -75,6 +75,8 @@ export type { CommandRouterDeps, CommandRouterResult } from './commands/router.j
|
|
|
75
75
|
// ── Status ──
|
|
76
76
|
export { DaemonStatusReporter } from './status/reporter.js';
|
|
77
77
|
export { buildManagedIdes, buildManagedClis, buildManagedAcps, buildAllManagedEntries, findCdpManager, hasCdpManager, isCdpConnected } from './status/builders.js';
|
|
78
|
+
export { buildStatusSnapshot } from './status/snapshot.js';
|
|
79
|
+
export type { StatusSnapshotOptions, StatusSnapshot } from './status/snapshot.js';
|
|
78
80
|
|
|
79
81
|
// ── Logger ──
|
|
80
82
|
export { LOG, installGlobalInterceptor, setLogLevel, getLogLevel, getRecentLogs } from './logging/logger.js';
|
|
@@ -97,6 +99,7 @@ export { readChatHistory } from './config/chat-history.js';
|
|
|
97
99
|
export { DaemonAgentStreamManager } from './agent-stream/index.js';
|
|
98
100
|
export { AgentStreamPoller } from './agent-stream/index.js';
|
|
99
101
|
export type { AgentStreamPollerDeps } from './agent-stream/index.js';
|
|
102
|
+
export { forwardAgentStreamsToIdeInstance } from './agent-stream/forward.js';
|
|
100
103
|
|
|
101
104
|
// ── Providers ──
|
|
102
105
|
export { ProviderLoader } from './providers/provider-loader.js';
|
|
@@ -122,4 +125,3 @@ export type { ExtensionInfo as InstallerExtensionInfo } from './installer.js';
|
|
|
122
125
|
// ── Boot / Lifecycle ──
|
|
123
126
|
export { initDaemonComponents, shutdownDaemonComponents } from './boot/daemon-lifecycle.js';
|
|
124
127
|
export type { DaemonInitConfig, DaemonComponents } from './boot/daemon-lifecycle.js';
|
|
125
|
-
|
package/src/status/reporter.ts
CHANGED
|
@@ -5,14 +5,9 @@
|
|
|
5
5
|
* Each Instance manages its own status/transition. This module only assembles + transmits.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import * as os from 'os';
|
|
9
|
-
import * as path from 'path';
|
|
10
|
-
import { loadConfig } from '../config/config.js';
|
|
11
|
-
import { getWorkspaceState } from '../config/workspaces.js';
|
|
12
|
-
import { getHostMemorySnapshot } from '../system/host-memory.js';
|
|
13
|
-
import { getWorkspaceActivity } from '../config/workspace-activity.js';
|
|
14
8
|
import { LOG } from '../logging/logger.js';
|
|
15
9
|
import { buildAllManagedEntries } from './builders.js';
|
|
10
|
+
import { buildStatusSnapshot } from './snapshot.js';
|
|
16
11
|
import type {
|
|
17
12
|
ProviderState,
|
|
18
13
|
IdeProviderState,
|
|
@@ -27,9 +22,8 @@ export interface StatusReporterDeps {
|
|
|
27
22
|
cdpManagers: Map<string, { isConnected: boolean }>;
|
|
28
23
|
p2p: { isConnected: boolean; isAvailable: boolean; connectionState: string; connectedPeerCount: number; screenshotActive: boolean; sendStatus(data: any): void } | null;
|
|
29
24
|
providerLoader: { resolve(type: string): any; getAll(): any[] };
|
|
30
|
-
adapters: Map<string, { cliType: string; cliName: string; workingDir: string; getStatus(): any; getPartialResponse(): string }>;
|
|
31
25
|
detectedIdes: any[];
|
|
32
|
-
|
|
26
|
+
instanceId: string;
|
|
33
27
|
daemonVersion?: string;
|
|
34
28
|
instanceManager: { collectAllStates(): ProviderState[]; collectStatesByCategory(cat: string): ProviderState[] };
|
|
35
29
|
getScreenshotUsage?: () => { dailyUsedMinutes: number; dailyBudgetMinutes: number; budgetExhausted: boolean } | null;
|
|
@@ -163,50 +157,26 @@ export class DaemonStatusReporter {
|
|
|
163
157
|
this.deps.cdpManagers as Map<string, any>,
|
|
164
158
|
);
|
|
165
159
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
const cfg = loadConfig();
|
|
171
|
-
const wsState = getWorkspaceState(cfg);
|
|
172
|
-
const memSnap = getHostMemorySnapshot();
|
|
173
|
-
|
|
174
160
|
// ═══ Assemble payload (P2P — required data only) ═══
|
|
175
161
|
const payload: Record<string, any> = {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
},
|
|
193
|
-
managedIdes,
|
|
194
|
-
managedClis,
|
|
195
|
-
managedAcps,
|
|
196
|
-
p2p: {
|
|
197
|
-
available: p2p?.isAvailable || false,
|
|
198
|
-
state: p2p?.connectionState || 'unavailable',
|
|
199
|
-
peers: p2p?.connectedPeerCount || 0,
|
|
200
|
-
screenshotActive: p2p?.screenshotActive || false,
|
|
201
|
-
},
|
|
162
|
+
...buildStatusSnapshot({
|
|
163
|
+
allStates,
|
|
164
|
+
cdpManagers: this.deps.cdpManagers as Map<string, unknown>,
|
|
165
|
+
providerLoader: this.deps.providerLoader,
|
|
166
|
+
detectedIdes: this.deps.detectedIdes || [],
|
|
167
|
+
instanceId: this.deps.instanceId,
|
|
168
|
+
version: this.deps.daemonVersion || 'unknown',
|
|
169
|
+
daemonMode: true,
|
|
170
|
+
timestamp: now,
|
|
171
|
+
p2p: {
|
|
172
|
+
available: p2p?.isAvailable || false,
|
|
173
|
+
state: p2p?.connectionState || 'unavailable',
|
|
174
|
+
peers: p2p?.connectedPeerCount || 0,
|
|
175
|
+
screenshotActive: p2p?.screenshotActive || false,
|
|
176
|
+
},
|
|
177
|
+
}),
|
|
202
178
|
screenshotUsage: this.deps.getScreenshotUsage?.() || null,
|
|
203
179
|
connectedExtensions: [],
|
|
204
|
-
detectedIdes: this.deps.detectedIdes || [],
|
|
205
|
-
availableProviders: this.deps.providerLoader.getAll().map((p: any) => ({
|
|
206
|
-
type: p.type, icon: p.icon || '💻', displayName: p.displayName || p.type,
|
|
207
|
-
category: p.category,
|
|
208
|
-
})),
|
|
209
|
-
timestamp: now,
|
|
210
180
|
};
|
|
211
181
|
|
|
212
182
|
// ═══ P2P transmit ═══
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared status snapshot builders.
|
|
3
|
+
*
|
|
4
|
+
* Used by:
|
|
5
|
+
* - DaemonStatusReporter (cloud)
|
|
6
|
+
* - daemon-standalone HTTP/WS status responses
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import * as os from 'os';
|
|
10
|
+
import { loadConfig } from '../config/config.js';
|
|
11
|
+
import { getWorkspaceState } from '../config/workspaces.js';
|
|
12
|
+
import { getWorkspaceActivity } from '../config/workspace-activity.js';
|
|
13
|
+
import { getHostMemorySnapshot } from '../system/host-memory.js';
|
|
14
|
+
import { buildAllManagedEntries, isCdpConnected } from './builders.js';
|
|
15
|
+
import type { ProviderState } from '../providers/provider-instance.js';
|
|
16
|
+
import type {
|
|
17
|
+
AvailableProviderInfo,
|
|
18
|
+
DetectedIdeInfo,
|
|
19
|
+
StatusReportPayload,
|
|
20
|
+
} from '../shared-types.js';
|
|
21
|
+
|
|
22
|
+
export interface StatusSnapshotOptions {
|
|
23
|
+
allStates: ProviderState[];
|
|
24
|
+
cdpManagers: Map<string, unknown>;
|
|
25
|
+
providerLoader: {
|
|
26
|
+
getAll(): Array<{
|
|
27
|
+
type: string;
|
|
28
|
+
icon?: string;
|
|
29
|
+
displayName?: string;
|
|
30
|
+
category: 'ide' | 'extension' | 'cli' | 'acp';
|
|
31
|
+
}>;
|
|
32
|
+
};
|
|
33
|
+
detectedIdes: Array<{
|
|
34
|
+
id: string;
|
|
35
|
+
name?: string;
|
|
36
|
+
displayName?: string;
|
|
37
|
+
installed?: boolean;
|
|
38
|
+
path?: string;
|
|
39
|
+
}>;
|
|
40
|
+
instanceId: string;
|
|
41
|
+
version: string;
|
|
42
|
+
daemonMode: boolean;
|
|
43
|
+
timestamp?: number;
|
|
44
|
+
p2p?: StatusReportPayload['p2p'];
|
|
45
|
+
machineNickname?: string | null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface StatusSnapshot extends StatusReportPayload {
|
|
49
|
+
availableProviders: AvailableProviderInfo[];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function buildDetectedIdeInfos(
|
|
53
|
+
detectedIdes: StatusSnapshotOptions['detectedIdes'],
|
|
54
|
+
cdpManagers: StatusSnapshotOptions['cdpManagers'],
|
|
55
|
+
): DetectedIdeInfo[] {
|
|
56
|
+
return detectedIdes
|
|
57
|
+
.filter((ide) => ide.installed !== false)
|
|
58
|
+
.map((ide) => ({
|
|
59
|
+
id: ide.id,
|
|
60
|
+
type: ide.id,
|
|
61
|
+
name: ide.displayName || ide.name || ide.id,
|
|
62
|
+
running: isCdpConnected(cdpManagers as Map<string, any>, ide.id),
|
|
63
|
+
...(ide.path ? { path: ide.path } : {}),
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function buildAvailableProviders(
|
|
68
|
+
providerLoader: StatusSnapshotOptions['providerLoader'],
|
|
69
|
+
): AvailableProviderInfo[] {
|
|
70
|
+
return providerLoader.getAll().map((provider) => ({
|
|
71
|
+
type: provider.type,
|
|
72
|
+
name: provider.displayName || provider.type,
|
|
73
|
+
displayName: provider.displayName || provider.type,
|
|
74
|
+
icon: provider.icon || '💻',
|
|
75
|
+
category: provider.category,
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function buildStatusSnapshot(options: StatusSnapshotOptions): StatusSnapshot {
|
|
80
|
+
const cfg = loadConfig();
|
|
81
|
+
const wsState = getWorkspaceState(cfg);
|
|
82
|
+
const memSnap = getHostMemorySnapshot();
|
|
83
|
+
const { managedIdes, managedClis, managedAcps } = buildAllManagedEntries(
|
|
84
|
+
options.allStates,
|
|
85
|
+
options.cdpManagers as Map<string, any>,
|
|
86
|
+
{
|
|
87
|
+
detectedIdes: options.detectedIdes.map((ide) => ({
|
|
88
|
+
id: ide.id,
|
|
89
|
+
installed: ide.installed !== false,
|
|
90
|
+
})),
|
|
91
|
+
},
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
instanceId: options.instanceId,
|
|
96
|
+
version: options.version,
|
|
97
|
+
daemonMode: options.daemonMode,
|
|
98
|
+
machine: {
|
|
99
|
+
hostname: os.hostname(),
|
|
100
|
+
platform: os.platform(),
|
|
101
|
+
arch: os.arch(),
|
|
102
|
+
cpus: os.cpus().length,
|
|
103
|
+
totalMem: memSnap.totalMem,
|
|
104
|
+
freeMem: memSnap.freeMem,
|
|
105
|
+
availableMem: memSnap.availableMem,
|
|
106
|
+
loadavg: os.loadavg(),
|
|
107
|
+
uptime: os.uptime(),
|
|
108
|
+
release: os.release(),
|
|
109
|
+
},
|
|
110
|
+
machineNickname: options.machineNickname ?? cfg.machineNickname ?? null,
|
|
111
|
+
timestamp: options.timestamp ?? Date.now(),
|
|
112
|
+
detectedIdes: buildDetectedIdeInfos(options.detectedIdes, options.cdpManagers),
|
|
113
|
+
...(options.p2p ? { p2p: options.p2p } : {}),
|
|
114
|
+
managedIdes,
|
|
115
|
+
managedClis,
|
|
116
|
+
managedAcps,
|
|
117
|
+
workspaces: wsState.workspaces,
|
|
118
|
+
defaultWorkspaceId: wsState.defaultWorkspaceId,
|
|
119
|
+
defaultWorkspacePath: wsState.defaultWorkspacePath,
|
|
120
|
+
workspaceActivity: getWorkspaceActivity(cfg, 15),
|
|
121
|
+
availableProviders: buildAvailableProviders(options.providerLoader),
|
|
122
|
+
};
|
|
123
|
+
}
|