neotoma 0.3.2 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -221,7 +221,7 @@ neotoma mcp config
221
221
 
222
222
  Marketing site: **https://neotoma.io** (GitHub Pages, deployed from **main**; custom domain set in repo Settings → Pages). See [Deployment](docs/infrastructure/deployment.md#marketing-site-neotomaio).
223
223
 
224
- ### Option 2: Clone repository (for development)
224
+ ### Option 2: Clone source checkout (for development)
225
225
 
226
226
  ```bash
227
227
  git clone https://github.com/markmhendrickson/neotoma.git
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
package/dist/cli/index.js CHANGED
@@ -492,7 +492,7 @@ async function validateNeotomaRepo(dir) {
492
492
  return null;
493
493
  }
494
494
  }
495
- const INIT_REQUIRED_MESSAGE = "Neotoma setup is required. Run 'neotoma init' to set repo path, or set NEOTOMA_REPO_ROOT.";
495
+ const INIT_REQUIRED_MESSAGE = "Neotoma setup is required. Run 'neotoma init' to set your Neotoma path, or set NEOTOMA_REPO_ROOT.";
496
496
  async function resolveRepoRootFromInitContext() {
497
497
  const config = await readConfig();
498
498
  let repoRoot = null;
@@ -511,7 +511,7 @@ async function persistRepoRootIfMissing(config, repoRoot) {
511
511
  if (config.repo_root)
512
512
  return;
513
513
  await writeConfig({ ...config, repo_root: repoRoot });
514
- process.stderr.write(dim("Saved repo path to config: ") + pathStyle(CONFIG_PATH) + "\n");
514
+ process.stderr.write(dim("Saved Neotoma path to config: ") + pathStyle(CONFIG_PATH) + "\n");
515
515
  }
516
516
  async function resolveAndPersistRepoRootFromInitContext() {
517
517
  const { config, repoRoot } = await resolveRepoRootFromInitContext();
@@ -520,8 +520,17 @@ async function resolveAndPersistRepoRootFromInitContext() {
520
520
  await persistRepoRootIfMissing(config, repoRoot);
521
521
  return repoRoot;
522
522
  }
523
+ /** Resolve the Neotoma package root from the running CLI install location. */
524
+ async function resolveRepoRootFromInstalledCli() {
525
+ const cliDir = path.dirname(fileURLToPath(import.meta.url));
526
+ return await findRepoRoot(cliDir);
527
+ }
523
528
  async function maybeRunInitForMissingRepo(promptEnabled) {
524
529
  let repoRoot = await resolveAndPersistRepoRootFromInitContext();
530
+ if (repoRoot)
531
+ return repoRoot;
532
+ // npm global/link installs can run from arbitrary cwd; fallback to the installed package root.
533
+ repoRoot = await resolveRepoRootFromInstalledCli();
525
534
  if (repoRoot)
526
535
  return repoRoot;
527
536
  if (!promptEnabled)
@@ -543,9 +552,9 @@ async function maybeRunInitForMissingRepo(promptEnabled) {
543
552
  return repoRoot;
544
553
  }
545
554
  async function loadNpmScripts() {
546
- const repoRoot = await resolveAndPersistRepoRootFromInitContext();
555
+ const repoRoot = (await resolveAndPersistRepoRootFromInitContext()) ?? (await resolveRepoRootFromInstalledCli());
547
556
  if (!repoRoot) {
548
- throw new Error("Not a Neotoma repo. Run from the repo root (package.json name must be 'neotoma'), run 'neotoma init' to set repo path, or set NEOTOMA_REPO_ROOT.");
557
+ throw new Error("Neotoma source checkout not found. Run from the source root (package.json name must be 'neotoma'), run 'neotoma init' to set your Neotoma path, or set NEOTOMA_REPO_ROOT.");
549
558
  }
550
559
  const pkgPath = path.join(repoRoot, "package.json");
551
560
  const raw = await fs.readFile(pkgPath, "utf-8");
@@ -1271,7 +1280,7 @@ async function pickSessionPorts(repoRoot) {
1271
1280
  return [a, b];
1272
1281
  }
1273
1282
  catch (err) {
1274
- throw new Error("Failed to pick session ports. Ensure you are in the Neotoma repo and scripts/pick-port.js exists. " +
1283
+ throw new Error("Failed to pick session ports. Ensure you are in a Neotoma source checkout and scripts/pick-port.js exists. " +
1275
1284
  (err instanceof Error ? err.message : String(err)));
1276
1285
  }
1277
1286
  }
@@ -1501,7 +1510,7 @@ program
1501
1510
  .option("--env <env>", "Preferred environment for this run: development or production (overrides configuration when starting session)")
1502
1511
  .option("--tunnel", "Start HTTPS tunnel (ngrok/cloudflared) with development/production servers; off by default")
1503
1512
  .option("--debug", "Show detailed initialization logs when starting session")
1504
- .option("--log-file <path>", "Append CLI stdout and stderr to this file (development default: repo data/logs/cli.<pid>.log when in a repo, else ~/.config/neotoma/cli.<pid>.log)")
1513
+ .option("--log-file <path>", "Append CLI stdout and stderr to this file (development default: <neotoma>/data/logs/cli.<pid>.log when a Neotoma path is configured, else ~/.config/neotoma/cli.<pid>.log)")
1505
1514
  .option("--no-log-file", "Do not append CLI output to the log file (no-op in prod)")
1506
1515
  .option("--no-update-check", "Disable update availability check");
1507
1516
  function isDebug() {
@@ -3075,12 +3084,12 @@ program
3075
3084
  let envPath = envRepoRoot ? path.join(envRepoRoot, ".env") : null;
3076
3085
  const mcpTokenEncryptionKey = randomBytes(32).toString("hex");
3077
3086
  let envContent = ""; // built after plan with final dataDir
3078
- // When not in a repo, prompt for repo path so we can create .env there.
3087
+ // When not in a source checkout, prompt for path so we can create .env there.
3079
3088
  // This runs in normal interactive init too (not only --advanced) so
3080
- // .env setup is not skipped just because init was started outside a repo.
3089
+ // .env setup is not skipped just because init was started outside a source checkout.
3081
3090
  if (!envRepoRoot && process.stdout.isTTY && !opts.skipEnv && !opts.yes) {
3082
- process.stdout.write(nl() + bullet(heading("Neotoma repo path")) + nl());
3083
- const raw = await askQuestion("Repo path [default: skip]: ");
3091
+ process.stdout.write(nl() + bullet(heading("Neotoma path")) + nl());
3092
+ const raw = await askQuestion("Neotoma path [default: skip]: ");
3084
3093
  const trimmed = raw.trim().replace(/^~(?=\/|$)/, process.env.HOME || "");
3085
3094
  if (trimmed) {
3086
3095
  const validated = await validateNeotomaRepo(trimmed);
@@ -3090,10 +3099,10 @@ program
3090
3099
  await persistRepoRootIfMissing(initConfig, envRepoRoot);
3091
3100
  envExamplePath = path.join(envRepoRoot, ".env.example");
3092
3101
  envPath = path.join(envRepoRoot, ".env");
3093
- process.stdout.write(bullet(success("Using repo: ") + pathStyle(envRepoRoot)) + "\n");
3102
+ process.stdout.write(bullet(success("Using Neotoma path: ") + pathStyle(envRepoRoot)) + "\n");
3094
3103
  }
3095
3104
  else {
3096
- process.stdout.write(bullet(warn("Not a valid Neotoma repo (package.json name must be 'neotoma'). Skipping .env setup.")) + "\n");
3105
+ process.stdout.write(bullet(warn("Not a valid Neotoma source checkout (package.json name must be 'neotoma'). Skipping .env setup.")) + "\n");
3097
3106
  }
3098
3107
  }
3099
3108
  process.stdout.write(nl());
@@ -3284,7 +3293,7 @@ program
3284
3293
  }
3285
3294
  // Create data directories and DBs (and build envContent) now that final dataDir is set
3286
3295
  envContent = `# Neotoma Environment Configuration
