@nuucognition/flint-cli 0.5.6-dev.0 → 0.5.6-dev.2

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 +153 -96
  2. package/package.json +4 -4
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,7 +5851,8 @@ 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
5858
  });
@@ -8298,26 +8299,26 @@ import { randomUUID as randomUUID2 } from "crypto";
8298
8299
  import { existsSync as existsSync22, readFileSync as readFileSync22 } from "fs";
8299
8300
  import { closeSync, existsSync as existsSync32, openSync, readSync, statSync, unwatchFile, watch, watchFile } from "fs";
8300
8301
  import { existsSync as existsSync42, readFileSync as readFileSync3, unwatchFile as unwatchFile2, watch as watch2, watchFile as watchFile2 } from "fs";
8301
- import { existsSync as existsSync52 } from "fs";
8302
- import { join as join22 } from "path";
8303
- import { homedir as homedir5 } from "os";
8304
- import { spawnSync as spawnSync3 } from "child_process";
8305
- import { readdirSync as readdirSync2, readFileSync as readFileSync4 } from "fs";
8306
8302
  import { existsSync as existsSync6 } from "fs";
8307
8303
  import { join as join32 } from "path";
8304
+ import { homedir as homedir5 } from "os";
8305
+ import { spawnSync as spawnSync3 } from "child_process";
8306
+ import { existsSync as existsSync52, 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";
8308
8311
  import { homedir as homedir22 } from "os";
8309
- import { spawnSync as spawnSync22 } from "child_process";
8310
- import { existsSync as existsSync7, readdirSync as readdirSync3, readFileSync as readFileSync5, statSync as statSync2 } from "fs";
8311
- import { spawnSync as spawnSync32 } from "child_process";
8312
- 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";
8313
8314
  import { homedir as homedir32 } from "os";
8314
- import { existsSync as existsSync8, readdirSync as readdirSync4, readFileSync as readFileSync6, statSync as statSync3 } from "fs";
8315
- import { spawnSync as spawnSync4 } from "child_process";
8315
+ import { existsSync as existsSync9, readdirSync as readdirSync4, readFileSync as readFileSync7, statSync as statSync3 } from "fs";
8316
+ import { spawnSync as spawnSync22 } from "child_process";
8316
8317
  import { homedir as homedir42 } from "os";
8317
- import { basename as basename22, join as join52 } from "path";
8318
- import { spawn as spawn4, spawnSync as spawnSync5 } from "child_process";
8319
- import { existsSync as existsSync9, readdirSync as readdirSync5, readFileSync as readFileSync7 } from "fs";
8320
- import { join as join62 } from "path";
8318
+ import { basename as basename22, join as join62 } from "path";
8319
+ import { spawn as spawn4, spawnSync as spawnSync32 } from "child_process";
8320
+ import { existsSync as existsSync10, readdirSync as readdirSync5, readFileSync as readFileSync8 } from "fs";
8321
+ import { join as join72 } from "path";
8321
8322
  import { homedir as homedir52 } from "os";
8322
8323
  var RUN_TRANSITIONS = {
8323
8324
  running: ["completed", "failed", "cancelled", "suspended"],
@@ -10214,9 +10215,34 @@ var JsonSessionWatcher = class {
10214
10215
  function createJsonSessionWatcher(transcriptPath, mapper, options) {
10215
10216
  return new JsonSessionWatcher(transcriptPath, mapper, options);
10216
10217
  }
10218
+ function isCommandOnPath(name) {
10219
+ const cmd = process.platform === "win32" ? "where" : "which";
10220
+ return spawnSync3(cmd, [name], { stdio: "ignore" }).status === 0;
10221
+ }
10222
+ function resolveCommand(name) {
10223
+ if (process.platform !== "win32") return { cmd: name, prependArgs: [] };
10224
+ const where = spawnSync3("where", [name], { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] });
10225
+ const firstLine = (where.stdout ?? "").trim().split(/\r?\n/)[0]?.trim();
10226
+ if (where.status !== 0 || !firstLine) return { cmd: name, prependArgs: [] };
10227
+ const resolved = firstLine;
10228
+ if (!resolved.toLowerCase().endsWith(".cmd")) return { cmd: resolved, prependArgs: [] };
10229
+ try {
10230
+ const content = readFileSync4(resolved, "utf-8");
10231
+ const matches = [...content.matchAll(/%(?:~dp0|dp0%)\\([^"%\r\n]+\.m?[jc]?[jt]s)/gi)];
10232
+ const last = matches.length > 0 ? matches[matches.length - 1] : void 0;
10233
+ if (last && last[1]) {
10234
+ const scriptPath = join22(dirname3(resolved), last[1]);
10235
+ if (existsSync52(scriptPath)) {
10236
+ return { cmd: process.execPath, prependArgs: [scriptPath] };
10237
+ }
10238
+ }
10239
+ } catch {
10240
+ }
10241
+ return { cmd: resolved, prependArgs: [] };
10242
+ }
10217
10243
  function buildTranscriptPath(cwd, nativeSessionId) {
10218
10244
  const sanitized = cwd.replace(/[^a-zA-Z0-9\-_]/g, "-");
10219
- return join22(homedir5(), ".claude", "projects", sanitized, `${nativeSessionId}.jsonl`);
10245
+ return join32(homedir5(), ".claude", "projects", sanitized, `${nativeSessionId}.jsonl`);
10220
10246
  }
10221
10247
  function createClaudeHarness() {
10222
10248
  return {
@@ -10264,7 +10290,7 @@ function createClaudeHarness() {
10264
10290
  },
10265
10291
  resolveTranscriptPath(nativeSessionId, cwd) {
10266
10292
  const candidate = buildTranscriptPath(cwd, nativeSessionId);
10267
- if (existsSync52(candidate)) {
10293
+ if (existsSync6(candidate)) {
10268
10294
  return candidate;
10269
10295
  }
10270
10296
  return null;
@@ -10279,12 +10305,12 @@ function createClaudeHarness() {
10279
10305
  return parseClaudeTranscript(content);
10280
10306
  },
10281
10307
  async isAvailable() {
10282
- return spawnSync3("which", ["claude"], { stdio: "ignore" }).status === 0;
10308
+ return isCommandOnPath("claude");
10283
10309
  }
10284
10310
  };
10285
10311
  }
10286
10312
  function listDateDirectories(root) {
10287
- if (!existsSync6(root)) {
10313
+ if (!existsSync7(root)) {
10288
10314
  return [];
10289
10315
  }
10290
10316
  const directories = [];
@@ -10292,15 +10318,15 @@ function listDateDirectories(root) {
10292
10318
  if (!year.isDirectory()) {
10293
10319
  continue;
10294
10320
  }
10295
- const yearPath = join32(root, year.name);
10321
+ const yearPath = join42(root, year.name);
10296
10322
  for (const month of readdirSync2(yearPath, { withFileTypes: true })) {
10297
10323
  if (!month.isDirectory()) {
10298
10324
  continue;
10299
10325
  }
10300
- const monthPath = join32(yearPath, month.name);
10326
+ const monthPath = join42(yearPath, month.name);
10301
10327
  for (const day of readdirSync2(monthPath, { withFileTypes: true })) {
10302
10328
  if (day.isDirectory()) {
10303
- directories.push(join32(monthPath, day.name));
10329
+ directories.push(join42(monthPath, day.name));
10304
10330
  }
10305
10331
  }
10306
10332
  }
@@ -10308,11 +10334,11 @@ function listDateDirectories(root) {
10308
10334
  return directories.sort((left, right) => right.localeCompare(left));
10309
10335
  }
10310
10336
  function resolveCodexSessionIndex(root, nativeSessionId) {
10311
- const indexPath = join32(root, "session_index.jsonl");
10312
- if (!existsSync6(indexPath)) {
10337
+ const indexPath = join42(root, "session_index.jsonl");
10338
+ if (!existsSync7(indexPath)) {
10313
10339
  return null;
10314
10340
  }
10315
- const lines = readFileSync4(indexPath, "utf-8").split("\n");
10341
+ const lines = readFileSync5(indexPath, "utf-8").split("\n");
10316
10342
  for (const line of lines) {
10317
10343
  const trimmed = line.trim();
10318
10344
  if (trimmed.length === 0) {
@@ -10364,7 +10390,7 @@ function createCodexHarness() {
10364
10390
  return args;
10365
10391
  },
10366
10392
  resolveTranscriptPath(nativeSessionId) {
10367
- const sessionsRoot = join32(homedir22(), ".codex", "sessions");
10393
+ const sessionsRoot = join42(homedir22(), ".codex", "sessions");
10368
10394
  const indexedPath = resolveCodexSessionIndex(sessionsRoot, nativeSessionId);
10369
10395
  if (indexedPath) {
10370
10396
  return indexedPath;
@@ -10372,7 +10398,7 @@ function createCodexHarness() {
10372
10398
  for (const directory of listDateDirectories(sessionsRoot)) {
10373
10399
  for (const entry of readdirSync2(directory)) {
10374
10400
  if (entry.includes(nativeSessionId) && entry.endsWith(".jsonl")) {
10375
- return join32(directory, entry);
10401
+ return join42(directory, entry);
10376
10402
  }
10377
10403
  }
10378
10404
  }
@@ -10388,7 +10414,7 @@ function createCodexHarness() {
10388
10414
  return parseCodexTranscript(content);
10389
10415
  },
10390
10416
  async isAvailable() {
10391
- return spawnSync22("which", ["codex"], { stdio: "ignore" }).status === 0;
10417
+ return isCommandOnPath("codex");
10392
10418
  }
10393
10419
  };
10394
10420
  }
@@ -10398,13 +10424,13 @@ function sanitizeFactoryCwd(cwd) {
10398
10424
  return cwd.replace(/[\\/]/g, "-");
10399
10425
  }
10400
10426
  function buildScopedTranscriptPath(cwd, nativeSessionId) {
10401
- return join42(homedir32(), ".factory", "sessions", sanitizeFactoryCwd(cwd), `${nativeSessionId}.jsonl`);
10427
+ return join52(homedir32(), ".factory", "sessions", sanitizeFactoryCwd(cwd), `${nativeSessionId}.jsonl`);
10402
10428
  }
10403
10429
  function buildLegacyTranscriptPath(nativeSessionId) {
10404
- return join42(homedir32(), ".factory", "sessions", `${nativeSessionId}.jsonl`);
10430
+ return join52(homedir32(), ".factory", "sessions", `${nativeSessionId}.jsonl`);
10405
10431
  }
10406
10432
  function getDroidSessionsRoot() {
10407
- return join42(homedir32(), ".factory", "sessions");
10433
+ return join52(homedir32(), ".factory", "sessions");
10408
10434
  }
10409
10435
  function parseStartedAtMs(startedAt) {
10410
10436
  if (typeof startedAt === "number" && Number.isFinite(startedAt)) {
@@ -10429,7 +10455,7 @@ function isTranscriptRecentEnough(transcriptPath, startedAt) {
10429
10455
  }
10430
10456
  function readDroidSessionId(transcriptPath) {
10431
10457
  try {
10432
- const firstLine = readFileSync5(transcriptPath, "utf-8").split(/\r?\n/, 1)[0]?.trim();
10458
+ const firstLine = readFileSync6(transcriptPath, "utf-8").split(/\r?\n/, 1)[0]?.trim();
10433
10459
  if (!firstLine) {
10434
10460
  return basename4(transcriptPath, ".jsonl");
10435
10461
  }
@@ -10442,10 +10468,10 @@ function readDroidSessionId(transcriptPath) {
10442
10468
  return basename4(transcriptPath, ".jsonl");
10443
10469
  }
10444
10470
  function listDroidTranscriptPaths(cwd) {
10445
- const candidateDirs = [join42(getDroidSessionsRoot(), sanitizeFactoryCwd(cwd)), getDroidSessionsRoot()];
10471
+ const candidateDirs = [join52(getDroidSessionsRoot(), sanitizeFactoryCwd(cwd)), getDroidSessionsRoot()];
10446
10472
  const transcriptPaths = /* @__PURE__ */ new Map();
10447
10473
  for (const directory of candidateDirs) {
10448
- if (!existsSync7(directory)) {
10474
+ if (!existsSync8(directory)) {
10449
10475
  continue;
10450
10476
  }
10451
10477
  try {
@@ -10453,7 +10479,7 @@ function listDroidTranscriptPaths(cwd) {
10453
10479
  if (!entry.isFile() || !entry.name.endsWith(".jsonl")) {
10454
10480
  continue;
10455
10481
  }
10456
- const transcriptPath = join42(directory, entry.name);
10482
+ const transcriptPath = join52(directory, entry.name);
10457
10483
  transcriptPaths.set(transcriptPath, statSync2(transcriptPath).mtimeMs);
10458
10484
  }
10459
10485
  } catch {
@@ -10469,7 +10495,7 @@ function discoverDroidNativeSessionByOrbhSessionId(cwd, orbhSessionId, options)
10469
10495
  continue;
10470
10496
  }
10471
10497
  try {
10472
- const content = readFileSync5(transcriptPath, "utf-8");
10498
+ const content = readFileSync6(transcriptPath, "utf-8");
10473
10499
  if (!content.includes(orbhSessionId)) {
10474
10500
  continue;
10475
10501
  }
@@ -10532,11 +10558,11 @@ function createDroidHarness() {
10532
10558
  },
10533
10559
  resolveTranscriptPath(nativeSessionId, cwd) {
10534
10560
  const scopedPath = buildScopedTranscriptPath(cwd, nativeSessionId);
10535
- if (existsSync7(scopedPath)) {
10561
+ if (existsSync8(scopedPath)) {
10536
10562
  return scopedPath;
10537
10563
  }
10538
10564
  const legacyPath = buildLegacyTranscriptPath(nativeSessionId);
10539
- if (existsSync7(legacyPath)) {
10565
+ if (existsSync8(legacyPath)) {
10540
10566
  return legacyPath;
10541
10567
  }
10542
10568
  return scopedPath;
@@ -10551,7 +10577,7 @@ function createDroidHarness() {
10551
10577
  return parseDroidTranscript(content, { transcriptPath: options?.transcriptPath });
10552
10578
  },
10553
10579
  async isAvailable() {
10554
- return spawnSync32("which", ["droid"], { stdio: "ignore" }).status === 0;
10580
+ return isCommandOnPath("droid");
10555
10581
  }
10556
10582
  };
10557
10583
  }
@@ -10562,24 +10588,24 @@ function slugifyProjectName(name) {
10562
10588
  return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
10563
10589
  }
10564
10590
  function getGeminiTmpRoot() {
10565
- return join52(homedir42(), ".gemini", "tmp");
10591
+ return join62(homedir42(), ".gemini", "tmp");
10566
10592
  }
10567
10593
  function getProjectSlug(cwd) {
10568
10594
  return slugifyProjectName(basename22(cwd));
10569
10595
  }
10570
10596
  function getGeminiChatsDir(cwd) {
10571
- return join52(getGeminiTmpRoot(), getProjectSlug(cwd), "chats");
10597
+ return join62(getGeminiTmpRoot(), getProjectSlug(cwd), "chats");
10572
10598
  }
10573
10599
  function listGeminiTranscriptPaths(cwd) {
10574
10600
  const chatsDir = getGeminiChatsDir(cwd);
10575
- if (!existsSync8(chatsDir)) {
10601
+ if (!existsSync9(chatsDir)) {
10576
10602
  return [];
10577
10603
  }
10578
- return readdirSync4(chatsDir).filter((entry) => entry.startsWith("session-") && entry.endsWith(".json")).map((entry) => join52(chatsDir, entry)).sort((left, right) => right.localeCompare(left));
10604
+ return readdirSync4(chatsDir).filter((entry) => entry.startsWith("session-") && entry.endsWith(".json")).map((entry) => join62(chatsDir, entry)).sort((left, right) => right.localeCompare(left));
10579
10605
  }
10580
10606
  function readGeminiSessionId(transcriptPath) {
10581
10607
  try {
10582
- const parsed = JSON.parse(readFileSync6(transcriptPath, "utf-8"));
10608
+ const parsed = JSON.parse(readFileSync7(transcriptPath, "utf-8"));
10583
10609
  return typeof parsed.sessionId === "string" ? parsed.sessionId : null;
10584
10610
  } catch {
10585
10611
  return null;
@@ -10625,7 +10651,7 @@ function resolveGeminiResumeTarget(nativeSessionId, cwd) {
10625
10651
  if (nativeSessionId === "latest" || /^\d+$/.test(nativeSessionId)) {
10626
10652
  return nativeSessionId;
10627
10653
  }
10628
- const result = spawnSync4("gemini", ["--list-sessions"], {
10654
+ const result = spawnSync22("gemini", ["--list-sessions"], {
10629
10655
  cwd,
10630
10656
  encoding: "utf-8",
10631
10657
  stdio: ["ignore", "pipe", "pipe"]
@@ -10657,7 +10683,7 @@ function discoverGeminiNativeSessionByOrbhSessionId(cwd, orbhSessionId, options)
10657
10683
  continue;
10658
10684
  }
10659
10685
  try {
10660
- const content = readFileSync6(transcriptPath, "utf-8");
10686
+ const content = readFileSync7(transcriptPath, "utf-8");
10661
10687
  if (!content.includes(orbhSessionId)) {
10662
10688
  continue;
10663
10689
  }
@@ -10738,7 +10764,7 @@ function createGeminiHarness() {
10738
10764
  return parseGeminiTranscript(content);
10739
10765
  },
10740
10766
  async isAvailable() {
10741
- return spawnSync4("which", ["gemini"], { stdio: "ignore" }).status === 0;
10767
+ return isCommandOnPath("gemini");
10742
10768
  }
10743
10769
  };
10744
10770
  }
@@ -10774,7 +10800,7 @@ function buildHarnessSpawnEnv(cwd, sessionId, baseEnv = process.env) {
10774
10800
  delete env.CODEX_THREAD_ID;
10775
10801
  delete env.CODEX_CI;
10776
10802
  delete env.CODEX_SESSION_ID;
10777
- const localBin = join62(homedir52(), ".local", "bin");
10803
+ const localBin = join72(homedir52(), ".local", "bin");
10778
10804
  if (env.PATH && !env.PATH.startsWith(localBin)) {
10779
10805
  env.PATH = `${localBin}:${env.PATH}`;
10780
10806
  }
@@ -10798,16 +10824,16 @@ function sendNotification2(session, exitCode) {
10798
10824
  const body = `${session.runtime}:${session.id}`;
10799
10825
  try {
10800
10826
  if (process.platform === "darwin") {
10801
- spawnSync5("osascript", ["-e", `display notification "${body}" with title "${title}"`], { stdio: "ignore" });
10827
+ spawnSync32("osascript", ["-e", `display notification "${body}" with title "${title}"`], { stdio: "ignore" });
10802
10828
  } else if (process.platform === "linux") {
10803
- spawnSync5("notify-send", [title, body], { stdio: "ignore" });
10829
+ spawnSync32("notify-send", [title, body], { stdio: "ignore" });
10804
10830
  }
10805
10831
  } catch {
10806
10832
  }
10807
10833
  }
10808
10834
  function listRecentCodexRollouts() {
10809
- const sessionsRoot = join62(homedir52(), ".codex", "sessions");
10810
- if (!existsSync9(sessionsRoot)) {
10835
+ const sessionsRoot = join72(homedir52(), ".codex", "sessions");
10836
+ if (!existsSync10(sessionsRoot)) {
10811
10837
  return [];
10812
10838
  }
10813
10839
  const paths = [];
@@ -10815,20 +10841,20 @@ function listRecentCodexRollouts() {
10815
10841
  if (!year.isDirectory()) {
10816
10842
  continue;
10817
10843
  }
10818
- const yearPath = join62(sessionsRoot, year.name);
10844
+ const yearPath = join72(sessionsRoot, year.name);
10819
10845
  for (const month of readdirSync5(yearPath, { withFileTypes: true })) {
10820
10846
  if (!month.isDirectory()) {
10821
10847
  continue;
10822
10848
  }
10823
- const monthPath = join62(yearPath, month.name);
10849
+ const monthPath = join72(yearPath, month.name);
10824
10850
  for (const day of readdirSync5(monthPath, { withFileTypes: true })) {
10825
10851
  if (!day.isDirectory()) {
10826
10852
  continue;
10827
10853
  }
10828
- const dayPath = join62(monthPath, day.name);
10854
+ const dayPath = join72(monthPath, day.name);
10829
10855
  for (const fileName of readdirSync5(dayPath)) {
10830
10856
  if (fileName.startsWith("rollout-") && fileName.endsWith(".jsonl")) {
10831
- paths.push(join62(dayPath, fileName));
10857
+ paths.push(join72(dayPath, fileName));
10832
10858
  }
10833
10859
  }
10834
10860
  }
@@ -10840,7 +10866,7 @@ function listCodexNativeSessionCandidates(cwd) {
10840
10866
  const candidates = [];
10841
10867
  for (const rolloutPath of listRecentCodexRollouts()) {
10842
10868
  try {
10843
- const [firstLine] = readFileSync7(rolloutPath, "utf-8").split("\n");
10869
+ const [firstLine] = readFileSync8(rolloutPath, "utf-8").split("\n");
10844
10870
  if (!firstLine) {
10845
10871
  continue;
10846
10872
  }
@@ -10893,8 +10919,9 @@ async function spawnHarnessProcess(options) {
10893
10919
  const run = addRun2(session, { nativeSessionId });
10894
10920
  session.status = "queued";
10895
10921
  writeSession(options.sessionsDir, session);
10896
- const command = options.command ?? harness.name;
10897
- const child = spawn4(command, harness.buildSpawnArgs(options.config), {
10922
+ const commandName = options.command ?? harness.name;
10923
+ const resolved = resolveCommand(commandName);
10924
+ const child = spawn4(resolved.cmd, [...resolved.prependArgs, ...harness.buildSpawnArgs(options.config)], {
10898
10925
  cwd: options.cwd,
10899
10926
  detached: true,
10900
10927
  stdio: ["ignore", "ignore", "pipe"],
@@ -12539,7 +12566,7 @@ minimatch.unescape = unescape;
12539
12566
 
12540
12567
  // ../../packages/flint-server/dist/index.js
12541
12568
  import { parse as parseYaml } from "yaml";
12542
- import { existsSync as existsSync10, watch as watch3 } from "fs";
12569
+ import { existsSync as existsSync11, watch as watch3 } from "fs";
12543
12570
  import { stat as stat22 } from "fs/promises";
12544
12571
  import path22 from "path";
12545
12572
  import { mkdir as mkdir5, readFile as readFile22, writeFile as writeFile3 } from "fs/promises";
@@ -13140,7 +13167,7 @@ function createResilientWatcher({
13140
13167
  if (closed) {
13141
13168
  return;
13142
13169
  }
13143
- if (!existsSync10(targetPath)) {
13170
+ if (!existsSync11(targetPath)) {
13144
13171
  scheduleRestart();
13145
13172
  return;
13146
13173
  }
@@ -14079,7 +14106,8 @@ function registerOrbhRoutes(app, ctx, options) {
14079
14106
  prompt: prompt6,
14080
14107
  extraArgs: session.runtime === "claude" ? ["--chrome"] : []
14081
14108
  });
14082
- const child = spawn22(harness.name, args, {
14109
+ const resolved = resolveCommand(harness.name);
14110
+ const child = spawn22(resolved.cmd, [...resolved.prependArgs, ...args], {
14083
14111
  cwd: ctx.flintPath,
14084
14112
  detached: true,
14085
14113
  stdio: ["ignore", "ignore", "pipe"],
@@ -16044,7 +16072,7 @@ import { Command as Command24 } from "commander";
16044
16072
  import pc29 from "picocolors";
16045
16073
  import { spawn as spawn7, execSync as execSync3 } from "child_process";
16046
16074
  import { createInterface as createInterface5 } from "readline";
16047
- import { existsSync as existsSync11, mkdirSync as mkdirSync3, readFileSync as readFileSync8, writeFileSync as writeFileSync2 } from "fs";
16075
+ import { existsSync as existsSync12, mkdirSync as mkdirSync3, readFileSync as readFileSync9, writeFileSync as writeFileSync2 } from "fs";
16048
16076
  import { randomUUID as randomUUID4 } from "crypto";
16049
16077
  import { join as join14 } from "path";
16050
16078
 
@@ -16249,7 +16277,7 @@ function exportOrbhSessionTranscript(session, flintPath) {
16249
16277
  }
16250
16278
  let content;
16251
16279
  try {
16252
- content = readFileSync8(transcriptPath, "utf-8");
16280
+ content = readFileSync9(transcriptPath, "utf-8");
16253
16281
  } catch {
16254
16282
  console.log(pc29.dim("Could not read transcript file."));
16255
16283
  return;
@@ -16278,7 +16306,8 @@ var CLIENT_INFO = {
16278
16306
  };
16279
16307
  async function bootstrapCodexSession(cwd, initPrompt) {
16280
16308
  return new Promise((resolve12, reject) => {
16281
- const proc = spawn7("codex", ["app-server"], {
16309
+ const codexCmd = resolveCommand("codex");
16310
+ const proc = spawn7(codexCmd.cmd, [...codexCmd.prependArgs, "app-server"], {
16282
16311
  stdio: ["pipe", "pipe", "pipe"],
16283
16312
  cwd
16284
16313
  });
@@ -16298,7 +16327,7 @@ async function bootstrapCodexSession(cwd, initPrompt) {
16298
16327
  let pollInterval = null;
16299
16328
  const startPolling = () => {
16300
16329
  pollInterval = setInterval(() => {
16301
- if (sessionPath && existsSync11(sessionPath)) {
16330
+ if (sessionPath && existsSync12(sessionPath)) {
16302
16331
  if (pollInterval) clearInterval(pollInterval);
16303
16332
  send({ method: "turn/interrupt", id: 4, params: { threadId } });
16304
16333
  setTimeout(() => {
@@ -16363,7 +16392,8 @@ codeCommand.command("claude").description("Open Claude Code TUI").option("-p, --
16363
16392
  sessionId = randomUUID4();
16364
16393
  args.push("--session-id", sessionId, await buildClaudeInitPrompt(sessionId));
16365
16394
  }
16366
- const child = spawn7("claude", args, {
16395
+ const claudeCmd = resolveCommand("claude");
16396
+ const child = spawn7(claudeCmd.cmd, [...claudeCmd.prependArgs, ...args], {
16367
16397
  cwd: flintPath,
16368
16398
  stdio: "inherit"
16369
16399
  });
@@ -16432,7 +16462,9 @@ codeCommand.command("codex").description("Open Codex TUI with session tracking")
16432
16462
  console.log(pc29.green(`Session ID: ${threadId}`));
16433
16463
  console.log("");
16434
16464
  const resumePrompt = options.continue ? `continuing session ${threadId}` : `your session id is ${threadId}`;
16435
- const child = spawn7("codex", [
16465
+ const codexResumeCmd = resolveCommand("codex");
16466
+ const child = spawn7(codexResumeCmd.cmd, [
16467
+ ...codexResumeCmd.prependArgs,
16436
16468
  "resume",
16437
16469
  threadId,
16438
16470
  "--dangerously-bypass-approvals-and-sandbox",
@@ -16530,7 +16562,8 @@ codeCommand.command("gemini").description("Open Gemini CLI with Orbh session tra
16530
16562
  writeSession(sessionsDir, fresh);
16531
16563
  });
16532
16564
  }
16533
- const child = spawn7("gemini", args, {
16565
+ const geminiCmd = resolveCommand("gemini");
16566
+ const child = spawn7(geminiCmd.cmd, [...geminiCmd.prependArgs, ...args], {
16534
16567
  cwd: flintPath,
16535
16568
  stdio: "inherit",
16536
16569
  env: { ...process.env, ORBH_SESSION_ID: session.id }
@@ -16594,7 +16627,7 @@ codeCommand.command("gemini").description("Open Gemini CLI with Orbh session tra
16594
16627
  // src/commands/helper.ts
16595
16628
  import { Command as Command25 } from "commander";
16596
16629
  import pc30 from "picocolors";
16597
- import { readdirSync as readdirSync6, existsSync as existsSync12, statSync as statSync4 } from "fs";
16630
+ import { readdirSync as readdirSync6, existsSync as existsSync13, statSync as statSync4 } from "fs";
16598
16631
  import { join as join15, basename as basename5 } from "path";
16599
16632
  function extractNumberFromFile(filename, typeName) {
16600
16633
  const regex = new RegExp(`^\\(${typeName}\\)\\s+(\\d+)`, "i");
@@ -16603,7 +16636,7 @@ function extractNumberFromFile(filename, typeName) {
16603
16636
  }
16604
16637
  function collectFilesRecursively(dirPath) {
16605
16638
  const files = [];
16606
- if (!existsSync12(dirPath)) {
16639
+ if (!existsSync13(dirPath)) {
16607
16640
  return files;
16608
16641
  }
16609
16642
  const entries = readdirSync6(dirPath);
@@ -16624,7 +16657,7 @@ function collectFilesRecursively(dirPath) {
16624
16657
  }
16625
16658
  function getNextNumber(flintPath, typeName) {
16626
16659
  const meshDir = join15(flintPath, "Mesh");
16627
- if (!existsSync12(meshDir)) {
16660
+ if (!existsSync13(meshDir)) {
16628
16661
  return 1;
16629
16662
  }
16630
16663
  const allFiles = collectFilesRecursively(meshDir);
@@ -16742,7 +16775,7 @@ var featuresCommand = createFeaturesCommand({
16742
16775
  import { Command as Command27 } from "commander";
16743
16776
  import pc32 from "picocolors";
16744
16777
  var VALID_TYPES = ["codebase", "flint"];
16745
- 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) => {
16778
+ 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) => {
16746
16779
  try {
16747
16780
  const flintPath = options.path || await findFlintRoot(process.cwd());
16748
16781
  if (!flintPath) {
@@ -16907,17 +16940,17 @@ function prompt5(message) {
16907
16940
  // src/commands/update.ts
16908
16941
  import { Command as Command29 } from "commander";
16909
16942
  import pc34 from "picocolors";
16910
- import { readFileSync as readFileSync9, existsSync as existsSync13 } from "fs";
16911
- import { dirname as dirname3, join as join16 } from "path";
16943
+ import { readFileSync as readFileSync10, existsSync as existsSync14 } from "fs";
16944
+ import { dirname as dirname4, join as join16 } from "path";
16912
16945
  import { fileURLToPath as fileURLToPath3 } from "url";
16913
16946
  import { execSync as execSync4 } from "child_process";
16914
16947
  import https from "https";
16915
- var __dirname2 = dirname3(fileURLToPath3(import.meta.url));
16948
+ var __dirname2 = dirname4(fileURLToPath3(import.meta.url));
16916
16949
  function readPkgVersion() {
16917
16950
  for (const rel of ["../..", ".."]) {
16918
16951
  const p = join16(__dirname2, rel, "package.json");
16919
- if (existsSync13(p)) {
16920
- return JSON.parse(readFileSync9(p, "utf-8")).version;
16952
+ if (existsSync14(p)) {
16953
+ return JSON.parse(readFileSync10(p, "utf-8")).version;
16921
16954
  }
16922
16955
  }
16923
16956
  throw new Error("Could not determine current version");
@@ -17792,8 +17825,8 @@ var tinderboxCommand = new Command35("tinderbox").description("Orchestrate opera
17792
17825
  // src/commands/orb.ts
17793
17826
  import { Command as Command36 } from "commander";
17794
17827
  import pc41 from "picocolors";
17795
- import { spawn as spawn8, spawnSync as spawnSync6, execSync as execSync5 } from "child_process";
17796
- import { existsSync as existsSync14, mkdirSync as mkdirSync4, readFileSync as readFileSync10, readdirSync as readdirSync7, statSync as statSync5, writeFileSync as writeFileSync3 } from "fs";
17828
+ import { spawn as spawn8, spawnSync as spawnSync4, execSync as execSync5 } from "child_process";
17829
+ import { existsSync as existsSync15, mkdirSync as mkdirSync4, readFileSync as readFileSync11, readdirSync as readdirSync7, statSync as statSync5, writeFileSync as writeFileSync3 } from "fs";
17797
17830
  import { join as join18 } from "path";
17798
17831
  import { homedir as homedir10 } from "os";
17799
17832
  import { createInterface as createInterface7 } from "readline";
@@ -17837,7 +17870,7 @@ function readTranscriptEntries(session, flintPath) {
17837
17870
  const transcriptPath = harness.resolveTranscriptPath(nativeId, flintPath);
17838
17871
  if (!transcriptPath) return null;
17839
17872
  try {
17840
- const content = readFileSync10(transcriptPath, "utf-8");
17873
+ const content = readFileSync11(transcriptPath, "utf-8");
17841
17874
  return harness.parseTranscript(content, { transcriptPath });
17842
17875
  } catch {
17843
17876
  return null;
@@ -17906,7 +17939,31 @@ function notify(title, message) {
17906
17939
  } catch {}
17907
17940
  }
17908
17941
 
17909
- const child = spawn(command, args, { cwd, stdio: ['ignore', 'ignore', 'pipe'] });
17942
+ // On Windows, resolve .cmd shims to the underlying node script
17943
+ let spawnCmd = command;
17944
+ let spawnArgs = args;
17945
+ if (process.platform === 'win32') {
17946
+ const where = spawnSync('where', [command], { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] });
17947
+ if (where.status === 0 && where.stdout) {
17948
+ const resolved = where.stdout.trim().split(/\r?\n/)[0].trim();
17949
+ if (resolved.toLowerCase().endsWith('.cmd')) {
17950
+ try {
17951
+ const content = readFileSync(resolved, 'utf-8');
17952
+ const matches = [...content.matchAll(/%(?:~dp0|dp0%)\\([^"%\r\n]+\.m?[jc]?[jt]s)/gi)];
17953
+ if (matches.length > 0) {
17954
+ const scriptPath = join(dirname(resolved), matches[matches.length - 1][1]);
17955
+ if (existsSync(scriptPath)) {
17956
+ spawnCmd = process.execPath;
17957
+ spawnArgs = [scriptPath, ...args];
17958
+ }
17959
+ }
17960
+ } catch {}
17961
+ } else {
17962
+ spawnCmd = resolved;
17963
+ }
17964
+ }
17965
+ }
17966
+ const child = spawn(spawnCmd, spawnArgs, { cwd, stdio: ['ignore', 'ignore', 'pipe'] });
17910
17967
 
17911
17968
  let stderr = '';
17912
17969
  child.stderr?.on('data', (chunk) => { stderr += chunk.toString(); });
@@ -18206,7 +18263,7 @@ function exportSessionTranscript(session, flintPath) {
18206
18263
  }
18207
18264
  let content;
18208
18265
  try {
18209
- content = readFileSync10(transcriptPath, "utf-8");
18266
+ content = readFileSync11(transcriptPath, "utf-8");
18210
18267
  } catch {
18211
18268
  console.log(pc41.dim("Could not read transcript file."));
18212
18269
  return;
@@ -19108,11 +19165,11 @@ orbCommand.command("watch").description("Stream a live session transcript to the
19108
19165
  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}`);
19109
19166
  console.log(pc41.dim(transcriptPath));
19110
19167
  console.log("");
19111
- if (!existsSync14(transcriptPath)) {
19168
+ if (!existsSync15(transcriptPath)) {
19112
19169
  process.stdout.write(pc41.dim("Waiting for transcript..."));
19113
19170
  await new Promise((resolve12, reject) => {
19114
19171
  const poll = setInterval(() => {
19115
- if (existsSync14(transcriptPath)) {
19172
+ if (existsSync15(transcriptPath)) {
19116
19173
  clearInterval(poll);
19117
19174
  process.stdout.write("\r\x1B[2K");
19118
19175
  resolve12();
@@ -19322,7 +19379,7 @@ orbCommand.command("ask").description("Ask a blocking question and wait for a re
19322
19379
  session.status = "blocked";
19323
19380
  writeSession(sessionsDir, session);
19324
19381
  try {
19325
- spawnSync6("osascript", ["-e", `display notification "${question.slice(0, 100)}" with title "Orbh Agent Needs Input"`], { stdio: "ignore" });
19382
+ spawnSync4("osascript", ["-e", `display notification "${question.slice(0, 100)}" with title "Orbh Agent Needs Input"`], { stdio: "ignore" });
19326
19383
  } catch {
19327
19384
  }
19328
19385
  const startTime = Date.now();
@@ -19356,7 +19413,7 @@ orbCommand.command("request").description("Post a deferred question and exit imm
19356
19413
  session.status = "deferred";
19357
19414
  writeSession(sessionsDir, session);
19358
19415
  try {
19359
- spawnSync6("osascript", ["-e", `display notification "${question.slice(0, 100)}" with title "Orbh Agent Needs Input"`], { stdio: "ignore" });
19416
+ spawnSync4("osascript", ["-e", `display notification "${question.slice(0, 100)}" with title "Orbh Agent Needs Input"`], { stdio: "ignore" });
19360
19417
  } catch {
19361
19418
  }
19362
19419
  console.log(`Question posted. Session ${shortId2(session.id)} is now deferred.`);
@@ -19392,7 +19449,7 @@ orbCommand.command("respond").description("Answer a pending question on a sessio
19392
19449
  console.log(`Response sent to session ${shortId2(session.id)}`);
19393
19450
  console.log(pc41.dim("Deferred question answered \u2014 auto-resuming session..."));
19394
19451
  const resumePrompt = `Your deferred question has been answered. Run \`flint orb requests ${session.id}\` to see the response, then continue working.`;
19395
- spawnSync6("flint", ["orb", "resume", session.id, resumePrompt], {
19452
+ spawnSync4("flint", ["orb", "resume", session.id, resumePrompt], {
19396
19453
  cwd: process.cwd(),
19397
19454
  stdio: "inherit"
19398
19455
  });
@@ -19531,15 +19588,15 @@ var steelCommand = new Command37("steel").description("Manage Steel UI state (.s
19531
19588
  );
19532
19589
 
19533
19590
  // src/index.ts
19534
- var __dirname3 = dirname4(fileURLToPath4(import.meta.url));
19535
- var pkg = JSON.parse(readFileSync11(join20(__dirname3, "..", "package.json"), "utf-8"));
19591
+ var __dirname3 = dirname5(fileURLToPath4(import.meta.url));
19592
+ var pkg = JSON.parse(readFileSync12(join20(__dirname3, "..", "package.json"), "utf-8"));
19536
19593
  var runtime = resolveRuntimeSync({ cliname: "flint" });
19537
19594
  var devAvailable = runtime.mode === "dev";
19538
19595
  var newDir = getConfigDir("flint");
19539
19596
  var oldDir = join20(homedir11(), ".flint");
19540
19597
  var intermediateDir = join20(homedir11(), ".nuucognition", ".flint");
19541
19598
  function migrateDir(sourceDir, label) {
19542
- if (!existsSync15(sourceDir)) return false;
19599
+ if (!existsSync16(sourceDir)) return false;
19543
19600
  try {
19544
19601
  const entries = readdirSync8(sourceDir);
19545
19602
  const filesToMigrate = entries.filter((e) => !e.startsWith(".DS_Store"));
@@ -19549,7 +19606,7 @@ function migrateDir(sourceDir, label) {
19549
19606
  for (const entry of filesToMigrate) {
19550
19607
  const src = join20(sourceDir, entry);
19551
19608
  const dest = join20(newDir, entry);
19552
- if (!existsSync15(dest)) {
19609
+ if (!existsSync16(dest)) {
19553
19610
  cpSync(src, dest, { recursive: true });
19554
19611
  migrated++;
19555
19612
  }
@@ -19617,7 +19674,7 @@ var COMMAND_MAP = [
19617
19674
  { featureId: "reference", command: referenceCommand },
19618
19675
  { featureId: "export", command: exportCommand },
19619
19676
  { featureId: "obsidian", command: obsidianCommand },
19620
- { featureId: "resolve", command: resolveCommand },
19677
+ { featureId: "resolve", command: resolveCommand2 },
19621
19678
  { featureId: "fulfill", command: fulfillCommand },
19622
19679
  { featureId: "update", command: updateCommand },
19623
19680
  { 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.0",
3
+ "version": "0.5.6-dev.2",
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/eslint-config": "0.0.0",
39
40
  "@nuucognition/flint-server": "0.0.1",
40
- "@nuucognition/flint": "0.1.0",
41
41
  "@nuucognition/flint-migrations": "0.1.0",
42
42
  "@nuucognition/typescript-config": "0.0.0",
43
- "@nuucognition/orbh": "0.0.1-dev.0",
44
- "@nuucognition/eslint-config": "0.0.0"
43
+ "@nuucognition/flint": "0.1.0",
44
+ "@nuucognition/orbh": "0.0.1-dev.0"
45
45
  },
46
46
  "scripts": {
47
47
  "predev": "turbo build --filter=@nuucognition/flint-cli^...",