@merittdev/horus 0.8.7 → 0.8.8

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.
Files changed (2) hide show
  1. package/dist/index.cjs +72 -50
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -65880,7 +65880,7 @@ init_cjs_shims();
65880
65880
 
65881
65881
  // ../../packages/core/src/version.ts
65882
65882
  init_cjs_shims();
65883
- var HORUS_VERSION = true ? "0.8.7" : "dev";
65883
+ var HORUS_VERSION = true ? "0.8.8" : "dev";
65884
65884
  var PINNED_SOURCE_VERSION = "1.5.0";
65885
65885
 
65886
65886
  // ../../packages/core/src/evidence.ts
@@ -70614,6 +70614,11 @@ async function loadConfig(configPath, opts) {
70614
70614
  } else {
70615
70615
  const jsPath = (0, import_node_path2.resolve)(cwd, "config/horus.config.js");
70616
70616
  const tsPath = (0, import_node_path2.resolve)(cwd, "config/horus.config.ts");
70617
+ if (!(0, import_node_fs2.existsSync)(jsPath) && !(0, import_node_fs2.existsSync)(tsPath)) {
70618
+ throw new Error(
70619
+ `No Horus config found for ${cwd}. Run \`horus index\` in this repo to set it up, or pass --config <path> / --name <project>.`
70620
+ );
70621
+ }
70617
70622
  target = (0, import_node_fs2.existsSync)(jsPath) ? jsPath : tsPath;
70618
70623
  }
70619
70624
  }
@@ -97273,6 +97278,50 @@ async function stitch(client, db, opts = {}) {
97273
97278
  };
97274
97279
  }
97275
97280
 
97281
+ // ../../packages/cli/src/lib/ensure-host.ts
97282
+ init_cjs_shims();
97283
+ function parseHostPort(hostUrl) {
97284
+ try {
97285
+ const port = parseInt(new URL(hostUrl).port, 10);
97286
+ return Number.isNaN(port) ? null : port;
97287
+ } catch {
97288
+ return null;
97289
+ }
97290
+ }
97291
+ function ensureHostReasonHint(reason) {
97292
+ switch (reason) {
97293
+ case "source-unavailable":
97294
+ return "horus-source is not installed \u2014 install it: pip install horus-source";
97295
+ case "version-mismatch":
97296
+ return "the installed horus-source backend does not match the version Horus is pinned to \u2014 reinstall the pinned version (run `horus status` to see it)";
97297
+ case "not-analyzed":
97298
+ return "this repo has not been indexed yet \u2014 run: horus index";
97299
+ case "bad-url":
97300
+ return "the configured source host URL is not a valid URL";
97301
+ default:
97302
+ return "the host did not become healthy \u2014 run: horus index";
97303
+ }
97304
+ }
97305
+ async function ensureSourceHost(root, hostUrl, opts = {}) {
97306
+ if (await isHostHealthy(hostUrl)) return { ok: true, hostUrl };
97307
+ if (!await sourceAvailable()) return { ok: false, reason: "source-unavailable" };
97308
+ try {
97309
+ await assertSourceVersionPinned();
97310
+ } catch {
97311
+ return { ok: false, reason: "version-mismatch" };
97312
+ }
97313
+ if (!isAnalyzed(root)) return { ok: false, reason: "not-analyzed" };
97314
+ const port = parseHostPort(hostUrl);
97315
+ if (port === null) return { ok: false, reason: "bad-url" };
97316
+ startHost(root, port);
97317
+ if (await waitForHost(hostUrl, opts.timeoutMs ?? 2e4)) {
97318
+ reconcileSpawnedHostPid(root, port);
97319
+ return { ok: true, hostUrl };
97320
+ }
97321
+ removeSpawnedHostRecord(root);
97322
+ return { ok: false, reason: "unhealthy" };
97323
+ }
97324
+
97276
97325
  // ../../packages/cli/src/commands/index-repo.ts
97277
97326
  async function stitchQueueMap(hostUrl, dbUrl, label) {
97278
97327
  const source = new SourceHttpClient({ baseUrl: hostUrl });
@@ -97286,6 +97335,14 @@ async function stitchQueueMap(hostUrl, dbUrl, label) {
97286
97335
  await sql2.end();
97287
97336
  }
97288
97337
  }