3287
- # Repo path is stored in ~/.config/neotoma by neotoma init (or set NEOTOMA_REPO_ROOT at runtime to override).
3296
+ # Neotoma path is stored in ~/.config/neotoma by neotoma init (or set NEOTOMA_REPO_ROOT at runtime to override).
3288
3297
 
3289
3298
  # Data directory (defaults to ./data)
3290
3299
  NEOTOMA_DATA_DIR=${dataDir}
@@ -3510,7 +3519,7 @@ NEOTOMA_MCP_TOKEN_ENCRYPTION_KEY=${mcpTokenEncryptionKey}
3510
3519
  if (!apiAlreadyRunning) {
3511
3520
  if (!repoRoot) {
3512
3521
  initAuthSummary.oauthDeferredReason =
3513
- "OAuth selected but no repo root found for temporary API startup.";
3522
+ "OAuth selected but no Neotoma source checkout was found for temporary API startup.";
3514
3523
  }
3515
3524
  else if (!isLocalHost(baseUrl)) {
3516
3525
  initAuthSummary.oauthDeferredReason =
@@ -3864,11 +3873,11 @@ NEOTOMA_MCP_TOKEN_ENCRYPTION_KEY=${mcpTokenEncryptionKey}
3864
3873
  process.stdout.write(dim("Could not check CLI instructions.") + nl());
3865
3874
  }
3866
3875
  }
