@reposkein/mcp 0.2.7 → 0.4.0
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/README.md +73 -1
- package/binary-digests.json +4 -4
- package/dist/SKILL.md +63 -1
- package/dist/cli/adr.d.ts +37 -0
- package/dist/cli/adr.js +231 -0
- package/dist/cli/adr.js.map +1 -0
- package/dist/cli/agentAdapters.d.ts +68 -0
- package/dist/cli/agentAdapters.js +223 -0
- package/dist/cli/agentAdapters.js.map +1 -0
- package/dist/cli/ansi.d.ts +24 -0
- package/dist/cli/ansi.js +40 -0
- package/dist/cli/ansi.js.map +1 -0
- package/dist/cli/doctor.d.ts +34 -2
- package/dist/cli/doctor.js +53 -5
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/doctorDecisions.d.ts +5 -0
- package/dist/cli/doctorDecisions.js +83 -0
- package/dist/cli/doctorDecisions.js.map +1 -0
- package/dist/cli/doctorFreshness.d.ts +43 -0
- package/dist/cli/doctorFreshness.js +111 -0
- package/dist/cli/doctorFreshness.js.map +1 -0
- package/dist/cli/doctorSummaries.d.ts +2 -0
- package/dist/cli/doctorSummaries.js +95 -0
- package/dist/cli/doctorSummaries.js.map +1 -0
- package/dist/cli/federatedDiscovery.d.ts +16 -0
- package/dist/cli/federatedDiscovery.js +75 -0
- package/dist/cli/federatedDiscovery.js.map +1 -0
- package/dist/cli/init.d.ts +69 -6
- package/dist/cli/init.js +194 -28
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/sourceSlices.d.ts +17 -0
- package/dist/cli/sourceSlices.js +59 -0
- package/dist/cli/sourceSlices.js.map +1 -0
- package/dist/cli/stats.d.ts +29 -0
- package/dist/cli/stats.js +180 -0
- package/dist/cli/stats.js.map +1 -0
- package/dist/cli/view.d.ts +71 -3
- package/dist/cli/view.js +147 -12
- package/dist/cli/view.js.map +1 -1
- package/dist/guard/decisionValidation.d.ts +29 -0
- package/dist/guard/decisionValidation.js +51 -0
- package/dist/guard/decisionValidation.js.map +1 -0
- package/dist/guard/summaryValidation.d.ts +3 -0
- package/dist/guard/summaryValidation.js +5 -3
- package/dist/guard/summaryValidation.js.map +1 -1
- package/dist/index.d.ts +48 -0
- package/dist/index.js +355 -78
- package/dist/index.js.map +1 -1
- package/dist/indexer/decisionsAffected.d.ts +42 -0
- package/dist/indexer/decisionsAffected.js +149 -0
- package/dist/indexer/decisionsAffected.js.map +1 -0
- package/dist/indexer/fetchBinary.d.ts +14 -0
- package/dist/indexer/fetchBinary.js +81 -40
- package/dist/indexer/fetchBinary.js.map +1 -1
- package/dist/indexer/runIndexer.d.ts +3 -2
- package/dist/indexer/runIndexer.js +8 -4
- package/dist/indexer/runIndexer.js.map +1 -1
- package/dist/profile/decisions.d.ts +37 -0
- package/dist/profile/decisions.js +112 -0
- package/dist/profile/decisions.js.map +1 -0
- package/dist/profile/types.d.ts +8 -0
- package/dist/store/GraphStore.d.ts +5 -0
- package/dist/store/JsonlGraphStore.d.ts +14 -3
- package/dist/store/JsonlGraphStore.js +66 -19
- package/dist/store/JsonlGraphStore.js.map +1 -1
- package/dist/store/decisions.d.ts +131 -0
- package/dist/store/decisions.js +321 -0
- package/dist/store/decisions.js.map +1 -0
- package/dist/store/indexedAt.d.ts +18 -0
- package/dist/store/indexedAt.js +56 -0
- package/dist/store/indexedAt.js.map +1 -0
- package/dist/store/instrumentTool.d.ts +40 -0
- package/dist/store/instrumentTool.js +82 -0
- package/dist/store/instrumentTool.js.map +1 -0
- package/dist/store/repoContextCache.d.ts +15 -0
- package/dist/store/repoContextCache.js +26 -0
- package/dist/store/repoContextCache.js.map +1 -0
- package/dist/store/repoSession.d.ts +63 -0
- package/dist/store/repoSession.js +123 -0
- package/dist/store/repoSession.js.map +1 -0
- package/dist/store/resolveRepoPath.d.ts +31 -0
- package/dist/store/resolveRepoPath.js +85 -0
- package/dist/store/resolveRepoPath.js.map +1 -0
- package/dist/store/sessionLog.d.ts +98 -0
- package/dist/store/sessionLog.js +216 -0
- package/dist/store/sessionLog.js.map +1 -0
- package/dist/store/sessionStats.d.ts +55 -0
- package/dist/store/sessionStats.js +140 -0
- package/dist/store/sessionStats.js.map +1 -0
- package/dist/store/sidecar.d.ts +39 -3
- package/dist/store/sidecar.js +89 -5
- package/dist/store/sidecar.js.map +1 -1
- package/dist/store/summaryShards.d.ts +117 -0
- package/dist/store/summaryShards.js +291 -0
- package/dist/store/summaryShards.js.map +1 -0
- package/dist/store/teamConfig.d.ts +13 -0
- package/dist/store/teamConfig.js +49 -0
- package/dist/store/teamConfig.js.map +1 -0
- package/dist/tools/getContextProfile.d.ts +1 -1
- package/dist/tools/getContextProfile.js +9 -1
- package/dist/tools/getContextProfile.js.map +1 -1
- package/dist/tools/getDecision.d.ts +6 -0
- package/dist/tools/getDecision.js +59 -0
- package/dist/tools/getDecision.js.map +1 -0
- package/dist/tools/impact.d.ts +1 -1
- package/dist/tools/impact.js +13 -1
- package/dist/tools/impact.js.map +1 -1
- package/dist/tools/indexerTools.d.ts +16 -2
- package/dist/tools/indexerTools.js +44 -5
- package/dist/tools/indexerTools.js.map +1 -1
- package/dist/tools/listDecisions.d.ts +19 -0
- package/dist/tools/listDecisions.js +93 -0
- package/dist/tools/listDecisions.js.map +1 -0
- package/dist/tools/reaffirmDecision.d.ts +11 -0
- package/dist/tools/reaffirmDecision.js +55 -0
- package/dist/tools/reaffirmDecision.js.map +1 -0
- package/dist/tools/recordDecision.d.ts +24 -0
- package/dist/tools/recordDecision.js +135 -0
- package/dist/tools/recordDecision.js.map +1 -0
- package/dist/tools/semanticFind.d.ts +9 -2
- package/dist/tools/semanticFind.js +44 -2
- package/dist/tools/semanticFind.js.map +1 -1
- package/dist/tools/setDecisionStatus.d.ts +8 -0
- package/dist/tools/setDecisionStatus.js +34 -0
- package/dist/tools/setDecisionStatus.js.map +1 -0
- package/dist/viz/assets/{graph.worker-CC7BeE-8.js → graph.worker-DkH6-lMU.js} +1 -1
- package/dist/viz/assets/index-CxqeGuRS.css +1 -0
- package/dist/viz/assets/index-DiNZyrXx.js +9 -0
- package/dist/viz/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
- package/dist/viz/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
- package/dist/viz/assets/jetbrains-mono-latin-700-normal-BYuf6tUa.woff2 +0 -0
- package/dist/viz/assets/r3f-BZY3QR6_.js +336 -0
- package/dist/viz/assets/tanstack-CjXr-L-s.js +62 -0
- package/dist/viz/assets/three-Cpu5RUEM.js +4116 -0
- package/dist/viz/index.html +5 -4
- package/package.json +5 -4
- package/dist/viz/assets/index-C_8UkiJ8.js +0 -9
- package/dist/viz/assets/r3f-Cku1OhB-.js +0 -277
- package/dist/viz/assets/tanstack-DyXcNRWk.js +0 -77
- package/dist/viz/assets/three-Z8XaLGmf.js +0 -3839
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** TS mirror of the indexer's GraphDelta (indexer/crates/core/src/delta.rs). */
|
|
2
|
+
export interface GraphDeltaJson {
|
|
3
|
+
added: string[];
|
|
4
|
+
removed: string[];
|
|
5
|
+
modified: string[];
|
|
6
|
+
counts: {
|
|
7
|
+
added: number;
|
|
8
|
+
removed: number;
|
|
9
|
+
modified: number;
|
|
10
|
+
};
|
|
11
|
+
truncated: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface DecisionAffected {
|
|
14
|
+
decision_id: string;
|
|
15
|
+
title: string;
|
|
16
|
+
why: "anchor_modified" | "anchor_removed" | "governed_path_changed";
|
|
17
|
+
}
|
|
18
|
+
/** Where hook-driven indexes park their delta: pre-commit / post-merge /
|
|
19
|
+
* post-checkout discard stdout, and post-merge (teammate changes landing) is
|
|
20
|
+
* exactly when decisions drift — the file bridges that gap to the next MCP
|
|
21
|
+
* call. Root repo only; nested repos' drift surfaces when they are reindexed
|
|
22
|
+
* through the MCP tools themselves. */
|
|
23
|
+
export declare function pendingDeltaPath(repoPath: string): string;
|
|
24
|
+
/** Reads AND consumes the pending delta (delete-on-read: each drift event is
|
|
25
|
+
* surfaced once). Corrupt files are consumed silently — a damaged advisory
|
|
26
|
+
* file must not wedge the pipeline. */
|
|
27
|
+
export declare function readPendingDelta(repoPath: string): GraphDeltaJson | null;
|
|
28
|
+
/** Drops the given node ids (suffix-tolerant) from the pending delta —
|
|
29
|
+
* called by record_decision, whose own refresh index would otherwise park a
|
|
30
|
+
* delta that flags the just-stamped decision as drifted on the next call.
|
|
31
|
+
* Deletes the file when nothing else remains; best-effort throughout. */
|
|
32
|
+
export declare function removeFromPendingDelta(repoPath: string, nodeIds: string[]): void;
|
|
33
|
+
/** Unions two deltas (id lists deduped; counts = union sizes). */
|
|
34
|
+
export declare function mergeDeltas(a: GraphDeltaJson, b: GraphDeltaJson): GraphDeltaJson;
|
|
35
|
+
/** Cross-references a delta against the decision log: which accepted/proposed
|
|
36
|
+
* decisions govern something that just changed? Anchor matching is
|
|
37
|
+
* suffix-tolerant across repo_ids; PATH governance is scoped to the root
|
|
38
|
+
* repo (`rootRepoId`) — nested child repos use child-relative paths, a
|
|
39
|
+
* different coordinate system, and are governed via anchors instead.
|
|
40
|
+
* Deterministic order (by decision id). The skill rule: re-read each and
|
|
41
|
+
* conform, supersede, or reaffirm. */
|
|
42
|
+
export declare function decisionsAffectedBy(repoPath: string, delta: GraphDeltaJson, rootRepoId: string): DecisionAffected[];
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { existsSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { loadDecisions, nodeIdRepo, nodeIdSuffix } from "../store/decisions.js";
|
|
4
|
+
import { neutralizeSummary } from "../guard/summaryValidation.js";
|
|
5
|
+
/** Where hook-driven indexes park their delta: pre-commit / post-merge /
|
|
6
|
+
* post-checkout discard stdout, and post-merge (teammate changes landing) is
|
|
7
|
+
* exactly when decisions drift — the file bridges that gap to the next MCP
|
|
8
|
+
* call. Root repo only; nested repos' drift surfaces when they are reindexed
|
|
9
|
+
* through the MCP tools themselves. */
|
|
10
|
+
export function pendingDeltaPath(repoPath) {
|
|
11
|
+
return join(repoPath, ".reposkein", "local", "last_delta.json");
|
|
12
|
+
}
|
|
13
|
+
/** Reads AND consumes the pending delta (delete-on-read: each drift event is
|
|
14
|
+
* surfaced once). Corrupt files are consumed silently — a damaged advisory
|
|
15
|
+
* file must not wedge the pipeline. */
|
|
16
|
+
export function readPendingDelta(repoPath) {
|
|
17
|
+
const p = pendingDeltaPath(repoPath);
|
|
18
|
+
if (!existsSync(p))
|
|
19
|
+
return null;
|
|
20
|
+
let delta = null;
|
|
21
|
+
try {
|
|
22
|
+
const parsed = JSON.parse(readFileSync(p, "utf8"));
|
|
23
|
+
if (Array.isArray(parsed.added) &&
|
|
24
|
+
Array.isArray(parsed.removed) &&
|
|
25
|
+
Array.isArray(parsed.modified)) {
|
|
26
|
+
delta = parsed;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
delta = null;
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
rmSync(p);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// best-effort consume
|
|
37
|
+
}
|
|
38
|
+
return delta;
|
|
39
|
+
}
|
|
40
|
+
/** Drops the given node ids (suffix-tolerant) from the pending delta —
|
|
41
|
+
* called by record_decision, whose own refresh index would otherwise park a
|
|
42
|
+
* delta that flags the just-stamped decision as drifted on the next call.
|
|
43
|
+
* Deletes the file when nothing else remains; best-effort throughout. */
|
|
44
|
+
export function removeFromPendingDelta(repoPath, nodeIds) {
|
|
45
|
+
if (nodeIds.length === 0)
|
|
46
|
+
return;
|
|
47
|
+
const p = pendingDeltaPath(repoPath);
|
|
48
|
+
if (!existsSync(p))
|
|
49
|
+
return;
|
|
50
|
+
try {
|
|
51
|
+
const delta = JSON.parse(readFileSync(p, "utf8"));
|
|
52
|
+
const drop = new Set(nodeIds.map(nodeIdSuffix).filter(Boolean));
|
|
53
|
+
const keep = (id) => {
|
|
54
|
+
const s = nodeIdSuffix(id);
|
|
55
|
+
return s === null || !drop.has(s);
|
|
56
|
+
};
|
|
57
|
+
const added = delta.added.filter(keep);
|
|
58
|
+
const removed = delta.removed.filter(keep);
|
|
59
|
+
const modified = delta.modified.filter(keep);
|
|
60
|
+
if (added.length === 0 && removed.length === 0 && modified.length === 0 && !delta.truncated) {
|
|
61
|
+
rmSync(p);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
writeFileSync(p, JSON.stringify({
|
|
65
|
+
added,
|
|
66
|
+
removed,
|
|
67
|
+
modified,
|
|
68
|
+
counts: { added: added.length, removed: removed.length, modified: modified.length },
|
|
69
|
+
truncated: delta.truncated,
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
// best-effort: a damaged advisory file must not break recording
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/** Unions two deltas (id lists deduped; counts = union sizes). */
|
|
77
|
+
export function mergeDeltas(a, b) {
|
|
78
|
+
const union = (x, y) => [...new Set([...x, ...y])].sort();
|
|
79
|
+
const added = union(a.added, b.added);
|
|
80
|
+
const removed = union(a.removed, b.removed);
|
|
81
|
+
const modified = union(a.modified, b.modified);
|
|
82
|
+
return {
|
|
83
|
+
added,
|
|
84
|
+
removed,
|
|
85
|
+
modified,
|
|
86
|
+
counts: { added: added.length, removed: removed.length, modified: modified.length },
|
|
87
|
+
truncated: a.truncated || b.truncated,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/** The path embedded in a File/Directory node id, or null. */
|
|
91
|
+
function pathOfNodeId(nodeId) {
|
|
92
|
+
const m = /^rs1:[^:]+:(?:file|dir):(.+)$/.exec(nodeId);
|
|
93
|
+
return m ? m[1] : null;
|
|
94
|
+
}
|
|
95
|
+
/** Cross-references a delta against the decision log: which accepted/proposed
|
|
96
|
+
* decisions govern something that just changed? Anchor matching is
|
|
97
|
+
* suffix-tolerant across repo_ids; PATH governance is scoped to the root
|
|
98
|
+
* repo (`rootRepoId`) — nested child repos use child-relative paths, a
|
|
99
|
+
* different coordinate system, and are governed via anchors instead.
|
|
100
|
+
* Deterministic order (by decision id). The skill rule: re-read each and
|
|
101
|
+
* conform, supersede, or reaffirm. */
|
|
102
|
+
export function decisionsAffectedBy(repoPath, delta, rootRepoId) {
|
|
103
|
+
const { decisions } = loadDecisions(repoPath);
|
|
104
|
+
const modifiedSuffixes = new Set(delta.modified.map(nodeIdSuffix).filter(Boolean));
|
|
105
|
+
const removedSuffixes = new Set(delta.removed.map(nodeIdSuffix).filter(Boolean));
|
|
106
|
+
const changed = [...delta.modified, ...delta.added, ...delta.removed]
|
|
107
|
+
.map((id) => ({ path: pathOfNodeId(id), repo: nodeIdRepo(id) }))
|
|
108
|
+
.filter((c) => c.path !== null);
|
|
109
|
+
const out = [];
|
|
110
|
+
for (const rec of decisions) {
|
|
111
|
+
if (rec.status !== "accepted" && rec.status !== "proposed")
|
|
112
|
+
continue;
|
|
113
|
+
let why = null;
|
|
114
|
+
for (const a of rec.anchors) {
|
|
115
|
+
const suffix = nodeIdSuffix(a.node_id);
|
|
116
|
+
if (suffix === null)
|
|
117
|
+
continue;
|
|
118
|
+
if (removedSuffixes.has(suffix)) {
|
|
119
|
+
why = "anchor_removed";
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
if (modifiedSuffixes.has(suffix)) {
|
|
123
|
+
why = "anchor_modified";
|
|
124
|
+
// keep scanning — a removed anchor outranks a modified one
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (!why) {
|
|
128
|
+
const governs = (c) => {
|
|
129
|
+
if (rec.anchors.some((a) => a.path === c.path && nodeIdRepo(a.node_id) === c.repo)) {
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
if (c.repo !== rootRepoId)
|
|
133
|
+
return false;
|
|
134
|
+
return rec.paths.some((g) => g === c.path || (g.endsWith("/") && c.path.startsWith(g)));
|
|
135
|
+
};
|
|
136
|
+
if (changed.some(governs))
|
|
137
|
+
why = "governed_path_changed";
|
|
138
|
+
}
|
|
139
|
+
if (why) {
|
|
140
|
+
out.push({
|
|
141
|
+
decision_id: rec.id,
|
|
142
|
+
title: neutralizeSummary(rec.title) ?? "",
|
|
143
|
+
why,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return out;
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=decisionsAffected.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decisionsAffected.js","sourceRoot":"","sources":["../../src/indexer/decisionsAffected.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type Dispatcher } from "undici";
|
|
1
2
|
/** Custom error class for integrity check failures. */
|
|
2
3
|
export declare class IntegrityError extends Error {
|
|
3
4
|
constructor(message: string);
|
|
@@ -5,6 +6,19 @@ export declare class IntegrityError extends Error {
|
|
|
5
6
|
/** `<platform>-<arch>` for the current host, or null if unsupported. */
|
|
6
7
|
export declare function platformKey(platform?: string, arch?: string): string | null;
|
|
7
8
|
export declare function isWindows(platform?: string): boolean;
|
|
9
|
+
/** Whether this host has a prebuilt indexer release asset. Convenience
|
|
10
|
+
* wrapper over `platformKey()` for call sites that just need a boolean
|
|
11
|
+
* (e.g. `init`'s pre-flight check, before attempting any fetch). */
|
|
12
|
+
export declare function isSupportedPlatform(platform?: string, arch?: string): boolean;
|
|
13
|
+
/** Printed when a host has no prebuilt indexer (darwin-x64, win32-arm64, …):
|
|
14
|
+
* the from-source fallback plus the offline override env var, so `init` can
|
|
15
|
+
* continue (write agent config, skip only the binary-dependent steps)
|
|
16
|
+
* instead of crashing. See docs/INSTALL.md §2 "Platform support". */
|
|
17
|
+
export declare function cargoInstallFallbackMessage(platform?: string, arch?: string): string;
|
|
18
|
+
export declare function proxyDispatcher(): Dispatcher | undefined;
|
|
19
|
+
/** For testing only: reset the cached proxy dispatcher so env var changes
|
|
20
|
+
* take effect on the next call. */
|
|
21
|
+
export declare function _resetProxyDispatcherCache(): void;
|
|
8
22
|
/** Release asset name for a platform key, e.g. reposkein-indexer-darwin-arm64. */
|
|
9
23
|
export declare function assetName(key: string): string;
|
|
10
24
|
/** GitHub Release download URL for the given version + platform key. */
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { createWriteStream, existsSync, mkdirSync, chmodSync, statSync, readFileSync, unlinkSync, renameSync } from "node:fs";
|
|
2
2
|
import { createHash, randomBytes } from "node:crypto";
|
|
3
|
-
import { get } from "node:https";
|
|
4
3
|
import { dirname, join } from "node:path";
|
|
5
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { pipeline } from "node:stream/promises";
|
|
6
|
+
import { request, EnvHttpProxyAgent } from "undici";
|
|
6
7
|
/** Supported platform keys → must match the release asset suffixes (D2).
|
|
7
8
|
* Intel macOS (darwin-x64) is intentionally unsupported: all Macs have shipped
|
|
8
9
|
* Apple Silicon since 2020, and GitHub's macos-13 Intel runners are scarce and
|
|
@@ -28,6 +29,48 @@ export function platformKey(platform = process.platform, arch = process.arch) {
|
|
|
28
29
|
export function isWindows(platform = process.platform) {
|
|
29
30
|
return platform === "win32";
|
|
30
31
|
}
|
|
32
|
+
/** Whether this host has a prebuilt indexer release asset. Convenience
|
|
33
|
+
* wrapper over `platformKey()` for call sites that just need a boolean
|
|
34
|
+
* (e.g. `init`'s pre-flight check, before attempting any fetch). */
|
|
35
|
+
export function isSupportedPlatform(platform = process.platform, arch = process.arch) {
|
|
36
|
+
return platformKey(platform, arch) !== null;
|
|
37
|
+
}
|
|
38
|
+
/** Printed when a host has no prebuilt indexer (darwin-x64, win32-arm64, …):
|
|
39
|
+
* the from-source fallback plus the offline override env var, so `init` can
|
|
40
|
+
* continue (write agent config, skip only the binary-dependent steps)
|
|
41
|
+
* instead of crashing. See docs/INSTALL.md §2 "Platform support". */
|
|
42
|
+
export function cargoInstallFallbackMessage(platform = process.platform, arch = process.arch) {
|
|
43
|
+
return (`reposkein: no prebuilt indexer for ${platform}-${arch}. Build from source:\n` +
|
|
44
|
+
" git clone https://github.com/reposkein/reposkein.git && cd reposkein\n" +
|
|
45
|
+
" cargo install --path indexer/crates/cli --root ./cargo-out\n" +
|
|
46
|
+
" export REPOSKEIN_INDEXER_BIN=$PWD/cargo-out/bin/reposkein-indexer\n" +
|
|
47
|
+
"Then re-run `reposkein-mcp init` (or `doctor`/`index`) with that env var set — " +
|
|
48
|
+
"REPOSKEIN_INDEXER_BIN is also the offline fallback on supported platforms " +
|
|
49
|
+
"when the GitHub Releases fetch is unreachable.");
|
|
50
|
+
}
|
|
51
|
+
/** Reads HTTP(S)_PROXY / NO_PROXY (either case) via undici's
|
|
52
|
+
* `EnvHttpProxyAgent` — the standard way to proxy `undici.request()` once
|
|
53
|
+
* undici is a direct dependency (the global `fetch`'s own undici instance
|
|
54
|
+
* isn't importable to attach a dispatcher to). Returns `undefined` (use
|
|
55
|
+
* undici's default, non-proxying dispatcher) when no proxy env var is set,
|
|
56
|
+
* so the common case pays zero extra cost. Cached per-process — proxy env
|
|
57
|
+
* vars don't change mid-run. */
|
|
58
|
+
let _proxyDispatcher;
|
|
59
|
+
export function proxyDispatcher() {
|
|
60
|
+
if (_proxyDispatcher !== undefined)
|
|
61
|
+
return _proxyDispatcher ?? undefined;
|
|
62
|
+
const hasProxyEnv = !!(process.env.HTTPS_PROXY ||
|
|
63
|
+
process.env.https_proxy ||
|
|
64
|
+
process.env.HTTP_PROXY ||
|
|
65
|
+
process.env.http_proxy);
|
|
66
|
+
_proxyDispatcher = hasProxyEnv ? new EnvHttpProxyAgent() : null;
|
|
67
|
+
return _proxyDispatcher ?? undefined;
|
|
68
|
+
}
|
|
69
|
+
/** For testing only: reset the cached proxy dispatcher so env var changes
|
|
70
|
+
* take effect on the next call. */
|
|
71
|
+
export function _resetProxyDispatcherCache() {
|
|
72
|
+
_proxyDispatcher = undefined;
|
|
73
|
+
}
|
|
31
74
|
/** Release asset name for a platform key, e.g. reposkein-indexer-darwin-arm64. */
|
|
32
75
|
export function assetName(key) {
|
|
33
76
|
return `reposkein-indexer-${key}${key.startsWith("win32") ? ".exe" : ""}`;
|
|
@@ -96,45 +139,43 @@ export function verifyDigest(tempPath, expected) {
|
|
|
96
139
|
}
|
|
97
140
|
/** Follows redirects (GitHub release assets redirect to a CDN) and streams the
|
|
98
141
|
* body to `dest`. Rejects on non-2xx (after redirects) or network error.
|
|
99
|
-
* Redirect hardening: only follows https:// redirects to github.com or
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}).on("error", reject);
|
|
137
|
-
});
|
|
142
|
+
* Redirect hardening: only follows https:// redirects to github.com or
|
|
143
|
+
* *.githubusercontent.com.
|
|
144
|
+
*
|
|
145
|
+
* Uses undici's `request()` (not node:https) so a `proxyDispatcher()` can be
|
|
146
|
+
* attached — that's the only way to honor HTTPS_PROXY/NO_PROXY for this
|
|
147
|
+
* fetch, since the global `fetch()`'s own undici instance isn't reachable to
|
|
148
|
+
* set a dispatcher on. `request()` never auto-follows redirects (no redirect
|
|
149
|
+
* interceptor configured), so they're handled manually below to keep the
|
|
150
|
+
* host allowlist in the loop. */
|
|
151
|
+
async function downloadTo(url, dest, redirects = 5) {
|
|
152
|
+
const res = await request(url, { dispatcher: proxyDispatcher() });
|
|
153
|
+
const status = res.statusCode;
|
|
154
|
+
if (status >= 300 && status < 400 && res.headers.location) {
|
|
155
|
+
await res.body.dump().catch(() => { });
|
|
156
|
+
if (redirects <= 0) {
|
|
157
|
+
throw new Error("too many redirects");
|
|
158
|
+
}
|
|
159
|
+
const locationHeader = res.headers.location;
|
|
160
|
+
const location = Array.isArray(locationHeader) ? locationHeader[0] : locationHeader;
|
|
161
|
+
const next = new URL(location, url);
|
|
162
|
+
if (next.protocol !== "https:") {
|
|
163
|
+
throw new Error(`reposkein: redirect to non-https URL rejected: ${next.href}`);
|
|
164
|
+
}
|
|
165
|
+
const host = next.hostname;
|
|
166
|
+
if (host !== "github.com" &&
|
|
167
|
+
host !== "objects.githubusercontent.com" &&
|
|
168
|
+
!host.endsWith(".githubusercontent.com")) {
|
|
169
|
+
throw new Error(`reposkein: redirect to non-allowlisted host rejected: ${host}`);
|
|
170
|
+
}
|
|
171
|
+
return downloadTo(next.href, dest, redirects - 1);
|
|
172
|
+
}
|
|
173
|
+
if (status !== 200) {
|
|
174
|
+
await res.body.dump().catch(() => { });
|
|
175
|
+
throw new Error(`download failed: HTTP ${status} for ${url}`);
|
|
176
|
+
}
|
|
177
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
178
|
+
await pipeline(res.body, createWriteStream(dest));
|
|
138
179
|
}
|
|
139
180
|
/** Downloads the indexer binary for this host into the package cache, verifies
|
|
140
181
|
* its integrity, makes it executable, and atomically renames it into place.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetchBinary.js","sourceRoot":"","sources":["../../src/indexer/fetchBinary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC9H,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"fetchBinary.js","sourceRoot":"","sources":["../../src/indexer/fetchBinary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC9H,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAmB,MAAM,QAAQ,CAAC;AAErE;;;uFAGuF;AACvF,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC;IACxB,cAAc;IACd,WAAW;IACX,aAAa;IACb,WAAW;CACZ,CAAC,CAAC;AAEH,uDAAuD;AACvD,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,wEAAwE;AACxE,MAAM,UAAU,WAAW,CACzB,WAAmB,OAAO,CAAC,QAAQ,EACnC,OAAe,OAAO,CAAC,IAAI;IAE3B,MAAM,GAAG,GAAG,GAAG,QAAQ,IAAI,IAAI,EAAE,CAAC;IAClC,OAAO,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,WAAmB,OAAO,CAAC,QAAQ;IAC3D,OAAO,QAAQ,KAAK,OAAO,CAAC;AAC9B,CAAC;AAED;;qEAEqE;AACrE,MAAM,UAAU,mBAAmB,CACjC,WAAmB,OAAO,CAAC,QAAQ,EACnC,OAAe,OAAO,CAAC,IAAI;IAE3B,OAAO,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,IAAI,CAAC;AAC9C,CAAC;AAED;;;sEAGsE;AACtE,MAAM,UAAU,2BAA2B,CACzC,WAAmB,OAAO,CAAC,QAAQ,EACnC,OAAe,OAAO,CAAC,IAAI;IAE3B,OAAO,CACL,sCAAsC,QAAQ,IAAI,IAAI,wBAAwB;QAC9E,0EAA0E;QAC1E,gEAAgE;QAChE,uEAAuE;QACvE,iFAAiF;QACjF,4EAA4E;QAC5E,gDAAgD,CACjD,CAAC;AACJ,CAAC;AAED;;;;;;iCAMiC;AACjC,IAAI,gBAA+C,CAAC;AAEpD,MAAM,UAAU,eAAe;IAC7B,IAAI,gBAAgB,KAAK,SAAS;QAAE,OAAO,gBAAgB,IAAI,SAAS,CAAC;IACzE,MAAM,WAAW,GAAG,CAAC,CAAC,CACpB,OAAO,CAAC,GAAG,CAAC,WAAW;QACvB,OAAO,CAAC,GAAG,CAAC,WAAW;QACvB,OAAO,CAAC,GAAG,CAAC,UAAU;QACtB,OAAO,CAAC,GAAG,CAAC,UAAU,CACvB,CAAC;IACF,gBAAgB,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,iBAAiB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAChE,OAAO,gBAAgB,IAAI,SAAS,CAAC;AACvC,CAAC;AAED;oCACoC;AACpC,MAAM,UAAU,0BAA0B;IACxC,gBAAgB,GAAG,SAAS,CAAC;AAC/B,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,OAAO,qBAAqB,GAAG,GAAG,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AAC5E,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,UAAU,CAAC,OAAe,EAAE,GAAW;IACrD,OAAO,6DAA6D,OAAO,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;AAClG,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,WAAW;IACzB,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACnE,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,gBAAgB;IAC9B,OAAO,IAAI,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC;AACjG,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,cAAc;IAC5B,+DAA+D;IAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,EAAE,cAAc,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAiB,CAAC;AAC3C,CAAC;AAED,yFAAyF;AACzF,IAAI,UAAU,GAA8C,SAAS,CAAC;AAEtE,SAAS,aAAa;IACpB,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO,UAAU,CAAC;IAChD,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,EAAE,qBAAqB,CAAC,CAAC;IACrD,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QAAC,UAAU,GAAG,IAAI,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;IACvD,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAA2B,CAAC;IAC3E,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;mFAEmF;AACnF,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;IAC5B,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC,CAAC,qCAAqC;IACpE,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IAC5B,IAAI,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC;QAAE,MAAM,IAAI,cAAc,CAAC,kEAAkE,IAAI,oBAAoB,CAAC,CAAC;IACzI,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;AAC3B,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,iBAAiB;IAC/B,UAAU,GAAG,SAAS,CAAC;AACzB,CAAC;AAED;;wFAEwF;AACxF,MAAM,UAAU,YAAY,CAAC,QAAgB,EAAE,QAAuB;IACpE,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yFAAyF,CAAC,CAAC;QAChH,OAAO;IACT,CAAC;IACD,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACjF,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,UAAU,CAAC,QAAQ,CAAC,CAAC;QACrB,MAAM,IAAI,cAAc,CAAC,sFAAsF,CAAC,CAAC;IACnH,CAAC;AACH,CAAC;AAED;;;;;;;;;;kCAUkC;AAClC,KAAK,UAAU,UAAU,CAAC,GAAW,EAAE,IAAY,EAAE,SAAS,GAAG,CAAC;IAChE,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,EAAE,eAAe,EAAE,EAAE,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC;IAC9B,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;QAC1D,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACtC,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACxC,CAAC;QACD,MAAM,cAAc,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC;QAC5C,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,cAAc,CAAC;QACrF,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACpC,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,kDAAkD,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACjF,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC3B,IACE,IAAI,KAAK,YAAY;YACrB,IAAI,KAAK,+BAA+B;YACxC,CAAC,IAAI,CAAC,QAAQ,CAAC,wBAAwB,CAAC,EACxC,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,yDAAyD,IAAI,EAAE,CAAC,CAAC;QACnF,CAAC;QACD,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC;IACpD,CAAC;IACD,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACnB,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,yBAAyB,MAAM,QAAQ,GAAG,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,MAAM,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;AACpD,CAAC;AAED;;;wBAGwB;AACxB,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,UAAkB,cAAc,EAAE;IACrE,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;IAC1B,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,sCAAsC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,IAAI;YACxE,iDAAiD,CACpD,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,GAAG,gBAAgB,EAAE,GAAG,OAAO,GAAG,OAAO,CAAC,GAAG,GAAG,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC/F,IAAI,CAAC;QACH,MAAM,UAAU,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;QACjD,YAAY,CAAC,IAAI,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;QACxC,IAAI,CAAC,SAAS,EAAE;YAAE,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACzC,UAAU,CAAC,IAAI,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACvC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC;YAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,yEAAyE,CAAC,CAAC;QAC7G,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,OAAO,gBAAgB,EAAE,CAAC;AAC5B,CAAC;AAED;;;;;;;uFAOuF;AACvF,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;IACnD,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAClC,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE;QAAE,OAAO,MAAM,CAAC;IACnE,IAAI,CAAC;QACH,OAAO,MAAM,cAAc,EAAE,CAAC;IAChC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,cAAc;YAAE,MAAM,GAAG,CAAC,CAAC,iDAAiD;QAC/F,OAAO,SAAS,EAAE,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,mBAAmB,CAAC;IACrE,CAAC;AACH,CAAC"}
|
|
@@ -3,8 +3,6 @@ export interface SpawnResult {
|
|
|
3
3
|
stdout: string;
|
|
4
4
|
stderr: string;
|
|
5
5
|
}
|
|
6
|
-
/** Repo root the indexer operates on: REPOSKEIN_REPO_PATH or cwd. */
|
|
7
|
-
export declare function repoPath(): string;
|
|
8
6
|
export declare function spawnIndexer(bin: string, args: string[]): Promise<SpawnResult>;
|
|
9
7
|
export interface IndexJsonStats {
|
|
10
8
|
repo_id: string;
|
|
@@ -13,6 +11,9 @@ export interface IndexJsonStats {
|
|
|
13
11
|
edges: number;
|
|
14
12
|
children: number;
|
|
15
13
|
warnings: string[];
|
|
14
|
+
/** Old-vs-new node diff (absent on a first index or when nothing changed) —
|
|
15
|
+
* see indexer/crates/core/src/delta.rs. */
|
|
16
|
+
graph_delta?: import("./decisionsAffected.js").GraphDeltaJson;
|
|
16
17
|
}
|
|
17
18
|
/** Parse the JSON object emitted by `index --json`. Returns null on parse failure. */
|
|
18
19
|
export declare function parseJsonStats(stdout: string): IndexJsonStats | null;
|
|
@@ -13,10 +13,14 @@ function buildChildEnv() {
|
|
|
13
13
|
}
|
|
14
14
|
return env;
|
|
15
15
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
// NOTE: there used to be a `repoPath()` here (REPOSKEIN_REPO_PATH ?? cwd),
|
|
17
|
+
// an independent repo-path resolver `tools/indexerTools.ts` called instead
|
|
18
|
+
// of using its caller's already-resolved active repo. That let init/reindex
|
|
19
|
+
// bypass session.select_repo entirely and index the wrong repo in workspace
|
|
20
|
+
// mode — removed; every caller now takes an explicit `repoPath` param
|
|
21
|
+
// sourced from mcp/src/store/repoSession.ts. Don't reintroduce an
|
|
22
|
+
// env/cwd-based resolver here — see mcp/src/store/resolveRepoPath.ts for the
|
|
23
|
+
// one central resolution algorithm.
|
|
20
24
|
export function spawnIndexer(bin, args) {
|
|
21
25
|
return new Promise((resolve, reject) => {
|
|
22
26
|
const child = spawn(bin, args, { env: buildChildEnv() });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runIndexer.js","sourceRoot":"","sources":["../../src/indexer/runIndexer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAExH,+FAA+F;AAC/F,MAAM,kBAAkB,GAAG,OAAO,CAAC;AACnC,qFAAqF;AACrF,MAAM,gBAAgB,GAAG,IAAI,GAAG,IAAI,CAAC;AAErC,SAAS,aAAa;IACpB,MAAM,GAAG,GAAsB,EAAE,CAAC;IAClC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACjD,IAAI,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YACtD,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACb,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAQD,
|
|
1
|
+
{"version":3,"file":"runIndexer.js","sourceRoot":"","sources":["../../src/indexer/runIndexer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type DecisionStatus } from "../store/decisions.js";
|
|
2
|
+
import type { TargetRow } from "./types.js";
|
|
3
|
+
/** A decision surfaced on a profile/impact target: enough to know it exists
|
|
4
|
+
* and whether the code drifted under it — full rationale via get_decision. */
|
|
5
|
+
export interface GoverningDecision {
|
|
6
|
+
id: string;
|
|
7
|
+
title: string;
|
|
8
|
+
status: DecisionStatus;
|
|
9
|
+
/** "direct" — an anchor names this node; "contains" — a decision path
|
|
10
|
+
* (exact file or dir prefix ending "/") covers the target's file. */
|
|
11
|
+
via: "direct" | "contains";
|
|
12
|
+
/** Direct anchors only: recorded hash vs the target's current hash. */
|
|
13
|
+
anchor_state?: "current" | "stale";
|
|
14
|
+
}
|
|
15
|
+
export interface TargetGovernance {
|
|
16
|
+
/** Max 5, accepted before proposed before deprecated; then newest first. */
|
|
17
|
+
decisions: GoverningDecision[];
|
|
18
|
+
/** Accepted decisions whose direct anchor on this node is stale — re-read
|
|
19
|
+
* the decision and conform, supersede, or reaffirm. */
|
|
20
|
+
needing_review: string[];
|
|
21
|
+
truncated: boolean;
|
|
22
|
+
}
|
|
23
|
+
/** Pure filesystem + target-row computation (no store round-trips): which
|
|
24
|
+
* decisions govern this node, and which of them the node has drifted under. */
|
|
25
|
+
export declare function governingDecisionsFor(repoPath: string, target: TargetRow, rootRepoId?: string): TargetGovernance;
|
|
26
|
+
/** Impact-shaped governance: for each decision, which of the given nodes it
|
|
27
|
+
* governs (the target plus impacted rows). */
|
|
28
|
+
export declare function governingDecisionsForNodes(repoPath: string, nodes: {
|
|
29
|
+
node_id: string;
|
|
30
|
+
file_path: string;
|
|
31
|
+
content_hash?: string | null;
|
|
32
|
+
}[], rootRepoId?: string): {
|
|
33
|
+
id: string;
|
|
34
|
+
title: string;
|
|
35
|
+
status: DecisionStatus;
|
|
36
|
+
governs: string[];
|
|
37
|
+
}[];
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { neutralizeSummary } from "../guard/summaryValidation.js";
|
|
2
|
+
import { loadDecisions, nodeIdRepo, nodeIdSuffix, } from "../store/decisions.js";
|
|
3
|
+
const MAX_GOVERNING = 5;
|
|
4
|
+
/** Only these statuses govern: rejected never held; superseded is history
|
|
5
|
+
* (reachable through the chain, not worth profile budget). */
|
|
6
|
+
const GOVERNING_ORDER = {
|
|
7
|
+
accepted: 0,
|
|
8
|
+
proposed: 1,
|
|
9
|
+
deprecated: 2,
|
|
10
|
+
};
|
|
11
|
+
function directAnchor(rec, targetId) {
|
|
12
|
+
const targetSuffix = nodeIdSuffix(targetId);
|
|
13
|
+
return rec.anchors.find((a) => a.node_id === targetId || (targetSuffix !== null && nodeIdSuffix(a.node_id) === targetSuffix));
|
|
14
|
+
}
|
|
15
|
+
/** Path governance for one node. Anchor paths match only within the anchored
|
|
16
|
+
* node's own repo; authored `paths` are ROOT-relative and never cross into
|
|
17
|
+
* nested child repos (child file_paths are child-relative — same-looking
|
|
18
|
+
* strings, different coordinate system; anchor child code directly instead).
|
|
19
|
+
* `rootRepoId` undefined → unscoped (single-repo callers/tests). */
|
|
20
|
+
function coversPath(rec, filePath, nodeRepo, rootRepoId) {
|
|
21
|
+
if (filePath === "")
|
|
22
|
+
return false;
|
|
23
|
+
for (const a of rec.anchors) {
|
|
24
|
+
if (a.path === filePath && (nodeRepo === null || nodeIdRepo(a.node_id) === nodeRepo)) {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (rootRepoId !== undefined && nodeRepo !== null && nodeRepo !== rootRepoId)
|
|
29
|
+
return false;
|
|
30
|
+
for (const p of rec.paths) {
|
|
31
|
+
if (p === filePath)
|
|
32
|
+
return true;
|
|
33
|
+
if (p.endsWith("/") && filePath.startsWith(p))
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
/** Pure filesystem + target-row computation (no store round-trips): which
|
|
39
|
+
* decisions govern this node, and which of them the node has drifted under. */
|
|
40
|
+
export function governingDecisionsFor(repoPath, target, rootRepoId) {
|
|
41
|
+
const { decisions } = loadDecisions(repoPath);
|
|
42
|
+
const matched = [];
|
|
43
|
+
const needing_review = [];
|
|
44
|
+
for (const rec of decisions) {
|
|
45
|
+
const order = GOVERNING_ORDER[rec.status];
|
|
46
|
+
if (order === undefined)
|
|
47
|
+
continue;
|
|
48
|
+
const anchor = directAnchor(rec, target.id);
|
|
49
|
+
let entry = null;
|
|
50
|
+
if (anchor) {
|
|
51
|
+
entry = {
|
|
52
|
+
id: rec.id,
|
|
53
|
+
title: neutralizeSummary(rec.title) ?? "",
|
|
54
|
+
status: rec.status,
|
|
55
|
+
via: "direct",
|
|
56
|
+
};
|
|
57
|
+
if (anchor.hash !== null && target.content_hash !== null) {
|
|
58
|
+
entry.anchor_state = anchor.hash === target.content_hash ? "current" : "stale";
|
|
59
|
+
if (entry.anchor_state === "stale" && rec.status === "accepted") {
|
|
60
|
+
needing_review.push(rec.id);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else if (coversPath(rec, target.file_path, target.repo_id || nodeIdRepo(target.id), rootRepoId)) {
|
|
65
|
+
entry = {
|
|
66
|
+
id: rec.id,
|
|
67
|
+
title: neutralizeSummary(rec.title) ?? "",
|
|
68
|
+
status: rec.status,
|
|
69
|
+
via: "contains",
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
if (entry)
|
|
73
|
+
matched.push(entry);
|
|
74
|
+
}
|
|
75
|
+
matched.sort((a, b) => {
|
|
76
|
+
const oa = GOVERNING_ORDER[a.status];
|
|
77
|
+
const ob = GOVERNING_ORDER[b.status];
|
|
78
|
+
if (oa !== ob)
|
|
79
|
+
return oa - ob;
|
|
80
|
+
// Ids embed the date — newest first, then lexicographic.
|
|
81
|
+
return a.id < b.id ? 1 : a.id > b.id ? -1 : 0;
|
|
82
|
+
});
|
|
83
|
+
const truncated = matched.length > MAX_GOVERNING;
|
|
84
|
+
return { decisions: matched.slice(0, MAX_GOVERNING), needing_review, truncated };
|
|
85
|
+
}
|
|
86
|
+
/** Impact-shaped governance: for each decision, which of the given nodes it
|
|
87
|
+
* governs (the target plus impacted rows). */
|
|
88
|
+
export function governingDecisionsForNodes(repoPath, nodes, rootRepoId) {
|
|
89
|
+
const { decisions } = loadDecisions(repoPath);
|
|
90
|
+
const out = [];
|
|
91
|
+
for (const rec of decisions) {
|
|
92
|
+
if (GOVERNING_ORDER[rec.status] === undefined)
|
|
93
|
+
continue;
|
|
94
|
+
const governs = [];
|
|
95
|
+
for (const n of nodes) {
|
|
96
|
+
if (directAnchor(rec, n.node_id) ||
|
|
97
|
+
coversPath(rec, n.file_path, nodeIdRepo(n.node_id), rootRepoId)) {
|
|
98
|
+
governs.push(n.node_id);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (governs.length > 0) {
|
|
102
|
+
out.push({
|
|
103
|
+
id: rec.id,
|
|
104
|
+
title: neutralizeSummary(rec.title) ?? "",
|
|
105
|
+
status: rec.status,
|
|
106
|
+
governs,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return out;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=decisions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decisions.js","sourceRoot":"","sources":["../../src/profile/decisions.ts"],"names":[],"mappings":"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"}
|