kantban-cli 0.1.36 → 0.1.38

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/platform.ts"],"sourcesContent":["import { platform } from 'node:os';\nimport { execFileSync } from 'node:child_process';\nimport { readFileSync, existsSync } from 'node:fs';\nimport { join, dirname, delimiter } from 'node:path';\n\nexport const IS_WINDOWS = platform() === 'win32';\n\n/** Normalize line endings to Unix-style (\\n). Strips \\r\\n and bare \\r. */\nexport function normalizeEol(text: string): string {\n return text.replace(/\\r\\n|\\r/g, '\\n');\n}\n\n/** Returns [shellExecutable, argsPrefix] for running shell commands.\n * Unix: ['/bin/sh', ['-c']] Windows: [cmd.exe /c] or [pwsh -NoProfile -Command] */\nexport function shellArgs(): [string, string[]] {\n if (IS_WINDOWS) {\n const comspec = process.env.COMSPEC || 'cmd.exe';\n // Detect PowerShell — uses -Command instead of /c\n if (/pwsh|powershell/i.test(comspec)) {\n return [comspec, ['-NoProfile', '-Command']];\n }\n return [comspec, ['/c']];\n }\n return ['/bin/sh', ['-c']];\n}\n\n/** Returns spawn options with shell:true on Windows for .cmd/.bat resolution. */\nexport function crossSpawnOptions<T extends Record<string, unknown>>(opts?: T): T & { shell: boolean } {\n return { ...(opts ?? {} as T), shell: IS_WINDOWS } as T & { shell: boolean };\n}\n\n/** Kill a process and its children. On Unix, tries process group first.\n * On Windows, uses `taskkill /T` for tree kill. Never throws. */\nexport function killProcessTree(pid: number, signal: NodeJS.Signals = 'SIGTERM'): void {\n if (IS_WINDOWS) {\n // taskkill /T kills the process tree; /F forces termination\n try { execFileSync('taskkill', ['/pid', String(pid), '/t', '/f'], { stdio: 'pipe' }); return; } catch { /* fall through */ }\n try { process.kill(pid); } catch { /* already dead */ }\n return;\n }\n // Unix: try process group kill first\n try { process.kill(-pid, signal); return; } catch { /* fall through */ }\n try { process.kill(pid, signal); } catch { /* already dead */ }\n}\n\n/** Returns platform-appropriate npx command ('npx' on Unix, 'npx.cmd' on Windows). */\nexport function npxCommand(): string {\n return IS_WINDOWS ? 'npx.cmd' : 'npx';\n}\n\n/** Synchronously find a command on PATH, similar to `which.sync`.\n * On Windows, checks PATHEXT extensions (.COM, .EXE, .CMD, .BAT, etc.).\n * Returns the first match or throws if not found. */\nfunction whichSync(command: string): string {\n const pathEnv = process.env['PATH'] || process.env['Path'] || defaultPath();\n const dirs = pathEnv.split(delimiter);\n const extensions = IS_WINDOWS\n ? (process.env['PATHEXT'] || '.COM;.EXE;.BAT;.CMD').toLowerCase().split(';')\n : [''];\n\n for (const dir of dirs) {\n for (const ext of extensions) {\n const candidate = join(dir, command + ext);\n if (existsSync(candidate)) return candidate;\n // Also try with original casing on Windows (PATHEXT is case-insensitive)\n if (IS_WINDOWS) {\n const candidateUpper = join(dir, command + ext.toUpperCase());\n if (candidateUpper !== candidate && existsSync(candidateUpper)) return candidateUpper;\n }\n }\n }\n throw new Error(`not found: ${command}`);\n}\n\n/**\n * Resolve a CLI command to [executable, prefixArgs] for direct invocation\n * WITHOUT cmd.exe on Windows. This avoids the 8191-char command line limit\n * that cmd.exe imposes (CreateProcessW supports 32,767 chars).\n *\n * On Windows, npm-installed CLI tools are `.cmd` wrappers that invoke Node.js\n * with a specific script. This function parses the wrapper and returns\n * ['node', ['path/to/script.js', ...extraFlags]] so spawn() can call Node directly.\n *\n * On Unix (or if resolution fails), returns [command, []] unchanged.\n */\nexport function resolveCommand(command: string): [cmd: string, prefixArgs: string[]] {\n if (!IS_WINDOWS) return [command, []];\n\n try {\n // Find the command on PATH — inline implementation to avoid ESM/CJS\n // interop issues with the `which` package in bundled ESM context.\n const resolved = whichSync(command);\n\n // If it's an .exe, use it directly — no shell needed\n if (resolved.toLowerCase().endsWith('.exe')) return [resolved, []];\n\n // If it's a .cmd, parse out the node script invocation\n if (resolved.toLowerCase().endsWith('.cmd')) {\n const content = readFileSync(resolved, 'utf-8');\n // Match: \"%_prog%\" [optional-flags] \"%dp0%\\path\\to\\script.js\" %*\n // The .cmd files generated by npm have this exact pattern on the last non-empty line.\n for (const line of content.split(/\\r?\\n/)) {\n const m = line.match(/\"%_prog%\"\\s+(.*?)\"%dp0%\\\\(.+?)\"\\s+%[*]/);\n if (m) {\n const flags = m[1]!.trim().split(/\\s+/).filter(Boolean);\n const scriptPath = join(dirname(resolved), m[2]!);\n return [process.execPath, [...flags, scriptPath]];\n }\n }\n }\n } catch {\n // which not found, or parsing failed — fall through\n }\n\n // Fallback: use the command as-is (will need shell: true)\n return [command, []];\n}\n\n/** Returns platform-appropriate default PATH when process.env.PATH is undefined. */\nexport function defaultPath(): string {\n if (IS_WINDOWS) {\n return [\n process.env.SystemRoot ? `${process.env.SystemRoot}\\\\System32` : 'C:\\\\Windows\\\\System32',\n process.env.SystemRoot || 'C:\\\\Windows',\n 'C:\\\\Program Files\\\\nodejs',\n process.env.APPDATA ? `${process.env.APPDATA}\\\\npm` : '',\n ].filter(Boolean).join(';');\n }\n return '/usr/local/bin:/usr/bin:/bin';\n}\n"],"mappings":"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","names":[]}
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  normalizeEol,
6
6
  shellArgs
7
- } from "./chunk-4VT3TGJ5.js";
7
+ } from "./chunk-5ZU2OOES.js";
8
8
 