3867
- // Persist repo root so "neotoma" can start servers from any cwd
3876
+ // Persist Neotoma source root so "neotoma" can start servers from any cwd
3868
3877
  let configRepoRoot = repoRoot ?? (await readConfig()).repo_root;
3869
- // In pretty mode (not json), ask for repo root if not found
3878
+ // In pretty mode (not json), ask for Neotoma path if not found
3870
3879
  if (!configRepoRoot && outputMode === "pretty" && useAdvancedPrompts) {
3871
- const pathInput = await askQuestion("Path to Neotoma repo [default: skip]: ");
3880
+ const pathInput = await askQuestion("Path to Neotoma source checkout [default: skip]: ");
3872
3881
  if (pathInput) {
3873
3882
  const validated = await validateNeotomaRepo(pathInput);
3874
3883
  if (validated)
@@ -3897,7 +3906,7 @@ NEOTOMA_MCP_TOKEN_ENCRYPTION_KEY=${mcpTokenEncryptionKey}
3897
3906
  await fs.writeFile(lateEnvPath, "");
3898
3907
  }
3899
3908
  if (outputMode === "pretty") {
3900
- process.stdout.write(bullet(success(".env created after repo path was provided.")) + "\n");
3909
+ process.stdout.write(bullet(success(".env created after Neotoma path was provided.")) + "\n");
3901
3910
  process.stdout.write(bullet(dim("Path: ") + pathStyle(lateEnvPath)) + "\n");
3902
3911
  }
3903
3912
  }
@@ -3910,7 +3919,7 @@ NEOTOMA_MCP_TOKEN_ENCRYPTION_KEY=${mcpTokenEncryptionKey}
3910
3919
  process.stdout.write(nl() + heading("✓ Neotoma initialized!") + nl());
3911
3920
  process.stdout.write(dim("Next step: run ") + pathStyle("neotoma") + dim(" to start a session.") + nl());
