@neat.is/core 0.5.2 → 0.5.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.
package/dist/cli.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  resolveNeatVersion,
10
10
  validateConnectorEntry,
11
11
  writeDaemonRecord
12
- } from "./chunk-DPEPI2N6.js";
12
+ } from "./chunk-X2AMX3QZ.js";
13
13
  import {
14
14
  buildSearchIndex
15
15
  } from "./chunk-BIY46Q6U.js";
@@ -68,7 +68,7 @@ import {
68
68
  startPersistLoop,
69
69
  startStalenessLoop,
70
70
  upsertConnectorEntry
71
- } from "./chunk-BI3XKGVG.js";
71
+ } from "./chunk-GJHEZC5K.js";
72
72
  import {
73
73
  startOtelGrpcReceiver
74
74
  } from "./chunk-I72HTUOG.js";
@@ -82,8 +82,8 @@ import {
82
82
  } from "./chunk-CFDPIMRP.js";
83
83
 
84
84
  // src/cli.ts
85
- import path9 from "path";
86
- import { promises as fs7 } from "fs";
85
+ import path10 from "path";
86
+ import { promises as fs8 } from "fs";
87
87
 
88
88
  // src/banner.ts
89
89
  import path from "path";
@@ -3852,8 +3852,181 @@ async function runConnectorCommand(rawArgs, deps = {}) {
3852
3852
  }
3853
3853
  }
3854
3854
 
3855
- // src/cli-verbs.ts
3855
+ // src/hooks-cli.ts
3856
3856
  import path8 from "path";
