@merittdev/horus 0.21.0 → 0.21.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/horus_source.whl +0 -0
- package/dist/index.cjs +86 -22
- package/package.json +1 -1
package/dist/horus_source.whl
CHANGED
|
Binary file
|
package/dist/index.cjs
CHANGED
|
@@ -3057,7 +3057,7 @@ var init_version = __esm({
|
|
|
3057
3057
|
"../../packages/core/src/version.ts"() {
|
|
3058
3058
|
"use strict";
|
|
3059
3059
|
init_cjs_shims();
|
|
3060
|
-
HORUS_VERSION = true ? "0.21.
|
|
3060
|
+
HORUS_VERSION = true ? "0.21.1" : "dev";
|
|
3061
3061
|
PINNED_SOURCE_VERSION = HORUS_VERSION;
|
|
3062
3062
|
SOURCE_PIN_ENFORCED = HORUS_VERSION !== "dev";
|
|
3063
3063
|
}
|
|
@@ -11591,24 +11591,50 @@ function decryptConnectorSecrets(root) {
|
|
|
11591
11591
|
}
|
|
11592
11592
|
return out2;
|
|
11593
11593
|
}
|
|
11594
|
+
function hasHorusIgnoreEntry(text2) {
|
|
11595
|
+
return text2.split("\n").map((l2) => l2.trim()).some((l2) => l2 === ".horus" || l2 === ".horus/" || l2 === "/.horus" || l2 === "/.horus/");
|
|
11596
|
+
}
|
|
11597
|
+
function gitInfoExcludePath(root) {
|
|
11598
|
+
const gitPath = (0, import_node_path2.join)(root, ".git");
|
|
11599
|
+
if (!(0, import_node_fs2.existsSync)(gitPath)) return null;
|
|
11600
|
+
let gitDir;
|
|
11601
|
+
try {
|
|
11602
|
+
const st3 = (0, import_node_fs2.statSync)(gitPath);
|
|
11603
|
+
if (st3.isDirectory()) {
|
|
11604
|
+
gitDir = gitPath;
|
|
11605
|
+
} else {
|
|
11606
|
+
const m5 = /^gitdir:\s*(.+?)\s*$/m.exec((0, import_node_fs2.readFileSync)(gitPath, "utf8"));
|
|
11607
|
+
if (!m5) return null;
|
|
11608
|
+
const resolved = m5[1];
|
|
11609
|
+
gitDir = resolved.startsWith("/") ? resolved : (0, import_node_path2.join)(root, resolved);
|
|
11610
|
+
}
|
|
11611
|
+
} catch {
|
|
11612
|
+
return null;
|
|
11613
|
+
}
|
|
11614
|
+
return (0, import_node_path2.join)(gitDir, "info", "exclude");
|
|
11615
|
+
}
|
|
11594
11616
|
function isHorusGitignored(root) {
|
|
11595
11617
|
if (!(0, import_node_fs2.existsSync)((0, import_node_path2.join)(root, ".git"))) return true;
|
|
11618
|
+
const excludePath = gitInfoExcludePath(root);
|
|
11619
|
+
if (excludePath !== null && (0, import_node_fs2.existsSync)(excludePath) && hasHorusIgnoreEntry((0, import_node_fs2.readFileSync)(excludePath, "utf8"))) {
|
|
11620
|
+
return true;
|
|
11621
|
+
}
|
|
11596
11622
|
const gitignorePath = (0, import_node_path2.join)(root, ".gitignore");
|
|
11597
|
-
|
|
11598
|
-
return (0, import_node_fs2.readFileSync)(gitignorePath, "utf8").split("\n").map((l2) => l2.trim()).some((l2) => l2 === ".horus" || l2 === ".horus/" || l2 === "/.horus" || l2 === "/.horus/");
|
|
11623
|
+
return (0, import_node_fs2.existsSync)(gitignorePath) && hasHorusIgnoreEntry((0, import_node_fs2.readFileSync)(gitignorePath, "utf8"));
|
|
11599
11624
|
}
|
|
11600
11625
|
function ensureProjectGitignore(root) {
|
|
11601
|
-
|
|
11602
|
-
|
|
11626
|
+
const excludePath = gitInfoExcludePath(root);
|
|
11627
|
+
if (excludePath === null) return;
|
|
11603
11628
|
const entry2 = ".horus/";
|
|
11604
|
-
|
|
11605
|
-
(0,
|
|
11606
|
-
|
|
11629
|
+
try {
|
|
11630
|
+
const infoDir = (0, import_node_path2.dirname)(excludePath);
|
|
11631
|
+
if (!(0, import_node_fs2.existsSync)(infoDir)) (0, import_node_fs2.mkdirSync)(infoDir, { recursive: true });
|
|
11632
|
+
const existing = (0, import_node_fs2.existsSync)(excludePath) ? (0, import_node_fs2.readFileSync)(excludePath, "utf8") : "";
|
|
11633
|
+
if (hasHorusIgnoreEntry(existing)) return;
|
|
11634
|
+
const prefix = existing.trim() === "" ? "" : existing.trimEnd() + "\n";
|
|
11635
|
+
(0, import_node_fs2.writeFileSync)(excludePath, prefix + entry2 + "\n");
|
|
11636
|
+
} catch {
|
|
11607
11637
|
}
|
|
11608
|
-
const existing = (0, import_node_fs2.readFileSync)(gitignorePath, "utf8");
|
|
11609
|
-
const alreadyIgnored = existing.split("\n").map((l2) => l2.trim()).some((l2) => l2 === ".horus" || l2 === ".horus/" || l2 === "/.horus" || l2 === "/.horus/");
|
|
11610
|
-
if (alreadyIgnored) return;
|
|
11611
|
-
(0, import_node_fs2.writeFileSync)(gitignorePath, existing.trimEnd() + "\n" + entry2 + "\n");
|
|
11612
11638
|
}
|
|
11613
11639
|
function patchLocalConnector(configPath, connectorType, patch, envName) {
|
|
11614
11640
|
const file = readLocalConfig(configPath);
|
|
@@ -12610,8 +12636,8 @@ var init_path_classify = __esm({
|
|
|
12610
12636
|
"../../packages/core/src/path-classify.ts"() {
|
|
12611
12637
|
"use strict";
|
|
12612
12638
|
init_cjs_shims();
|
|
12613
|
-
TEST_DIRS = /* @__PURE__ */ new Set(["test", "tests", "__tests__", "spec", "specs", "testdata", "fixtures", "__fixtures__", "__mocks__", "e2e"]);
|
|
12614
|
-
DOCS_DIRS = /* @__PURE__ */ new Set(["docs", "doc", "docs_src", "website"]);
|
|
12639
|
+
TEST_DIRS = /* @__PURE__ */ new Set(["test", "tests", "__tests__", "spec", "specs", "testdata", "fixtures", "__fixtures__", "__testfixtures__", "testfixtures", "__mocks__", "e2e"]);
|
|
12640
|
+
DOCS_DIRS = /* @__PURE__ */ new Set(["docs", "doc", "docs_src", "website", "www", "site"]);
|
|
12615
12641
|
EXAMPLE_DIRS = /* @__PURE__ */ new Set([
|
|
12616
12642
|
"examples",
|
|
12617
12643
|
"example",
|
|
@@ -12642,8 +12668,17 @@ var init_path_classify = __esm({
|
|
|
12642
12668
|
function isGenericQueueName(name2) {
|
|
12643
12669
|
return GENERIC_QUEUE_NAMES.has(name2.toLowerCase());
|
|
12644
12670
|
}
|
|
12671
|
+
function isConstantShapedQueueName(name2) {
|
|
12672
|
+
return /^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)+$/.test(name2);
|
|
12673
|
+
}
|
|
12674
|
+
function needsWorkerVouch(name2) {
|
|
12675
|
+
return isGenericQueueName(name2) || isConstantShapedQueueName(name2);
|
|
12676
|
+
}
|
|
12645
12677
|
function isPlausibleQueueName(name2) {
|
|
12646
|
-
|
|
12678
|
+
if (name2.length === 0 || name2.length > 100) return false;
|
|
12679
|
+
if (/[\s<>{}()`"';$]/.test(name2)) return false;
|
|
12680
|
+
if ((name2.match(/\./g)?.length ?? 0) >= 2) return false;
|
|
12681
|
+
return true;
|
|
12647
12682
|
}
|
|
12648
12683
|
function isFixtureQueueEdge(edge) {
|
|
12649
12684
|
const files = [edge.producerFile, edge.workerFile].filter(
|
|
@@ -12652,12 +12687,20 @@ function isFixtureQueueEdge(edge) {
|
|
|
12652
12687
|
if (files.length > 0) return files.every((f5) => !isProductPath(f5));
|
|
12653
12688
|
return isGenericQueueName(edge.queueName);
|
|
12654
12689
|
}
|
|
12690
|
+
function isEnumConstantEdge(edge) {
|
|
12691
|
+
const pf = edge.producerFile;
|
|
12692
|
+
const wf = edge.workerFile;
|
|
12693
|
+
if (pf == null || pf === "" || pf !== wf) return false;
|
|
12694
|
+
const base2 = (pf.split("/").pop() ?? pf).toLowerCase();
|
|
12695
|
+
return /(enum|constant|attribute|telemetry)/.test(base2);
|
|
12696
|
+
}
|
|
12655
12697
|
function shouldKeepQueueEdge(edge) {
|
|
12656
|
-
return isPlausibleQueueName(edge.queueName) && !isFixtureQueueEdge(edge);
|
|
12698
|
+
return isPlausibleQueueName(edge.queueName) && !isFixtureQueueEdge(edge) && !isEnumConstantEdge(edge);
|
|
12657
12699
|
}
|
|
12658
12700
|
function isRealWorkerEvidence(edge) {
|
|
12659
12701
|
const sym = edge.workerSymbol;
|
|
12660
12702
|
if (sym == null || sym === "") return false;
|
|
12703
|
+
if (isConstantShapedQueueName(sym)) return false;
|
|
12661
12704
|
const file = edge.workerFile;
|
|
12662
12705
|
if (file != null && file !== "") {
|
|
12663
12706
|
if (!isProductPath(file)) return false;
|
|
@@ -12675,7 +12718,7 @@ function filterQueueEdges(edges) {
|
|
|
12675
12718
|
if (isRealWorkerEvidence(e)) hasRealWorker.add(e.queueName);
|
|
12676
12719
|
}
|
|
12677
12720
|
return kept.filter(
|
|
12678
|
-
(e) => !
|
|
12721
|
+
(e) => !needsWorkerVouch(e.queueName) || hasRealWorker.has(e.queueName)
|
|
12679
12722
|
);
|
|
12680
12723
|
}
|
|
12681
12724
|
var GENERIC_QUEUE_NAMES;
|
|
@@ -12745,6 +12788,7 @@ __export(src_exports, {
|
|
|
12745
12788
|
getHeadSha: () => getHeadSha,
|
|
12746
12789
|
getMasterKeyForRead: () => getMasterKeyForRead,
|
|
12747
12790
|
horusConfigSchema: () => horusConfigSchema,
|
|
12791
|
+
isConstantShapedQueueName: () => isConstantShapedQueueName,
|
|
12748
12792
|
isEncryptedSecret: () => isEncryptedSecret,
|
|
12749
12793
|
isFixtureQueueEdge: () => isFixtureQueueEdge,
|
|
12750
12794
|
isGenericQueueName: () => isGenericQueueName,
|
|
@@ -97300,6 +97344,7 @@ function correlate(evidence2, opts) {
|
|
|
97300
97344
|
|
|
97301
97345
|
// ../../packages/engine/src/seeds.ts
|
|
97302
97346
|
init_cjs_shims();
|
|
97347
|
+
init_src();
|
|
97303
97348
|
var PREFER = /resolver|controller|\bservice\b|route|router|handler|gateway|processor|worker|consumer|repository|usecase|use-case|endpoint/i;
|
|
97304
97349
|
var DEMOTE = /\butil|helper|\bscript|backfill|legacy|migration|seeder|fixture|\bmock\b|\btest\b|\bspec\b/i;
|
|
97305
97350
|
var PRESENTATION_NAME = /^(build|format|render|compose|serialize)[A-Z].*(Message|Markup|Html|Text|Label|Summary|Notification|String)$/;
|
|
@@ -97483,9 +97528,8 @@ function scoreSeed(s5, index2, hintTokens, changedFiles, hintHasCode, qualifier,
|
|
|
97483
97528
|
return score;
|
|
97484
97529
|
}
|
|
97485
97530
|
function isDeprioritizedSeedPath(filePath) {
|
|
97486
|
-
|
|
97487
|
-
|
|
97488
|
-
);
|
|
97531
|
+
const kind = classifyPath(filePath);
|
|
97532
|
+
return kind === "test" || kind === "docs" || kind === "example" || kind === "vendored";
|
|
97489
97533
|
}
|
|
97490
97534
|
function isDeprioritizedSeed(s5) {
|
|
97491
97535
|
return isDeprioritizedSeedPath(s5.filePath) || isCodegenPath(s5.filePath) || isTypeDeclarationSymbol(s5);
|
|
@@ -98706,7 +98750,8 @@ async function investigate(input, deps) {
|
|
|
98706
98750
|
}
|
|
98707
98751
|
const degradedNoSource = !code;
|
|
98708
98752
|
const changeWindowDays = deps.changeWindowDays ?? DEFAULT_CHANGE_WINDOW_DAYS;
|
|
98709
|
-
const
|
|
98753
|
+
const autoAnchorIso = input.since === void 0 && deps.repoPath !== void 0 ? await latestCommitDate(deps.repoPath) : void 0;
|
|
98754
|
+
const changeRangeLabel = input.since !== void 0 ? `${input.since}..HEAD` : autoAnchorIso !== void 0 ? `the ${changeWindowDays} days before the last commit (${autoAnchorIso.slice(0, 10)})` : `the last ${changeWindowDays} days`;
|
|
98710
98755
|
let recentChanges;
|
|
98711
98756
|
if (deps.repoPath) {
|
|
98712
98757
|
try {
|
|
@@ -101250,6 +101295,10 @@ function isTestOrExamplePath(p5) {
|
|
|
101250
101295
|
const kind = classifyPath(p5);
|
|
101251
101296
|
return kind === "test" || kind === "docs" || kind === "example";
|
|
101252
101297
|
}
|
|
101298
|
+
var DATA_FILE_RE2 = /(^|\/)(datasets?|seed(?:s|-?data)?|dictionar(?:y|ies)|word-?lists?|locales?|i18n|corpus)(\/|$)|(^|\/)(first-?names?|last-?names?|sur-?names?|full-?names?|countries|cities|nouns|adjectives|verbs|words|colou?rs|jobs?-?titles?|emojis?)\.[jt]sx?$/i;
|
|
101299
|
+
function isDataFilePath(p5) {
|
|
101300
|
+
return DATA_FILE_RE2.test(p5);
|
|
101301
|
+
}
|
|
101253
101302
|
async function discoverArchitecture(deps) {
|
|
101254
101303
|
const nodeStats = await (async () => {
|
|
101255
101304
|
try {
|
|
@@ -101358,7 +101407,13 @@ async function discoverArchitecture(deps) {
|
|
|
101358
101407
|
const matches = await deps.code.filesContaining?.(markers, 500) ?? {};
|
|
101359
101408
|
return markers.map((marker) => ({
|
|
101360
101409
|
name: marker,
|
|
101361
|
-
|
|
101410
|
+
// Count only genuine product source. `classifyPath === 'product'` additionally drops
|
|
101411
|
+
// config/lockfiles (a marker in `pnpm-lock.yaml`/`package.json` is a transitive dep,
|
|
101412
|
+
// not an integration) and vendored trees over the old test/example-only filter;
|
|
101413
|
+
// data files are excluded because their string contents collide with markers.
|
|
101414
|
+
files: (matches[marker] ?? []).filter(
|
|
101415
|
+
(p5) => p5 !== "" && classifyPath(p5) === "product" && !isDataFilePath(p5)
|
|
101416
|
+
).length
|
|
101362
101417
|
})).filter((r) => r.files > 0).sort((a2, b5) => b5.files - a2.files);
|
|
101363
101418
|
} catch {
|
|
101364
101419
|
return [];
|
|
@@ -124676,6 +124731,15 @@ async function runIndex(opts) {
|
|
|
124676
124731
|
console.error(import_picocolors41.default.red(` source analysis failed: ${err2.message}`));
|
|
124677
124732
|
return 1;
|
|
124678
124733
|
}
|
|
124734
|
+
const incomplete = isAnalyzed(root) ? indexNeedsReanalyze(root) : "no index was produced";
|
|
124735
|
+
if (incomplete) {
|
|
124736
|
+
console.error(
|
|
124737
|
+
import_picocolors41.default.red(
|
|
124738
|
+
` source analysis did not finish (${incomplete}) \u2014 the index has symbols but no embeddings. Re-run \`horus init\` to resume (the embedding cache is warm).`
|
|
124739
|
+
)
|
|
124740
|
+
);
|
|
124741
|
+
return 1;
|
|
124742
|
+
}
|
|
124679
124743
|
} else {
|
|
124680
124744
|
console.log(import_picocolors41.default.dim(" already analyzed"));
|
|
124681
124745
|
}
|