@adhdev/daemon-core 0.6.69 → 0.6.71
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 +1 -0
- package/dist/index.js +73 -20
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/src/cli-adapters/provider-cli-adapter.ts +34 -3
- package/src/config/config.ts +51 -16
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adhdev/daemon-core",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.71",
|
|
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": {
|
|
@@ -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
|
|