3857
+ import os from "os";
3858
+ import { promises as fs7 } from "fs";
3859
+ import { fileURLToPath as fileURLToPath3 } from "url";
3860
+ var HOOK_FILENAME = "neat-search-nudge.mjs";
3861
+ var GUIDE_FILENAME = "GRAPH_FIRST.md";
3862
+ var GUIDE_INSTALL_NAME = "neat-graph-first.md";
3863
+ var HOOK_MATCHER = "Grep|Glob|Bash";
3864
+ function moduleDir() {
3865
+ return typeof __dirname !== "undefined" ? __dirname : path8.dirname(fileURLToPath3(import.meta.url));
3866
+ }
3867
+ async function readSkillAsset(rel) {
3868
+ const here = moduleDir();
3869
+ const candidates = [
3870
+ path8.resolve(here, "../../claude-skill", rel),
3871
+ path8.resolve(here, "../../../claude-skill", rel),
3872
+ path8.resolve(here, "../claude-skill", rel)
3873
+ ];
3874
+ for (const candidate of candidates) {
3875
+ try {
3876
+ return await fs7.readFile(candidate, "utf8");
3877
+ } catch {
3878
+ }
3879
+ }
3880
+ throw new Error(
3881
+ `neat hooks: could not find @neat.is/claude-skill/${rel} \u2014 is the package installed?`
3882
+ );
3883
+ }
3884
+ function neatHome() {
3885
+ const override = process.env.NEAT_HOME;
3886
+ if (override && override.length > 0) return path8.resolve(override);
3887
+ return path8.join(os.homedir(), ".neat");
3888
+ }
3889
+ function claudeSettingsPath() {
3890
+ const override = process.env.NEAT_CLAUDE_SETTINGS;
3891
+ if (override && override.length > 0) return path8.resolve(override);
3892
+ const home = process.env.HOME ?? process.env.USERPROFILE ?? os.homedir();
3893
+ return path8.join(home, ".claude", "settings.json");
3894
+ }
3895
+ function installedHookPath() {
3896
+ return path8.join(neatHome(), "hooks", HOOK_FILENAME);
3897
+ }
3898
+ function isNeatSearchEntry(entry2) {
3899
+ return (entry2.hooks ?? []).some(
3900
+ (h) => typeof h.command === "string" && h.command.includes(HOOK_FILENAME)
3901
+ );
3902
+ }
3903
+ function neatHookEntry(command) {
3904
+ return { matcher: HOOK_MATCHER, hooks: [{ type: "command", command }] };
3905
+ }
3906
+ function hookCommand(scriptPath) {
3907
+ return `node "${scriptPath}"`;
3908
+ }
3909
+ async function runHooks(opts) {
3910
+ if (opts.printHook) {
3911
+ process.stdout.write(await readSkillAsset(`hooks/${HOOK_FILENAME}`));
3912
+ return { exitCode: 0 };
3913
+ }
3914
+ if (opts.printGuide) {
3915
+ process.stdout.write(await readSkillAsset(GUIDE_FILENAME));
3916
+ return { exitCode: 0 };
3917
+ }
3918
+ if (opts.printSettings) {
3919
+ const block = {
3920
+ hooks: { PreToolUse: [neatHookEntry(hookCommand(installedHookPath()))] }
3921
+ };
3922
+ process.stdout.write(JSON.stringify(block, null, 2) + "\n");
3923
+ return { exitCode: 0 };
3924
+ }
3925
+ if (opts.apply) {
3926
+ const hookScript = await readSkillAsset(`hooks/${HOOK_FILENAME}`);
3927
+ const guide = await readSkillAsset(GUIDE_FILENAME);
3928
+ const scriptPath = installedHookPath();
3929
+ await fs7.mkdir(path8.dirname(scriptPath), { recursive: true });
3930
+ await fs7.writeFile(scriptPath, hookScript, { mode: 493 });
3931
+ const guidePath = path8.join(neatHome(), GUIDE_INSTALL_NAME);
3932
+ await fs7.writeFile(guidePath, guide, "utf8");
3933
+ const settingsFile = claudeSettingsPath();
3934
+ let settings = {};
3935
+ try {
3936
+ settings = JSON.parse(await fs7.readFile(settingsFile, "utf8"));
3937
+ } catch (err) {
3938
+ if (err.code !== "ENOENT") {
3939
+ console.error(
3940
+ `neat hooks: failed to read ${settingsFile} \u2014 ${err.message}`
3941
+ );
3942
+ return { exitCode: 1 };
3943
+ }
3944
+ }
3945
+ const hooks = settings.hooks ?? {};
3946
+ const preToolUse = Array.isArray(hooks.PreToolUse) ? [...hooks.PreToolUse] : [];
3947
+ const command = hookCommand(scriptPath);
3948
+ const existingIdx = preToolUse.findIndex(isNeatSearchEntry);
3949
+ if (existingIdx >= 0) {
3950
+ preToolUse[existingIdx] = neatHookEntry(command);
3951
+ } else {
3952
+ preToolUse.push(neatHookEntry(command));
3953
+ }
3954
+ const merged = {
3955
+ ...settings,
3956
+ hooks: { ...hooks, PreToolUse: preToolUse }
3957
+ };
3958
+ await fs7.mkdir(path8.dirname(settingsFile), { recursive: true });
3959
+ await fs7.writeFile(settingsFile, JSON.stringify(merged, null, 2) + "\n", "utf8");
3960
+ console.log(`neat hooks: installed the search-nudge hook`);
3961
+ console.log(` script: ${scriptPath}`);
3962
+ console.log(` settings: ${settingsFile} (PreToolUse \u2192 ${HOOK_MATCHER})`);
3963
+ console.log(` guidance: ${guidePath}`);
3964
+ console.log("");
3965
+ console.log("restart Claude Code to load the hook. On a Grep/Glob or a Bash grep,");
3966
+ console.log("your agent will now be nudged to query NEAT first.");
3967
+ console.log("");
3968
+ console.log("The hook is Claude-Code-specific. For agents on other harnesses, paste");
3969
+ console.log(`the guidance above into your project instructions (CLAUDE.md / AGENTS.md).`);
3970
+ return { exitCode: 0 };
3971
+ }
3972
+ usage();
3973
+ return { exitCode: 0 };
3974
+ }
3975
+ function usage() {
3976
+ console.log("neat hooks \u2014 wire NEAT into your agent so it queries the graph before grepping");
3977
+ console.log("");
3978
+ console.log(" --apply install the Claude Code search-nudge hook and write the");
3979
+ console.log(" graph-first guidance to ~/.neat/, merging into");
3980
+ console.log(" ~/.claude/settings.json without touching your other hooks");
3981
+ console.log(" --print-hook print the hook script to stdout");
3982
+ console.log(" --print-guide print the agent-agnostic graph-first guidance to stdout");
3983
+ console.log(" --print-settings print the settings.json PreToolUse block --apply would add");
3984
+ console.log("");
3985
+ console.log("The hook is a gentle, non-blocking nudge \u2014 searches still run. It is");
3986
+ console.log("Claude-Code-specific; other harnesses get the same steer from the guidance.");
3987
+ }
3988
+ async function runHooksCommand(args) {
3989
+ const opts = {
3990
+ apply: false,
3991
+ printHook: false,
3992
+ printGuide: false,
3993
+ printSettings: false
3994
+ };
3995
+ for (const arg of args) {
3996
+ switch (arg) {
3997
+ case "--apply":
3998
+ opts.apply = true;
3999
+ break;
4000
+ case "--print-hook":
4001
+ opts.printHook = true;
4002
+ break;
4003
+ case "--print-guide":
4004
+ opts.printGuide = true;
4005
+ break;
4006
+ case "--print-settings":
4007
+ opts.printSettings = true;
4008
+ break;
4009
+ case "-h":
4010
+ case "--help":
4011
+ usage();
4012
+ return 0;
4013
+ default:
4014
+ console.error(`neat hooks: unknown flag "${arg}"`);
4015
+ usage();
4016
+ return 2;
4017
+ }
4018
+ }
4019
+ try {
4020
+ const { exitCode } = await runHooks(opts);
4021
+ return exitCode;
4022
+ } catch (err) {
4023
+ console.error(err.message);
4024
+ return 1;
4025
+ }
4026
+ }
4027
+
4028
+ // src/cli-verbs.ts
4029
+ import path9 from "path";
3857
4030
 
