@adhdev/daemon-core 0.7.20 → 0.7.22

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhdev/daemon-core",
3
- "version": "0.7.20",
3
+ "version": "0.7.22",
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",
@@ -228,6 +228,9 @@ function looksLikeMachOOrElf(filePath: string): boolean {
228
228
 
229
229
  function shSingleQuote(arg: string): string {
230
230
  if (/^[a-zA-Z0-9@%_+=:,./-]+$/.test(arg)) return arg;
231
+ if (os.platform() === 'win32') {
232
+ return `"${arg.replace(/"/g, '""')}"`;
233
+ }
231
234
  return `'${arg.replace(/'/g, `'\\''`)}'`;
232
235
  }
233
236
 
@@ -322,22 +322,25 @@ export async function handleAutoImplement(ctx: DevServerContext, type: string, r
322
322
 
323
323
  // 6. Construct the complete shell command per-agent
324
324
  let shellCmd: string;
325
+ const isWin = os.platform() === 'win32';
326
+ const escapeArg = (a: string) => isWin ? `"${a.replace(/"/g, '""')}"` : `'${a.replace(/'/g, "'\\''")}'`;
325
327
 
326
328
  if (command === 'claude') {
327
329
  // Claude Code: autonomous agent mode (no --print), skip permissions, prompt via meta-prompt
328
330
  const args = [...baseArgs, '--dangerously-skip-permissions'];
329
331
  if (model) args.push('--model', model);
330
- const escapedArgs = args.map(a => `'${a.replace(/'/g, "'\\''")}'`).join(' ');
332
+ const escapedArgs = args.map(escapeArg).join(' ');
331
333
  const metaPrompt = `Read the file at ${promptFile} and follow ALL the instructions. Implement the specific function requested, then test it via CDP curl targeting 127.0.0.1:19280, wait for confirmation of success, and then close. DO NOT start working on other features not listed in the prompt constraint.`;
332
- shellCmd = `${command} ${escapedArgs} -p "${metaPrompt}"`;
334
+ shellCmd = `${command} ${escapedArgs} -p ${escapeArg(metaPrompt)}`;
333
335
  } else if (command === 'gemini') {
334
336
  // Gemini CLI: non-interactive prompt mode
335
337
  // We can't use @file syntax (causes Parts object parsing bug) or $(cat) (arg too long).
336
338
  // Solution: meta-prompt that tells Gemini to read the instructions file itself.
337
339
  const args = [...baseArgs, '-y', '-s', 'false'];
338
340
  if (model) args.push('-m', model);
339
- const escapedArgs = args.map(a => `'${a.replace(/'/g, "'\\''")}'`).join(' ');
340
- shellCmd = `${command} ${escapedArgs} -p "Read the file at ${promptFile} and follow ALL the instructions in it exactly. Do not ask questions, just execute."`;
341
+ const escapedArgs = args.map(escapeArg).join(' ');
342
+ const metaPrompt = `Read the file at ${promptFile} and follow ALL the instructions in it exactly. Do not ask questions, just execute.`;
343
+ shellCmd = `${command} ${escapedArgs} -p ${escapeArg(metaPrompt)}`;
341
344
 
342
345
  } else if (command === 'codex') {
343
346
  const args = ['exec', ...baseArgs];
@@ -348,13 +351,17 @@ export async function handleAutoImplement(ctx: DevServerContext, type: string, r
348
351
  args.push('--skip-git-repo-check');
349
352
  }
350
353
  if (model) args.push('--model', model);
351
- const escapedArgs = args.map(a => `'${a.replace(/'/g, "'\\''")}'`).join(' ');
354
+ const escapedArgs = args.map(escapeArg).join(' ');
352
355
  const metaPrompt = `Read the file at ${promptFile} and follow ALL instructions strictly. DO NOT spend time exploring the filesystem or other providers. You have full authority to implement ALL required script files and independently test them against 127.0.0.1:19280 via CDP CURL. Upon complete validation of ALL assigned files, print exactly "_PIPELINE_COMPLETE_SIGNAL_" to gracefully close the pipeline. DO NOT WAIT FOR APPROVAL, execute completely autonomously.`;
353
- shellCmd = `${command} ${escapedArgs} "${metaPrompt}"`;
356
+ shellCmd = `${command} ${escapedArgs} ${escapeArg(metaPrompt)}`;
354
357
  } else {
355
358
  // Generic fallback: pipe prompt via stdin
356
- const escapedArgs = baseArgs.map(a => `'${a.replace(/'/g, "'\\''")}'`).join(' ');
357
- shellCmd = `cat '${promptFile}' | ${command} ${escapedArgs}`;
359
+ const escapedArgs = baseArgs.map(escapeArg).join(' ');
360
+ if (isWin) {
361
+ shellCmd = `type "${promptFile}" | ${command} ${escapedArgs}`;
362
+ } else {
363
+ shellCmd = `cat '${promptFile}' | ${command} ${escapedArgs}`;
364
+ }
358
365
  }
