@appchy/jarvis 0.1.44 → 0.1.46

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/bin.js CHANGED
@@ -4606,22 +4606,23 @@ function harness2() {
4606
4606
  return script && python ? [python, script] : INSTALLED;
4607
4607
  }
4608
4608
  function sessionContext(repo) {
4609
- return say(["context", "--project", repo]);
4609
+ return say(repo, ["context"]);
4610
4610
  }
4611
4611
  function sessionMethod(repo) {
4612
- return say(["method", "--project", repo]);
4612
+ return say(repo, ["method"]);
4613
4613
  }
4614
4614
  function wrapBrief(repo) {
4615
- return say(["wrap", "--project", repo]);
4615
+ return say(repo, ["wrap"]);
4616
4616
  }
4617
4617
  var PATIENCE = 1e4;
4618
- function say(args, timeout = PATIENCE) {
4618
+ function say(repo, args, timeout = PATIENCE) {
4619
4619
  try {
4620
4620
  const [command, ...prefix] = harness2();
4621
- const ran = spawnSync(command, [...prefix, ...args], {
4621
+ const { WORK_DIR: _inherited, ...ambient } = process.env;
4622
+ const ran = spawnSync(command, [...prefix, ...args, "--project", repo], {
4622
4623
  encoding: "utf-8",
4623
4624
  timeout,
4624
- env: { ...process.env, PYTHONDONTWRITEBYTECODE: "1" }
4625
+ env: { ...ambient, CLAUDE_PROJECT_DIR: repo, PYTHONDONTWRITEBYTECODE: "1" }
4625
4626
  });
4626
4627
  if (ran.status !== 0) return null;
4627
4628
  return ran.stdout.trim() ? ran.stdout.trimEnd() : null;
@@ -5770,9 +5771,9 @@ var VENDOR_SUBPATHS = [
5770
5771
  "backends",
5771
5772
  "embedders",
5772
5773
  "finders",
5774
+ "labelers",
5773
5775
  "linkers",
5774
5776
  "persistences",
5775
- "rerankers",
5776
5777
  "stores"
5777
5778
  ];
5778
5779
  function toVendorAlias(dir) {
@@ -5809,11 +5810,11 @@ function validateConfig(value, path22) {
5809
5810
  const search3 = c.search;
5810
5811
  if (search3 !== void 0) {
5811
5812
  if (typeof search3.embedder?.embed !== "function")
5812
- fail("`search.embedder` must be an embedder (e.g. localEmbeddings())");
5813
+ fail("`search.embedder` must be an embedder (e.g. openaiEmbeddings())");
5813
5814
  if (search3.store !== void 0 && typeof search3.store.query !== "function")
5814
5815
  fail("`search.store` must be a vector store");
5815
5816
  if (search3.reranker !== void 0 && typeof search3.reranker.rerank !== "function")
5816
- fail("`search.reranker` must be a reranker (e.g. localReranker())");
5817
+ fail("`search.reranker` must be a reranker");
5817
5818
  }
5818
5819
  }
5819
5820
 
@@ -5822,6 +5823,7 @@ async function buildEmbeddings(config2, graph2) {
5822
5823
  const cfg = config2.search;
5823
5824
  if (!cfg) return void 0;
5824
5825
  const embedder2 = cfg.embedder.resolve ? await cfg.embedder.resolve() : cfg.embedder;
5826
+ if (!embedder2) return declined(cfg.embedder, "no semantic index was built");
5825
5827
  const storeImpl = cfg.store;
5826
5828
  const nodes = cfg.types ? cfg.types.flatMap((t) => graph2.nodes(t)) : graph2.nodes();
5827
5829
  const ctx = { repoRoot: config2.repoRoot };
@@ -5880,6 +5882,7 @@ async function loadEmbeddings(config2, graph2) {
5880
5882
  const cfg = config2.search;
5881
5883
  if (!cfg) return void 0;
5882
5884
  const embedder2 = cfg.embedder.resolve ? await cfg.embedder.resolve() : cfg.embedder;
5885
+ if (!embedder2) return declined(cfg.embedder, "search is lexical");
5883
5886
  await probeEmbedder(embedder2);
5884
5887
  const storeImpl = cfg.store;
5885
5888
  const nodes = cfg.types ? cfg.types.flatMap((t) => graph2.nodes(t)) : graph2.nodes();
@@ -5911,6 +5914,13 @@ function toRuntime(cfg, embedder2, storeImpl, items) {
5911
5914
  ...cfg.confidence ? { confidence: cfg.confidence } : {}
5912
5915
  };
5913
5916
  }
5917
+ function declined(embedder2, consequence) {
5918
+ process.stderr.write(
5919
+ `[data:warn] embedder ${embedder2.name} is not available on this machine \u2014 ${consequence}. Token-overlap (BM25) search still applies.
5920
+ `
5921
+ );
5922
+ return void 0;
5923
+ }
5914
5924
  async function probeEmbedder(embedder2) {
5915
5925
  try {
5916
5926
  await embedder2.embed(["probe"]);
@@ -9613,7 +9623,7 @@ import { createRequire as createRequire2 } from "module";
9613
9623
  var _require = createRequire2(import.meta.url);
9614
9624
  var VERSION2 = _require("../package.json").version ?? "0.0.0";
9615
9625
  var IS_DEV = String(_require("../package.json").name ?? "").endsWith("-dev");
9616
- var SHA = "d64996d";
9626
+ var SHA = "d68669d";
9617
9627
  var BUILT = "2026-09-07";
9618
9628
  var BUILD = SHA ?? "source";
9619
9629
  var BUILD_LABEL = `${SHA ? `${VERSION2} (${SHA}${BUILT ? ` ${BUILT}` : ""})` : `${VERSION2} (source)`}${IS_DEV ? " \u2014 development build" : ""}`;
@@ -10614,6 +10624,33 @@ function register15(program) {
10614
10624
  });
10615
10625
  }
10616
10626
 
10627
+ // src/commands/model.ts
10628
+ function register16(program) {
10629
+ const model = program.command("model").description("Model access for the map's semantic search, on this machine");
10630
+ model.command("key").argument("[key]", "The OpenAI key to store. Omit it to see what is set.").option("--show", "Say whether a key is set, without printing it").option("--clear", "Forget the stored key").description("Set the OpenAI key the map embeds with").action((key, opts) => {
10631
+ const config2 = loadConfig();
10632
+ if (!config2) {
10633
+ console.error("This machine has no jarvis config yet \u2014 run `jarvis init` first.");
10634
+ process.exitCode = 1;
10635
+ return;
10636
+ }
10637
+ if (opts.clear) {
10638
+ saveConfig({ ...config2, openaiApiKey: void 0 });
10639
+ console.log("Forgotten. The map will build with no semantic index.");
10640
+ return;
10641
+ }
10642
+ if (!key || opts.show) {
10643
+ console.log(
10644
+ config2.openaiApiKey ? `A key is set (\u2026${config2.openaiApiKey.slice(-4)}). The map embeds with it.` : "No key set. The map builds with no semantic index and search stays lexical."
10645
+ );
10646
+ if (!key) console.log("Set one with `jarvis model key <key>`.");
10647
+ return;
10648
+ }
10649
+ saveConfig({ ...config2, openaiApiKey: key });
10650
+ console.log("Stored. Run `jarvis build graph` to build the semantic index.");
10651
+ });
10652
+ }
10653
+
10617
10654
  // src/graph/build.ts
10618
10655
  import { mkdirSync as mkdirSync2, readFileSync as readFileSync6, rmSync, statSync as statSync3, writeFileSync as writeFileSync3 } from "fs";
10619
10656
  import { dirname as dirname5, resolve as resolve7 } from "path";
@@ -10787,12 +10824,6 @@ async function runBuild(cwd, argv = []) {
10787
10824
  if (argv.includes("--rebuild")) process.env.JARVIS_DATA_REBUILD = "1";
10788
10825
  else process.env.JARVIS_DATA_REFRESH = "1";
10789
10826
  if (argv.includes("--label")) process.env.JARVIS_DATA_LABEL = "1";
10790
- const labelBackend = readFlag(argv, "--backend");
10791
- if (labelBackend) process.env.JARVIS_DATA_BACKEND = labelBackend;
10792
- const labelModel = readFlag(argv, "--model");
10793
- if (labelModel) process.env.JARVIS_DATA_MODEL = labelModel;
10794
- const labelTier = readFlag(argv, "--tier");
10795
- if (labelTier) process.env.JARVIS_DATA_TIER = labelTier;
10796
10827
  const lock = acquireBuildLock(cwd);
10797
10828
  if (!lock) {
10798
10829
  process.stderr.write(
@@ -10846,13 +10877,6 @@ ${formatLedger(ledger)}
10846
10877
  }
10847
10878
  return errors > 0 ? 1 : 0;
10848
10879
  }
10849
- function readFlag(argv, flag2) {
10850
- const exact = argv.indexOf(flag2);
10851
- if (exact >= 0) return argv[exact + 1];
10852
- const prefix = `${flag2}=`;
10853
- const inline = argv.find((arg) => arg.startsWith(prefix));
10854
- return inline ? inline.slice(prefix.length) : void 0;
10855
- }
10856
10880
  var DEFAULT_STALE_MS = 10 * 60 * 1e3;
10857
10881
  function acquireBuildLock(repoRoot, options = {}) {
10858
10882
  const staleMs = options.staleMs ?? DEFAULT_STALE_MS;
@@ -10913,16 +10937,13 @@ function loadEnvFile(path22) {
10913
10937
  }
10914
10938
 
10915
10939
  // src/commands/build.ts
10916
- function register16(program) {
10940
+ function register17(program) {
10917
10941
  const build2 = program.command("build").description("Build an artifact from this repo");
10918
- build2.command("graph").description("Read the repo's jarvis.config.ts, build the graph, and say what is wrong with it").option("--repo <path>", "The repo to map. Default: the working directory").option("--rebuild", "LAST RESORT: throw the graph away and re-extract from scratch").option("--label", "Re-name the detected communities through the configured labeler").option("--gate", "Fail when a governance class has more findings than this repo carries").option("--backend <name>", "Label the communities as this backend").option("--model <name>", "Label the communities with this model").option("--tier <tier>", "Label the communities at this tier").action(async (opts) => {
10942
+ build2.command("graph").description("Read the repo's jarvis.config.ts, build the graph, and say what is wrong with it").option("--repo <path>", "The repo to map. Default: the working directory").option("--rebuild", "LAST RESORT: throw the graph away and re-extract from scratch").option("--label", "Re-name the detected communities through the configured labeler").option("--gate", "Fail when a governance class has more findings than this repo carries").action(async (opts) => {
10919
10943
  const argv = [
10920
10944
  ...opts.rebuild ? ["--rebuild"] : [],
10921
10945
  ...opts.label ? ["--label"] : [],
10922
- ...opts.gate ? ["--gate"] : [],
10923
- ...opts.backend ? ["--backend", opts.backend] : [],
10924
- ...opts.model ? ["--model", opts.model] : [],
10925
- ...opts.tier ? ["--tier", opts.tier] : []
10946
+ ...opts.gate ? ["--gate"] : []
10926
10947
  ];
10927
10948
  process.exitCode = await runBuild(resolveRepo(opts.repo), argv);
10928
10949
  });
@@ -10976,7 +10997,7 @@ function isRedirected(req) {
10976
10997
  }
10977
10998
 
10978
10999
  // src/commands/dev.ts
10979
- function register17(program) {
11000
+ function register18(program) {
10980
11001
  const dev = program.command("dev").description("Run a development build in a repo, without replacing the installed jarvis");
10981
11002
  dev.command("use").argument("[where]", "'here' for the working directory, 'all' for every repo", "here").option("--root <path>", "The checkout to run. Default: the one already recorded").description("Point a repo at the development build").action((where, opts) => {
10982
11003
  const current = readDevRedirect();
@@ -11690,7 +11711,7 @@ async function brief2(repo) {
11690
11711
  }
11691
11712
 
11692
11713
  // src/commands/serve.ts
11693
- function register18(program) {
11714
+ function register19(program) {
11694
11715
  program.command("serve").description("Serve this repo to an agent over stdio \u2014 what an .mcp.json launches").option("--repo <path>", "The repo to serve. Default: the working directory").action(async (opts) => {
11695
11716
  const repo = resolveRepo(opts.repo);
11696
11717
  const problem = harnessProblem();
@@ -11752,7 +11773,7 @@ function refuseNamedConfigDir() {
11752
11773
  );
11753
11774
  return true;
11754
11775
  }
11755
- function register19(program) {
11776
+ function register20(program) {
11756
11777
  const hooks = program.command("hooks").description("Wire this machine's Claude Code to jarvis \u2014 no pairing, no daemon");
11757
11778
  hooks.command("install").description("Install the Claude Code hooks (the session block and the rules on edit)").action(() => {
11758
11779
  if (refuseNamedConfigDir()) process.exit(1);
@@ -11807,7 +11828,7 @@ Open Claude Code in a repo that has a work/ tree to see them.`);
11807
11828
 
11808
11829
  // src/commands/work.ts
11809
11830
  import { spawnSync as spawnSync3 } from "child_process";
11810
- function register20(program) {
11831
+ function register21(program) {
11811
11832
  program.command("work").description("The board \u2014 take work, prove it, finish it").argument("[args...]", "Passed to the harness untouched").allowUnknownOption().passThroughOptions().helpOption(false).action((passed) => {
11812
11833
  const problem = harnessProblem();
11813
11834
  if (problem) {
@@ -11850,6 +11871,7 @@ function createCli() {
11850
11871
  register18(program);
11851
11872
  register19(program);
11852
11873
  register20(program);
11874
+ register21(program);
11853
11875
  return program;
11854
11876
  }
11855
11877