3912
3921
  if (!envRepoRoot) {
3913
- process.stdout.write(bullet(dim(".env is created when run from the repo, when a repo path is saved in config, or when you enter a repo path during init. Data is under ~/neotoma/data.")) + "\n");
3922
+ process.stdout.write(bullet(dim(".env is created when run from a Neotoma source checkout, when a Neotoma path is saved in config, or when you enter a Neotoma path during init. Data is under ~/neotoma/data.")) + "\n");
3914
3923
  }
3915
3924
  }
3916
3925
  catch (err) {
@@ -3948,7 +3957,7 @@ siteCommand
3948
3957
  // leave null
3949
3958
  }
3950
3959
  if (!repoRoot) {
3951
- process.stderr.write("Not a Neotoma repo. Run from the repo root or run " +
3960
+ process.stderr.write("Neotoma source checkout not found. Run from the source root or run " +
3952
3961
  pathStyle("neotoma init") +
3953
3962
  " first.\n");
3954
3963
  process.exitCode = 1;
@@ -6091,7 +6100,7 @@ apiCommand
6091
6100
  stop_ran: ran,
6092
6101
  message: ran
6093
6102
  ? "Stop command completed for port " + port + "."
6094
- : "Run from repo root to stop: node scripts/kill_port.js " + port,
6103
+ : "Run from Neotoma source root to stop: node scripts/kill_port.js " + port,
6095
6104
  }, outputMode);
6096
6105
  return;
6097
6106
  }
@@ -6101,7 +6110,7 @@ apiCommand
6101
6110
  else {
6102
6111
  process.stdout.write(bullet("To stop the API server: " +
6103
6112
  pathStyle("node scripts/kill_port.js " + port) +
6104
- " (from repo root)") + "\n");
6113
+ " (from Neotoma source root)") + "\n");
6105
6114
  }
6106
6115
  });
6107
6116
  apiCommand
@@ -6148,7 +6157,7 @@ apiCommand
6148
6157
  pathStyle("neotoma api stop") +
6149
6158
  dim(" (configured port) or ") +
6150
6159
  pathStyle("node scripts/kill_port.js <port>") +
6151
- dim(" from repo root.") +
6160
+ dim(" from Neotoma source root.") +
6152
6161
  nl());
6153
6162
  });
6154
6163
  apiCommand
@@ -8694,8 +8703,8 @@ export function buildInstallationBoxLines(mcpConfigs, cliScan, initContext, repo
8694
8703
  lines.push("");
8695
8704
  }
8696
8705
  else {
8697
- lines.push("Repo path " + mark(false) + " Not configured (run " + pathStyle("neotoma init") + " or set NEOTOMA_REPO_ROOT)");
8698
- lines.push(".env file " + mark(false) + " (set repo path first)");
8706
+ lines.push("Neotoma path " + mark(false) + " Not configured (run " + pathStyle("neotoma init") + " or set NEOTOMA_REPO_ROOT)");
8707
+ lines.push(".env file " + mark(false) + " (set Neotoma path first)");
8699
8708
  lines.push("");
8700
8709
  }
8701
8710
  const mcpByPlatform = getMcpStatusByPlatform(mcpConfigs, repoRoot ?? null);