359
366
 
360
367
  sendAutoImplSSE(ctx, { event: 'progress', data: { function: '_init', status: 'spawning', message: `Spawning agent: ${shellCmd.substring(0, 200)}... (prompt: ${prompt.length} chars)` } });
@@ -380,7 +387,7 @@ export async function handleAutoImplement(ctx: DevServerContext, type: string, r
380
387
  isPty = true;
381
388
  } catch (err: any) {
382
389
  ctx.log(`PTY not available, using child_process: ${err.message}`);
383
- child = spawnFn('sh', ['-c', shellCmd], {
390
+ child = spawnFn(isWin ? 'cmd.exe' : 'sh', [isWin ? '/c' : '-c', shellCmd], {
384
391
  cwd: providerDir,
385
392
  shell: false,
386
393
  timeout: 900000,
@@ -15,9 +15,11 @@ import * as path from 'path';
15
15
  import * as os from 'os';
16
16
 
17
17
  // ─── Config ──────────────────────────────────
18
- const LOG_DIR = process.platform === 'darwin'
19
- ? path.join(os.homedir(), 'Library', 'Logs', 'adhdev')
20
- : path.join(os.homedir(), '.local', 'share', 'adhdev', 'logs');
18
+ const LOG_DIR = process.platform === 'win32'
19
+ ? path.join(process.env.LOCALAPPDATA || process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Local'), 'adhdev', 'logs')
20
+ : process.platform === 'darwin'
21
+ ? path.join(os.homedir(), 'Library', 'Logs', 'adhdev')
22
+ : path.join(os.homedir(), '.local', 'share', 'adhdev', 'logs');
21
23
 
22
24
  const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
23
25
  const MAX_DAYS = 7;
@@ -36,9 +36,11 @@ export function setLogLevel(level: LogLevel): void {
36
36
 
37
37
  export function getLogLevel(): LogLevel { return currentLevel; }
38
38
  // ─── File logging (date-based rolling) ──────────────────────────────
39
- const LOG_DIR = process.platform === 'darwin'
40
- ? path.join(os.homedir(), 'Library', 'Logs', 'adhdev')
41
- : path.join(os.homedir(), '.local', 'share', 'adhdev', 'logs');
39
+ const LOG_DIR = process.platform === 'win32'
40
+ ? path.join(process.env.LOCALAPPDATA || process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Local'), 'adhdev', 'logs')
41
+ : process.platform === 'darwin'
42
+ ? path.join(os.homedir(), 'Library', 'Logs', 'adhdev')
43
+ : path.join(os.homedir(), '.local', 'share', 'adhdev', 'logs');
42
44
 
43
45
  const MAX_LOG_SIZE = 5 * 1024 * 1024; // 5MB per day
44
46
  const MAX_LOG_DAYS = 7; // 7-day retention