@mnemonik/cli 7.105.1 → 7.106.1

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/dist/router.js CHANGED
@@ -857,6 +857,7 @@ var init_hookRuntime = __esm({
857
857
 
858
858
  // packages/cli/src/router.ts
859
859
  import { humanReason, humanReport, humanIdentityState } from "./humanReason.js";
860
+ import { helpScreen } from "./help.js";
860
861
  import { enableScanner, updateScannerRoots } from "./scanner/enable.js";
861
862
  import { controlScanner, scannerReceipt } from "./scanner/control.js";
862
863
  import { updateScanner } from "./scanner/update.js";
@@ -5304,6 +5305,8 @@ var alreadyConnectedFolderLine = (name2) => ` \u2713 ${name2} is already connec
5304
5305
  var removedFolderLine = (name2) => ` \u2713 ${name2} is no longer connected.`;
5305
5306
  var projectDeletionWarning = (name2) => `Deleting ${name2} removes its memories, code index and summaries for everyone. This cannot be undone.`;
5306
5307
  var projectDeletedLine = (name2) => `Deleted ${name2}.`;
5308
+ var NOTHING_DELETED_LINE = "Nothing was deleted.";
5309
+ var dataDeletePrompt = (projectId) => `This deletes everything background indexing has sent for ${projectId} from your account. Type yes to continue.`;
5307
5310
  var stillWatchedLine = (root) => `The folder is still being indexed. Run mnemonik remove ${root} to stop that.`;
5308
5311
  var identityFileKeptLine = "This folder's .mnemonik.json still points at the deleted project. Connecting the folder again creates a new project.";
5309
5312
  var CODEX_SIGNED_IN_MESSAGE = "Codex is signed in to Mnemonik.";
@@ -5360,28 +5363,7 @@ var values = /* @__PURE__ */ new Set([
5360
5363
  "project",
5361
5364
  "exclusions"
5362
5365
  ]);
5363
- var help = `Usage: mnemonik <command> [options]
5364
-
5365
- Commands:
5366
- install
5367
- status
5368
- connect <${hostOrder.join("|")}>
5369
- project <init|setup|status|link|ensure|delete>
5370
- add <folder>
5371
- remove <folder>
5372
- data delete --project <id>
5373
- diagnostics <preview|send>
5374
- doctor
5375
- repair
5376
- update
5377
- uninstall
5378
- auth login
5379
- auth status
5380
- auth logout [--host <host>] [--confirm]
5381
- logout
5382
-
5383
- Global options: --json --non-interactive --no-browser --help --version
5384
- Install consent: --accept-indexing --accept-limited --apply`;
5366
+ var help = helpScreen([]) ?? "";
5385
5367
  function parse(args2) {
5386
5368
  const positionals = [];
5387
5369
  const flags2 = /* @__PURE__ */ new Map();
@@ -6045,7 +6027,7 @@ async function deleteProjectCommand(parsed, rest, deps, output) {
6045
6027
  typed = String((await readline[Symbol.asyncIterator]().next()).value ?? "").trim();
6046
6028
  readline.close();
6047
6029
  if (typed.toLowerCase() !== project.name.toLowerCase()) {
6048
- output.line("Nothing was deleted.");
6030
+ output.line(NOTHING_DELETED_LINE);
6049
6031
  return 130;
6050
6032
  }
6051
6033
  }
@@ -6090,7 +6072,10 @@ async function deleteProjectCommand(parsed, rest, deps, output) {
6090
6072
  }
6091
6073
  async function runCli(args2, deps = {}) {
6092
6074
  const parsed = parse(args2);
6093
- const silent = parsed.flags.has("automatic");
6075
+ const helpIndex = args2.findIndex(
6076
+ (argument) => argument === "--help" || argument.startsWith("--help=")
6077
+ );
6078
+ const silent = helpIndex === -1 && parsed.flags.has("automatic");
6094
6079
  const discard = { write: () => {
6095
6080
  } };
6096
6081
  const stdout = silent ? discard : deps.stdout ?? process.stdout;
@@ -6098,6 +6083,16 @@ async function runCli(args2, deps = {}) {
6098
6083
  const output = new Output(stdout, stderr, {
6099
6084
  home: deps.home ?? homedir3()
6100
6085
  });
6086
+ const usageError = (positionals) => {
6087
+ stderr.write(helpScreen(positionals) ?? help);
6088
+ return 2;
6089
+ };
6090
+ if (helpIndex !== -1) {
6091
+ const positionals = args2.slice(0, helpIndex).filter((argument) => !argument.startsWith("--"));
6092
+ const screen = helpScreen(positionals);
6093
+ stdout.write(screen ?? helpScreen(positionals.slice(0, 1)) ?? help);
6094
+ return screen ? 0 : 2;
6095
+ }
6101
6096
  if (process.env.MNEMONIK_DEV_RELEASE_DIR && !silent)
6102
6097
  stderr.write(
6103
6098
  "WARNING: MNEMONIK_DEV_RELEASE_DIR uses development artifacts; readiness remains LIMITED.\n"
@@ -6109,15 +6104,13 @@ async function runCli(args2, deps = {}) {
6109
6104
  output.line(await packageVersion());
6110
6105
  return 0;
6111
6106
  }
6112
- if (parsed.flags.has("help") || !parsed.positionals.length) {
6113
- if (parsed.positionals.length && !parsed.flags.has("help"))
6114
- return output.error(`Unknown command: ${parsed.positionals[0]}`), 2;
6115
- output.line(help);
6107
+ if (!parsed.positionals.length) {
6108
+ stdout.write(help);
6116
6109
  return 0;
6117
6110
  }
6118
6111
  const [command, subcommand, ...rest] = parsed.positionals;
6119
6112
  if (command === "install") {
6120
- if (subcommand) return output.error(`Unexpected argument: ${subcommand}`), 2;
6113
+ if (subcommand) return usageError(["install"]);
6121
6114
  return installCommand(parsed, deps, output);
6122
6115
  }
6123
6116
  if (command === "roots" || command === "add" || command === "remove") {
@@ -6125,7 +6118,7 @@ async function runCli(args2, deps = {}) {
6125
6118
  const actionArguments = command === "roots" ? rest : [subcommand, ...rest].filter(Boolean);
6126
6119
  const invalid = allowed(parsed, ["accept-indexing", "apply", "no-browser", "non-git"]);
6127
6120
  if (invalid || !["add", "remove", "list"].includes(action ?? "") || actionArguments.length !== (action === "list" ? 0 : 1))
6128
- return output.error(invalid ?? "Usage: mnemonik add <folder> or mnemonik remove <folder>"), 2;
6121
+ return invalid ? (output.error(invalid), 2) : usageError([command]);
6129
6122
  const stateDir = deps.installStateDir ?? stateDirectory(process.platform, process.env, deps.home);
6130
6123
  const saved = JSON.parse(
6131
6124
  await readFile3(`${stateDir}/scanner/state.json`, "utf8").catch(() => "null")
@@ -6136,7 +6129,7 @@ async function runCli(args2, deps = {}) {
6136
6129
  else for (const root of saved.config.roots) output.line(root);
6137
6130
  return 0;
6138
6131
  }
6139
- if (action === "add" && (parsed.flags.has("non-interactive") || parsed.flags.has("json")) && !parsed.flags.has("apply"))
6132
+ if ((action === "add" || action === "remove") && (parsed.flags.has("non-interactive") || parsed.flags.has("json")) && !parsed.flags.has("apply"))
6140
6133
  return actionRequired2(output, parsed.flags.has("json"), "Rerun with --apply", "--apply");
6141
6134
  const pathArgument = actionArguments[0] ?? "";
6142
6135
  const requested = action === "add" ? await realpath(pathArgument) : saved.config.roots.find((root) => root === pathArgument) ?? pathArgument;
@@ -6208,7 +6201,8 @@ async function runCli(args2, deps = {}) {
6208
6201
  }
6209
6202
  if (command === "auth" && subcommand === "logout" && parsed.flags.get("component") === "scanner") {
6210
6203
  const invalid = allowed(parsed, ["component"]);
6211
- if (invalid || rest.length) return output.error(invalid ?? "Unexpected argument"), 2;
6204
+ if (invalid || rest.length)
6205
+ return invalid ? (output.error(invalid), 2) : usageError(["auth", "logout"]);
6212
6206
  try {
6213
6207
  const stateDir = deps.installStateDir ?? stateDirectory(process.platform, process.env, deps.home);
6214
6208
  const saved = JSON.parse(await readFile3(`${stateDir}/scanner/state.json`, "utf8"));
@@ -6236,10 +6230,27 @@ async function runCli(args2, deps = {}) {
6236
6230
  }
6237
6231
  }
6238
6232
  if (command === "data") {
6239
- const invalid = allowed(parsed, ["project"]);
6233
+ const invalid = allowed(parsed, ["project", "confirm"]);
6240
6234
  const project = parsed.flags.get("project");
6241
6235
  if (invalid || subcommand !== "delete" || rest.length || typeof project !== "string")
6242
- return output.error(invalid ?? "Usage: mnemonik data delete --project <id>"), 2;
6236
+ return invalid ? (output.error(invalid), 2) : usageError(["data", "delete"]);
6237
+ if (!parsed.flags.has("confirm")) {
6238
+ if (parsed.flags.has("non-interactive") || parsed.flags.has("json"))
6239
+ return actionRequired2(
6240
+ output,
6241
+ parsed.flags.has("json"),
6242
+ "Rerun with --confirm",
6243
+ "--confirm"
6244
+ );
6245
+ output.line(dataDeletePrompt(project));
6246
+ const readline = createInterface({ input: deps.input ?? process.stdin, terminal: false });
6247
+ const answer = String((await readline[Symbol.asyncIterator]().next()).value ?? "").trim();
6248
+ readline.close();
6249
+ if (!/^(?:y|yes)$/iu.test(answer)) {
6250
+ output.line(NOTHING_DELETED_LINE);
6251
+ return 130;
6252
+ }
6253
+ }
6243
6254
  try {
6244
6255
  const bearer = await ensureCliAuth(deps, output, false);
6245
6256
  const result = await deleteScannerIndex(project, bearer, deps.grantFetch);
@@ -6256,7 +6267,7 @@ async function runCli(args2, deps = {}) {
6256
6267
  }
6257
6268
  if ((command === "update" || command === "uninstall") && parsed.flags.get("component") === "scanner") {
6258
6269
  const invalid = allowed(parsed, ["component", "confirm"]);
6259
- if (invalid || subcommand) return output.error(invalid ?? "Unexpected argument"), 2;
6270
+ if (invalid || subcommand) return invalid ? (output.error(invalid), 2) : usageError([command]);
6260
6271
  try {
6261
6272
  const options = {
6262
6273
  stateDir: deps.installStateDir ?? stateDirectory(process.platform, process.env, deps.home),
@@ -6337,8 +6348,7 @@ async function runCli(args2, deps = {}) {
6337
6348
  "apply",
6338
6349
  ...command === "update" ? ["automatic"] : []
6339
6350
  ]);
6340
- if (invalid || subcommand)
6341
- return output.error(invalid ?? `Unexpected argument: ${subcommand}`), 2;
6351
+ if (invalid || subcommand) return invalid ? (output.error(invalid), 2) : usageError([command]);
6342
6352
  if (command === "uninstall" && parsed.flags.has("non-interactive")) {
6343
6353
  const missing = requireConsent(parsed, output, ["confirm"]);
6344
6354
  if (missing !== void 0) return missing;
@@ -6348,8 +6358,7 @@ async function runCli(args2, deps = {}) {
6348
6358
  }
6349
6359
  if (command === "update") {
6350
6360
  const invalid = allowed(parsed, ["automatic"]);
6351
- if (invalid || subcommand)
6352
- return output.error(invalid ?? `Unexpected argument: ${subcommand}`), 2;
6361
+ if (invalid || subcommand) return invalid ? (output.error(invalid), 2) : usageError(["update"]);
6353
6362
  const runtimeUpdate = deps.runtimeUpdate;
6354
6363
  if (!runtimeUpdate)
6355
6364
  return placeholder(
@@ -6375,16 +6384,14 @@ async function runCli(args2, deps = {}) {
6375
6384
  return 0;
6376
6385
  }
6377
6386
  if (command === "doctor") {
6378
- if (subcommand) return output.error(`Unexpected argument: ${subcommand}`), 2;
6387
+ if (subcommand) return usageError(["doctor"]);
6379
6388
  return doctorCommand(parsed, deps, output);
6380
6389
  }
6381
6390
  if (command === "diagnostics") {
6382
6391
  const invalid = allowed(parsed, subcommand === "preview" ? ["out"] : []);
6383
6392
  const bundleId = rest[0];
6384
6393
  if (invalid || !["preview", "send"].includes(subcommand ?? "") || subcommand === "preview" && rest.length || subcommand === "send" && (rest.length !== 1 || !bundleId))
6385
- return output.error(
6386
- invalid ?? "Usage: mnemonik diagnostics preview [--out <file>] | send <bundle-id>"
6387
- ), 2;
6394
+ return invalid ? (output.error(invalid), 2) : usageError(["diagnostics"]);
6388
6395
  try {
6389
6396
  const result = subcommand === "preview" ? await previewDiagnostics(
6390
6397
  parsed.flags.get("out"),
@@ -6425,8 +6432,7 @@ Preview: ${preview.path}
6425
6432
  }
6426
6433
  if (command === "status") {
6427
6434
  const invalid = allowed(parsed, []);
6428
- if (invalid || subcommand)
6429
- return output.error(invalid ?? `Unexpected argument: ${subcommand}`), 2;
6435
+ if (invalid || subcommand) return invalid ? (output.error(invalid), 2) : usageError(["status"]);
6430
6436
  const document = await collectCurrentInstallation(deps, output);
6431
6437
  const version = await packageVersion();
6432
6438
  const store = new RuntimeStore(
@@ -6446,7 +6452,7 @@ Preview: ${preview.path}
6446
6452
  const invalid = allowed(parsed, ["scope"]);
6447
6453
  if (invalid) return output.error(invalid), 2;
6448
6454
  if (!subcommand || rest.length || !hostOrder.includes(subcommand))
6449
- return output.error(`Usage: mnemonik connect <${hostOrder.join("|")}>`), 2;
6455
+ return usageError(["connect"]);
6450
6456
  const host = subcommand;
6451
6457
  const editor = (await localEditorStatus(deps.home ?? homedir3())).find(
6452
6458
  (candidate) => candidate.host === host
@@ -6480,11 +6486,11 @@ Preview: ${preview.path}
6480
6486
  }
6481
6487
  if (command === "project") {
6482
6488
  if (!subcommand || !["init", "setup", "status", "link", "ensure", "delete"].includes(subcommand))
6483
- return output.error("Usage: mnemonik project <init|setup|status|link|ensure|delete>"), 2;
6489
+ return usageError(["project"]);
6484
6490
  if (subcommand === "delete") {
6485
6491
  const unknown = allowed(parsed, ["confirm"]);
6486
6492
  if (unknown || rest.length > 1)
6487
- return output.error(unknown ?? "Usage: mnemonik project delete [<project id or name>]"), 2;
6493
+ return unknown ? (output.error(unknown), 2) : usageError(["project", "delete"]);
6488
6494
  return deleteProjectCommand(parsed, rest, deps, output);
6489
6495
  }
6490
6496
  const invalid = allowed(
@@ -6493,8 +6499,7 @@ Preview: ${preview.path}
6493
6499
  );
6494
6500
  if (invalid) return output.error(invalid), 2;
6495
6501
  if (subcommand === "ensure") {
6496
- if (rest.length || !parsed.flags.has("agent") || !parsed.flags.has("json"))
6497
- return output.error("Usage: mnemonik project ensure --agent --json"), 2;
6502
+ if (rest.length) return usageError(["project", "ensure"]);
6498
6503
  return ensureProjectForAgent({
6499
6504
  output,
6500
6505
  cwd: deps.cwd ?? process.cwd(),
@@ -6507,9 +6512,7 @@ Preview: ${preview.path}
6507
6512
  if (missing !== void 0) return missing;
6508
6513
  }
6509
6514
  if (subcommand === "link" && (rest.length < 1 || rest.length > 2) || subcommand !== "link" && rest.length > 1)
6510
- return output.error(
6511
- `Usage: mnemonik project ${subcommand}${subcommand === "link" ? " <project-id> [path]" : " [path]"}`
6512
- ), 2;
6515
+ return usageError(["project", subcommand]);
6513
6516
  return runProjectCommand(
6514
6517
  {
6515
6518
  command: subcommand,
@@ -6535,10 +6538,7 @@ Preview: ${preview.path}
6535
6538
  );
6536
6539
  }
6537
6540
  if (command === "identity") {
6538
- if (subcommand !== "migrate")
6539
- return output.error(
6540
- "Usage: mnemonik identity migrate [paths] [--report|--backup]\n mnemonik identity migrate [--apply|--verify|--rollback <run-id>]"
6541
- ), 2;
6541
+ if (subcommand !== "migrate") return usageError(["identity", "migrate"]);
6542
6542
  const invalid = allowed(parsed, ["report", "backup", "apply", "verify", "rollback"]);
6543
6543
  if (invalid) return output.error(invalid), 2;
6544
6544
  const selected = ["report", "backup", "apply", "verify", "rollback"].filter(
@@ -6589,7 +6589,9 @@ Preview: ${preview.path}
6589
6589
  "uninstall",
6590
6590
  "status"
6591
6591
  ].includes(subcommand))
6592
- return output.error("Usage: mnemonik scanner <enable|start|stop|uninstall|status>"), 2;
6592
+ return usageError(
6593
+ subcommand && helpScreen(["scanner", subcommand]) ? ["scanner", subcommand] : ["scanner"]
6594
+ );
6593
6595
  const invalid = allowed(
6594
6596
  parsed,
6595
6597
  subcommand === "enable" ? ["accept-indexing", "apply", "scan-roots", "exclusions", "no-browser"] : subcommand === "export-preview" ? ["out"] : []
@@ -6726,7 +6728,9 @@ Preview: ${preview.path}
6726
6728
  if (command === "auth") {
6727
6729
  const invalid = allowed(parsed, ["host", "confirm", "no-browser", "reopen-install"]);
6728
6730
  if (invalid || rest.length || !["login", "status", "logout"].includes(subcommand ?? "") || parsed.flags.has("reopen-install") && subcommand !== "login")
6729
- return output.error(invalid ?? "Usage: mnemonik auth <login|status|logout> [--host <host>]"), 2;
6731
+ return invalid ? (output.error(invalid), 2) : usageError(
6732
+ subcommand && helpScreen(["auth", subcommand]) ? ["auth", subcommand] : ["auth"]
6733
+ );
6730
6734
  const host = parsed.flags.get("host");
6731
6735
  if (host && !hostOrder.includes(host)) return output.error("Invalid host"), 2;
6732
6736
  if (subcommand === "login") {
@@ -6820,7 +6824,7 @@ Preview: ${preview.path}
6820
6824
  return 0;
6821
6825
  }
6822
6826
  if (command === "logout") {
6823
- if (subcommand) return output.error(`Unexpected argument: ${subcommand}`), 2;
6827
+ if (subcommand) return usageError(["logout"]);
6824
6828
  const invalid = allowed(parsed, []);
6825
6829
  if (invalid) return output.error(invalid), 2;
6826
6830
  await auth(deps, output, false).logout();
@@ -6828,16 +6832,17 @@ Preview: ${preview.path}
6828
6832
  else output.line("Logged out.");
6829
6833
  return 0;
6830
6834
  }
6831
- output.error(`Unknown command: ${command}`);
6832
- return 2;
6835
+ return usageError([]);
6833
6836
  }
6834
6837
  var serializeReadiness2 = (input) => devReadiness(serializeReadiness(input));
6835
6838
  export {
6836
6839
  CODEX_SIGNED_IN_MESSAGE,
6837
6840
  CONNECT_NOT_APPROVED_MESSAGE,
6841
+ NOTHING_DELETED_LINE,
6838
6842
  alreadyConnectedFolderLine,
6839
6843
  connectFolderPrompt,
6840
6844
  connectedFolderLine,
6845
+ dataDeletePrompt,
6841
6846
  help,
6842
6847
  identityFileKeptLine,
6843
6848
  maintenanceExitCode,