@nuucognition/flint-cli 0.5.6-dev.1 → 0.5.6-dev.3

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.
Files changed (2) hide show
  1. package/dist/index.js +208 -98
  2. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -403,9 +403,9 @@ var require_brace_expansion = __commonJS({
403
403
 
404
404
  // src/index.ts
405
405
  import { Command as Command38 } from "commander";
406
- import { readFileSync as readFileSync11, existsSync as existsSync15, cpSync, mkdirSync as mkdirSync5, readdirSync as readdirSync8 } from "fs";
406
+ import { readFileSync as readFileSync12, existsSync as existsSync16, cpSync, mkdirSync as mkdirSync5, readdirSync as readdirSync8 } from "fs";
407
407
  import { fileURLToPath as fileURLToPath4 } from "url";
408
- import { dirname as dirname4, join as join20 } from "path";
408
+ import { dirname as dirname5, join as join20 } from "path";
409
409
  import { homedir as homedir11 } from "os";
410
410
  import pc43 from "picocolors";
411
411
 
@@ -5851,10 +5851,10 @@ function sendNotification(title, message) {
5851
5851
  }
5852
5852
  }
5853
5853
 
5854
- const child = spawn('claude', claudeArgs, {
5854
+ const agentCmd = resolveCommand('claude');
5855
+ const child = spawn(agentCmd.cmd, [...agentCmd.prependArgs, ...claudeArgs], {
5855
5856
  cwd: flintPath,
5856
5857
  stdio: ['ignore', 'ignore', 'pipe'],
5857
- shell: process.platform === 'win32',
5858
5858
  });
5859
5859
 
5860
5860
  let stderr = '';
@@ -8299,24 +8299,26 @@ import { randomUUID as randomUUID2 } from "crypto";
8299
8299
  import { existsSync as existsSync22, readFileSync as readFileSync22 } from "fs";
8300
8300
  import { closeSync, existsSync as existsSync32, openSync, readSync, statSync, unwatchFile, watch, watchFile } from "fs";
8301
8301
  import { existsSync as existsSync42, readFileSync as readFileSync3, unwatchFile as unwatchFile2, watch as watch2, watchFile as watchFile2 } from "fs";
8302
- import { existsSync as existsSync52 } from "fs";
8303
- import { join as join22 } from "path";
8304
- import { homedir as homedir5 } from "os";
8305
- import { spawnSync as spawnSync3 } from "child_process";
8306
- import { readdirSync as readdirSync2, readFileSync as readFileSync4 } from "fs";
8307
8302
  import { existsSync as existsSync6 } from "fs";
8308
8303
  import { join as join32 } from "path";
8304
+ import { homedir as homedir5 } from "os";
8305
+ import { spawnSync as spawnSync3 } from "child_process";
8306
+ import { appendFileSync, existsSync as existsSync52, mkdirSync as mkdirSync22, readFileSync as readFileSync4 } from "fs";
8307
+ import { dirname as dirname3, join as join22 } from "path";
8308
+ import { readdirSync as readdirSync2, readFileSync as readFileSync5 } from "fs";
8309
+ import { existsSync as existsSync7 } from "fs";
8310
+ import { join as join42 } from "path";
8309
8311
  import { homedir as homedir22 } from "os";
8310
- import { existsSync as existsSync7, readdirSync as readdirSync3, readFileSync as readFileSync5, statSync as statSync2 } from "fs";
8311
- import { basename as basename4, join as join42 } from "path";
8312
+ import { existsSync as existsSync8, readdirSync as readdirSync3, readFileSync as readFileSync6, statSync as statSync2 } from "fs";
8313
+ import { basename as basename4, join as join52 } from "path";
8312
8314
  import { homedir as homedir32 } from "os";
8313
- import { existsSync as existsSync8, readdirSync as readdirSync4, readFileSync as readFileSync6, statSync as statSync3 } from "fs";
8315
+ import { existsSync as existsSync9, readdirSync as readdirSync4, readFileSync as readFileSync7, statSync as statSync3 } from "fs";
8314
8316
  import { spawnSync as spawnSync22 } from "child_process";
8315
8317
  import { homedir as homedir42 } from "os";
8316
- import { basename as basename22, join as join52 } from "path";
8318
+ import { basename as basename22, join as join62 } from "path";
8317
8319
  import { spawn as spawn4, spawnSync as spawnSync32 } from "child_process";
8318
- import { existsSync as existsSync9, readdirSync as readdirSync5, readFileSync as readFileSync7 } from "fs";
8319
- import { join as join62 } from "path";
8320
+ import { existsSync as existsSync10, readdirSync as readdirSync5, readFileSync as readFileSync8 } from "fs";
8321
+ import { join as join72 } from "path";
8320
8322
  import { homedir as homedir52 } from "os";
8321
8323
  var RUN_TRANSITIONS = {
8322
8324
  running: ["completed", "failed", "cancelled", "suspended"],
@@ -10213,14 +10215,68 @@ var JsonSessionWatcher = class {
10213
10215
  function createJsonSessionWatcher(transcriptPath, mapper, options) {
10214
10216
  return new JsonSessionWatcher(transcriptPath, mapper, options);
10215
10217
  }
10218
+ function debugLog(message) {
10219
+ if (process.platform !== "win32") return;
10220
+ try {
10221
+ const root = process.env.FLINT_ROOT || process.cwd();
10222
+ const logDir = join22(root, ".flint");
10223
+ mkdirSync22(logDir, { recursive: true });
10224
+ const ts = (/* @__PURE__ */ new Date()).toISOString();
10225
+ appendFileSync(join22(logDir, "orbh-debug.log"), `[${ts}] ${message}
10226
+ `);
10227
+ } catch {
10228
+ }
10229
+ }
10216
10230
  function isCommandOnPath(name) {
10217
10231
  const cmd = process.platform === "win32" ? "where" : "which";
10218
- return spawnSync3(cmd, [name], { stdio: "ignore" }).status === 0;
10232
+ const result = spawnSync3(cmd, [name], { stdio: "ignore" });
10233
+ debugLog(`isCommandOnPath(${name}): ${cmd} \u2192 exit ${result.status}`);
10234
+ return result.status === 0;
10235
+ }
10236
+ function resolveCommand(name) {
10237
+ if (process.platform !== "win32") return { cmd: name, prependArgs: [] };
10238
+ debugLog(`resolveCommand(${name}): starting`);
10239
+ const where = spawnSync3("where", [name], { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] });
10240
+ debugLog(`resolveCommand(${name}): where exit=${where.status}, stdout=${JSON.stringify(where.stdout ?? "")}`);
10241
+ const firstLine = (where.stdout ?? "").trim().split(/\r?\n/)[0]?.trim();
10242
+ if (where.status !== 0 || !firstLine) {
10243
+ debugLog(`resolveCommand(${name}): where failed \u2014 returning bare name`);
10244
+ return { cmd: name, prependArgs: [] };
10245
+ }
10246
+ const resolved = firstLine;
10247
+ debugLog(`resolveCommand(${name}): resolved path = ${resolved}`);
10248
+ if (!resolved.toLowerCase().endsWith(".cmd")) {
10249
+ debugLog(`resolveCommand(${name}): not .cmd \u2014 using resolved path directly`);
10250
+ return { cmd: resolved, prependArgs: [] };
10251
+ }
10252
+ try {
10253
+ const content = readFileSync4(resolved, "utf-8");
10254
+ debugLog(`resolveCommand(${name}): .cmd content (${content.length} chars):
10255
+ ${content}`);
10256
+ const matches = [...content.matchAll(/%(?:~dp0|dp0%)\\([^"%\r\n]+\.m?[jc]?[jt]s)/gi)];
10257
+ debugLog(`resolveCommand(${name}): regex matches = ${JSON.stringify(matches.map((m) => m[0]))}`);
10258
+ const last = matches.length > 0 ? matches[matches.length - 1] : void 0;
10259
+ if (last && last[1]) {
10260
+ const scriptPath = join22(dirname3(resolved), last[1]);
10261
+ const scriptExists = existsSync52(scriptPath);
10262
+ debugLog(`resolveCommand(${name}): script path = ${scriptPath}, exists = ${scriptExists}`);
10263
+ if (scriptExists) {
10264
+ const result = { cmd: process.execPath, prependArgs: [scriptPath] };
10265
+ debugLog(`resolveCommand(${name}): SUCCESS \u2192 ${result.cmd} ${result.prependArgs.join(" ")}`);
10266
+ return result;
10267
+ }
10268
+ } else {
10269
+ debugLog(`resolveCommand(${name}): no regex match found in .cmd content`);
10270
+ }
10271
+ } catch (err) {
10272
+ debugLog(`resolveCommand(${name}): error parsing .cmd: ${err}`);
10273
+ }
10274
+ debugLog(`resolveCommand(${name}): FALLBACK \u2192 using resolved path ${resolved}`);
10275
+ return { cmd: resolved, prependArgs: [] };
10219
10276
  }
10220
- var SPAWN_SHELL = process.platform === "win32";
10221
10277
  function buildTranscriptPath(cwd, nativeSessionId) {
10222
10278
  const sanitized = cwd.replace(/[^a-zA-Z0-9\-_]/g, "-");
10223
- return join22(homedir5(), ".claude", "projects", sanitized, `${nativeSessionId}.jsonl`);
10279
+ return join32(homedir5(), ".claude", "projects", sanitized, `${nativeSessionId}.jsonl`);
10224
10280
  }
10225
10281
  function createClaudeHarness() {
10226
10282
  return {
@@ -10268,7 +10324,7 @@ function createClaudeHarness() {
10268
10324
  },
10269
10325
  resolveTranscriptPath(nativeSessionId, cwd) {
10270
10326
  const candidate = buildTranscriptPath(cwd, nativeSessionId);
10271
- if (existsSync52(candidate)) {
10327
+ if (existsSync6(candidate)) {
10272
10328
  return candidate;
10273
10329
  }
10274
10330
  return null;
@@ -10288,7 +10344,7 @@ function createClaudeHarness() {
10288
10344
  };
10289
10345
  }
10290
10346
  function listDateDirectories(root) {
10291
- if (!existsSync6(root)) {
10347
+ if (!existsSync7(root)) {
10292
10348
  return [];
10293
10349
  }
10294
10350
  const directories = [];
@@ -10296,15 +10352,15 @@ function listDateDirectories(root) {
10296
10352
  if (!year.isDirectory()) {
10297
10353
  continue;
10298
10354
  }
10299
- const yearPath = join32(root, year.name);
10355
+ const yearPath = join42(root, year.name);
10300
10356
  for (const month of readdirSync2(yearPath, { withFileTypes: true })) {
10301
10357
  if (!month.isDirectory()) {
10302
10358
  continue;
10303
10359
  }
10304
- const monthPath = join32(yearPath, month.name);
10360
+ const monthPath = join42(yearPath, month.name);
10305
10361
  for (const day of readdirSync2(monthPath, { withFileTypes: true })) {
10306
10362
  if (day.isDirectory()) {
10307
- directories.push(join32(monthPath, day.name));
10363
+ directories.push(join42(monthPath, day.name));
10308
10364
  }
10309
10365
  }
10310
10366
  }
@@ -10312,11 +10368,11 @@ function listDateDirectories(root) {
10312
10368
  return directories.sort((left, right) => right.localeCompare(left));
10313
10369
  }
10314
10370
  function resolveCodexSessionIndex(root, nativeSessionId) {
10315
- const indexPath = join32(root, "session_index.jsonl");
10316
- if (!existsSync6(indexPath)) {
10371
+ const indexPath = join42(root, "session_index.jsonl");
10372
+ if (!existsSync7(indexPath)) {
10317
10373
  return null;
10318
10374
  }
10319
- const lines = readFileSync4(indexPath, "utf-8").split("\n");
10375
+ const lines = readFileSync5(indexPath, "utf-8").split("\n");
10320
10376
  for (const line of lines) {
10321
10377
  const trimmed = line.trim();
10322
10378
  if (trimmed.length === 0) {
@@ -10368,7 +10424,7 @@ function createCodexHarness() {
10368
10424
  return args;
10369
10425
  },
10370
10426
  resolveTranscriptPath(nativeSessionId) {
10371
- const sessionsRoot = join32(homedir22(), ".codex", "sessions");
10427
+ const sessionsRoot = join42(homedir22(), ".codex", "sessions");
10372
10428
  const indexedPath = resolveCodexSessionIndex(sessionsRoot, nativeSessionId);
10373
10429
  if (indexedPath) {
10374
10430
  return indexedPath;
@@ -10376,7 +10432,7 @@ function createCodexHarness() {
10376
10432
  for (const directory of listDateDirectories(sessionsRoot)) {
10377
10433
  for (const entry of readdirSync2(directory)) {
10378
10434
  if (entry.includes(nativeSessionId) && entry.endsWith(".jsonl")) {
10379
- return join32(directory, entry);
10435
+ return join42(directory, entry);
10380
10436
  }
10381
10437
  }
10382
10438
  }
@@ -10402,13 +10458,13 @@ function sanitizeFactoryCwd(cwd) {
10402
10458
  return cwd.replace(/[\\/]/g, "-");
10403
10459
  }
10404
10460
  function buildScopedTranscriptPath(cwd, nativeSessionId) {
10405
- return join42(homedir32(), ".factory", "sessions", sanitizeFactoryCwd(cwd), `${nativeSessionId}.jsonl`);
10461
+ return join52(homedir32(), ".factory", "sessions", sanitizeFactoryCwd(cwd), `${nativeSessionId}.jsonl`);
10406
10462
  }
10407
10463
  function buildLegacyTranscriptPath(nativeSessionId) {
10408
- return join42(homedir32(), ".factory", "sessions", `${nativeSessionId}.jsonl`);
10464
+ return join52(homedir32(), ".factory", "sessions", `${nativeSessionId}.jsonl`);
10409
10465
  }
10410
10466
  function getDroidSessionsRoot() {
10411
- return join42(homedir32(), ".factory", "sessions");
10467
+ return join52(homedir32(), ".factory", "sessions");
10412
10468
  }
10413
10469
  function parseStartedAtMs(startedAt) {
10414
10470
  if (typeof startedAt === "number" && Number.isFinite(startedAt)) {
@@ -10433,7 +10489,7 @@ function isTranscriptRecentEnough(transcriptPath, startedAt) {
10433
10489
  }
10434
10490
  function readDroidSessionId(transcriptPath) {
10435
10491
  try {
10436
- const firstLine = readFileSync5(transcriptPath, "utf-8").split(/\r?\n/, 1)[0]?.trim();
10492
+ const firstLine = readFileSync6(transcriptPath, "utf-8").split(/\r?\n/, 1)[0]?.trim();
10437
10493
  if (!firstLine) {
10438
10494
  return basename4(transcriptPath, ".jsonl");
10439
10495
  }
@@ -10446,10 +10502,10 @@ function readDroidSessionId(transcriptPath) {
10446
10502
  return basename4(transcriptPath, ".jsonl");
10447
10503
  }
10448
10504
  function listDroidTranscriptPaths(cwd) {
10449
- const candidateDirs = [join42(getDroidSessionsRoot(), sanitizeFactoryCwd(cwd)), getDroidSessionsRoot()];
10505
+ const candidateDirs = [join52(getDroidSessionsRoot(), sanitizeFactoryCwd(cwd)), getDroidSessionsRoot()];
10450
10506
  const transcriptPaths = /* @__PURE__ */ new Map();
10451
10507
  for (const directory of candidateDirs) {
10452
- if (!existsSync7(directory)) {
10508
+ if (!existsSync8(directory)) {
10453
10509
  continue;
10454
10510
  }
10455
10511
  try {
@@ -10457,7 +10513,7 @@ function listDroidTranscriptPaths(cwd) {
10457
10513
  if (!entry.isFile() || !entry.name.endsWith(".jsonl")) {
10458
10514
  continue;
10459
10515
  }
10460
- const transcriptPath = join42(directory, entry.name);
10516
+ const transcriptPath = join52(directory, entry.name);
10461
10517
  transcriptPaths.set(transcriptPath, statSync2(transcriptPath).mtimeMs);
10462
10518
  }
10463
10519
  } catch {
@@ -10473,7 +10529,7 @@ function discoverDroidNativeSessionByOrbhSessionId(cwd, orbhSessionId, options)
10473
10529
  continue;
10474
10530
  }
10475
10531
  try {
10476
- const content = readFileSync5(transcriptPath, "utf-8");
10532
+ const content = readFileSync6(transcriptPath, "utf-8");
10477
10533
  if (!content.includes(orbhSessionId)) {
10478
10534
  continue;
10479
10535
  }
@@ -10536,11 +10592,11 @@ function createDroidHarness() {
10536
10592
  },
10537
10593
  resolveTranscriptPath(nativeSessionId, cwd) {
10538
10594
  const scopedPath = buildScopedTranscriptPath(cwd, nativeSessionId);
10539
- if (existsSync7(scopedPath)) {
10595
+ if (existsSync8(scopedPath)) {
10540
10596
  return scopedPath;
10541
10597
  }
10542
10598
  const legacyPath = buildLegacyTranscriptPath(nativeSessionId);
10543
- if (existsSync7(legacyPath)) {
10599
+ if (existsSync8(legacyPath)) {
10544
10600
  return legacyPath;
10545
10601
  }
10546
10602
  return scopedPath;
@@ -10566,24 +10622,24 @@ function slugifyProjectName(name) {
10566
10622
  return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
10567
10623
  }
10568
10624
  function getGeminiTmpRoot() {
10569
- return join52(homedir42(), ".gemini", "tmp");
10625
+ return join62(homedir42(), ".gemini", "tmp");
10570
10626
  }
10571
10627
  function getProjectSlug(cwd) {
10572
10628
  return slugifyProjectName(basename22(cwd));
10573
10629
  }
10574
10630
  function getGeminiChatsDir(cwd) {
10575
- return join52(getGeminiTmpRoot(), getProjectSlug(cwd), "chats");
10631
+ return join62(getGeminiTmpRoot(), getProjectSlug(cwd), "chats");
10576
10632
  }
10577
10633
  function listGeminiTranscriptPaths(cwd) {
10578
10634
  const chatsDir = getGeminiChatsDir(cwd);
10579
- if (!existsSync8(chatsDir)) {
10635
+ if (!existsSync9(chatsDir)) {
10580
10636
  return [];
10581
10637
  }
10582
- return readdirSync4(chatsDir).filter((entry) => entry.startsWith("session-") && entry.endsWith(".json")).map((entry) => join52(chatsDir, entry)).sort((left, right) => right.localeCompare(left));
10638
+ return readdirSync4(chatsDir).filter((entry) => entry.startsWith("session-") && entry.endsWith(".json")).map((entry) => join62(chatsDir, entry)).sort((left, right) => right.localeCompare(left));
10583
10639
  }
10584
10640
  function readGeminiSessionId(transcriptPath) {
10585
10641
  try {
10586
- const parsed = JSON.parse(readFileSync6(transcriptPath, "utf-8"));
10642
+ const parsed = JSON.parse(readFileSync7(transcriptPath, "utf-8"));
10587
10643
  return typeof parsed.sessionId === "string" ? parsed.sessionId : null;
10588
10644
  } catch {
10589
10645
  return null;
@@ -10661,7 +10717,7 @@ function discoverGeminiNativeSessionByOrbhSessionId(cwd, orbhSessionId, options)
10661
10717
  continue;
10662
10718
  }
10663
10719
  try {
10664
- const content = readFileSync6(transcriptPath, "utf-8");
10720
+ const content = readFileSync7(transcriptPath, "utf-8");
10665
10721
  if (!content.includes(orbhSessionId)) {
10666
10722
  continue;
10667
10723
  }
@@ -10778,7 +10834,7 @@ function buildHarnessSpawnEnv(cwd, sessionId, baseEnv = process.env) {
10778
10834
  delete env.CODEX_THREAD_ID;
10779
10835
  delete env.CODEX_CI;
10780
10836
  delete env.CODEX_SESSION_ID;
10781
- const localBin = join62(homedir52(), ".local", "bin");
10837
+ const localBin = join72(homedir52(), ".local", "bin");
10782
10838
  if (env.PATH && !env.PATH.startsWith(localBin)) {
10783
10839
  env.PATH = `${localBin}:${env.PATH}`;
10784
10840
  }
@@ -10810,8 +10866,8 @@ function sendNotification2(session, exitCode) {
10810
10866
  }
10811
10867
  }
10812
10868
  function listRecentCodexRollouts() {
10813
- const sessionsRoot = join62(homedir52(), ".codex", "sessions");
10814
- if (!existsSync9(sessionsRoot)) {
10869
+ const sessionsRoot = join72(homedir52(), ".codex", "sessions");
10870
+ if (!existsSync10(sessionsRoot)) {
10815
10871
  return [];
10816
10872
  }
10817
10873
  const paths = [];
@@ -10819,20 +10875,20 @@ function listRecentCodexRollouts() {
10819
10875
  if (!year.isDirectory()) {
10820
10876
  continue;
10821
10877
  }
10822
- const yearPath = join62(sessionsRoot, year.name);
10878
+ const yearPath = join72(sessionsRoot, year.name);
10823
10879
  for (const month of readdirSync5(yearPath, { withFileTypes: true })) {
10824
10880
  if (!month.isDirectory()) {
10825
10881
  continue;
10826
10882
  }
10827
- const monthPath = join62(yearPath, month.name);
10883
+ const monthPath = join72(yearPath, month.name);
10828
10884
  for (const day of readdirSync5(monthPath, { withFileTypes: true })) {
10829
10885
  if (!day.isDirectory()) {
10830
10886
  continue;
10831
10887
  }
10832
- const dayPath = join62(monthPath, day.name);
10888
+ const dayPath = join72(monthPath, day.name);
10833
10889
  for (const fileName of readdirSync5(dayPath)) {
10834
10890
  if (fileName.startsWith("rollout-") && fileName.endsWith(".jsonl")) {
10835
- paths.push(join62(dayPath, fileName));
10891
+ paths.push(join72(dayPath, fileName));
10836
10892
  }
10837
10893
  }
10838
10894
  }
@@ -10844,7 +10900,7 @@ function listCodexNativeSessionCandidates(cwd) {
10844
10900
  const candidates = [];
10845
10901
  for (const rolloutPath of listRecentCodexRollouts()) {
10846
10902
  try {
10847
- const [firstLine] = readFileSync7(rolloutPath, "utf-8").split("\n");
10903
+ const [firstLine] = readFileSync8(rolloutPath, "utf-8").split("\n");
10848
10904
  if (!firstLine) {
10849
10905
  continue;
10850
10906
  }
@@ -10897,13 +10953,13 @@ async function spawnHarnessProcess(options) {
10897
10953
  const run = addRun2(session, { nativeSessionId });
10898
10954
  session.status = "queued";
10899
10955
  writeSession(options.sessionsDir, session);
10900
- const command = options.command ?? harness.name;
10901
- const child = spawn4(command, harness.buildSpawnArgs(options.config), {
10956
+ const commandName = options.command ?? harness.name;
10957
+ const resolved = resolveCommand(commandName);
10958
+ const child = spawn4(resolved.cmd, [...resolved.prependArgs, ...harness.buildSpawnArgs(options.config)], {
10902
10959
  cwd: options.cwd,
10903
10960
  detached: true,
10904
10961
  stdio: ["ignore", "ignore", "pipe"],
10905
- env: buildHarnessSpawnEnv(options.cwd, options.sessionId),
10906
- shell: process.platform === "win32"
10962
+ env: buildHarnessSpawnEnv(options.cwd, options.sessionId)
10907
10963
  });
10908
10964
  let stderr = "";
10909
10965
  child.stderr?.on("data", (chunk) => {
@@ -12544,7 +12600,7 @@ minimatch.unescape = unescape;
12544
12600
 
12545
12601
  // ../../packages/flint-server/dist/index.js
12546
12602
  import { parse as parseYaml } from "yaml";
12547
- import { existsSync as existsSync10, watch as watch3 } from "fs";
12603
+ import { existsSync as existsSync11, watch as watch3 } from "fs";
12548
12604
  import { stat as stat22 } from "fs/promises";
12549
12605
  import path22 from "path";
12550
12606
  import { mkdir as mkdir5, readFile as readFile22, writeFile as writeFile3 } from "fs/promises";
@@ -13145,7 +13201,7 @@ function createResilientWatcher({
13145
13201
  if (closed) {
13146
13202
  return;
13147
13203
  }
13148
- if (!existsSync10(targetPath)) {
13204
+ if (!existsSync11(targetPath)) {
13149
13205
  scheduleRestart();
13150
13206
  return;
13151
13207
  }
@@ -14084,12 +14140,12 @@ function registerOrbhRoutes(app, ctx, options) {
14084
14140
  prompt: prompt6,
14085
14141
  extraArgs: session.runtime === "claude" ? ["--chrome"] : []
14086
14142
  });
14087
- const child = spawn22(harness.name, args, {
14143
+ const resolved = resolveCommand(harness.name);
14144
+ const child = spawn22(resolved.cmd, [...resolved.prependArgs, ...args], {
14088
14145
  cwd: ctx.flintPath,
14089
14146
  detached: true,
14090
14147
  stdio: ["ignore", "ignore", "pipe"],
14091
- env: buildHarnessSpawnEnv(ctx.flintPath, session.id),
14092
- shell: process.platform === "win32"
14148
+ env: buildHarnessSpawnEnv(ctx.flintPath, session.id)
14093
14149
  });
14094
14150
  let stderr = "";
14095
14151
  child.stderr?.on("data", (chunk) => {
@@ -16050,7 +16106,7 @@ import { Command as Command24 } from "commander";
16050
16106
  import pc29 from "picocolors";
16051
16107
  import { spawn as spawn7, execSync as execSync3 } from "child_process";
16052
16108
  import { createInterface as createInterface5 } from "readline";
16053
- import { existsSync as existsSync11, mkdirSync as mkdirSync3, readFileSync as readFileSync8, writeFileSync as writeFileSync2 } from "fs";
16109
+ import { existsSync as existsSync12, mkdirSync as mkdirSync3, readFileSync as readFileSync9, writeFileSync as writeFileSync2 } from "fs";
16054
16110
  import { randomUUID as randomUUID4 } from "crypto";
16055
16111
  import { join as join14 } from "path";
16056
16112
 
@@ -16255,7 +16311,7 @@ function exportOrbhSessionTranscript(session, flintPath) {
16255
16311
  }
16256
16312
  let content;
16257
16313
  try {
16258
- content = readFileSync8(transcriptPath, "utf-8");
16314
+ content = readFileSync9(transcriptPath, "utf-8");
16259
16315
  } catch {
16260
16316
  console.log(pc29.dim("Could not read transcript file."));
16261
16317
  return;
@@ -16284,10 +16340,10 @@ var CLIENT_INFO = {
16284
16340
  };
16285
16341
  async function bootstrapCodexSession(cwd, initPrompt) {
16286
16342
  return new Promise((resolve12, reject) => {
16287
- const proc = spawn7("codex", ["app-server"], {
16343
+ const codexCmd = resolveCommand("codex");
16344
+ const proc = spawn7(codexCmd.cmd, [...codexCmd.prependArgs, "app-server"], {
16288
16345
  stdio: ["pipe", "pipe", "pipe"],
16289
- cwd,
16290
- shell: process.platform === "win32"
16346
+ cwd
16291
16347
  });
16292
16348
  const rl = createInterface5({ input: proc.stdout });
16293
16349
  const send = (msg) => proc.stdin.write(`${JSON.stringify(msg)}
@@ -16305,7 +16361,7 @@ async function bootstrapCodexSession(cwd, initPrompt) {
16305
16361
  let pollInterval = null;
16306
16362
  const startPolling = () => {
16307
16363
  pollInterval = setInterval(() => {
16308
- if (sessionPath && existsSync11(sessionPath)) {
16364
+ if (sessionPath && existsSync12(sessionPath)) {
16309
16365
  if (pollInterval) clearInterval(pollInterval);
16310
16366
  send({ method: "turn/interrupt", id: 4, params: { threadId } });
16311
16367
  setTimeout(() => {
@@ -16370,10 +16426,10 @@ codeCommand.command("claude").description("Open Claude Code TUI").option("-p, --
16370
16426
  sessionId = randomUUID4();
16371
16427
  args.push("--session-id", sessionId, await buildClaudeInitPrompt(sessionId));
16372
16428
  }
16373
- const child = spawn7("claude", args, {
16429
+ const claudeCmd = resolveCommand("claude");
16430
+ const child = spawn7(claudeCmd.cmd, [...claudeCmd.prependArgs, ...args], {
16374
16431
  cwd: flintPath,
16375
- stdio: "inherit",
16376
- shell: process.platform === "win32"
16432
+ stdio: "inherit"
16377
16433
  });
16378
16434
  child.on("error", (err) => {
16379
16435
  if (err.code === "ENOENT") {
@@ -16440,15 +16496,16 @@ codeCommand.command("codex").description("Open Codex TUI with session tracking")
16440
16496
  console.log(pc29.green(`Session ID: ${threadId}`));
16441
16497
  console.log("");
16442
16498
  const resumePrompt = options.continue ? `continuing session ${threadId}` : `your session id is ${threadId}`;
16443
- const child = spawn7("codex", [
16499
+ const codexResumeCmd = resolveCommand("codex");
16500
+ const child = spawn7(codexResumeCmd.cmd, [
16501
+ ...codexResumeCmd.prependArgs,
16444
16502
  "resume",
16445
16503
  threadId,
16446
16504
  "--dangerously-bypass-approvals-and-sandbox",
16447
16505
  resumePrompt
16448
16506
  ], {
16449
16507
  cwd: flintPath,
16450
- stdio: "inherit",
16451
- shell: process.platform === "win32"
16508
+ stdio: "inherit"
16452
16509
  });
16453
16510
  child.on("error", (err) => {
16454
16511
  console.error(pc29.red(`Error: ${err.message}`));
@@ -16539,11 +16596,11 @@ codeCommand.command("gemini").description("Open Gemini CLI with Orbh session tra
16539
16596
  writeSession(sessionsDir, fresh);
16540
16597
  });
16541
16598
  }
16542
- const child = spawn7("gemini", args, {
16599
+ const geminiCmd = resolveCommand("gemini");
16600
+ const child = spawn7(geminiCmd.cmd, [...geminiCmd.prependArgs, ...args], {
16543
16601
  cwd: flintPath,
16544
16602
  stdio: "inherit",
16545
- env: { ...process.env, ORBH_SESSION_ID: session.id },
16546
- shell: process.platform === "win32"
16603
+ env: { ...process.env, ORBH_SESSION_ID: session.id }
16547
16604
  });
16548
16605
  if (child.pid) {
16549
16606
  updateCurrentRun2(session, { pid: child.pid });
@@ -16604,7 +16661,7 @@ codeCommand.command("gemini").description("Open Gemini CLI with Orbh session tra
16604
16661
  // src/commands/helper.ts
16605
16662
  import { Command as Command25 } from "commander";
16606
16663
  import pc30 from "picocolors";
16607
- import { readdirSync as readdirSync6, existsSync as existsSync12, statSync as statSync4 } from "fs";
16664
+ import { readdirSync as readdirSync6, existsSync as existsSync13, statSync as statSync4 } from "fs";
16608
16665
  import { join as join15, basename as basename5 } from "path";
16609
16666
  function extractNumberFromFile(filename, typeName) {
16610
16667
  const regex = new RegExp(`^\\(${typeName}\\)\\s+(\\d+)`, "i");
@@ -16613,7 +16670,7 @@ function extractNumberFromFile(filename, typeName) {
16613
16670
  }
16614
16671
  function collectFilesRecursively(dirPath) {
16615
16672
  const files = [];
16616
- if (!existsSync12(dirPath)) {
16673
+ if (!existsSync13(dirPath)) {
16617
16674
  return files;
16618
16675
  }
16619
16676
  const entries = readdirSync6(dirPath);
@@ -16634,7 +16691,7 @@ function collectFilesRecursively(dirPath) {
16634
16691
  }
16635
16692
  function getNextNumber(flintPath, typeName) {
16636
16693
  const meshDir = join15(flintPath, "Mesh");
16637
- if (!existsSync12(meshDir)) {
16694
+ if (!existsSync13(meshDir)) {
16638
16695
  return 1;
16639
16696
  }
16640
16697
  const allFiles = collectFilesRecursively(meshDir);
@@ -16752,7 +16809,7 @@ var featuresCommand = createFeaturesCommand({
16752
16809
  import { Command as Command27 } from "commander";
16753
16810
  import pc32 from "picocolors";
16754
16811
  var VALID_TYPES = ["codebase", "flint"];
16755
- var resolveCommand = new Command27("resolve").description("Resolve a reference to its local path").argument("<type>", "Reference type: codebase, flint, or source").argument("<name>", 'Name of the reference to resolve (or "FlintName/ExportName" for sources)').option("-p, --path <dir>", "Path to flint (default: auto-detect)").option("--json", "Output as JSON").action(async (type, name, options) => {
16812
+ var resolveCommand2 = new Command27("resolve").description("Resolve a reference to its local path").argument("<type>", "Reference type: codebase, flint, or source").argument("<name>", 'Name of the reference to resolve (or "FlintName/ExportName" for sources)').option("-p, --path <dir>", "Path to flint (default: auto-detect)").option("--json", "Output as JSON").action(async (type, name, options) => {
16756
16813
  try {
16757
16814
  const flintPath = options.path || await findFlintRoot(process.cwd());
16758
16815
  if (!flintPath) {
@@ -16917,17 +16974,17 @@ function prompt5(message) {
16917
16974
  // src/commands/update.ts
16918
16975
  import { Command as Command29 } from "commander";
16919
16976
  import pc34 from "picocolors";
16920
- import { readFileSync as readFileSync9, existsSync as existsSync13 } from "fs";
16921
- import { dirname as dirname3, join as join16 } from "path";
16977
+ import { readFileSync as readFileSync10, existsSync as existsSync14 } from "fs";
16978
+ import { dirname as dirname4, join as join16 } from "path";
16922
16979
  import { fileURLToPath as fileURLToPath3 } from "url";
16923
16980
  import { execSync as execSync4 } from "child_process";
16924
16981
  import https from "https";
16925
- var __dirname2 = dirname3(fileURLToPath3(import.meta.url));
16982
+ var __dirname2 = dirname4(fileURLToPath3(import.meta.url));
16926
16983
  function readPkgVersion() {
16927
16984
  for (const rel of ["../..", ".."]) {
16928
16985
  const p = join16(__dirname2, rel, "package.json");
16929
- if (existsSync13(p)) {
16930
- return JSON.parse(readFileSync9(p, "utf-8")).version;
16986
+ if (existsSync14(p)) {
16987
+ return JSON.parse(readFileSync10(p, "utf-8")).version;
16931
16988
  }
16932
16989
  }
16933
16990
  throw new Error("Could not determine current version");
@@ -17803,7 +17860,7 @@ var tinderboxCommand = new Command35("tinderbox").description("Orchestrate opera
17803
17860
  import { Command as Command36 } from "commander";
17804
17861
  import pc41 from "picocolors";
17805
17862
  import { spawn as spawn8, spawnSync as spawnSync4, execSync as execSync5 } from "child_process";
17806
- import { existsSync as existsSync14, mkdirSync as mkdirSync4, readFileSync as readFileSync10, readdirSync as readdirSync7, statSync as statSync5, writeFileSync as writeFileSync3 } from "fs";
17863
+ import { existsSync as existsSync15, mkdirSync as mkdirSync4, readFileSync as readFileSync11, readdirSync as readdirSync7, statSync as statSync5, writeFileSync as writeFileSync3 } from "fs";
17807
17864
  import { join as join18 } from "path";
17808
17865
  import { homedir as homedir10 } from "os";
17809
17866
  import { createInterface as createInterface7 } from "readline";
@@ -17847,7 +17904,7 @@ function readTranscriptEntries(session, flintPath) {
17847
17904
  const transcriptPath = harness.resolveTranscriptPath(nativeId, flintPath);
17848
17905
  if (!transcriptPath) return null;
17849
17906
  try {
17850
- const content = readFileSync10(transcriptPath, "utf-8");
17907
+ const content = readFileSync11(transcriptPath, "utf-8");
17851
17908
  return harness.parseTranscript(content, { transcriptPath });
17852
17909
  } catch {
17853
17910
  return null;
@@ -17869,7 +17926,7 @@ function formatTokenSummary(usage) {
17869
17926
  }
17870
17927
  var DETACHED_ORB_MONITOR = String.raw`
17871
17928
  const { spawn, spawnSync } = require('node:child_process');
17872
- const { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync, renameSync } = require('node:fs');
17929
+ const { appendFileSync, existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync, renameSync } = require('node:fs');
17873
17930
  const { basename, dirname, join } = require('node:path');
17874
17931
  const { homedir } = require('node:os');
17875
17932
 
@@ -17878,6 +17935,17 @@ if (!configJson) process.exit(1);
17878
17935
 
17879
17936
  const { sessionPath, cwd, command, args } = JSON.parse(configJson);
17880
17937
 
17938
+ function debugLog(msg) {
17939
+ if (process.platform !== 'win32') return;
17940
+ try {
17941
+ const logDir = join(cwd, '.flint');
17942
+ mkdirSync(logDir, { recursive: true });
17943
+ appendFileSync(join(logDir, 'orbh-debug.log'), '[' + new Date().toISOString() + '] [monitor] ' + msg + '\n');
17944
+ } catch {}
17945
+ }
17946
+
17947
+ debugLog('Monitor started. command=' + command + ', args=' + JSON.stringify(args).slice(0, 200));
17948
+
17881
17949
  function readSession() {
17882
17950
  try { return JSON.parse(readFileSync(sessionPath, 'utf-8')); }
17883
17951
  catch { return null; }
@@ -17916,12 +17984,53 @@ function notify(title, message) {
17916
17984
  } catch {}
17917
17985
  }
17918
17986
 
17919
- const child = spawn(command, args, { cwd, stdio: ['ignore', 'ignore', 'pipe'], shell: process.platform === 'win32' });
17987
+ // On Windows, resolve .cmd shims to the underlying node script
17988
+ let spawnCmd = command;
17989
+ let spawnArgs = args;
17990
+ if (process.platform === 'win32') {
17991
+ debugLog('Resolving command: ' + command);
17992
+ const where = spawnSync('where', [command], { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] });
17993
+ debugLog('where exit=' + where.status + ', stdout=' + JSON.stringify((where.stdout || '').trim()));
17994
+ if (where.status === 0 && where.stdout) {
17995
+ const resolved = where.stdout.trim().split(/\r?\n/)[0].trim();
17996
+ debugLog('Resolved path: ' + resolved);
17997
+ if (resolved.toLowerCase().endsWith('.cmd')) {
17998
+ try {
17999
+ const content = readFileSync(resolved, 'utf-8');
18000
+ debugLog('.cmd content (' + content.length + ' chars):\n' + content);
18001
+ const matches = [...content.matchAll(/%(?:~dp0|dp0%)\\([^"%\r\n]+\.m?[jc]?[jt]s)/gi)];
18002
+ debugLog('Regex matches: ' + JSON.stringify(matches.map(m => m[0])));
18003
+ if (matches.length > 0) {
18004
+ const scriptPath = join(dirname(resolved), matches[matches.length - 1][1]);
18005
+ const scriptExists = existsSync(scriptPath);
18006
+ debugLog('Script path: ' + scriptPath + ', exists: ' + scriptExists);
18007
+ if (scriptExists) {
18008
+ spawnCmd = process.execPath;
18009
+ spawnArgs = [scriptPath, ...args];
18010
+ }
18011
+ } else {
18012
+ debugLog('No regex matches in .cmd content');
18013
+ }
18014
+ } catch (e) {
18015
+ debugLog('Error parsing .cmd: ' + e);
18016
+ }
18017
+ } else {
18018
+ spawnCmd = resolved;
18019
+ }
18020
+ } else {
18021
+ debugLog('where failed — using bare command name');
18022
+ }
18023
+ }
18024
+ debugLog('Final spawn: cmd=' + spawnCmd + ', args[0..2]=' + JSON.stringify(spawnArgs.slice(0, 3)));
18025
+ const child = spawn(spawnCmd, spawnArgs, { cwd, stdio: ['ignore', 'ignore', 'pipe'] });
17920
18026
 
17921
18027
  let stderr = '';
17922
18028
  child.stderr?.on('data', (chunk) => { stderr += chunk.toString(); });
17923
18029
 
17924
- child.on('error', () => {
18030
+ debugLog('Spawn initiated, pid=' + (child.pid || 'none'));
18031
+
18032
+ child.on('error', (err) => {
18033
+ debugLog('Spawn ERROR: ' + err.message + ' (code=' + err.code + ')');
17925
18034
  const s = readSession();
17926
18035
  if (s) {
17927
18036
  s.status = 'failed';
@@ -18048,6 +18157,7 @@ if (command === 'gemini') {
18048
18157
  }
18049
18158
 
18050
18159
  child.on('exit', (code) => {
18160
+ debugLog('Child exited with code=' + code + ', stderr=' + (stderr || '(empty)').slice(0, 500));
18051
18161
  const s = readSession();
18052
18162
  if (!s) { process.exit(typeof code === 'number' ? code : 1); return; }
18053
18163
  const desc = (s.title || s.description || s.prompt || '').slice(0, 60);
@@ -18216,7 +18326,7 @@ function exportSessionTranscript(session, flintPath) {
18216
18326
  }
18217
18327
  let content;
18218
18328
  try {
18219
- content = readFileSync10(transcriptPath, "utf-8");
18329
+ content = readFileSync11(transcriptPath, "utf-8");
18220
18330
  } catch {
18221
18331
  console.log(pc41.dim("Could not read transcript file."));
18222
18332
  return;
@@ -19118,11 +19228,11 @@ orbCommand.command("watch").description("Stream a live session transcript to the
19118
19228
  console.log(`${pc41.bold("Watching")} ${pc41.cyan(shortId2(session.id))} ${pc41.dim("\xB7")} ${session.runtime}${watchTitle} ${pc41.dim("\xB7")} ${statusIcon2(session.status)} ${session.status}${watchMeta}`);
19119
19229
  console.log(pc41.dim(transcriptPath));
19120
19230
  console.log("");
19121
- if (!existsSync14(transcriptPath)) {
19231
+ if (!existsSync15(transcriptPath)) {
19122
19232
  process.stdout.write(pc41.dim("Waiting for transcript..."));
19123
19233
  await new Promise((resolve12, reject) => {
19124
19234
  const poll = setInterval(() => {
19125
- if (existsSync14(transcriptPath)) {
19235
+ if (existsSync15(transcriptPath)) {
19126
19236
  clearInterval(poll);
19127
19237
  process.stdout.write("\r\x1B[2K");
19128
19238
  resolve12();
@@ -19541,15 +19651,15 @@ var steelCommand = new Command37("steel").description("Manage Steel UI state (.s
19541
19651
  );
19542
19652
 
19543
19653
  // src/index.ts
19544
- var __dirname3 = dirname4(fileURLToPath4(import.meta.url));
19545
- var pkg = JSON.parse(readFileSync11(join20(__dirname3, "..", "package.json"), "utf-8"));
19654
+ var __dirname3 = dirname5(fileURLToPath4(import.meta.url));
19655
+ var pkg = JSON.parse(readFileSync12(join20(__dirname3, "..", "package.json"), "utf-8"));
19546
19656
  var runtime = resolveRuntimeSync({ cliname: "flint" });
19547
19657
  var devAvailable = runtime.mode === "dev";
19548
19658
  var newDir = getConfigDir("flint");
19549
19659
  var oldDir = join20(homedir11(), ".flint");
19550
19660
  var intermediateDir = join20(homedir11(), ".nuucognition", ".flint");
19551
19661
  function migrateDir(sourceDir, label) {
19552
- if (!existsSync15(sourceDir)) return false;
19662
+ if (!existsSync16(sourceDir)) return false;
19553
19663
  try {
19554
19664
  const entries = readdirSync8(sourceDir);
19555
19665
  const filesToMigrate = entries.filter((e) => !e.startsWith(".DS_Store"));
@@ -19559,7 +19669,7 @@ function migrateDir(sourceDir, label) {
19559
19669
  for (const entry of filesToMigrate) {
19560
19670
  const src = join20(sourceDir, entry);
19561
19671
  const dest = join20(newDir, entry);
19562
- if (!existsSync15(dest)) {
19672
+ if (!existsSync16(dest)) {
19563
19673
  cpSync(src, dest, { recursive: true });
19564
19674
  migrated++;
19565
19675
  }
@@ -19627,7 +19737,7 @@ var COMMAND_MAP = [
19627
19737
  { featureId: "reference", command: referenceCommand },
19628
19738
  { featureId: "export", command: exportCommand },
19629
19739
  { featureId: "obsidian", command: obsidianCommand },
19630
- { featureId: "resolve", command: resolveCommand },
19740
+ { featureId: "resolve", command: resolveCommand2 },
19631
19741
  { featureId: "fulfill", command: fulfillCommand },
19632
19742
  { featureId: "update", command: updateCommand },
19633
19743
  { featureId: "send", command: sendCommand },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuucognition/flint-cli",
3
- "version": "0.5.6-dev.1",
3
+ "version": "0.5.6-dev.3",
4
4
  "type": "module",
5
5
  "description": "Flint cognitive workspace CLI",
6
6
  "license": "PROPRIETARY",
@@ -36,12 +36,12 @@
36
36
  "tsup": "^8.3.5",
37
37
  "tsx": "^4.19.2",
38
38
  "typescript": "^5.9.2",
39
- "@nuucognition/flint-server": "0.0.1",
40
39
  "@nuucognition/flint": "0.1.0",
41
- "@nuucognition/flint-migrations": "0.1.0",
42
- "@nuucognition/typescript-config": "0.0.0",
40
+ "@nuucognition/flint-server": "0.0.1",
43
41
  "@nuucognition/orbh": "0.0.1-dev.0",
44
- "@nuucognition/eslint-config": "0.0.0"
42
+ "@nuucognition/eslint-config": "0.0.0",
43
+ "@nuucognition/typescript-config": "0.0.0",
44
+ "@nuucognition/flint-migrations": "0.1.0"
45
45
  },
46
46
  "scripts": {
47
47
  "predev": "turbo build --filter=@nuucognition/flint-cli^...",