@adhdev/daemon-core 0.9.47 → 0.9.48

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.
@@ -5,4 +5,5 @@ export declare function parseCliScriptResult(result: unknown): {
5
5
  export declare function getCliScriptCommand(payload: any): {
6
6
  type: string;
7
7
  text?: string;
8
+ enterCount?: number;
8
9
  } | null;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhdev/session-host-core",
3
- "version": "0.9.47",
3
+ "version": "0.9.48",
4
4
  "description": "ADHDev local session host core \u2014 session registry, protocol, buffers",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhdev/daemon-core",
3
- "version": "0.9.47",
3
+ "version": "0.9.48",
4
4
  "description": "ADHDev daemon core \u2014 CDP, IDE detection, providers, command execution",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -343,7 +343,12 @@ async function executeProviderScript(h: CommandHelpers, args: any, scriptName: s
343
343
  if (cliCommand?.type === 'send_message' && cliCommand.text) {
344
344
  await adapter.sendMessage(cliCommand.text);
345
345
  } else if (cliCommand?.type === 'pty_write' && cliCommand.text && adapter.writeRaw) {
346
+ const enterCount = cliCommand.enterCount || 1;
346
347
  await adapter.writeRaw(cliCommand.text + '\r');
348
+ for (let i = 1; i < enterCount; i += 1) {
349
+ await new Promise(resolve => setTimeout(resolve, 50));
350
+ await adapter.writeRaw('\r');
351
+ }
347
352
  }
348
353
  applyProviderPatch(h, args, parsed.payload);
349
354
  return {
@@ -6,5 +6,31 @@ export interface DaemonUpgradeHelperPayload {
6
6
  cwd?: string;
7
7
  sessionHostAppName?: string;
8
8
  }
9
+ export interface CurrentGlobalInstallSurface {
10
+ npmExecutable: string;
11
+ npmArgsPrefix?: string[];
12
+ packageRoot: string | null;
13
+ installPrefix: string | null;
14
+ execOptions?: { shell: boolean };
15
+ }
16
+ export interface PinnedGlobalInstallCommand {
17
+ command: string;
18
+ args: string[];
19
+ surface: CurrentGlobalInstallSurface;
20
+ execOptions: { shell: boolean };
21
+ }
22
+ export declare function resolveCurrentGlobalInstallSurface(options: {
23
+ packageName: string;
24
+ currentCliPath?: string;
25
+ nodeExecutable?: string;
26
+ platform?: NodeJS.Platform;
27
+ }): CurrentGlobalInstallSurface;
28
+ export declare function buildPinnedGlobalInstallCommand(options: {
29
+ packageName: string;
30
+ targetVersion: string;
31
+ currentCliPath?: string;
32
+ nodeExecutable?: string;
33
+ platform?: NodeJS.Platform;
34
+ }): PinnedGlobalInstallCommand;
9
35
  export declare function spawnDetachedDaemonUpgradeHelper(payload: DaemonUpgradeHelperPayload): void;
10
36
  export declare function maybeRunDaemonUpgradeHelperFromEnv(): Promise<boolean>;
@@ -17,14 +17,17 @@ export interface DaemonUpgradeHelperPayload {
17
17
 
18
18
  export interface CurrentGlobalInstallSurface {
19
19
  npmExecutable: string;
20
+ npmArgsPrefix?: string[];
20
21
  packageRoot: string | null;
21
22
  installPrefix: string | null;
23
+ execOptions?: { shell: boolean };
22
24
  }
23
25
 
24
26
  export interface PinnedGlobalInstallCommand {
25
27
  command: string;
26
28
  args: string[];
27
29
  surface: CurrentGlobalInstallSurface;
30
+ execOptions: { shell: boolean };
28
31
  }
29
32
 
30
33
  function getUpgradeLogPath(): string {
@@ -43,18 +46,32 @@ function appendUpgradeLog(message: string): void {
43
46
  }
44
47
  }
45
48
 
46
- function resolveSiblingNpmExecutable(nodeExecutable: string): string {
49
+ function resolveSiblingNpmInvocation(nodeExecutable: string, platform: NodeJS.Platform = process.platform): {
50
+ executable: string;
51
+ argsPrefix: string[];
52
+ execOptions: { shell: boolean };
53
+ } {
47
54
  const binDir = path.dirname(nodeExecutable);
48
- const candidates = process.platform === 'win32'
49
- ? ['npm.cmd', 'npm.exe', 'npm']
50
- : ['npm'];
51
- for (const candidate of candidates) {
55
+ if (platform === 'win32') {
56
+ const npmCliPath = path.join(binDir, 'node_modules', 'npm', 'bin', 'npm-cli.js');
57
+ if (fs.existsSync(npmCliPath)) {
58
+ return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: { shell: false } };
59
+ }
60
+ for (const candidate of ['npm.exe', 'npm']) {
61
+ const candidatePath = path.join(binDir, candidate);
62
+ if (fs.existsSync(candidatePath)) {
63
+ return { executable: candidatePath, argsPrefix: [], execOptions: { shell: false } };
64
+ }
65
+ }
66
+ return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: { shell: false } };
67
+ }
68
+ for (const candidate of ['npm']) {
52
69
  const candidatePath = path.join(binDir, candidate);
53
70
  if (fs.existsSync(candidatePath)) {
54
- return candidatePath;
71
+ return { executable: candidatePath, argsPrefix: [], execOptions: { shell: false } };
55
72
  }
56
73
  }
57
- return 'npm';
74
+ return { executable: 'npm', argsPrefix: [], execOptions: { shell: false } };
58
75
  }
59
76
 
60
77
  function findCurrentPackageRoot(currentCliPath: string | undefined, packageName: string): string | null {
@@ -117,12 +134,16 @@ export function resolveCurrentGlobalInstallSurface(options: {
117
134
  packageName: string;
118
135
  currentCliPath?: string;
119
136
  nodeExecutable?: string;
137
+ platform?: NodeJS.Platform;
120
138
  }): CurrentGlobalInstallSurface {
121
139
  const packageRoot = findCurrentPackageRoot(options.currentCliPath || process.argv[1], options.packageName);
140
+ const npmInvocation = resolveSiblingNpmInvocation(options.nodeExecutable || process.execPath, options.platform);
122
141
  return {
123
- npmExecutable: resolveSiblingNpmExecutable(options.nodeExecutable || process.execPath),
142
+ npmExecutable: npmInvocation.executable,
143
+ npmArgsPrefix: npmInvocation.argsPrefix,
124
144
  packageRoot,
125
145
  installPrefix: packageRoot ? resolveInstallPrefixFromPackageRoot(packageRoot, options.packageName) : null,
146
+ execOptions: npmInvocation.execOptions,
126
147
  };
127
148
  }
128
149
 
@@ -131,9 +152,10 @@ export function buildPinnedGlobalInstallCommand(options: {
131
152
  targetVersion: string;
132
153
  currentCliPath?: string;
133
154
  nodeExecutable?: string;
155
+ platform?: NodeJS.Platform;
134
156
  }): PinnedGlobalInstallCommand {
135
157
  const surface = resolveCurrentGlobalInstallSurface(options);
136
- const args = ['install', '-g', `${options.packageName}@${options.targetVersion || 'latest'}`, '--force'];
158
+ const args = [...(surface.npmArgsPrefix || []), 'install', '-g', `${options.packageName}@${options.targetVersion || 'latest'}`, '--force'];
137
159
  if (surface.installPrefix) {
138
160
  args.push('--prefix', surface.installPrefix);
139
161
  }
@@ -141,11 +163,12 @@ export function buildPinnedGlobalInstallCommand(options: {
141
163
  command: surface.npmExecutable,
142
164
  args,
143
165
  surface,
166
+ execOptions: surface.execOptions || getNpmExecOptions(options.platform),
144
167
  };
145
168
  }
146
169
 
147
- function getNpmExecOptions(): { shell: boolean } {
148
- return { shell: process.platform === 'win32' };
170
+ function getNpmExecOptions(_platform: NodeJS.Platform = process.platform): { shell: boolean } {
171
+ return { shell: false };
149
172
  }
150
173
 
151
174
  function killPid(pid: number): boolean {
@@ -249,12 +272,11 @@ function removeDaemonPidFile(): void {
249
272
  }
250
273
 
251
274
  function cleanupStaleGlobalInstallDirs(pkgName: string, surface: CurrentGlobalInstallSurface): void {
252
- const npmExecOpts = getNpmExecOptions();
253
275
  const prefixArgs = surface.installPrefix ? ['--prefix', surface.installPrefix] : [];
254
- const npmRoot = execFileSync(surface.npmExecutable, ['root', '-g', ...prefixArgs], { encoding: 'utf8', ...npmExecOpts }).trim();
276
+ const npmRoot = execFileSync(surface.npmExecutable, [...(surface.npmArgsPrefix || []), 'root', '-g', ...prefixArgs], { encoding: 'utf8', ...surface.execOptions }).trim();
255
277
  if (!npmRoot) return;
256
278
  const npmPrefix = surface.installPrefix
257
- || execFileSync(surface.npmExecutable, ['prefix', '-g', ...prefixArgs], { encoding: 'utf8', ...npmExecOpts }).trim();
279
+ || execFileSync(surface.npmExecutable, [...(surface.npmArgsPrefix || []), 'prefix', '-g', ...prefixArgs], { encoding: 'utf8', ...surface.execOptions }).trim();
258
280
  const binDir = process.platform === 'win32' ? npmPrefix : path.join(npmPrefix, 'bin');
259
281
  const packageBaseName = pkgName.startsWith('@') ? pkgName.split('/')[1] : pkgName;
260
282
  const binNames = new Set<string>([packageBaseName]);
@@ -331,7 +353,7 @@ async function runDaemonUpgradeHelper(payload: DaemonUpgradeHelperPayload): Prom
331
353
  encoding: 'utf8',
332
354
  stdio: 'pipe',
333
355
  maxBuffer: 20 * 1024 * 1024,
334
- ...getNpmExecOptions(),
356
+ ...installCommand.execOptions,
335
357
  },
336
358
  );
337
359
  if (installOutput.trim()) {
@@ -601,7 +601,12 @@ export class CliProviderInstance implements ProviderInstance {
601
601
  if (cliCommand?.type === 'send_message' && cliCommand.text) {
602
602
  await this.adapter.sendMessage(cliCommand.text);
603
603
  } else if (cliCommand?.type === 'pty_write' && cliCommand.text) {
604
+ const enterCount = cliCommand.enterCount || 1;
604
605
  await this.adapter.writeRaw(cliCommand.text + '\r');
606
+ for (let i = 1; i < enterCount; i += 1) {
607
+ await new Promise(resolve => setTimeout(resolve, 50));
608
+ await this.adapter.writeRaw('\r');
609
+ }
605
610
  }
606
611
 
607
612
  this.applyProviderResponse(parsed.payload, { phase: 'immediate' });
@@ -18,7 +18,7 @@ export function parseCliScriptResult(result: unknown): { success: boolean; paylo
18
18
  return { success: true, payload: result }
19
19
  }
20
20
 
21
- export function getCliScriptCommand(payload: any): { type: string; text?: string } | null {
21
+ export function getCliScriptCommand(payload: any): { type: string; text?: string; enterCount?: number } | null {
22
22
  if (!payload || typeof payload !== 'object') return null
23
23
 
24
24
  if (typeof payload.sendMessage === 'string' && payload.sendMessage.trim()) {
@@ -35,5 +35,8 @@ export function getCliScriptCommand(payload: any): { type: string; text?: string
35
35
  ? command.message.trim()
36
36
  : ''
37
37
  if (!text) return null
38
- return { type: command.type, text }
38
+ const enterCount = Number.isInteger(command.enterCount) && command.enterCount > 0 && command.enterCount <= 5
39
+ ? command.enterCount
40
+ : undefined
41
+ return { type: command.type, text, ...(enterCount ? { enterCount } : {}) }
39
42
  }