9
9
  // src/lib/gate-runner.ts
10
10
  import { execFile } from "child_process";
@@ -104,4 +104,4 @@ export {
104
104
  formatGateErrors,
105
105
  runGates
106
106
  };
107
- //# sourceMappingURL=chunk-GCDCGOWL.js.map
107
+ //# sourceMappingURL=chunk-MKKHLFA5.js.map
@@ -3,9 +3,9 @@ import {
3
3
  RalphLoop,
4
4
  cleanupMcpConfig,
5
5
  generateMcpConfig
6
- } from "./chunk-YFBFQAFI.js";
6
+ } from "./chunk-2CY5OPZN.js";
7
7
  import "./chunk-DAFLEMLK.js";
8
- import "./chunk-4VT3TGJ5.js";
8
+ import "./chunk-5ZU2OOES.js";
9
9
 
10
10
  // src/commands/cron.ts
11
11
  import { readFileSync } from "fs";
@@ -102,4 +102,4 @@ async function runCron(client, args) {
102
102
  export {
103
103
  runCron
104
104
  };
105
- //# sourceMappingURL=cron-HKGLRBVM.js.map
105
+ //# sourceMappingURL=cron-3R2UWFO7.js.map
package/dist/index.js CHANGED
@@ -25,22 +25,22 @@ async function main() {
25
25
  break;
26
26
  }
27
27
  case "work": {
28
- const { runWork } = await import("./work-RECDDPXT.js");
28
+ const { runWork } = await import("./work-45GILGKD.js");
29
29
  await runWork(client, args);
30
30
  break;
31
31
  }
32
32
  case "pipeline": {
33
33
  if (args[0] === "stop") {
34
- const { stopPipeline } = await import("./pipeline-N7Z43P6P.js");
34
+ const { stopPipeline } = await import("./pipeline-IAKINX5A.js");
35
35
  await stopPipeline(args.slice(1));
36
36
  } else {
37
- const { runPipeline } = await import("./pipeline-N7Z43P6P.js");
37
+ const { runPipeline } = await import("./pipeline-IAKINX5A.js");
38
38
  await runPipeline(client, args);
39
39
  }
40
40
  break;
41
41
  }
42
42
  case "cron": {
43
- const { runCron } = await import("./cron-HKGLRBVM.js");
43
+ const { runCron } = await import("./cron-3R2UWFO7.js");
44
44
  await runCron(client, args);
45
45
  break;
46
46
  }
@@ -5,13 +5,13 @@ import {
5
5
  import {
6
6
  formatGateErrors,
7
7
  runGates
8
- } from "../chunk-GCDCGOWL.js";
8
+ } from "../chunk-MKKHLFA5.js";
9
9
  import {
10
10
  parseGateConfig,
11
11
  parseTimeout,
12
12
  resolveGatesForColumn
13
13
  } from "../chunk-DAFLEMLK.js";
14
- import "../chunk-4VT3TGJ5.js";
14
+ import "../chunk-5ZU2OOES.js";
15
15
 
16
16
  // src/lib/gate-proxy-server.ts
17
17
  import { readFileSync } from "fs";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runGates
3
- } from "./chunk-GCDCGOWL.js";
3
+ } from "./chunk-MKKHLFA5.js";
4
4
  import {
5
5
  ClaudeProvider,
6
6
  RalphLoop,
@@ -12,7 +12,7 @@ import {
12
12
  generateMcpConfig,
13
13
  parseJsonFromLlmOutput,
14
14
  parseStuckDetectionResponse
15
- } from "./chunk-YFBFQAFI.js";
15
+ } from "./chunk-2CY5OPZN.js";
16
16
  import {
17
17
  LoopCheckpointSchema,
18
18
  VerdictSchema,
@@ -24,8 +24,9 @@ import {
24
24
  IS_WINDOWS,
25
25
  crossSpawnOptions,
26
26
  killProcessTree,
27
- normalizeEol
28
- } from "./chunk-4VT3TGJ5.js";
27
+ normalizeEol,
28
+ resolveCommand
29
+ } from "./chunk-5ZU2OOES.js";
29
30
 