@@ -9151,12 +9160,12 @@ export async function runCli(argv = process.argv) {
9151
9160
  const repoRoot = await resolveAndPersistRepoRootFromInitContext();
9152
9161
  const guidanceLines = [];
9153
9162
  if (!repoRoot) {
9154
- guidanceLines.push("Neotoma repo is not configured in this shell.", "Run 'neotoma init' to set repo path, or set NEOTOMA_REPO_ROOT to your Neotoma repo.");
9163
+ guidanceLines.push("Neotoma path is not configured in this shell.", "Run 'neotoma init' to set your Neotoma path, or set NEOTOMA_REPO_ROOT to a Neotoma source checkout.");
9155
9164
  }
9156
9165
  else {
9157
9166
  const envPath = path.join(repoRoot, ".env");
9158
9167
  if (!(await pathExists(envPath))) {
9159
- guidanceLines.push("Neotoma repo is configured, but .env is missing.", "Run 'neotoma init' to create .env defaults, or create " +
9168
+ guidanceLines.push("Neotoma path is configured, but .env is missing.", "Run 'neotoma init' to create .env defaults, or create " +
9160
9169
  pathStyle(envPath) +
9161
9170
  " manually.");
9162
9171
  }
@@ -9170,7 +9179,8 @@ export async function runCli(argv = process.argv) {
9170
9179
  if (noSession) {
9171
9180
  debugLog("No-session mode: showing intro panel and command menu (no REPL)");
9172
9181
  const v = version ?? (await getCliVersion());
9173
- const repoRootForLocal = await findRepoRoot(process.cwd());
9182
+ const repoRootForLocal = (await resolveAndPersistRepoRootFromInitContext()) ??
9183
+ (await resolveRepoRootFromInstalledCli());
9174
9184
  const introStatsOrFallback = repoRootForLocal
9175
9185
  ? await getDualEnvIntroStats(repoRootForLocal, LOCAL_DEV_USER_ID)
9176
9186
  : ["Production data: unavailable", "Development data: unavailable"];
@@ -9553,7 +9563,7 @@ export async function runCli(argv = process.argv) {
9553
9563
  }
9554
9564
  else {
9555
9565
  sessionRepoRoot = undefined;
9556
- debugLog("No Neotoma repo found; session only (no servers)");
9566
+ debugLog("No Neotoma source checkout found; session only (no servers)");
9557
9567
  if (version != null) {
9558
9568
  const introContent = buildIntroBoxContent(version, ["Production data: unavailable", "Development data: unavailable"], undefined);
9559
9569
  await printIntroBlock(version, [], preferredEnv, {
@@ -9561,7 +9571,7 @@ export async function runCli(argv = process.argv) {
9561
9571
  title: introContent.title,
9562
9572
  });
9563
9573
  }
9564
- process.stdout.write(dim("Not in a Neotoma repo. Session only, servers are not started.") + "\n\n");
9574
+ process.stdout.write(dim("Not in a Neotoma source checkout. Session only, servers are not started.") + "\n\n");
9565
9575
  }
9566
9576
  }
9567
9577
  else {
@@ -9572,7 +9582,8 @@ export async function runCli(argv = process.argv) {
9572
9582
  const version = await getCliVersion();
9573
9583
  const mcpStdioCount = await detectNeotomaMcpStdioProcessCount();
9574
9584
  const apiLines = buildApiBoxLines(discoveredInstances, mcpStdioCount);
9575
- const repoRootForLocal = await findRepoRoot(process.cwd());
9585
+ const repoRootForLocal = (await resolveAndPersistRepoRootFromInitContext()) ??
9586
+ (await resolveRepoRootFromInstalledCli());
9576
9587
  const introStatsOrFallback = repoRootForLocal
9577
9588
  ? await getDualEnvIntroStats(repoRootForLocal, LOCAL_DEV_USER_ID)
9578
9589
  : ["Production data: unavailable", "Development data: unavailable"];
@@ -9766,7 +9777,8 @@ export async function runCli(argv = process.argv) {
9766
9777
  else {
9767
9778
  // No sessionRepoRoot (e.g. cwd not in Neotoma repo) but we have API instances: still show full status block.
9768
9779
  // Resolve repo from cwd for direct local DB reads (intro + recent events) when possible.
9769
- const repoRootForLocal = await findRepoRoot(process.cwd());
9780
+ const repoRootForLocal = (await resolveAndPersistRepoRootFromInitContext()) ??
9781
+ (await resolveRepoRootFromInstalledCli());
9770
9782
  const effectiveUserId = userIdForWatch ?? LOCAL_DEV_USER_ID;
9771
9783
  const introStatsOrFallback = repoRootForLocal
9772
9784
  ? await getDualEnvIntroStats(repoRootForLocal, effectiveUserId)