@sonnechasser/ntrp 1.4.2 → 1.4.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 (3) hide show
  1. package/dist/index.js +167 -148
  2. package/dist/mcp/server.js +120 -101
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -849,13 +849,21 @@ var init_theme = __esm({
849
849
  });
850
850
 
851
851
  // src/services/handoff-skill.ts
852
- import { mkdirSync as mkdirSync3 } from "fs";
852
+ import { existsSync as existsSync2, mkdirSync as mkdirSync3 } from "fs";
853
853
  import { basename as basename2, join as join2 } from "path";
854
854
  import { homedir as homedir3 } from "os";
855
855
  import chalk2 from "chalk";
856
- function defaultAiInboxDir() {
856
+ function legacyAiInboxDir() {
857
857
  return join2(homedir3(), "Documents", "Claude", "ntrp-inbox");
858
858
  }
859
+ function defaultAiInboxDirDisplay() {
860
+ return "~/Documents/ntrp-inbox";
861
+ }
862
+ function defaultAiInboxDir() {
863
+ const legacy = legacyAiInboxDir();
864
+ if (existsSync2(legacy)) return legacy;
865
+ return join2(homedir3(), "Documents", "ntrp-inbox");
866
+ }
859
867
  function handoffLocations() {
860
868
  const archiveRoot = getExportsDir();
861
869
  const archiveLatestDir = join2(archiveRoot, "latest");
@@ -948,7 +956,7 @@ function filenamePattern(ctx) {
948
956
  return `${datePrefix}*${ext}`;
949
957
  }
950
958
  function buildStandingSkillMarkdown(loc = handoffLocations()) {
951
- const inboxBlock = loc.inboxDir ? `Inbox (preferred \u2014 point Claude Desktop / a project / Cursor at this folder):
959
+ const inboxBlock = loc.inboxDir ? `Inbox (preferred \u2014 point Claude, ChatGPT, Cursor, or another desktop AI at this folder):
952
960
  \`${loc.inboxDir}\`
953
961
 
954
962
  Start with:
@@ -1071,7 +1079,9 @@ function maybePrintAiInboxNudge() {
1071
1079
  if (getConfigValue("ai-inbox-nudge-seen") === "true") return;
1072
1080
  setConfigValue("ai-inbox-nudge-seen", "true");
1073
1081
  console.log(
1074
- " " + chalk2.dim("Set a pickup folder. Type /inbox set ~/Documents/Claude/ntrp-inbox then /inbox skill")
1082
+ " " + chalk2.dim(
1083
+ `Set a pickup folder. Type /inbox set ${defaultAiInboxDirDisplay()} then /inbox skill`
1084
+ )
1075
1085
  );
1076
1086
  }
1077
1087
  function printHandoffDelivered(event, opts = {}) {
@@ -1091,7 +1101,9 @@ function printStandingSkill() {
1091
1101
  console.log();
1092
1102
  console.log(" " + bold("NTRP handoff finder skill"));
1093
1103
  console.log(
1094
- " " + chalk2.dim("Paste this skill once into Claude, ChatGPT, or Cursor. Later handoffs do not print it again.")
1104
+ " " + chalk2.dim(
1105
+ "Paste this skill once into your desktop AI (Claude, ChatGPT, Cursor, \u2026). Later handoffs do not print it again."
1106
+ )
1095
1107
  );
1096
1108
  printPlainBlock(buildStandingSkillMarkdown(loc));
1097
1109
  console.log(" " + chalk2.dim("Written: ") + (loc.inboxSkill ?? loc.archiveSkill));
@@ -1144,7 +1156,7 @@ import {
1144
1156
  appendFileSync,
1145
1157
  copyFileSync,
1146
1158
  cpSync,
1147
- existsSync as existsSync2,
1159
+ existsSync as existsSync3,
1148
1160
  mkdirSync as mkdirSync4,
1149
1161
  readFileSync as readFileSync2,
1150
1162
  readdirSync,
@@ -1165,13 +1177,13 @@ function ensureExportsLayout(root = getExportsDir()) {
1165
1177
  mkdirSync4(join3(root, sub), { recursive: true });
1166
1178
  }
1167
1179
  const readme = join3(root, "README.md");
1168
- if (!existsSync2(readme)) {
1180
+ if (!existsSync3(readme)) {
1169
1181
  writeFileSync3(readme, ARCHIVE_README, "utf-8");
1170
1182
  }
1171
- if (!existsSync2(join3(root, "INDEX.md"))) {
1183
+ if (!existsSync3(join3(root, "INDEX.md"))) {
1172
1184
  writeFileSync3(join3(root, "INDEX.md"), "# NTRP exports\n\n_No exports yet._\n", "utf-8");
1173
1185
  }
1174
- if (!existsSync2(join3(root, "manifest.jsonl"))) {
1186
+ if (!existsSync3(join3(root, "manifest.jsonl"))) {
1175
1187
  writeFileSync3(join3(root, "manifest.jsonl"), "", "utf-8");
1176
1188
  }
1177
1189
  return root;
@@ -1205,7 +1217,7 @@ function ensureInboxLayout(inbox) {
1205
1217
  mkdirSync4(join3(inbox, "archive"), { recursive: true });
1206
1218
  const readme = join3(inbox, "README.md");
1207
1219
  writeFileSync3(readme, buildInboxReadme(), "utf-8");
1208
- if (!existsSync2(join3(inbox, "INDEX.md"))) {
1220
+ if (!existsSync3(join3(inbox, "INDEX.md"))) {
1209
1221
  writeFileSync3(join3(inbox, "INDEX.md"), "# NTRP AI inbox\n\n_No exports synced yet._\n", "utf-8");
1210
1222
  }
1211
1223
  }
@@ -1214,7 +1226,7 @@ function manifestPath(root = getExportsDir()) {
1214
1226
  }
1215
1227
  function readManifestEvents(root = getExportsDir()) {
1216
1228
  const path = manifestPath(root);
1217
- if (!existsSync2(path)) return [];
1229
+ if (!existsSync3(path)) return [];
1218
1230
  const text = readFileSync2(path, "utf-8");
1219
1231
  const events = [];
1220
1232
  for (const line of text.split("\n")) {
@@ -1269,7 +1281,7 @@ function updateArchiveLatest(kind, sourcePath, root) {
1269
1281
  }
1270
1282
  function copyPath(src, dest) {
1271
1283
  mkdirSync4(dirname2(dest), { recursive: true });
1272
- if (existsSync2(dest)) {
1284
+ if (existsSync3(dest)) {
1273
1285
  rmSync(dest, { recursive: true, force: true });
1274
1286
  }
1275
1287
  const st = statSync(src);
@@ -1289,7 +1301,7 @@ function regenerateIndex(root = getExportsDir()) {
1289
1301
  const withHistory = items.filter((e) => (e.previous_paths?.length ?? 0) > 0);
1290
1302
  const latestDir = join3(root, "latest");
1291
1303
  const latestLines = [];
1292
- if (existsSync2(latestDir)) {
1304
+ if (existsSync3(latestDir)) {
1293
1305
  for (const name of readdirSync(latestDir).sort()) {
1294
1306
  latestLines.push(`- \`latest/${name}\` \u2192 \`${join3(latestDir, name)}\``);
1295
1307
  }
@@ -1299,7 +1311,7 @@ function regenerateIndex(root = getExportsDir()) {
1299
1311
  "",
1300
1312
  `Archive root: \`${root}\``,
1301
1313
  "",
1302
- "Set an inbox with `/onboard` or `/inbox set`. Paste `SKILL.md` once into Claude. Later handoffs overwrite `latest-handoff.md`.",
1314
+ "Set an inbox with `/onboard` or `/inbox set`. Paste `SKILL.md` once into your desktop AI. Later handoffs overwrite `latest-handoff.md`.",
1303
1315
  "",
1304
1316
  "## Latest pointers",
1305
1317
  ""
@@ -1349,18 +1361,18 @@ function regenerateInboxIndex(inbox) {
1349
1361
  const lines = [
1350
1362
  "# NTRP AI inbox",
1351
1363
  "",
1352
- "Start here. Install `SKILL.md` once in Claude. Newest prompt: `latest-handoff.md`. Catalog: `INDEX.md`.",
1364
+ "Start here. Install `SKILL.md` once in your desktop AI. Newest prompt: `latest-handoff.md`. Catalog: `INDEX.md`.",
1353
1365
  "",
1354
1366
  `Canonical archive: \`${archiveRoot}\` (see \`${join3(archiveRoot, "INDEX.md")}\`).`,
1355
1367
  "",
1356
1368
  "## Latest pointers",
1357
1369
  ""
1358
1370
  ];
1359
- if (existsSync2(join3(inbox, "SKILL.md"))) {
1371
+ if (existsSync3(join3(inbox, "SKILL.md"))) {
1360
1372
  lines.push("- [`SKILL.md`](./SKILL.md) \u2014 standing finder. Paste once into your agent.");
1361
1373
  }
1362
1374
  const latestNames = readdirSync(inbox).filter((n) => n.startsWith("latest-")).sort();
1363
- if (latestNames.length === 0 && !existsSync2(join3(inbox, "SKILL.md"))) {
1375
+ if (latestNames.length === 0 && !existsSync3(join3(inbox, "SKILL.md"))) {
1364
1376
  lines.push("_None yet. Run a handoff after `/inbox set`._");
1365
1377
  } else {
1366
1378
  for (const name of latestNames) {
@@ -1388,7 +1400,7 @@ This folder is the landing folder for NTRP handoffs. Desktop AI tools read files
1388
1400
 
1389
1401
  ## Start here
1390
1402
 
1391
- 1. Install \`SKILL.md\` once in Claude, ChatGPT, or Cursor. Then tell the agent to open the latest NTRP handoff.
1403
+ 1. Install \`SKILL.md\` once in Claude, ChatGPT, Cursor, or another desktop AI. Then tell the agent to open the latest NTRP handoff.
1392
1404
  2. The newest prompt is \`latest-handoff.md\` (or \`latest-handoff-deck.md\` and similar).
1393
1405
  3. \`latest-pickup.md\` names the file that was just written.
1394
1406
 
@@ -1406,7 +1418,7 @@ Set the folder with \`/inbox set <path>\`. Print the skill with \`/inbox skill\`
1406
1418
  `;
1407
1419
  }
1408
1420
  function pruneInboxArchive(archiveDir, keep = INBOX_ARCHIVE_KEEP) {
1409
- if (!existsSync2(archiveDir)) return;
1421
+ if (!existsSync3(archiveDir)) return;
1410
1422
  const entries2 = readdirSync(archiveDir).map((name) => {
1411
1423
  const p = join3(archiveDir, name);
1412
1424
  try {
@@ -1422,7 +1434,7 @@ function pruneInboxArchive(archiveDir, keep = INBOX_ARCHIVE_KEEP) {
1422
1434
  function syncAiInbox(entry) {
1423
1435
  const inbox = getAiInboxDir();
1424
1436
  if (!inbox) return null;
1425
- if (!existsSync2(entry.path)) return null;
1437
+ if (!existsSync3(entry.path)) return null;
1426
1438
  ensureInboxLayout(inbox);
1427
1439
  const archiveDir = join3(inbox, "archive");
1428
1440
  mkdirSync4(archiveDir, { recursive: true });
@@ -1446,7 +1458,7 @@ function syncRecentToInbox(limit = 10) {
1446
1458
  const items = listExports({ limit });
1447
1459
  let n = 0;
1448
1460
  for (const item of items) {
1449
- if (!existsSync2(item.path)) continue;
1461
+ if (!existsSync3(item.path)) continue;
1450
1462
  const inboxPath = syncAiInbox(item);
1451
1463
  if (inboxPath) {
1452
1464
  appendManifestEvent({
@@ -1460,14 +1472,14 @@ function syncRecentToInbox(limit = 10) {
1460
1472
  }
1461
1473
  regenerateInboxIndex(inbox);
1462
1474
  regenerateIndex();
1463
- const newest = items.find((e) => existsSync2(e.path));
1475
+ const newest = items.find((e) => existsSync3(e.path));
1464
1476
  if (newest) persistHandoffSkillFiles(newest);
1465
1477
  return n;
1466
1478
  }
1467
1479
  function recordExportWrite(opts) {
1468
1480
  const root = ensureExportsLayout();
1469
1481
  const path = resolve3(opts.path);
1470
- if (!existsSync2(path)) {
1482
+ if (!existsSync3(path)) {
1471
1483
  throw new Error(`Export path does not exist: ${path}`);
1472
1484
  }
1473
1485
  updateArchiveLatest(opts.kind, path, root);
@@ -1492,14 +1504,14 @@ function moveExport(idOrPath, destDir) {
1492
1504
  if (!item) {
1493
1505
  throw new Error(`No export matching "${idOrPath}". Try /exports list.`);
1494
1506
  }
1495
- if (!existsSync2(item.path)) {
1507
+ if (!existsSync3(item.path)) {
1496
1508
  throw new Error(`Export file missing on disk: ${item.path}`);
1497
1509
  }
1498
1510
  const destRoot = resolveUserPath(destDir);
1499
1511
  mkdirSync4(destRoot, { recursive: true });
1500
1512
  const name = basename3(item.path);
1501
1513
  let destPath = join3(destRoot, name);
1502
- if (existsSync2(destPath)) {
1514
+ if (existsSync3(destPath)) {
1503
1515
  destPath = join3(destRoot, `${exportStamp()}-${name}`);
1504
1516
  }
1505
1517
  renameSync(item.path, destPath);
@@ -1527,13 +1539,13 @@ function archiveIndexPath() {
1527
1539
  }
1528
1540
  function archiveLatestHandoffPath() {
1529
1541
  const p = join3(ensureExportsLayout(), "latest", "handoff.md");
1530
- return existsSync2(p) ? p : null;
1542
+ return existsSync3(p) ? p : null;
1531
1543
  }
1532
1544
  function inboxLatestHandoffPath() {
1533
1545
  const inbox = getAiInboxDir();
1534
1546
  if (!inbox) return null;
1535
1547
  const p = join3(inbox, "latest-handoff.md");
1536
- return existsSync2(p) ? p : null;
1548
+ return existsSync3(p) ? p : null;
1537
1549
  }
1538
1550
  function formatExportLocationLines(event) {
1539
1551
  const lines = [`Archive: ${event.path}`];
@@ -1575,10 +1587,10 @@ This archive stores handoffs, reports, notes, CSV receipts, and publish packages
1575
1587
  Set a dedicated inbox for desktop AI instead of this folder:
1576
1588
 
1577
1589
  \`\`\`
1578
- /inbox set ~/Documents/Claude/ntrp-inbox
1590
+ /inbox set ~/Documents/ntrp-inbox
1579
1591
  \`\`\`
1580
1592
 
1581
- After \`/inbox set\` or the optional \`/onboard\` step, paste \`latest/SKILL.md\` once into Claude. Later \`/handoff\` overwrites \`latest-handoff.md\`. The skill is not printed again.
1593
+ After \`/inbox set\` or the optional \`/onboard\` step, paste \`latest/SKILL.md\` once into your desktop AI. Later \`/handoff\` overwrites \`latest-handoff.md\`. The skill is not printed again.
1582
1594
  `;
1583
1595
  }
1584
1596
  });
@@ -1808,7 +1820,7 @@ __export(transcript_exports, {
1808
1820
  startSessionTranscript: () => startSessionTranscript,
1809
1821
  stopSessionTranscript: () => stopSessionTranscript
1810
1822
  });
1811
- import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync5, rmSync as rmSync2 } from "fs";
1823
+ import { existsSync as existsSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync5, rmSync as rmSync2 } from "fs";
1812
1824
  import { join as join4 } from "path";
1813
1825
  function startSessionTranscript(ctx) {
1814
1826
  if (ctx.oneShot || state) return;
@@ -1819,7 +1831,7 @@ function startSessionTranscript(ctx) {
1819
1831
  function rebindSessionTranscript(ctx) {
1820
1832
  if (!state || state.sessionId === ctx.sessionId) return;
1821
1833
  const priorJson = join4(getSessionsDir(), `${state.sessionId}.json`);
1822
- if (existsSync3(priorJson)) {
1834
+ if (existsSync4(priorJson)) {
1823
1835
  finalizeCurrentFile("switched session");
1824
1836
  } else {
1825
1837
  discardSessionTranscript(state.sessionId);
@@ -1893,7 +1905,7 @@ function removeTees() {
1893
1905
  function createState(sessionId) {
1894
1906
  const filePath = transcriptPathForSession(sessionId);
1895
1907
  let base = "";
1896
- if (existsSync3(filePath)) {
1908
+ if (existsSync4(filePath)) {
1897
1909
  try {
1898
1910
  base = readFileSync3(filePath, "utf-8").trimEnd() + "\n";
1899
1911
  } catch {
@@ -2012,12 +2024,12 @@ __export(connection_exports, {
2012
2024
  run: () => run,
2013
2025
  setActiveDbPath: () => setActiveDbPath
2014
2026
  });
2015
- import { mkdirSync as mkdirSync5, existsSync as existsSync4, rmSync as rmSync3 } from "fs";
2027
+ import { mkdirSync as mkdirSync5, existsSync as existsSync5, rmSync as rmSync3 } from "fs";
2016
2028
  import { dirname as dirname3, join as join5, resolve as resolve4 } from "path";
2017
2029
  function ensureDir2() {
2018
2030
  secureNtrpHome();
2019
2031
  const dir = dirname3(activeDbPath);
2020
- if (!existsSync4(dir)) {
2032
+ if (!existsSync5(dir)) {
2021
2033
  mkdirSync5(dir, { recursive: true, mode: 448 });
2022
2034
  }
2023
2035
  }
@@ -3285,14 +3297,14 @@ CREATE INDEX IF NOT EXISTS idx_health_readings_batch ON health_readings(upload_b
3285
3297
 
3286
3298
  // src/config/install.ts
3287
3299
  import { randomUUID as randomUUID3 } from "crypto";
3288
- import { existsSync as existsSync5, mkdirSync as mkdirSync6, readFileSync as readFileSync4, unlinkSync, writeFileSync as writeFileSync6 } from "fs";
3300
+ import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync4, unlinkSync, writeFileSync as writeFileSync6 } from "fs";
3289
3301
  import { join as join6 } from "path";
3290
3302
  function installPath() {
3291
3303
  return join6(ntrpHome(), "install.json");
3292
3304
  }
3293
3305
  function ensureDir3() {
3294
3306
  const dir = ntrpHome();
3295
- if (!existsSync5(dir)) {
3307
+ if (!existsSync6(dir)) {
3296
3308
  mkdirSync6(dir, { recursive: true });
3297
3309
  }
3298
3310
  }
@@ -3304,7 +3316,7 @@ function isValidInstall(value) {
3304
3316
  function ensureInstall() {
3305
3317
  if (cachedInstall) return cachedInstall;
3306
3318
  const path = installPath();
3307
- if (existsSync5(path)) {
3319
+ if (existsSync6(path)) {
3308
3320
  try {
3309
3321
  const parsed = JSON.parse(readFileSync4(path, "utf-8"));
3310
3322
  if (isValidInstall(parsed)) {
@@ -3340,7 +3352,7 @@ var init_install = __esm({
3340
3352
  });
3341
3353
 
3342
3354
  // src/config/progress-migrate.ts
3343
- import { existsSync as existsSync6, readFileSync as readFileSync5, renameSync as renameSync2, writeFileSync as writeFileSync7 } from "fs";
3355
+ import { existsSync as existsSync7, readFileSync as readFileSync5, renameSync as renameSync2, writeFileSync as writeFileSync7 } from "fs";
3344
3356
  import { join as join7 } from "path";
3345
3357
  function legacyStatePath() {
3346
3358
  return join7(ntrpHome(), "state.json");
@@ -3357,9 +3369,9 @@ function isValidLegacyState(value) {
3357
3369
  return s.schema_version === 1 && typeof s.total_minutes_saved === "number" && Array.isArray(s.credits) && Array.isArray(s.milestones_unlocked);
3358
3370
  }
3359
3371
  function migrateLegacyStateIfNeeded(installId) {
3360
- if (existsSync6(progressPath())) return null;
3372
+ if (existsSync7(progressPath())) return null;
3361
3373
  const legacyPath = legacyStatePath();
3362
- if (!existsSync6(legacyPath)) return null;
3374
+ if (!existsSync7(legacyPath)) return null;
3363
3375
  try {
3364
3376
  const parsed = JSON.parse(readFileSync5(legacyPath, "utf-8"));
3365
3377
  if (!isValidLegacyState(parsed)) return null;
@@ -3476,7 +3488,7 @@ var init_usage_backfill = __esm({
3476
3488
  });
3477
3489
 
3478
3490
  // src/config/progress.ts
3479
- import { existsSync as existsSync7, mkdirSync as mkdirSync7, readFileSync as readFileSync6, unlinkSync as unlinkSync2, writeFileSync as writeFileSync8 } from "fs";
3491
+ import { existsSync as existsSync8, mkdirSync as mkdirSync7, readFileSync as readFileSync6, unlinkSync as unlinkSync2, writeFileSync as writeFileSync8 } from "fs";
3480
3492
  import { join as join8 } from "path";
3481
3493
  function progressPath2() {
3482
3494
  return join8(ntrpHome(), "progress.json");
@@ -3489,7 +3501,7 @@ function legacyStateBackupPath2() {
3489
3501
  }
3490
3502
  function ensureDir4() {
3491
3503
  const dir = ntrpHome();
3492
- if (!existsSync7(dir)) {
3504
+ if (!existsSync8(dir)) {
3493
3505
  mkdirSync7(dir, { recursive: true });
3494
3506
  }
3495
3507
  }
@@ -3520,7 +3532,7 @@ function reconcileInstallId(state2) {
3520
3532
  }
3521
3533
  function readProgressFile() {
3522
3534
  const path = progressPath2();
3523
- if (!existsSync7(path)) return { state: null, changed: false };
3535
+ if (!existsSync8(path)) return { state: null, changed: false };
3524
3536
  try {
3525
3537
  const parsed = JSON.parse(readFileSync6(path, "utf-8"));
3526
3538
  if (!isValidProgress(parsed)) return { state: null, changed: false };
@@ -3568,7 +3580,7 @@ function saveProgress(state2) {
3568
3580
  function wipeProgressFiles() {
3569
3581
  installMismatchWarned = false;
3570
3582
  for (const path of [progressPath2(), legacyStatePath2(), legacyStateBackupPath2()]) {
3571
- if (existsSync7(path)) {
3583
+ if (existsSync8(path)) {
3572
3584
  unlinkSync2(path);
3573
3585
  }
3574
3586
  }
@@ -4283,7 +4295,7 @@ __export(providers_exports, {
4283
4295
  resetProvidersCache: () => resetProvidersCache,
4284
4296
  saveCustomProvider: () => saveCustomProvider
4285
4297
  });
4286
- import { existsSync as existsSync8, readFileSync as readFileSync7 } from "fs";
4298
+ import { existsSync as existsSync9, readFileSync as readFileSync7 } from "fs";
4287
4299
  import { join as join9 } from "path";
4288
4300
  function providersPath() {
4289
4301
  return join9(ntrpHome(), "providers.json");
@@ -4291,7 +4303,7 @@ function providersPath() {
4291
4303
  function loadCustomProviders() {
4292
4304
  if (cachedEntries) return cachedEntries;
4293
4305
  const path = providersPath();
4294
- if (!existsSync8(path)) {
4306
+ if (!existsSync9(path)) {
4295
4307
  cachedEntries = [];
4296
4308
  return cachedEntries;
4297
4309
  }
@@ -5080,7 +5092,7 @@ var init_openai_compat = __esm({
5080
5092
  });
5081
5093
 
5082
5094
  // src/ai/llm/models-cache.ts
5083
- import { existsSync as existsSync9, readFileSync as readFileSync8, writeFileSync as writeFileSync9 } from "fs";
5095
+ import { existsSync as existsSync10, readFileSync as readFileSync8, writeFileSync as writeFileSync9 } from "fs";
5084
5096
  import { join as join10 } from "path";
5085
5097
  function cachePath() {
5086
5098
  return join10(ntrpHome(), "models.json");
@@ -5088,7 +5100,7 @@ function cachePath() {
5088
5100
  function loadFile() {
5089
5101
  if (cached) return cached;
5090
5102
  const path = cachePath();
5091
- if (!existsSync9(path)) {
5103
+ if (!existsSync10(path)) {
5092
5104
  cached = { version: 1, providers: {} };
5093
5105
  return cached;
5094
5106
  }
@@ -5765,7 +5777,7 @@ __export(pseudonymize_exports, {
5765
5777
  wipePrivacyStore: () => wipePrivacyStore
5766
5778
  });
5767
5779
  import { createHmac, randomBytes } from "crypto";
5768
- import { existsSync as existsSync10, mkdirSync as mkdirSync8, readFileSync as readFileSync10, rmSync as rmSync4, chmodSync as chmodSync2 } from "fs";
5780
+ import { existsSync as existsSync11, mkdirSync as mkdirSync8, readFileSync as readFileSync10, rmSync as rmSync4, chmodSync as chmodSync2 } from "fs";
5769
5781
  import { join as join11 } from "path";
5770
5782
  function privacyDir() {
5771
5783
  return join11(ntrpHome(), "privacy");
@@ -5784,7 +5796,7 @@ function chmodQuiet2(path, mode) {
5784
5796
  }
5785
5797
  function ensurePrivacyDir() {
5786
5798
  const dir = privacyDir();
5787
- if (!existsSync10(dir)) {
5799
+ if (!existsSync11(dir)) {
5788
5800
  mkdirSync8(dir, { recursive: true, mode: 448 });
5789
5801
  }
5790
5802
  chmodQuiet2(dir, 448);
@@ -5821,7 +5833,7 @@ function rebuildIndexes() {
5821
5833
  function loadSecret() {
5822
5834
  ensurePrivacyDir();
5823
5835
  const path = secretPath();
5824
- if (existsSync10(path)) {
5836
+ if (existsSync11(path)) {
5825
5837
  const raw = readFileSync10(path);
5826
5838
  const buf = raw.length >= 32 ? raw.subarray(0, 32) : Buffer.from(raw.toString("utf-8").trim(), "hex");
5827
5839
  if (buf.length >= 16) return buf.length === 32 ? buf : Buffer.concat([buf], 32);
@@ -5835,7 +5847,7 @@ function loadLexicon() {
5835
5847
  ensurePrivacyDir();
5836
5848
  secret = loadSecret();
5837
5849
  entries = [];
5838
- if (existsSync10(lexiconPath())) {
5850
+ if (existsSync11(lexiconPath())) {
5839
5851
  try {
5840
5852
  const parsed = JSON.parse(readFileSync10(lexiconPath(), "utf-8"));
5841
5853
  if (parsed?.version === 1 && Array.isArray(parsed.entries)) {
@@ -6127,7 +6139,7 @@ function wipePrivacyStore() {
6127
6139
  loaded = false;
6128
6140
  dirty = false;
6129
6141
  const dir = privacyDir();
6130
- if (existsSync10(dir)) {
6142
+ if (existsSync11(dir)) {
6131
6143
  rmSync4(dir, { recursive: true, force: true });
6132
6144
  }
6133
6145
  }
@@ -6267,10 +6279,10 @@ var init_pseudonymize = __esm({
6267
6279
  });
6268
6280
 
6269
6281
  // src/config/profile.ts
6270
- import { readFileSync as readFileSync11, writeFileSync as writeFileSync10, existsSync as existsSync11, mkdirSync as mkdirSync9 } from "fs";
6282
+ import { readFileSync as readFileSync11, writeFileSync as writeFileSync10, existsSync as existsSync12, mkdirSync as mkdirSync9 } from "fs";
6271
6283
  import { join as join12 } from "path";
6272
6284
  function ensureDir5() {
6273
- if (!existsSync11(NTRP_DIR3)) {
6285
+ if (!existsSync12(NTRP_DIR3)) {
6274
6286
  mkdirSync9(NTRP_DIR3, { recursive: true });
6275
6287
  }
6276
6288
  }
@@ -6278,14 +6290,14 @@ function profilePath() {
6278
6290
  return PROFILE_PATH;
6279
6291
  }
6280
6292
  function profileExists() {
6281
- return existsSync11(PROFILE_PATH);
6293
+ return existsSync12(PROFILE_PATH);
6282
6294
  }
6283
6295
  function isProfileConfigured(profile = loadProfile()) {
6284
6296
  if (!profile) return false;
6285
6297
  return profile.company_name.trim().length > 0;
6286
6298
  }
6287
6299
  function loadProfile() {
6288
- if (!existsSync11(PROFILE_PATH)) return null;
6300
+ if (!existsSync12(PROFILE_PATH)) return null;
6289
6301
  try {
6290
6302
  const parsed = JSON.parse(readFileSync11(PROFILE_PATH, "utf-8"));
6291
6303
  if (!parsed || typeof parsed !== "object") return null;
@@ -6341,7 +6353,7 @@ __export(lexicon_seed_exports, {
6341
6353
  seedOperatorIdentity: () => seedOperatorIdentity,
6342
6354
  wipePrivacyStore: () => wipePrivacyStore2
6343
6355
  });
6344
- import { existsSync as existsSync12 } from "fs";
6356
+ import { existsSync as existsSync13 } from "fs";
6345
6357
  function invalidateLexiconSeed() {
6346
6358
  dbSeedGeneration = -1;
6347
6359
  }
@@ -6403,7 +6415,7 @@ function seedOperatorIdentity(name, url) {
6403
6415
  }
6404
6416
  async function seedFromDuckDB() {
6405
6417
  const dbPath = getActiveDbPath();
6406
- if (!existsSync12(dbPath)) return;
6418
+ if (!existsSync13(dbPath)) return;
6407
6419
  const { all: all2, getConnectionGeneration: getConnectionGeneration2 } = await Promise.resolve().then(() => (init_connection(), connection_exports));
6408
6420
  const gen = getConnectionGeneration2();
6409
6421
  if (dbSeedGeneration !== -1 && gen === dbSeedGeneration) return;
@@ -6816,7 +6828,7 @@ async function llmCompleteText(surface, system, userMessage, max_tokens, ctx) {
6816
6828
  }
6817
6829
  async function llmStreamText(surface, system, userMessage, max_tokens, ctx) {
6818
6830
  let fullText = "";
6819
- let meta = { model_used: "unknown", provider_used: "anthropic", failover: false };
6831
+ let meta = { model_used: "unknown", provider_used: "unknown", failover: false };
6820
6832
  for await (const event of streamWithFailover(
6821
6833
  {
6822
6834
  surface,
@@ -7120,7 +7132,7 @@ var init_errors2 = __esm({
7120
7132
 
7121
7133
  // src/strategies/readers.ts
7122
7134
  import { createHash } from "crypto";
7123
- import { existsSync as existsSync13, readFileSync as readFileSync12 } from "fs";
7135
+ import { existsSync as existsSync14, readFileSync as readFileSync12 } from "fs";
7124
7136
  import { extname, resolve as resolve5 } from "path";
7125
7137
  import { parse as parseYaml } from "yaml";
7126
7138
  import { PDFParse } from "pdf-parse";
@@ -7130,7 +7142,7 @@ async function readStrategyFile(pathOrDash) {
7130
7142
  return createDocument("stdin", null, text2, {});
7131
7143
  }
7132
7144
  const sourcePath = resolve5(pathOrDash);
7133
- if (!existsSync13(sourcePath)) {
7145
+ if (!existsSync14(sourcePath)) {
7134
7146
  throw new NtrpError("strategy_file_not_found", `Strategy file not found: ${pathOrDash}`, 2 /* Usage */);
7135
7147
  }
7136
7148
  const ext = extname(sourcePath).toLowerCase();
@@ -7199,7 +7211,7 @@ var init_readers = __esm({
7199
7211
  });
7200
7212
 
7201
7213
  // src/memory/knowledge.ts
7202
- import { existsSync as existsSync14, readFileSync as readFileSync13, appendFileSync as appendFileSync2, readdirSync as readdirSync2 } from "fs";
7214
+ import { existsSync as existsSync15, readFileSync as readFileSync13, appendFileSync as appendFileSync2, readdirSync as readdirSync2 } from "fs";
7203
7215
  import { join as join13 } from "path";
7204
7216
  import { randomUUID as randomUUID4 } from "crypto";
7205
7217
  function knowledgePath() {
@@ -7207,7 +7219,7 @@ function knowledgePath() {
7207
7219
  }
7208
7220
  function loadKnowledgeChunks() {
7209
7221
  const path = knowledgePath();
7210
- if (!existsSync14(path)) return [];
7222
+ if (!existsSync15(path)) return [];
7211
7223
  const out = [];
7212
7224
  for (const line of readFileSync13(path, "utf-8").split("\n")) {
7213
7225
  const trimmed = line.trim();
@@ -7298,7 +7310,7 @@ var init_knowledge = __esm({
7298
7310
  });
7299
7311
 
7300
7312
  // src/ai/privacy.ts
7301
- import { existsSync as existsSync15, mkdirSync as mkdirSync10, appendFileSync as appendFileSync3 } from "fs";
7313
+ import { existsSync as existsSync16, mkdirSync as mkdirSync10, appendFileSync as appendFileSync3 } from "fs";
7302
7314
  import { homedir as homedir4 } from "os";
7303
7315
  import { join as join14 } from "path";
7304
7316
  function scrubSensitiveText(text) {
@@ -7319,7 +7331,7 @@ function stripPII(obj) {
7319
7331
  return out;
7320
7332
  }
7321
7333
  function ensureAuditDir() {
7322
- if (!existsSync15(AUDIT_DIR)) {
7334
+ if (!existsSync16(AUDIT_DIR)) {
7323
7335
  mkdirSync10(AUDIT_DIR, { recursive: true });
7324
7336
  }
7325
7337
  }
@@ -7435,14 +7447,14 @@ __export(playbook_exports, {
7435
7447
  matchTriggeredPlays: () => matchTriggeredPlays,
7436
7448
  withKnownRecommendedPlays: () => withKnownRecommendedPlays
7437
7449
  });
7438
- import { existsSync as existsSync16, readFileSync as readFileSync14, appendFileSync as appendFileSync4 } from "fs";
7450
+ import { existsSync as existsSync17, readFileSync as readFileSync14, appendFileSync as appendFileSync4 } from "fs";
7439
7451
  import { join as join15 } from "path";
7440
7452
  function playsPath() {
7441
7453
  return join15(getMemoryDir(), PLAYS_FILE);
7442
7454
  }
7443
7455
  function getCustomPlays() {
7444
7456
  const path = playsPath();
7445
- if (!existsSync16(path)) return [];
7457
+ if (!existsSync17(path)) return [];
7446
7458
  const out = [];
7447
7459
  for (const line of readFileSync14(path, "utf-8").split("\n")) {
7448
7460
  const trimmed = line.trim();
@@ -8330,7 +8342,7 @@ __export(store_exports2, {
8330
8342
  rewriteJsonl: () => rewriteJsonl,
8331
8343
  scrubText: () => scrubText
8332
8344
  });
8333
- import { existsSync as existsSync17, readFileSync as readFileSync15, appendFileSync as appendFileSync5, readdirSync as readdirSync4, writeFileSync as writeFileSync12 } from "fs";
8345
+ import { existsSync as existsSync18, readFileSync as readFileSync15, appendFileSync as appendFileSync5, readdirSync as readdirSync4, writeFileSync as writeFileSync12 } from "fs";
8334
8346
  import { join as join18 } from "path";
8335
8347
  import { randomUUID as randomUUID5 } from "crypto";
8336
8348
  function memPath(file) {
@@ -8338,7 +8350,7 @@ function memPath(file) {
8338
8350
  }
8339
8351
  function readJsonl(file) {
8340
8352
  const path = memPath(file);
8341
- if (!existsSync17(path)) return [];
8353
+ if (!existsSync18(path)) return [];
8342
8354
  const out = [];
8343
8355
  for (const line of readFileSync15(path, "utf-8").split("\n")) {
8344
8356
  const trimmed = line.trim();
@@ -8717,7 +8729,7 @@ __export(context_exports, {
8717
8729
  transcriptPathForSession: () => transcriptPathForSession
8718
8730
  });
8719
8731
  import { basename as basename5, join as join19, resolve as resolve7, sep as sep4 } from "path";
8720
- import { existsSync as existsSync18, mkdirSync as mkdirSync11, writeFileSync as writeFileSync13, readFileSync as readFileSync16, readdirSync as readdirSync5, statSync as statSync3, rmSync as rmSync5 } from "fs";
8732
+ import { existsSync as existsSync19, mkdirSync as mkdirSync11, writeFileSync as writeFileSync13, readFileSync as readFileSync16, readdirSync as readdirSync5, statSync as statSync3, rmSync as rmSync5 } from "fs";
8721
8733
  import { homedir as homedir6 } from "os";
8722
8734
  import { randomUUID as randomUUID6 } from "crypto";
8723
8735
  function isSessionStale(s) {
@@ -8736,14 +8748,14 @@ function ntrpHomeDir() {
8736
8748
  }
8737
8749
  function getSessionsDir() {
8738
8750
  const dir = join19(ntrpHomeDir(), "sessions");
8739
- if (!existsSync18(dir)) {
8751
+ if (!existsSync19(dir)) {
8740
8752
  mkdirSync11(dir, { recursive: true });
8741
8753
  }
8742
8754
  return dir;
8743
8755
  }
8744
8756
  function getDatasetsDir() {
8745
8757
  const dir = join19(ntrpHomeDir(), "datasets");
8746
- if (!existsSync18(dir)) {
8758
+ if (!existsSync19(dir)) {
8747
8759
  mkdirSync11(dir, { recursive: true });
8748
8760
  }
8749
8761
  return dir;
@@ -9754,7 +9766,7 @@ var init_admin_confirm = __esm({
9754
9766
  });
9755
9767
 
9756
9768
  // src/services/scratch-wipe.ts
9757
- import { existsSync as existsSync19, rmSync as rmSync6, unlinkSync as unlinkSync3 } from "fs";
9769
+ import { existsSync as existsSync20, rmSync as rmSync6, unlinkSync as unlinkSync3 } from "fs";
9758
9770
  import { join as join20 } from "path";
9759
9771
  async function performScratchWipe(opts = {}) {
9760
9772
  const home = ntrpHome();
@@ -9784,7 +9796,7 @@ async function performScratchWipe(opts = {}) {
9784
9796
  );
9785
9797
  }
9786
9798
  for (const { path, kind } of targets) {
9787
- if (!existsSync19(path)) continue;
9799
+ if (!existsSync20(path)) continue;
9788
9800
  try {
9789
9801
  if (kind === "dir") {
9790
9802
  rmSync6(path, { recursive: true, force: true });
@@ -12336,11 +12348,11 @@ var init_guide_slides = __esm({
12336
12348
  };
12337
12349
  HANDOFF = {
12338
12350
  id: "handoff",
12339
- label: "Ship work to Claude",
12340
- tagline: "Teach the inbox once. Later, tell Claude to pick it up.",
12351
+ label: "Ship work to your AI",
12352
+ tagline: "Teach the inbox once. Later, tell your AI to pick it up.",
12341
12353
  visual: {
12342
12354
  kind: "layer_stack",
12343
- caption: "You and Claude find and open the file. NTRP only writes.",
12355
+ caption: "You and your AI find and open the file. NTRP only writes.",
12344
12356
  layers: [
12345
12357
  { label: "Set a pickup folder (demo, onboard, or /inbox set)" },
12346
12358
  { label: "Paste the finder skill once (/inbox skill)", highlight: true },
@@ -12349,18 +12361,18 @@ var init_guide_slides = __esm({
12349
12361
  ]
12350
12362
  },
12351
12363
  lines: [
12352
- 'Type "ship a board deck" or type /handoff. Files land in ~/Documents/Claude/ntrp-inbox by default. Type /inbox set to change the folder.',
12364
+ 'Type "ship a board deck" or type /handoff. Files land in ~/Documents/ntrp-inbox by default. Type /inbox set to change the folder.',
12353
12365
  "",
12354
- "During demo or company setup, or any time, type /inbox skill. Paste a standing finder into Claude, ChatGPT, or Cursor once. That skill tells the tool to follow latest-handoff.md and INDEX.md.",
12366
+ "During demo or company setup, or any time, type /inbox skill. Paste a standing finder into Claude, ChatGPT, Cursor, or another desktop AI once. That skill tells the tool to follow latest-handoff.md and INDEX.md.",
12355
12367
  "",
12356
- 'After that, each /handoff prints "Handoff ready". You will not get a paste block every write. Tell Claude: pick up the latest NTRP handoff.',
12368
+ 'After that, each /handoff prints "Handoff ready". You will not get a paste block every write. Tell your AI: pick up the latest NTRP handoff.',
12357
12369
  "",
12358
- "If you skipped this step, NTRP asks once when you load your own data. Skip then, and type /inbox set ~/Documents/Claude/ntrp-inbox. Then type /inbox skill. Type /handoff skill to reprint the same finder."
12370
+ "If you skipped this step, NTRP asks once when you load your own data. Skip then, and type /inbox set ~/Documents/ntrp-inbox. Then type /inbox skill. Type /handoff skill to reprint the same finder."
12359
12371
  ],
12360
12372
  deepdive: [
12361
12373
  "Inbox copies: latest-handoff.md, latest-pickup.md, SKILL.md, INDEX.md. Dated files also live under ~/.ntrp/exports/.",
12362
12374
  "Type /exports to list writes. Type /inbox show to print the folder and the latest pointer. Type /handoff --print to show the prompt body in the terminal.",
12363
- "Audience-framed Metric definitions append to decks and reports. Claude then has the same glossary you walked.",
12375
+ "Audience-framed Metric definitions append to decks and reports. Your AI then has the same glossary you walked.",
12364
12376
  "Type /end to close a session. NTRP writes a transcript plus a 1-page context brief under ~/.ntrp/sessions/."
12365
12377
  ]
12366
12378
  };
@@ -12556,7 +12568,7 @@ function paintIntro(opts) {
12556
12568
  "",
12557
12569
  "Vital signs (after) \u2014 Freshness, Flow Rate, Drop Rate, Signal:Noise, Thread Depth \u2014 NTRP's own ontology. Each has a dollar translation. Scores gate in layer order: first red wins.",
12558
12570
  "",
12559
- "How to use NTRP (after vitals) \u2014 talk in English, ask without a key, ship a handoff to Claude once, stay in the diagnose \u2192 plan loop.",
12571
+ "How to use NTRP (after vitals) \u2014 talk in English, ask without a key, ship a handoff to your AI once, stay in the diagnose \u2192 plan loop.",
12560
12572
  "",
12561
12573
  chalk10.dim("No AI key needed for this tour. Press Enter to advance; type /deepdive (or d) on any slide for more.")
12562
12574
  ],
@@ -12576,7 +12588,7 @@ function paintClose(opts) {
12576
12588
  ` ${paint("accent", "/diagnose")} \u2014 five vital signs + dollars at risk`,
12577
12589
  ` ${paint("accent", "/metrics")} \u2014 SaaS scorecard (ARR, NRR, coverage\u2026)`,
12578
12590
  ` ${paint("accent", "/deepdive")} \u2014 replay this tour \xB7 ${paint("accent", "/deepdive guide")} how-to only`,
12579
- ` ${paint("accent", "/handoff")} \u2014 ship a file; teach Claude the inbox once (/inbox skill)`,
12591
+ ` ${paint("accent", "/handoff")} \u2014 ship a file; teach the inbox once (/inbox skill)`,
12580
12592
  ` ${paint("accent", "/strategy")} \u2014 measurable plan \xB7 ${paint("accent", "/help")} shortcuts`,
12581
12593
  "",
12582
12594
  "Fourteen more SaaS metrics live behind /deepdive list \u2014 including unit economics that unlock when spend data lands.",
@@ -12744,7 +12756,7 @@ async function offerFirstRunTour(ctx) {
12744
12756
  console.log();
12745
12757
  console.log(" " + bold("Onboarding tour") + chalk10.dim(" \u2014 ~3 minutes, no AI key required"));
12746
12758
  console.log(
12747
- " " + chalk10.dim("SaaS numbers, five vitals, then how to talk to NTRP and ship work to Claude.")
12759
+ " " + chalk10.dim("SaaS numbers, five vitals, then how to talk to NTRP and ship work to your AI.")
12748
12760
  );
12749
12761
  const tourDefault = firstRunTourDefaultChoice();
12750
12762
  if (tourDefault === "skip") {
@@ -16237,7 +16249,7 @@ __export(play_outcomes_exports, {
16237
16249
  listPlayOutcomes: () => listPlayOutcomes,
16238
16250
  recordPlayOutcomes: () => recordPlayOutcomes
16239
16251
  });
16240
- import { existsSync as existsSync20, readFileSync as readFileSync17, appendFileSync as appendFileSync6 } from "fs";
16252
+ import { existsSync as existsSync21, readFileSync as readFileSync17, appendFileSync as appendFileSync6 } from "fs";
16241
16253
  import { join as join21 } from "path";
16242
16254
  import { randomUUID as randomUUID7 } from "crypto";
16243
16255
  function outcomesPath() {
@@ -16245,7 +16257,7 @@ function outcomesPath() {
16245
16257
  }
16246
16258
  function listPlayOutcomes() {
16247
16259
  const path = outcomesPath();
16248
- if (!existsSync20(path)) return [];
16260
+ if (!existsSync21(path)) return [];
16249
16261
  const out = [];
16250
16262
  for (const line of readFileSync17(path, "utf-8").split("\n")) {
16251
16263
  const trimmed = line.trim();
@@ -19238,7 +19250,7 @@ var init_markdown = __esm({
19238
19250
  import chalk16 from "chalk";
19239
19251
  function formatLlmAttribution(meta) {
19240
19252
  if (!meta.model_used) return null;
19241
- const provider = meta.provider_used ?? "anthropic";
19253
+ const provider = meta.provider_used ?? "unknown";
19242
19254
  let line = `via ${formatModelLabel(provider, meta.model_used)}`;
19243
19255
  if (meta.failover) {
19244
19256
  line += " (auto-failover)";
@@ -19714,16 +19726,16 @@ var init_terminal = __esm({
19714
19726
  });
19715
19727
 
19716
19728
  // src/demo/taxonomy-cache.ts
19717
- import { readFileSync as readFileSync18, writeFileSync as writeFileSync14, existsSync as existsSync21, mkdirSync as mkdirSync12, unlinkSync as unlinkSync4 } from "fs";
19729
+ import { readFileSync as readFileSync18, writeFileSync as writeFileSync14, existsSync as existsSync22, mkdirSync as mkdirSync12, unlinkSync as unlinkSync4 } from "fs";
19718
19730
  import { homedir as homedir7 } from "os";
19719
19731
  import { join as join22 } from "path";
19720
19732
  function ensureDir6() {
19721
- if (!existsSync21(NTRP_DIR4)) {
19733
+ if (!existsSync22(NTRP_DIR4)) {
19722
19734
  mkdirSync12(NTRP_DIR4, { recursive: true });
19723
19735
  }
19724
19736
  }
19725
19737
  function loadCachedTaxonomy(profile) {
19726
- if (!existsSync21(TAXONOMY_PATH)) return null;
19738
+ if (!existsSync22(TAXONOMY_PATH)) return null;
19727
19739
  try {
19728
19740
  const parsed = JSON.parse(readFileSync18(TAXONOMY_PATH, "utf-8"));
19729
19741
  if (!parsed || typeof parsed !== "object") return null;
@@ -19738,7 +19750,7 @@ function saveCachedTaxonomy(taxonomy) {
19738
19750
  writeFileSync14(TAXONOMY_PATH, JSON.stringify(taxonomy, null, 2) + "\n");
19739
19751
  }
19740
19752
  function invalidateTaxonomy() {
19741
- if (existsSync21(TAXONOMY_PATH)) {
19753
+ if (existsSync22(TAXONOMY_PATH)) {
19742
19754
  try {
19743
19755
  unlinkSync4(TAXONOMY_PATH);
19744
19756
  } catch {
@@ -20208,7 +20220,7 @@ __export(inbox_setup_exports, {
20208
20220
  shouldOfferInboxSkillSetup: () => shouldOfferInboxSkillSetup
20209
20221
  });
20210
20222
  import chalk19 from "chalk";
20211
- import { existsSync as existsSync22 } from "fs";
20223
+ import { existsSync as existsSync23 } from "fs";
20212
20224
  function markDemoOffered() {
20213
20225
  setConfigValue("ai-inbox-nudge-seen", "true");
20214
20226
  }
@@ -20225,7 +20237,7 @@ function shouldOfferInboxSkillSetup(beat) {
20225
20237
  return !hasProductionOffered();
20226
20238
  }
20227
20239
  function printSkipHint(beat) {
20228
- const setCmd = paint("accent", "/inbox set ~/Documents/Claude/ntrp-inbox");
20240
+ const setCmd = paint("accent", `/inbox set ${defaultAiInboxDirDisplay()}`);
20229
20241
  const skillCmd = paint("accent", "/inbox skill");
20230
20242
  if (beat === "demo") {
20231
20243
  console.log(
@@ -20237,13 +20249,15 @@ function printSkipHint(beat) {
20237
20249
  " " + chalk19.dim("Skipped. NTRP will not ask again. Type ") + setCmd + chalk19.dim(" then ") + skillCmd + chalk19.dim(" at any time.")
20238
20250
  );
20239
20251
  }
20240
- async function reuseInboxFolderIfPresent(session, beat, folderPath = defaultAiInboxDir()) {
20252
+ async function reuseInboxFolderIfPresent(session, beat, folderPath) {
20241
20253
  if (getAiInboxDir()) return false;
20242
- if (!existsSync22(folderPath)) return false;
20243
- console.log(" " + chalk19.dim("Pickup folder still on disk: ") + folderPath);
20254
+ const candidates = folderPath ? [folderPath] : [.../* @__PURE__ */ new Set([defaultAiInboxDir(), legacyAiInboxDir()])];
20255
+ const existing = candidates.find((p) => existsSync23(p));
20256
+ if (!existing) return false;
20257
+ console.log(" " + chalk19.dim("Pickup folder still on disk: ") + existing);
20244
20258
  const reuse = await session.confirm("Reuse this pickup folder?", true);
20245
20259
  if (!reuse) return false;
20246
- const resolved = setAiInboxDir(folderPath);
20260
+ const resolved = setAiInboxDir(existing);
20247
20261
  markDemoOffered();
20248
20262
  if (beat === "production") markProductionOffered();
20249
20263
  console.log();
@@ -20258,7 +20272,7 @@ async function offerInboxSkillSetup(session, opts = {}) {
20258
20272
  const beat = opts.beat ?? "production";
20259
20273
  if (!shouldOfferInboxSkillSetup(beat)) return;
20260
20274
  console.log();
20261
- console.log(" " + bold("Teach Claude where handoffs live"));
20275
+ console.log(" " + bold("Teach your AI where handoffs live"));
20262
20276
  console.log(
20263
20277
  " " + chalk19.dim(
20264
20278
  "Optional. NTRP copies every handoff into one folder. You paste instructions once; later /handoff just writes the file."
@@ -20269,7 +20283,10 @@ async function offerInboxSkillSetup(session, opts = {}) {
20269
20283
  }
20270
20284
  console.log();
20271
20285
  if (await reuseInboxFolderIfPresent(session, beat)) return;
20272
- const want = await session.confirm("Set a pickup folder for Claude, ChatGPT, or Cursor?", true);
20286
+ const want = await session.confirm(
20287
+ "Set a pickup folder for Claude, ChatGPT, Cursor, or another desktop AI?",
20288
+ true
20289
+ );
20273
20290
  if (!want) {
20274
20291
  if (beat === "demo") markDemoOffered();
20275
20292
  else markProductionOffered();
@@ -20301,10 +20318,12 @@ async function offerInboxSkillSetup(session, opts = {}) {
20301
20318
  console.log(" " + chalk19.dim(`Synced ${n} recent export${n === 1 ? "" : "s"}.`));
20302
20319
  }
20303
20320
  console.log(
20304
- " " + chalk19.dim("Paste this skill into Claude once. Later, tell Claude to open the latest NTRP handoff.")
20321
+ " " + chalk19.dim(
20322
+ "Paste this skill into your desktop AI once. Later, tell it to open the latest NTRP handoff."
20323
+ )
20305
20324
  );
20306
20325
  printStandingSkill();
20307
- await session.askPressEnter("Paste the skill into Claude. Then continue");
20326
+ await session.askPressEnter("Paste the skill into your AI. Then continue");
20308
20327
  console.log(" " + chalk19.dim("Done. Later handoffs write to that folder. The skill is not printed again."));
20309
20328
  console.log();
20310
20329
  }
@@ -20339,7 +20358,7 @@ __export(ingest_exports, {
20339
20358
  handler: () => handler2
20340
20359
  });
20341
20360
  import chalk20 from "chalk";
20342
- import { readFileSync as readFileSync19, existsSync as existsSync23 } from "fs";
20361
+ import { readFileSync as readFileSync19, existsSync as existsSync24 } from "fs";
20343
20362
  import { basename as basename6 } from "path";
20344
20363
  async function handler2(args, ctx) {
20345
20364
  const { positional, flags } = parseArgs2(args, [
@@ -20363,7 +20382,7 @@ async function handler2(args, ctx) {
20363
20382
  console.error(chalk20.dim(" /ingest --demo [--scenario <name>]"));
20364
20383
  process.exit(1);
20365
20384
  }
20366
- if (!existsSync23(file)) {
20385
+ if (!existsSync24(file)) {
20367
20386
  console.error(chalk20.red(` File not found: ${file}`));
20368
20387
  process.exit(1);
20369
20388
  }
@@ -20951,7 +20970,7 @@ function buildUserMessage(input) {
20951
20970
  async function* streamFindings(input, ctx) {
20952
20971
  assertReplAi(ctx);
20953
20972
  const userMessage = buildUserMessage(input);
20954
- let meta = { model_used: "unknown", provider_used: "anthropic", failover: false };
20973
+ let meta = { model_used: "unknown", provider_used: "unknown", failover: false };
20955
20974
  const scanner = new StreamingJsonArrayParser();
20956
20975
  let streamed = 0;
20957
20976
  for await (const event of streamWithFailover(
@@ -22449,9 +22468,9 @@ async function handleGetSessionBrief(input) {
22449
22468
  if (!target) {
22450
22469
  return { error: `No session matching "${raw}".` };
22451
22470
  }
22452
- const { existsSync: existsSync35, readFileSync: readFileSync24 } = await import("fs");
22471
+ const { existsSync: existsSync36, readFileSync: readFileSync24 } = await import("fs");
22453
22472
  const briefPath = contextDocPathForSession2(target.id);
22454
- if (!existsSync35(briefPath)) {
22473
+ if (!existsSync36(briefPath)) {
22455
22474
  return {
22456
22475
  session_id: target.id,
22457
22476
  error: "No context brief on disk for this session (created before brief storage existed).",
@@ -23166,7 +23185,7 @@ async function* agenticFindings(computeResult, divergences, options) {
23166
23185
  const priorMessages = priorRaw.length > 0 && typeof priorRaw[0] === "object" && priorRaw[0] !== null && "content" in priorRaw[0] ? normalizeThread(priorRaw) : priorRaw;
23167
23186
  const conversational = mode === "fresh" || mode === "think";
23168
23187
  const messages = conversational && priorMessages.length > 0 && options.userQuestion ? [...priorMessages, { role: "user", content: options.userQuestion }] : [{ role: "user", content: initialContext }];
23169
- let lastMeta = { provider_used: "anthropic", model_used: "unknown" };
23188
+ let lastMeta = { provider_used: "unknown", model_used: "unknown" };
23170
23189
  const loopGuard = new ToolLoopGuard();
23171
23190
  const allowedTools = new Set(tools.map((t) => t.name));
23172
23191
  async function callLlm(msgs, tokens, withTools) {
@@ -25132,7 +25151,7 @@ __export(new_exports, {
25132
25151
  handler: () => handler6
25133
25152
  });
25134
25153
  import chalk26 from "chalk";
25135
- import { existsSync as existsSync24 } from "fs";
25154
+ import { existsSync as existsSync25 } from "fs";
25136
25155
  import { basename as basename7 } from "path";
25137
25156
  async function handler6(args, ctx) {
25138
25157
  const { positional, flags } = parseArgs2(args, ["demo", "empty", "list-scenarios", "regen-taxonomy"]);
@@ -25154,7 +25173,7 @@ async function handler6(args, ctx) {
25154
25173
  console.error(chalk26.red(" Usage: /new <file.csv> | --demo [--scenario <name>] | --empty [--lens health|metrics]"));
25155
25174
  return;
25156
25175
  }
25157
- if (source.kind === "file" && !existsSync24(source.path)) {
25176
+ if (source.kind === "file" && !existsSync25(source.path)) {
25158
25177
  console.error(chalk26.red(` File not found: ${source.path}`));
25159
25178
  return;
25160
25179
  }
@@ -25381,7 +25400,7 @@ __export(end_exports, {
25381
25400
  handler: () => handler7
25382
25401
  });
25383
25402
  import chalk27 from "chalk";
25384
- import { existsSync as existsSync25 } from "fs";
25403
+ import { existsSync as existsSync26 } from "fs";
25385
25404
  async function handler7(args, ctx) {
25386
25405
  if (args.length > 0) {
25387
25406
  console.error(chalk27.red(" Usage: /end"));
@@ -25418,10 +25437,10 @@ async function handler7(args, ctx) {
25418
25437
  if (summary) {
25419
25438
  console.log(" " + chalk27.dim(summary));
25420
25439
  }
25421
- if (existsSync25(transcriptPathForSession(endedId))) {
25440
+ if (existsSync26(transcriptPathForSession(endedId))) {
25422
25441
  console.log(" " + chalk27.dim("Transcript: ") + chalk27.dim(transcriptPathForSession(endedId)));
25423
25442
  }
25424
- if (existsSync25(contextDocPathForSession(endedId))) {
25443
+ if (existsSync26(contextDocPathForSession(endedId))) {
25425
25444
  console.log(" " + chalk27.dim("Context brief: ") + chalk27.dim(contextDocPathForSession(endedId)));
25426
25445
  }
25427
25446
  console.log();
@@ -25443,7 +25462,7 @@ __export(session_exports, {
25443
25462
  });
25444
25463
  import chalk28 from "chalk";
25445
25464
  import { join as join23 } from "path";
25446
- import { existsSync as existsSync26 } from "fs";
25465
+ import { existsSync as existsSync27 } from "fs";
25447
25466
  async function handler8(args, ctx) {
25448
25467
  const sub = args[0];
25449
25468
  if (!sub) return listSessionsView(ctx);
@@ -25589,7 +25608,7 @@ async function pickUp(idArg, ctx) {
25589
25608
  );
25590
25609
  }
25591
25610
  const contextPath = contextDocPathForSession(target.id);
25592
- if (existsSync26(contextPath)) {
25611
+ if (existsSync27(contextPath)) {
25593
25612
  console.log(" " + chalk28.dim("Context brief: ") + chalk28.dim(contextPath));
25594
25613
  }
25595
25614
  console.log();
@@ -28799,7 +28818,7 @@ async function* strategistPlanSession(options) {
28799
28818
  })
28800
28819
  }
28801
28820
  ];
28802
- let lastMeta = { provider_used: "anthropic", model_used: "unknown" };
28821
+ let lastMeta = { provider_used: "unknown", model_used: "unknown" };
28803
28822
  const loopGuard = new ToolLoopGuard();
28804
28823
  const allowedTools = new Set(tools.map((t) => t.name));
28805
28824
  const callLlm = async (surface, withTools, maxTokens = STAGE_MAX_TOKENS) => {
@@ -31131,7 +31150,7 @@ var init_checkout = __esm({
31131
31150
  });
31132
31151
 
31133
31152
  // src/services/setup.ts
31134
- import { existsSync as existsSync27, mkdirSync as mkdirSync17, readFileSync as readFileSync20, writeFileSync as writeFileSync19 } from "fs";
31153
+ import { existsSync as existsSync28, mkdirSync as mkdirSync17, readFileSync as readFileSync20, writeFileSync as writeFileSync19 } from "fs";
31135
31154
  import { join as join29 } from "path";
31136
31155
  function setupCheck() {
31137
31156
  const home = ntrpHome();
@@ -31834,7 +31853,7 @@ async function handleDeliverFlow(input, ctx) {
31834
31853
  }
31835
31854
  console.log();
31836
31855
  console.log(" " + chalk52.bold("Deliverable preview"));
31837
- console.log(" " + chalk52.dim("NTRP writes the file to your inbox after you confirm. If you set the inbox during demo or company setup, Claude can find the folder."));
31856
+ console.log(" " + chalk52.dim("NTRP writes the file to your inbox after you confirm. If you set the inbox during demo or company setup, your AI can find the folder."));
31838
31857
  console.log(" " + chalk52.dim("\u2500".repeat(56)));
31839
31858
  const preview = draft.markdown.split("\n").slice(0, 12);
31840
31859
  for (const l of preview) {
@@ -33134,7 +33153,7 @@ __export(sessions_exports, {
33134
33153
  handler: () => handler35
33135
33154
  });
33136
33155
  import chalk62 from "chalk";
33137
- import { existsSync as existsSync28 } from "fs";
33156
+ import { existsSync as existsSync29 } from "fs";
33138
33157
  async function handler35(args, _ctx) {
33139
33158
  const sub = args[0] ?? "list";
33140
33159
  if (sub === "list" || !args[0]) {
@@ -33241,12 +33260,12 @@ function showSession(idArg) {
33241
33260
  console.log();
33242
33261
  const transcriptPath = transcriptPathForSession(session.id);
33243
33262
  const contextPath = contextDocPathForSession(session.id);
33244
- if (existsSync28(transcriptPath) || existsSync28(contextPath)) {
33263
+ if (existsSync29(transcriptPath) || existsSync29(contextPath)) {
33245
33264
  console.log(" " + chalk62.dim("\u2500".repeat(40)));
33246
- if (existsSync28(contextPath)) {
33265
+ if (existsSync29(contextPath)) {
33247
33266
  console.log(" " + chalk62.dim("Context brief: ") + chalk62.dim(contextPath));
33248
33267
  }
33249
- if (existsSync28(transcriptPath)) {
33268
+ if (existsSync29(transcriptPath)) {
33250
33269
  console.log(" " + chalk62.dim("Full transcript: ") + chalk62.dim(transcriptPath));
33251
33270
  }
33252
33271
  console.log();
@@ -33518,7 +33537,7 @@ var init_privacy_notice = __esm({
33518
33537
  "Computed scores and dollar aggregates still go to the provider you connected.",
33519
33538
  "If you turn on web retrieval, named-account queries are refused. Generic GTM terms may go to Tavily or Brave.",
33520
33539
  "A custom --base-url receives the same tokenized payload.",
33521
- "MCP hosts (for example Claude Desktop) see tokens, not account names. Use the CLI to read real names.",
33540
+ "MCP hosts (for example Claude Desktop or Cursor) see tokens, not account names. Use the CLI to read real names.",
33522
33541
  "Keys stay in ~/.ntrp/config.json on this machine (mode 600).",
33523
33542
  "NTRP is a diagnostic. It does not change CRM records or send email.",
33524
33543
  "Type /privacy to read this notice again."
@@ -34582,20 +34601,20 @@ var init_model = __esm({
34582
34601
  });
34583
34602
 
34584
34603
  // src/config/update-check.ts
34585
- import { existsSync as existsSync29, mkdirSync as mkdirSync18, readFileSync as readFileSync21, unlinkSync as unlinkSync5, writeFileSync as writeFileSync20 } from "fs";
34604
+ import { existsSync as existsSync30, mkdirSync as mkdirSync18, readFileSync as readFileSync21, unlinkSync as unlinkSync5, writeFileSync as writeFileSync20 } from "fs";
34586
34605
  import { join as join33 } from "path";
34587
34606
  function cachePath2() {
34588
34607
  return join33(ntrpHome(), "update-check.json");
34589
34608
  }
34590
34609
  function ensureDir7() {
34591
34610
  const dir = ntrpHome();
34592
- if (!existsSync29(dir)) {
34611
+ if (!existsSync30(dir)) {
34593
34612
  mkdirSync18(dir, { recursive: true });
34594
34613
  }
34595
34614
  }
34596
34615
  function loadUpdateCheckCache() {
34597
34616
  const path = cachePath2();
34598
- if (!existsSync29(path)) return null;
34617
+ if (!existsSync30(path)) return null;
34599
34618
  try {
34600
34619
  const parsed = JSON.parse(readFileSync21(path, "utf-8"));
34601
34620
  if (!parsed || typeof parsed !== "object" || typeof parsed.lastCheck !== "number" || typeof parsed.latestVersion !== "string") {
@@ -34616,7 +34635,7 @@ function isCacheFresh(cache2, ttlMs = CACHE_TTL_MS2) {
34616
34635
  }
34617
34636
  function invalidateUpdateCheckCache() {
34618
34637
  const path = cachePath2();
34619
- if (existsSync29(path)) {
34638
+ if (existsSync30(path)) {
34620
34639
  unlinkSync5(path);
34621
34640
  }
34622
34641
  }
@@ -34630,11 +34649,11 @@ var init_update_check = __esm({
34630
34649
  });
34631
34650
 
34632
34651
  // src/version.ts
34633
- import { existsSync as existsSync30, readFileSync as readFileSync22 } from "fs";
34652
+ import { existsSync as existsSync31, readFileSync as readFileSync22 } from "fs";
34634
34653
  import { dirname as dirname6, join as join34 } from "path";
34635
34654
  import { fileURLToPath } from "url";
34636
34655
  function readVersionFromPackageJson(packageJsonPath) {
34637
- if (!existsSync30(packageJsonPath)) return null;
34656
+ if (!existsSync31(packageJsonPath)) return null;
34638
34657
  try {
34639
34658
  const pkg = JSON.parse(readFileSync22(packageJsonPath, "utf-8"));
34640
34659
  if (typeof pkg.version === "string" && pkg.version.length > 0) return pkg.version;
@@ -34774,7 +34793,7 @@ __export(relaunch_exports, {
34774
34793
  resolveRelaunchEntry: () => resolveRelaunchEntry,
34775
34794
  updateRestartSummary: () => updateRestartSummary
34776
34795
  });
34777
- import { existsSync as existsSync31 } from "fs";
34796
+ import { existsSync as existsSync32 } from "fs";
34778
34797
  import { join as join35 } from "path";
34779
34798
  import { fileURLToPath as fileURLToPath2 } from "url";
34780
34799
  import { spawnSync } from "child_process";
@@ -34800,7 +34819,7 @@ function npmGlobalEntry() {
34800
34819
  const listed = spawnSync("npm", ["root", "-g"], { encoding: "utf-8" });
34801
34820
  if (listed.status !== 0) return null;
34802
34821
  const entry = join35(listed.stdout.trim(), NPM_PACKAGE, "dist/index.js");
34803
- return existsSync31(entry) ? entry : null;
34822
+ return existsSync32(entry) ? entry : null;
34804
34823
  }
34805
34824
  function thisBundleEntry() {
34806
34825
  return fileURLToPath2(import.meta.url);
@@ -34810,10 +34829,10 @@ function resolveRelaunchEntry(toVersion) {
34810
34829
  (p) => Boolean(p)
34811
34830
  );
34812
34831
  for (const entry of candidates) {
34813
- if (!existsSync31(entry)) continue;
34832
+ if (!existsSync32(entry)) continue;
34814
34833
  if (readVersionNearEntry(entry) === toVersion) return entry;
34815
34834
  }
34816
- return candidates.find((p) => existsSync31(p)) ?? thisBundleEntry();
34835
+ return candidates.find((p) => existsSync32(p)) ?? thisBundleEntry();
34817
34836
  }
34818
34837
  function relaunchArgv(toVersion) {
34819
34838
  return [resolveRelaunchEntry(toVersion)];
@@ -35336,7 +35355,7 @@ __export(exports_exports, {
35336
35355
  handler: () => handler48
35337
35356
  });
35338
35357
  import chalk78 from "chalk";
35339
- import { existsSync as existsSync32 } from "fs";
35358
+ import { existsSync as existsSync33 } from "fs";
35340
35359
  import { join as join36 } from "path";
35341
35360
  function usage4() {
35342
35361
  console.log(chalk78.dim(" Usage:"));
@@ -35448,7 +35467,7 @@ async function runInboxSet(args, ctx) {
35448
35467
  const pathArg = args.join(" ").trim();
35449
35468
  if (!pathArg) {
35450
35469
  console.error(chalk78.red(" Usage: /inbox set <path>"));
35451
- console.error(chalk78.dim(" Example: /inbox set ~/Documents/Claude/ntrp-inbox"));
35470
+ console.error(chalk78.dim(" Example: /inbox set ~/Documents/ntrp-inbox"));
35452
35471
  if (ctx.oneShot) process.exit(1);
35453
35472
  return;
35454
35473
  }
@@ -35478,7 +35497,7 @@ async function runInboxSet(args, ctx) {
35478
35497
  console.log();
35479
35498
  console.log(" " + paint("accent", "AI inbox set"));
35480
35499
  console.log(" " + chalk78.dim(setTo));
35481
- console.log(" " + chalk78.dim("Point Claude Desktop or another desktop AI at this folder."));
35500
+ console.log(" " + chalk78.dim("Point Claude, ChatGPT, Cursor, or another desktop AI at this folder."));
35482
35501
  if (n > 0) {
35483
35502
  console.log(" " + chalk78.dim(`Synced ${n} recent export${n === 1 ? "" : "s"} into the inbox.`));
35484
35503
  }
@@ -35495,7 +35514,7 @@ function runMove(args, ctx) {
35495
35514
  }
35496
35515
  try {
35497
35516
  const destDir = resolveUserPath(dest);
35498
- if (!existsSync32(destDir)) {
35517
+ if (!existsSync33(destDir)) {
35499
35518
  }
35500
35519
  const event = moveExport(idOrName, destDir);
35501
35520
  console.log();
@@ -35848,12 +35867,12 @@ args: [show|set <path>|skill|clear]
35848
35867
  handler: ../commands/exports.ts
35849
35868
  ---
35850
35869
 
35851
- Set a folder that Claude Desktop or any desktop AI can read.
35870
+ Set a folder that any desktop AI can read (Claude, ChatGPT, Cursor, \u2026).
35852
35871
  NTRP copies each handoff to that folder.
35853
35872
  NTRP overwrites \`latest-handoff.md\` and \`latest-handoff-deck.md\`. The app then finds the newest file.
35854
35873
  NTRP also writes \`SKILL.md\`. That file holds finder instructions with your paths.
35855
35874
  Demo setup offers this once. Loading your own data (CSV ingest or \`/onboard\`) asks again if the folder is not set. Skip on that production step and NTRP will not ask again. Type \`/inbox skill\` or \`/handoff skill\` to print the finder. Type \`/inbox set\` at any time.
35856
- Paste that skill once into Claude, ChatGPT, or Cursor. Later handoffs need no new paste.
35875
+ Paste that skill once into Claude, ChatGPT, Cursor, or another desktop AI. Later handoffs need no new paste.
35857
35876
  \`INDEX.md\` in that folder links to the archive.
35858
35877
  A path outside ~/.ntrp needs a confirm. Handoffs carry analysis text.
35859
35878
  \`clear\` does not delete files. It only removes the config pointer.`
@@ -36204,9 +36223,9 @@ args: [<metric>|guide|list|tour]
36204
36223
  handler: ../commands/deepdive.ts
36205
36224
  ---
36206
36225
 
36207
- CLI slide deck: SaaS refresher, five vital signs (definition, formula, visual, dollar translation), then a how-to section (talk, ask, ship to Claude, loop).
36208
- Bare \`/deepdive\` runs the full onboarding tour. Type \`/deepdive guide\` to jump to how to use NTRP (includes teaching Claude the inbox once).
36209
- Type \`/deepdive handoff\` for the ship-to-Claude slide. Type \`/deepdive <metric>\` to jump to one metric card.
36226
+ CLI slide deck: SaaS refresher, five vital signs (definition, formula, visual, dollar translation), then a how-to section (talk, ask, ship to your AI, loop).
36227
+ Bare \`/deepdive\` runs the full onboarding tour. Type \`/deepdive guide\` to jump to how to use NTRP (includes teaching the inbox once).
36228
+ Type \`/deepdive handoff\` for the ship-to-AI slide. Type \`/deepdive <metric>\` to jump to one metric card.
36210
36229
  Type \`/deepdive list\` to print the catalog. Works without an AI key. Re-run anytime from the homescreen.
36211
36230
  Live values overlay when an analysis exists.`
36212
36231
  },
@@ -36527,7 +36546,7 @@ Remaining nuances merge into a custom_context paragraph that flows into all AI s
36527
36546
  });
36528
36547
 
36529
36548
  // src/ai/prompt-parts.ts
36530
- import { existsSync as existsSync33, readFileSync as readFileSync23 } from "fs";
36549
+ import { existsSync as existsSync34, readFileSync as readFileSync23 } from "fs";
36531
36550
  import { join as join37 } from "path";
36532
36551
  function buildCompanyProfileBlock() {
36533
36552
  const p = loadProfile();
@@ -36548,7 +36567,7 @@ function buildCompanyProfileBlock() {
36548
36567
  function loadAnalystFile() {
36549
36568
  const path = join37(ntrpHome(), ANALYST_FILE_NAME);
36550
36569
  try {
36551
- if (!existsSync33(path)) return null;
36570
+ if (!existsSync34(path)) return null;
36552
36571
  const raw = sanitizeExternalText(readFileSync23(path, "utf-8").trim());
36553
36572
  if (!raw) return null;
36554
36573
  if (raw.length <= ANALYST_FILE_MAX_CHARS) return raw;
@@ -37054,7 +37073,7 @@ __export(ingest_chat_exports, {
37054
37073
  loadDemoFromChat: () => loadDemoFromChat,
37055
37074
  looksLikeFilePath: () => looksLikeFilePath
37056
37075
  });
37057
- import { existsSync as existsSync34 } from "fs";
37076
+ import { existsSync as existsSync35 } from "fs";
37058
37077
  import { basename as basename9, resolve as resolve9 } from "path";
37059
37078
  import { homedir as homedir8 } from "os";
37060
37079
  import chalk80 from "chalk";
@@ -37074,11 +37093,11 @@ function extractFilePath(input) {
37074
37093
  const m = trimmed.match(re);
37075
37094
  if (m?.[1]) {
37076
37095
  const p = expandPath(m[1]);
37077
- if (existsSync34(p)) return p;
37096
+ if (existsSync35(p)) return p;
37078
37097
  }
37079
37098
  if (!m?.[1] && re.test(trimmed) && trimmed.toLowerCase().endsWith(".csv")) {
37080
37099
  const p = expandPath(trimmed.replace(/^["']|["']$/g, ""));
37081
- if (existsSync34(p)) return p;
37100
+ if (existsSync35(p)) return p;
37082
37101
  }
37083
37102
  }
37084
37103
  return null;