97338
+ async function hostServesRepo(hostUrl, root) {
97339
+ try {
97340
+ const info2 = await new SourceHttpClient({ baseUrl: hostUrl }).hostInfo();
97341
+ return (0, import_node_path10.resolve)(info2.repoPath) === (0, import_node_path10.resolve)(root);
97342
+ } catch {
97343
+ return true;
97344
+ }
97345
+ }
97289
97346
  function findConfiguredRepo(config2, root) {
97290
97347
  const target = (0, import_node_path10.resolve)(root);
97291
97348
  for (const p5 of config2.projects) {
@@ -97372,7 +97429,7 @@ async function runIndex(opts) {
97372
97429
  let hostUrl;
97373
97430
  let spawned = false;
97374
97431
  for (const candidate of [configuredHost, readSourceHostUrl(root) ?? void 0]) {
97375
- if (candidate && await isHostHealthy(candidate)) {
97432
+ if (candidate && await isHostHealthy(candidate) && await hostServesRepo(candidate, root)) {
97376
97433
  hostUrl = candidate;
97377
97434
  break;
97378
97435
  }
@@ -97403,7 +97460,17 @@ async function runIndex(opts) {
97403
97460
  } else {
97404
97461
  console.log(import_picocolors3.default.dim(" already analyzed"));
97405
97462
  }
97406
- const port = await findFreePort();
97463
+ const priorPort = parseHostPort(configuredHost ?? "") ?? parseHostPort(readSourceHostUrl(root) ?? "");
97464
+ let port;
97465
+ if (priorPort !== null) {
97466
+ try {
97467
+ port = await findFreePort(priorPort, priorPort);
97468
+ } catch {
97469
+ port = await findFreePort();
97470
+ }
97471
+ } else {
97472
+ port = await findFreePort();
97473
+ }
97407
97474
  hostUrl = `http://127.0.0.1:${port}`;
97408
97475
  console.log(import_picocolors3.default.dim(` starting source-intelligence host on port ${port}\u2026`));
97409
97476
  startHost(root, port);
@@ -97418,7 +97485,8 @@ async function runIndex(opts) {
97418
97485
  }
97419
97486
  await stitchQueueMap(hostUrl, dbUrl, label);
97420
97487
  buildKnowledgeIndex(root, config2, label, configuredProject, opts);
97421
- if (spawned && !isConfigured) {
97488
+ const hasLocalConfig = discoverLocalConfig(root) !== null;
97489
+ if (!isConfigured && !hasLocalConfig) {
97422
97490
  const file = {
97423
97491
  version: 1,
97424
97492
  project: {
@@ -110339,52 +110407,6 @@ async function maybePromptFeedback(opts) {
110339
110407
  // ../../packages/cli/src/lib/investigation-runner.ts
110340
110408
  init_cjs_shims();
110341
110409
  var import_picocolors9 = __toESM(require_picocolors(), 1);
110342
-
110343
- // ../../packages/cli/src/lib/ensure-host.ts
110344
- init_cjs_shims();
110345
- function parseHostPort(hostUrl) {
110346
- try {
110347
- const port = parseInt(new URL(hostUrl).port, 10);
110348
- return Number.isNaN(port) ? null : port;
110349
- } catch {
110350
- return null;
110351
- }
110352
- }
110353
- function ensureHostReasonHint(reason) {
110354
- switch (reason) {
110355
- case "source-unavailable":
110356
- return "horus-source is not installed \u2014 install it: pip install horus-source";
110357
- case "version-mismatch":
110358
- return "the installed horus-source backend does not match the version Horus is pinned to \u2014 reinstall the pinned version (run `horus status` to see it)";
110359
- case "not-analyzed":
110360
- return "this repo has not been indexed yet \u2014 run: horus index";
110361
- case "bad-url":
110362
- return "the configured source host URL is not a valid URL";
110363
- default:
110364
- return "the host did not become healthy \u2014 run: horus index";
110365
- }
110366
- }
110367
- async function ensureSourceHost(root, hostUrl, opts = {}) {
110368
- if (await isHostHealthy(hostUrl)) return { ok: true, hostUrl };
110369
- if (!await sourceAvailable()) return { ok: false, reason: "source-unavailable" };
110370
- try {
110371
- await assertSourceVersionPinned();
110372
- } catch {
110373
- return { ok: false, reason: "version-mismatch" };
110374
- }
110375
- if (!isAnalyzed(root)) return { ok: false, reason: "not-analyzed" };
110376
- const port = parseHostPort(hostUrl);
110377
- if (port === null) return { ok: false, reason: "bad-url" };
110378
- startHost(root, port);
110379
- if (await waitForHost(hostUrl, opts.timeoutMs ?? 2e4)) {
110380
- reconcileSpawnedHostPid(root, port);
110381
- return { ok: true, hostUrl };
110382
- }
110383
- removeSpawnedHostRecord(root);
110384
- return { ok: false, reason: "unhealthy" };
110385
- }
110386
-
110387
- // ../../packages/cli/src/lib/investigation-runner.ts
110388
110410
  async function buildInvestigationContext(renv, opts) {
110389
110411
  const log = opts.log ?? ((l2) => console.error(l2));
110390
110412
  const code = codeForEnv(renv);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@merittdev/horus",
3
- "version": "0.8.7",
3
+ "version": "0.8.8",
4
4
  "description": "Local-first, source-aware production-incident investigation engine",
5
5
  "type": "module",
6
6
  "bin": {