neotoma 0.3.8 → 0.3.9

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.
File without changes
@@ -82,6 +82,11 @@ export type InitContextStatus = {
82
82
  };
83
83
  /** Resolve data dir and .env status for init box for project/user env targets. */
84
84
  export declare function getInitContextStatus(repoRoot: string | null): Promise<InitContextStatus | null>;
85
+ /**
86
+ * Treat init as satisfied if either project-scoped or user-scoped context is ready.
87
+ * This avoids false negatives when one scope is configured and the other is not.
88
+ */
89
+ export declare function hasAnyInitializedContext(repoRoot: string | null): Promise<boolean>;
85
90
  export declare function buildInstallationBoxLines(mcpConfigs: McpConfigStatus[], cliScan: CliInstructionScanSummary | null, initContext?: InitContextStatus | null, repoRoot?: string | null): string[];
86
91
  type IntroBoxContent = {
87
92
  lines: string[];
@@ -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
@@ -3313,8 +3313,9 @@ const initCommand = program
3313
3313
  .option("--force", "Overwrite existing configuration")
3314
3314
  .option("--skip-db", "Skip database initialization")
3315
3315
  .option("--skip-env", "Skip interactive .env creation and variable prompts")
3316
- .option("-y, --yes", "Apply the default init plan without prompts")
3317
- .option("--advanced", "Use personalization mode (step-by-step setup prompts, including optional source path prompts)")
3316
+ .option("-y, --yes", "Apply the default init plan without prompts (default behavior)")
3317
+ .option("--interactive", "Enable interactive setup prompts (plan review + personalization prompts)")
3318
+ .option("--advanced", "Alias for --interactive (step-by-step setup prompts, including optional source path prompts)")
3318
3319
  .option("--auth-mode <mode>", "Auth setup mode: dev_local, oauth, or key_derived (non-interactive shortcut)")
3319
3320
  .option("--scope <scope>", "Configuration scope: user, project, both, or skip (applies to MCP + CLI updates)")
3320
3321
  .option("--configure-mcp <choice>", "Configure MCP entries: yes/no (skip corresponding prompt when provided)")
@@ -3328,7 +3329,9 @@ const initCommand = program
3328
3329
  .action(async (opts) => {
3329
3330
  try {
3330
3331
  const outputMode = resolveOutputMode();
3331
- let useAdvancedPrompts = Boolean(opts.advanced);
3332
+ const interactiveRequested = Boolean(opts.interactive || opts.advanced);
3333
+ let useAdvancedPrompts = interactiveRequested;
3334
+ const applyDefaultsWithoutPrompts = Boolean(opts.yes || !interactiveRequested);
3332
3335
  const authModeFromFlag = normalizeInitAuthMode(opts.authMode);
3333
3336
  if (opts.authMode && (!authModeFromFlag || authModeFromFlag === "skip")) {
3334
3337
  throw new Error("Invalid --auth-mode. Use dev_local, oauth, or key_derived.");
@@ -3402,7 +3405,7 @@ const initCommand = program
3402
3405
  // If user explicitly provides --data-dir or a personalized path, sync .env to that value.
3403
3406
  let forceSyncDataDirToEnv = Boolean(opts.dataDir?.trim());
3404
3407
  const shouldOfferPackageTargetPrompt = process.stdout.isTTY &&
3405
- !opts.yes &&
3408
+ !applyDefaultsWithoutPrompts &&
3406
3409
  useCurrentDirTargetsFromFlag == null &&
3407
3410
  (repoRoot == null || repoRootSource === "config");
3408
3411
  if (shouldOfferPackageTargetPrompt) {
@@ -3458,14 +3461,19 @@ const initCommand = program
3458
3461
  const alreadyInitializedMessage = "Neotoma is already initialized at " +
3459
3462
  pathStyle(detectedInitializedDataDir) +
3460
3463
  ". Run init again?";
3461
- if (process.stdout.isTTY && outputMode === "pretty" && !opts.yes) {
3464
+ const alreadyInitializedContinueMessage = "Neotoma is already initialized at " +
3465
+ pathStyle(detectedInitializedDataDir) +
3466
+ ". Continuing with init (non-interactive mode).";
3467
+ if (process.stdout.isTTY &&
3468
+ outputMode === "pretty" &&
3469
+ !applyDefaultsWithoutPrompts) {
3462
3470
  const shouldContinue = await askYesNo(`${alreadyInitializedMessage} [y/N]: `);
3463
3471
  if (!shouldContinue) {
3464
3472
  throw new InitAbortError();
3465
3473
  }
3466
3474
  }
3467
3475
  else if (process.stdout.isTTY && outputMode === "pretty") {
3468
- process.stdout.write(bullet(dim(alreadyInitializedMessage + " Continuing.")) + "\n");
3476
+ process.stdout.write(bullet(dim(alreadyInitializedContinueMessage)) + "\n");
3469
3477
  }
3470
3478
  }
3471
3479
  if (process.stdout.isTTY && useAdvancedPrompts) {
@@ -3656,7 +3664,10 @@ const initCommand = program
3656
3664
  let personalizedAuthMode = null;
3657
3665
  let earlyOpenAiPrompted = false;
3658
3666
  let earlyOpenAiInput = "";
3659
- if (outputMode === "pretty" && process.stdout.isTTY && !opts.yes && !useAdvancedPrompts) {
3667
+ if (outputMode === "pretty" &&
3668
+ process.stdout.isTTY &&
3669
+ !applyDefaultsWithoutPrompts &&
3670
+ !useAdvancedPrompts) {
3660
3671
  const configuredAuth = await detectConfiguredAuthMode(envPath);
3661
3672
  const envExists = envPath ? await pathExists(envPath) : false;
3662
3673
  const plannedAuthMode = authModeFromFlag ?? configuredAuth?.mode ?? defaultInitAuthMode;
@@ -3957,7 +3968,12 @@ const initCommand = program
3957
3968
  }
3958
3969
  }
3959
3970
  }
3960
- if (!useAdvancedPrompts && !opts.skipEnv && envPath && outputMode === "pretty" && process.stdout.isTTY) {
3971
+ if (interactiveRequested &&
3972
+ !useAdvancedPrompts &&
3973
+ !opts.skipEnv &&
3974
+ envPath &&
3975
+ outputMode === "pretty" &&
3976
+ process.stdout.isTTY) {
3961
3977
  let existingOpenAi = (process.env.OPENAI_API_KEY ?? "").trim();
3962
3978
  if (!existingOpenAi) {
3963
3979
  try {
@@ -4275,7 +4291,7 @@ NEOTOMA_MCP_TOKEN_ENCRYPTION_KEY=${mcpTokenEncryptionKey}
4275
4291
  else if (initAuthSummary.mode === "key_derived") {
4276
4292
  process.stdout.write(nl());
4277
4293
  const resolvedKeySource = keySourceFromFlag ??
4278
- (opts.yes ? "skip" : normalizeInitKeySource(await askQuestion("Create new key [1] or path to existing key [2] [default: 1]: ")) ??
4294
+ (applyDefaultsWithoutPrompts ? "skip" : normalizeInitKeySource(await askQuestion("Create new key [1] or path to existing key [2] [default: 1]: ")) ??
4279
4295
  "create");
4280
4296
  if (resolvedKeySource === "create") {
4281
4297
  const keysDir = path.join(CONFIG_DIR, "keys");
@@ -4403,7 +4419,7 @@ NEOTOMA_MCP_TOKEN_ENCRYPTION_KEY=${mcpTokenEncryptionKey}
4403
4419
  const reason = opts.skipEnv ? "--skip-env" : "no env target";
4404
4420
  setInitProgress("env", "skipped", reason);
4405
4421
  }
4406
- else if (process.stdout.isTTY) {
4422
+ else {
4407
4423
  setInitProgress("env", "in_progress");
4408
4424
  suspendLiveProgress();
4409
4425
  const envPathStr = envPath;
@@ -4476,7 +4492,7 @@ NEOTOMA_MCP_TOKEN_ENCRYPTION_KEY=${mcpTokenEncryptionKey}
4476
4492
  if (openAiSet) {
4477
4493
  envOpenAiOutcome = "already_set";
4478
4494
  }
4479
- const shouldPromptOpenAi = !opts.yes && outputMode === "pretty" && process.stdout.isTTY;
4495
+ const shouldPromptOpenAi = interactiveRequested && outputMode === "pretty" && process.stdout.isTTY;
4480
4496
  if (!openAiSet && openAiKeyFromFlag) {
4481
4497
  let envText;
4482
4498
  try {
@@ -4620,9 +4636,6 @@ NEOTOMA_MCP_TOKEN_ENCRYPTION_KEY=${mcpTokenEncryptionKey}
4620
4636
  setInitProgress("env", "done", envDetailParts.join(", "));
4621
4637
  setInitProgressSummaryLines("env", envSummaryLines);
4622
4638
  }
4623
- else {
4624
- setInitProgress("env", "skipped", "non-interactive output");
4625
- }
4626
4639
  if (keyPath) {
4627
4640
  suspendLiveProgress();
4628
4641
  process.stdout.write(nl() + heading("Encryption enabled") + nl());
@@ -5019,6 +5032,21 @@ NEOTOMA_MCP_TOKEN_ENCRYPTION_KEY=${mcpTokenEncryptionKey}
5019
5032
  }
5020
5033
  process.stdout.write(nl() + heading("✓ Neotoma initialized!") + nl());
5021
5034
  process.stdout.write("Run " + pathStyle("neotoma") + " to start a session." + nl());
5035
+ if (outputMode === "pretty") {
5036
+ process.stdout.write(nl() + heading("Additional configuration options") + nl());
5037
+ process.stdout.write(bullet("Interactive setup walkthrough: " + pathStyle("neotoma init --interactive")) + "\n");
5038
+ process.stdout.write(bullet("Set OpenAI key later: " +
5039
+ pathStyle("neotoma init --yes --skip-db --openai-api-key <key>")) + "\n");
5040
+ process.stdout.write(bullet("Check/update MCP config: " + pathStyle("neotoma mcp check")) + "\n");
5041
+ process.stdout.write(bullet("Refresh CLI instructions: " + pathStyle("neotoma cli-instructions check")) + "\n");
5042
+ process.stdout.write(bullet("API status: " + pathStyle("neotoma api status")) + "\n");
5043
+ process.stdout.write(bullet("Start API server: " + pathStyle("neotoma api start --env dev --background")) + "\n");
5044
+ process.stdout.write(bullet("View API logs: " + pathStyle("neotoma api logs --env dev --follow")) + "\n");
5045
+ process.stdout.write(bullet("Authentication status/login: " +
5046
+ pathStyle("neotoma auth status") +
5047
+ " / " +
5048
+ pathStyle("neotoma auth login")) + "\n");
5049
+ }
5022
5050
  // Release stdin after interactive prompts so Node can exit immediately.
5023
5051
  process.stdin.pause();
5024
5052
  await new Promise((resolve) => process.stdout.write("", () => resolve()));
@@ -5160,9 +5188,12 @@ let resetCompletionPrinted = false;
5160
5188
  program
5161
5189
  .command("reset")
5162
5190
  .description("Reset local Neotoma to a clean slate: back up and remove local Neotoma state, clean MCP/config instructions, and attempt global npm uninstall only when run from within a Neotoma repo (never back up/remove data dir configured via NEOTOMA_DATA_DIR in .env)")
5163
- .option("-y, --yes", "Skip confirmation prompt")
5191
+ .option("-y, --yes", "Skip confirmation prompt (default behavior)")
5192
+ .option("--interactive", "Enable confirmation prompt before reset")
5164
5193
  .action(async (opts) => {
5165
5194
  const outputMode = resolveOutputMode();
5195
+ const interactiveRequested = Boolean(opts.interactive);
5196
+ const applyDefaultsWithoutPrompts = Boolean(opts.yes || !interactiveRequested);
5166
5197
  const { repoRoot } = await resolveRepoRootFromInitContext();
5167
5198
  const ts = backupTimestamp();
5168
5199
  const homeDir = process.env.HOME || process.env.USERPROFILE || os.homedir();
@@ -5208,7 +5239,7 @@ program
5208
5239
  mcpConfigTargets.add(path.join(repoRoot, ".mcp.json"));
5209
5240
  mcpConfigTargets.add(path.join(repoRoot, ".codex", "config.toml"));
5210
5241
  }
5211
- if (process.stdout.isTTY && !opts.yes && outputMode !== "json") {
5242
+ if (process.stdout.isTTY && !applyDefaultsWithoutPrompts && outputMode !== "json") {
5212
5243
  process.stdout.write(heading("Neotoma reset") + nl() + nl());
5213
5244
  process.stdout.write("This will:" + nl());
5214
5245
  process.stdout.write(bullet("Back up and remove local Neotoma state (config, env, keys, instructions, and data directories).") + nl());
@@ -9985,6 +10016,18 @@ export async function getInitContextStatus(repoRoot) {
9985
10016
  const dataDirExists = await pathExists(dataDir);
9986
10017
  return { dataDirExists, envFileExists, dataDir, envFilePath: envPath, envTarget };
9987
10018
  }
10019
+ /**
10020
+ * Treat init as satisfied if either project-scoped or user-scoped context is ready.
10021
+ * This avoids false negatives when one scope is configured and the other is not.
10022
+ */
10023
+ export async function hasAnyInitializedContext(repoRoot) {
10024
+ const projectContext = await getInitContextStatus(repoRoot);
10025
+ if (projectContext?.envFileExists && projectContext.dataDirExists) {
10026
+ return true;
10027
+ }
10028
+ const userContext = await getInitContextStatus(null);
10029
+ return Boolean(userContext?.envFileExists && userContext.dataDirExists);
10030
+ }
9988
10031
  export function buildInstallationBoxLines(mcpConfigs, cliScan, initContext, repoRoot) {
9989
10032
  const mark = (ok) => (ok ? "✅" : "❌");
9990
10033
  const hasPath = (value) => mcpConfigs.some((config) => config.path.toLowerCase().includes(value));
@@ -10464,8 +10507,8 @@ export async function runCli(argv = process.argv) {
10464
10507
  // For plain `neotoma` startup, require init before rendering any status boxes or prompts.
10465
10508
  if (noArgs && !isInitCommand && !isResetCommand) {
10466
10509
  const { repoRoot } = await resolveRepoRootFromInitContext();
10467
- const initContext = await getInitContextStatus(repoRoot);
10468
- if (!initContext?.envFileExists || !initContext.dataDirExists) {
10510
+ const hasInitializedContext = await hasAnyInitializedContext(repoRoot);
10511
+ if (!hasInitializedContext) {
10469
10512
  process.stderr.write(NO_ARGS_INIT_REQUIRED_MESSAGE + "\n");
10470
10513
  process.exitCode = 1;
10471
10514
  return;