3858
4031
  // src/cli-client.ts
3859
4032
  import { Provenance as Provenance2 } from "@neat.is/types";
@@ -3881,10 +4054,10 @@ function createHttpClient(baseUrl, bearerToken) {
3881
4054
  const root = baseUrl.replace(/\/$/, "");
3882
4055
  const authHeader = bearerToken && bearerToken.length > 0 ? { authorization: `Bearer ${bearerToken}` } : {};
3883
4056
  return {
3884
- async get(path10) {
4057
+ async get(path11) {
3885
4058
  let res;
3886
4059
  try {
3887
- res = await fetch(`${root}${path10}`, {
4060
+ res = await fetch(`${root}${path11}`, {
3888
4061
  headers: { ...authHeader }
3889
4062
  });
3890
4063
  } catch (err) {
@@ -3896,16 +4069,16 @@ function createHttpClient(baseUrl, bearerToken) {
3896
4069
  const body = await res.text().catch(() => "");
3897
4070
  throw new HttpError(
3898
4071
  res.status,
3899
- `${res.status} ${res.statusText} on GET ${path10}: ${body}`,
4072
+ `${res.status} ${res.statusText} on GET ${path11}: ${body}`,
3900
4073
  body
3901
4074
  );
3902
4075
  }
3903
4076
  return await res.json();
3904
4077
  },
3905
- async post(path10, body) {
4078
+ async post(path11, body) {
3906
4079
  let res;
3907
4080
  try {
3908
- res = await fetch(`${root}${path10}`, {
4081
+ res = await fetch(`${root}${path11}`, {
3909
4082
  method: "POST",
3910
4083
  headers: { "content-type": "application/json", ...authHeader },
3911
4084
  body: JSON.stringify(body)
@@ -3919,7 +4092,7 @@ function createHttpClient(baseUrl, bearerToken) {
3919
4092
  const text = await res.text().catch(() => "");
3920
4093
  throw new HttpError(
3921
4094
  res.status,
3922
- `${res.status} ${res.statusText} on POST ${path10}: ${text}`,
4095
+ `${res.status} ${res.statusText} on POST ${path11}: ${text}`,
3923
4096
  text
3924
4097
  );
3925
4098
  }
@@ -3933,12 +4106,12 @@ function projectPath(project, suffix) {
3933
4106
  }
3934
4107
  async function runRootCause(client, input) {
3935
4108
  const qs = input.errorId ? `?errorId=${encodeURIComponent(input.errorId)}` : "";
3936
- const path10 = projectPath(
4109
+ const path11 = projectPath(
3937
4110
  input.project,
3938
4111
  `/graph/root-cause/${encodeURIComponent(input.errorNode)}${qs}`
3939
4112
  );
3940
4113
  try {
3941
- const result = await client.get(path10);
4114
+ const result = await client.get(path11);
3942
4115
  const arrowPath = result.traversalPath.join(" \u2190 ");
3943
4116
  const provenances = result.edgeProvenances.length ? result.edgeProvenances.join(", ") : "(direct, no edges traversed)";
3944
4117
  const summary = `Root cause for ${input.errorNode} is ${result.rootCauseNode}. ` + result.rootCauseReason + (result.fixRecommendation ? ` Recommended fix: ${result.fixRecommendation}.` : "");
@@ -3964,12 +4137,12 @@ async function runRootCause(client, input) {
3964
4137
  }
3965
4138
  async function runBlastRadius(client, input) {
3966
4139
  const qs = input.depth !== void 0 ? `?depth=${input.depth}` : "";
3967
- const path10 = projectPath(
4140
+ const path11 = projectPath(
3968
4141
  input.project,
3969
4142
  `/graph/blast-radius/${encodeURIComponent(input.nodeId)}${qs}`
3970
4143
  );
3971
4144
  try {
3972
- const result = await client.get(path10);
4145
+ const result = await client.get(path11);
3973
4146
  if (result.totalAffected === 0) {
3974
4147
  return {
3975
4148
  summary: `${result.origin} has no dependents. Nothing else would break if it failed.`
@@ -4003,12 +4176,12 @@ function formatBlastEntry(n) {
4003
4176
  }
4004
4177
  async function runDependencies(client, input) {
4005
4178
  const depth = input.depth ?? 3;
4006
- const path10 = projectPath(
4179
+ const path11 = projectPath(
4007
4180
  input.project,
4008
4181
  `/graph/dependencies/${encodeURIComponent(input.nodeId)}?depth=${depth}`
4009
4182
  );
4010
4183
  try {
4011
- const result = await client.get(path10);
4184
+ const result = await client.get(path11);
4012
4185
  if (result.total === 0) {
4013
4186
  return {
4014
4187
  summary: depth === 1 ? `${input.nodeId} has no direct dependencies in the graph.` : `${input.nodeId} has no dependencies (BFS to depth ${depth}).`
@@ -4100,9 +4273,9 @@ function formatDuration(ms) {
4100
4273
  return `${Math.round(h / 24)}d`;
4101
4274
  }
4102
4275
  async function runIncidents(client, input) {
4103
- const path10 = input.nodeId ? projectPath(input.project, `/incidents/${encodeURIComponent(input.nodeId)}`) : projectPath(input.project, "/incidents");
4276
+ const path11 = input.nodeId ? projectPath(input.project, `/incidents/${encodeURIComponent(input.nodeId)}`) : projectPath(input.project, "/incidents");
4104
4277
  try {
4105
- const body = await client.get(path10);
4278
+ const body = await client.get(path11);
4106
4279
  const events = body.events;
4107
4280
  if (events.length === 0) {
4108
4281
  return {
@@ -4392,7 +4565,7 @@ async function resolveProjectEntry(opts) {
4392
4565
  const cwd = opts.cwd ?? process.cwd();
4393
4566
  const resolvedCwd = await normalizeProjectPath(cwd);
4394
4567
  for (const entry2 of entries) {
4395
- if (resolvedCwd === entry2.path || resolvedCwd.startsWith(`${entry2.path}${path8.sep}`)) {
4568
+ if (resolvedCwd === entry2.path || resolvedCwd.startsWith(`${entry2.path}${path9.sep}`)) {
4396
4569
  return entry2;
4397
4570
  }
4398
4571
  }
@@ -4557,7 +4730,7 @@ function isNpxInvocation() {
4557
4730
  function commandPrefix() {
4558
4731
  return isNpxInvocation() ? "npx neat.is" : "neat";
4559
4732
  }
4560
- function usage() {
4733
+ function usage2() {
4561
4734
  const neat = commandPrefix();
4562
4735
  console.log("Installed via npx? Prefix commands with `npx neat.is`, or install once: `npm i -g neat.is`.");
4563
4736
  console.log("");
@@ -4594,6 +4767,14 @@ function usage() {
4594
4767
  console.log(" Flags:");
4595
4768
  console.log(" --print-config print the JSON snippet to stdout");
4596
4769
  console.log(" --apply merge mcpServers.neat into ~/.claude.json");
4770
+ console.log(" hooks Wire NEAT into your agent so it queries the graph before");
4771
+ console.log(" grepping. Installs a gentle Claude Code search-nudge hook and");
4772
+ console.log(" writes agent-agnostic graph-first guidance for other harnesses.");
4773
+ console.log(" Flags:");
4774
+ console.log(" --apply install the hook + guidance");
4775
+ console.log(" --print-hook print the hook script");
4776
+ console.log(" --print-guide print the graph-first guidance");
4777
+ console.log(" --print-settings print the settings.json block --apply adds");
4597
4778
  console.log(" deploy Detect the deploy substrate, generate NEAT_AUTH_TOKEN,");
4598
4779
  console.log(" emit a docker-compose / systemd / docker run artifact, and");
4599
4780
  console.log(" print the OTel env-vars block to paste into your platform.");
@@ -4838,7 +5019,7 @@ async function buildPatchSections(services, project) {
4838
5019
  }
4839
5020
  async function runInit(opts) {
4840
5021
  const written = [];
4841
- const stat = await fs7.stat(opts.scanPath).catch(() => null);
5022
+ const stat = await fs8.stat(opts.scanPath).catch(() => null);
4842
5023
  if (!stat || !stat.isDirectory()) {
4843
5024
  console.error(`neat init: ${opts.scanPath} is not a directory`);
4844
5025
  return { exitCode: 2, writtenFiles: written };
@@ -4847,13 +5028,13 @@ async function runInit(opts) {
4847
5028
  printDiscoveryReport(opts, services);
4848
5029
  const sections = opts.noInstall ? [] : await buildPatchSections(services, opts.project);
4849
5030
  const patch = renderPatch(sections);
4850
- const patchPath = path9.join(opts.scanPath, "neat.patch");
5031
+ const patchPath = path10.join(opts.scanPath, "neat.patch");
4851
5032
  if (opts.dryRun) {
4852
- await fs7.writeFile(patchPath, patch, "utf8");
5033
+ await fs8.writeFile(patchPath, patch, "utf8");
4853
5034
  written.push(patchPath);
4854
5035
  console.log(`dry-run: patch written to ${patchPath}`);
4855
- const gitignorePath = path9.join(opts.scanPath, ".gitignore");
4856
- const gitignoreExists = await fs7.stat(gitignorePath).then(() => true).catch(() => false);
5036
+ const gitignorePath = path10.join(opts.scanPath, ".gitignore");
5037
+ const gitignoreExists = await fs8.stat(gitignorePath).then(() => true).catch(() => false);
4857
5038
  const verb = gitignoreExists ? "append" : "create";
4858
5039
  console.log(`dry-run: would ${verb} ${gitignorePath} (add neat-out/)`);
4859
5040
  console.log("rerun without --dry-run to register and snapshot.");
@@ -4864,9 +5045,9 @@ async function runInit(opts) {
4864
5045
  const graph = getGraph(graphKey);
4865
5046
  const projectPaths = pathsForProject(
4866
5047
  graphKey,
4867
- path9.join(opts.scanPath, "neat-out")
5048
+ path10.join(opts.scanPath, "neat-out")
4868
5049
  );
4869
- const errorsPath = path9.join(path9.dirname(opts.outPath), path9.basename(projectPaths.errorsPath));
5050
+ const errorsPath = path10.join(path10.dirname(opts.outPath), path10.basename(projectPaths.errorsPath));
4870
5051
  const result = await extractFromDirectory(graph, opts.scanPath, { errorsPath });
4871
5052
  await saveGraphToDisk(graph, opts.outPath);
4872
5053
  written.push(opts.outPath);
@@ -4945,7 +5126,7 @@ async function runInit(opts) {
4945
5126
  console.log("Run `npm install` (or your language equivalent) to refresh lockfiles.");
4946
5127
  }
4947
5128
  } else {
4948
- await fs7.writeFile(patchPath, patch, "utf8");
5129
+ await fs8.writeFile(patchPath, patch, "utf8");
4949
5130
  written.push(patchPath);
4950
5131
  }
4951
5132
  }
@@ -4985,9 +5166,9 @@ var CLAUDE_SKILL_CONFIG = {
4985
5166
  };
4986
5167
  function claudeConfigPath() {
4987
5168
  const override = process.env.NEAT_CLAUDE_CONFIG;
4988
- if (override && override.length > 0) return path9.resolve(override);
5169
+ if (override && override.length > 0) return path10.resolve(override);
4989
5170
  const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
4990
- return path9.join(home, ".claude.json");
5171
+ return path10.join(home, ".claude.json");
4991
5172
  }
4992
5173
  async function runSkill(opts) {
4993
5174
  const snippet = JSON.stringify(CLAUDE_SKILL_CONFIG, null, 2) + "\n";
@@ -4999,7 +5180,7 @@ async function runSkill(opts) {
4999
5180
  const target = claudeConfigPath();
5000
5181
  let existing = {};
5001
5182
  try {
5002
- existing = JSON.parse(await fs7.readFile(target, "utf8"));
5183
+ existing = JSON.parse(await fs8.readFile(target, "utf8"));
5003
5184
  } catch (err) {
5004
5185
  if (err.code !== "ENOENT") {
5005
5186
  console.error(`neat skill: failed to read ${target} \u2014 ${err.message}`);
@@ -5011,10 +5192,13 @@ async function runSkill(opts) {
5011
5192
  ...existing,
5012
5193
  mcpServers: { ...mcp, neat: CLAUDE_SKILL_CONFIG.mcpServers.neat }
5013
5194
  };
5014
- await fs7.mkdir(path9.dirname(target), { recursive: true });
5015
- await fs7.writeFile(target, JSON.stringify(merged, null, 2) + "\n", "utf8");
5195
+ await fs8.mkdir(path10.dirname(target), { recursive: true });
5196
+ await fs8.writeFile(target, JSON.stringify(merged, null, 2) + "\n", "utf8");
5016
5197
  console.log(`neat skill: wrote mcpServers.neat to ${target}`);
5017
5198
  console.log("restart Claude Code to pick up the new MCP server.");
5199
+ console.log("");
5200
+ console.log("Tip: run `neat hooks --apply` to also install the search-nudge hook, so");
5201
+ console.log("your agent reaches for the graph before it grep-scans the repo.");
5018
5202
  return { exitCode: 0 };
5019
5203
  }
5020
5204
  console.log("neat skill \u2014 Claude Code MCP drop-in for NEAT");
@@ -5027,13 +5211,16 @@ async function runSkill(opts) {
5027
5211
  console.log("");
5028
5212
  console.log("The MCP server reads NEAT_CORE_URL for the daemon URL \u2014 point it at a");
5029
5213
  console.log("non-default daemon by editing that value in the generated config.");
5214
+ console.log("");
5215
+ console.log("See also `neat hooks --apply` \u2014 the search-nudge hook + graph-first guidance");
5216
+ console.log("that steer an agent to query the graph before falling back to text search.");
5030
5217
  return { exitCode: 0 };
5031
5218
  }
5032
5219
  async function main() {
5033
5220
  const argv = process.argv.slice(2);
5034
5221
  const cmd0 = argv[0];
5035
5222
  if (cmd0 === "-h" || cmd0 === "--help") {
5036
- usage();
5223
+ usage2();
5037
5224
  process.exit(0);
5038
5225
  }
5039
5226
  if (cmd0 === "--version" || cmd0 === "-v" || cmd0 === "version") {
@@ -5045,6 +5232,11 @@ async function main() {
5045
5232
  if (code !== 0) process.exit(code);
5046
5233
  return;
5047
5234
  }
5235
+ if (cmd0 === "hooks") {
5236
+ const code = await runHooksCommand(argv.slice(1));
5237
+ if (code !== 0) process.exit(code);
5238
+ return;
5239
+ }
5048
5240
  const argvParsed = parseArgs(argv);
5049
5241
  if (argvParsed.positional.length === 0) {
5050
5242
  const orchestratorCode2 = await tryOrchestrator(process.cwd(), argvParsed);
@@ -5059,19 +5251,19 @@ async function main() {
5059
5251
  const target = positional[0];
5060
5252
  if (!target) {
5061
5253
  console.error("neat init: missing <path>");
5062
- usage();
5254
+ usage2();
5063
5255
  process.exit(2);
5064
5256
  }
5065
5257
  if (apply3 && dryRun) {
5066
5258
  console.error("neat init: --apply and --dry-run are mutually exclusive");
5067
5259
  process.exit(2);
5068
5260
  }
5069
- const scanPath = path9.resolve(target);
5261
+ const scanPath = path10.resolve(target);
5070
5262
  const projectExplicit = parsed.project !== null;
5071
- const projectName = projectExplicit ? project : path9.basename(scanPath);
5263
+ const projectName = projectExplicit ? project : path10.basename(scanPath);
5072
5264
  const projectKey = projectExplicit ? project : DEFAULT_PROJECT;
5073
- const fallback = pathsForProject(projectKey, path9.join(scanPath, "neat-out")).snapshotPath;
5074
- const outPath = path9.resolve(process.env.NEAT_OUT_PATH ?? fallback);
5265
+ const fallback = pathsForProject(projectKey, path10.join(scanPath, "neat-out")).snapshotPath;
5266
+ const outPath = path10.resolve(process.env.NEAT_OUT_PATH ?? fallback);
5075
5267
  const result = await runInit({
5076
5268
  scanPath,
5077
5269
  outPath,
@@ -5089,24 +5281,24 @@ async function main() {
5089
5281
  const target = positional[0];
5090
5282
  if (!target) {
5091
5283
  console.error("neat watch: missing <path>");
5092
- usage();
5284
+ usage2();
5093
5285
  process.exit(2);
5094
5286
  }
5095
- const scanPath = path9.resolve(target);
5096
- const stat = await fs7.stat(scanPath).catch(() => null);
5287
+ const scanPath = path10.resolve(target);
5288
+ const stat = await fs8.stat(scanPath).catch(() => null);
5097
5289
  if (!stat || !stat.isDirectory()) {
5098
5290
  console.error(`neat watch: ${scanPath} is not a directory`);
5099
5291
  process.exit(2);
5100
5292
  }
5101
- const projectPaths = pathsForProject(project, path9.join(scanPath, "neat-out"));
5102
- const outPath = path9.resolve(process.env.NEAT_OUT_PATH ?? projectPaths.snapshotPath);
5103
- const errorsPath = path9.resolve(
5104
- process.env.NEAT_ERRORS_PATH ?? path9.join(path9.dirname(outPath), path9.basename(projectPaths.errorsPath))
5293
+ const projectPaths = pathsForProject(project, path10.join(scanPath, "neat-out"));
5294
+ const outPath = path10.resolve(process.env.NEAT_OUT_PATH ?? projectPaths.snapshotPath);
5295
+ const errorsPath = path10.resolve(
5296
+ process.env.NEAT_ERRORS_PATH ?? path10.join(path10.dirname(outPath), path10.basename(projectPaths.errorsPath))
5105
5297
  );
5106
- const staleEventsPath = path9.resolve(
5107
- process.env.NEAT_STALE_EVENTS_PATH ?? path9.join(path9.dirname(outPath), path9.basename(projectPaths.staleEventsPath))
5298
+ const staleEventsPath = path10.resolve(
5299
+ process.env.NEAT_STALE_EVENTS_PATH ?? path10.join(path10.dirname(outPath), path10.basename(projectPaths.staleEventsPath))
5108
5300
  );
5109
- const embeddingsCachePath = process.env.NEAT_EMBEDDINGS_CACHE_PATH ? path9.resolve(process.env.NEAT_EMBEDDINGS_CACHE_PATH) : void 0;
5301
+ const embeddingsCachePath = process.env.NEAT_EMBEDDINGS_CACHE_PATH ? path10.resolve(process.env.NEAT_EMBEDDINGS_CACHE_PATH) : void 0;
5110
5302
  const handle = await startWatch(getGraph(project), {
5111
5303
  scanPath,
5112
5304
  outPath,
@@ -5148,7 +5340,7 @@ async function main() {
5148
5340
  const name = positional[0];
5149
5341
  if (!name) {
5150
5342
  console.error("neat pause: missing <name>");
5151
- usage();
5343
+ usage2();
5152
5344
  process.exit(2);
5153
5345
  }
5154
5346
  const daemon = await findDaemonByProject(name);
@@ -5173,7 +5365,7 @@ async function main() {
5173
5365
  const name = positional[0];
5174
5366
  if (!name) {
5175
5367
  console.error("neat resume: missing <name>");
5176
- usage();
5368
+ usage2();
5177
5369
  process.exit(2);
5178
5370
  }
5179
5371
  const daemon = await findDaemonByProject(name);
@@ -5203,7 +5395,7 @@ async function main() {
5203
5395
  const name = positional[0];
5204
5396
  if (!name) {
5205
5397
  console.error("neat uninstall: missing <name>");
5206
- usage();
5398
+ usage2();
5207
5399
  process.exit(2);
5208
5400
  }
5209
5401
  const daemon = await findDaemonByProject(name);
@@ -5285,15 +5477,15 @@ async function main() {
5285
5477
  return;
5286
5478
  }
5287
5479
  console.error(`neat: unknown command "${cmd}"`);
5288
- usage();
5480
+ usage2();
5289
5481
  process.exit(1);
5290
5482
  }
5291
5483
  async function tryOrchestrator(cmd, parsed) {
5292
- const scanPath = path9.resolve(cmd);
5293
- const stat = await fs7.stat(scanPath).catch(() => null);
5484
+ const scanPath = path10.resolve(cmd);
5485
+ const stat = await fs8.stat(scanPath).catch(() => null);
5294
5486
  if (!stat || !stat.isDirectory()) return null;
5295
5487
  const projectExplicit = parsed.project !== null;
5296
- const projectName = projectExplicit ? parsed.project : path9.basename(scanPath);
5488
+ const projectName = projectExplicit ? parsed.project : path10.basename(scanPath);
5297
5489
  const result = await runOrchestrator({
5298
5490
  scanPath,
5299
5491
  project: projectName,
@@ -5549,6 +5741,6 @@ export {
5549
5741
  runInit,
5550
5742
  runQueryVerb,
5551
5743
  runSkill,
5552
- usage
5744
+ usage2 as usage
5553
5745
  };
5554
5746
  //# sourceMappingURL=cli.js.map