30
31
  // src/commands/pipeline.ts
31
32
  import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync4, readFileSync as readFileSync3, unlinkSync as unlinkSync3, existsSync as existsSync3, appendFileSync as appendFileSync2 } from "fs";
@@ -3341,10 +3342,12 @@ var CodexProvider = class {
3341
3342
  }
3342
3343
  }
3343
3344
  return new Promise((resolve) => {
3344
- const child = spawn2("codex", args, {
3345
+ const [cmd, prefixArgs] = resolveCommand("codex");
3346
+ const resolvedArgs = [...prefixArgs, ...args];
3347
+ const child = spawn2(cmd, resolvedArgs, {
3345
3348
  stdio: ["ignore", "pipe", "pipe"],
3346
3349
  env: { ...process.env, ...env },
3347
- ...crossSpawnOptions()
3350
+ ...prefixArgs.length > 0 ? {} : crossSpawnOptions()
3348
3351
  });
3349
3352
  const parser = new CodexJsonlParser();
3350
3353
  parser.onEvent = (event) => request.onStreamEvent?.(event);
@@ -3714,10 +3717,12 @@ var GeminiProvider = class _GeminiProvider {
3714
3717
  this.copySettingsToDir(settingsDir, request.workingDirectory);
3715
3718
  }
3716
3719
  return new Promise((resolve) => {
3717
- const child = spawn3("gemini", args, {
3720
+ const [cmd, prefixArgs] = resolveCommand("gemini");
3721
+ const resolvedArgs = [...prefixArgs, ...args];
3722
+ const child = spawn3(cmd, resolvedArgs, {
3718
3723
  stdio: ["pipe", "pipe", "pipe"],
3719
3724
  cwd: cwd || void 0,
3720
- ...crossSpawnOptions()
3725
+ ...prefixArgs.length > 0 ? {} : crossSpawnOptions()
3721
3726
  });
3722
3727
  const parser = new GeminiJsonlParser();
3723
3728
  parser.onEvent = (event) => request.onStreamEvent?.(event);
@@ -4209,8 +4214,8 @@ async function runPipeline(client, args) {
4209
4214
  }
4210
4215
  const mcpConfigPath = generateMcpConfig(client.baseUrl, client.token, opts.boardId);
4211
4216
  const boardProviderConfig = {
4212
- default_provider: opts.provider ?? void 0,
4213
- intelligence_provider: opts.provider ?? void 0
4217
+ ...opts.provider ? { default_provider: opts.provider } : {},
4218
+ ...opts.provider ? { intelligence_provider: opts.provider } : {}
4214
4219
  };
4215
4220
  const intelligenceProvider = registry.resolveForIntelligence(boardProviderConfig);
4216
4221
  const logBaseDir = join3(homedir2(), ".kantban", "pipelines");
@@ -4891,4 +4896,4 @@ export {
4891
4896
  runPipeline,
4892
4897
  stopPipeline
4893
4898
  };
4894
- //# sourceMappingURL=pipeline-N7Z43P6P.js.map
4899
+ //# sourceMappingURL=pipeline-IAKINX5A.js.map