@mutmutco/cli 4.0.18 → 4.1.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/dist/main.cjs +2654 -450
- package/dist/repo-index-v4.cjs +392 -59
- package/package.json +1 -1
package/dist/repo-index-v4.cjs
CHANGED
|
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
REPO_INDEX_V4_SCHEMA: () => REPO_INDEX_V4_SCHEMA,
|
|
34
|
+
V4_DELTA_DEEPEN_STEPS: () => V4_DELTA_DEEPEN_STEPS,
|
|
34
35
|
V4_GRAPH_MAX_EDGES: () => V4_GRAPH_MAX_EDGES,
|
|
35
36
|
V4_GRAPH_MAX_EDGES_PER_FILE: () => V4_GRAPH_MAX_EDGES_PER_FILE,
|
|
36
37
|
V4_MAX_ARTIFACT_BYTES: () => V4_MAX_ARTIFACT_BYTES,
|
|
@@ -39,10 +40,23 @@ __export(index_exports, {
|
|
|
39
40
|
V4_STAGE_MAX_RECORDS: () => V4_STAGE_MAX_RECORDS,
|
|
40
41
|
buildGraphEdges: () => buildGraphEdges,
|
|
41
42
|
buildRepoIndexV4: () => buildRepoIndexV4,
|
|
43
|
+
buildRepoIndexV4Detailed: () => buildRepoIndexV4Detailed,
|
|
42
44
|
buildStructuralChunks: () => buildStructuralChunks,
|
|
45
|
+
buildStructuralChunksForPaths: () => buildStructuralChunksForPaths,
|
|
46
|
+
canonicalRepoIndexPaths: () => canonicalRepoIndexPaths,
|
|
47
|
+
changedPaths: () => changedPaths,
|
|
48
|
+
compareV4Chunks: () => compareV4Chunks,
|
|
43
49
|
encodedStageBytes: () => encodedStageBytes,
|
|
50
|
+
formatV4BuildMetrics: () => formatV4BuildMetrics,
|
|
51
|
+
gitRunner: () => gitRunner,
|
|
44
52
|
graphEdgesForSource: () => graphEdgesForSource,
|
|
53
|
+
isRepoIndexDeltaCompatible: () => isRepoIndexDeltaCompatible,
|
|
45
54
|
languageForPath: () => languageForPath,
|
|
55
|
+
parseNameStatusZ: () => parseNameStatusZ,
|
|
56
|
+
planRepoIndexV4Delta: () => planRepoIndexV4Delta,
|
|
57
|
+
readRepoIndexProvenance: () => readRepoIndexProvenance,
|
|
58
|
+
removedPaths: () => removedPaths,
|
|
59
|
+
repoIndexV4DeltaBase: () => repoIndexV4DeltaBase,
|
|
46
60
|
repoIndexV4StorePath: () => repoIndexV4StorePath,
|
|
47
61
|
shardRepoIndexV4: () => shardRepoIndexV4,
|
|
48
62
|
structuralChunksForSource: () => structuralChunksForSource
|
|
@@ -50,10 +64,189 @@ __export(index_exports, {
|
|
|
50
64
|
module.exports = __toCommonJS(index_exports);
|
|
51
65
|
|
|
52
66
|
// src/repo-index-v4/chunks.ts
|
|
53
|
-
var
|
|
67
|
+
var import_node_crypto3 = require("node:crypto");
|
|
54
68
|
var import_node_fs2 = require("node:fs");
|
|
55
69
|
var import_node_path3 = require("node:path");
|
|
56
70
|
|
|
71
|
+
// ../infra/repo-index-path-policy.mjs
|
|
72
|
+
var HARD_DENY = Object.freeze([
|
|
73
|
+
/(^|\/)\.env(\.|$)/i,
|
|
74
|
+
/(^|\/)\.env\./i,
|
|
75
|
+
/credentials/i,
|
|
76
|
+
/secrets?\.json$/i,
|
|
77
|
+
/\.pem$/i,
|
|
78
|
+
/\.p12$/i,
|
|
79
|
+
/\.key$/i,
|
|
80
|
+
/(^|\/)id_rsa/i,
|
|
81
|
+
/(^|\/)id_ed25519/i,
|
|
82
|
+
/\.keystore$/i
|
|
83
|
+
]);
|
|
84
|
+
function isHardDeniedRepoIndexPath(value) {
|
|
85
|
+
return typeof value !== "string" || HARD_DENY.some((pattern) => pattern.test(value));
|
|
86
|
+
}
|
|
87
|
+
function isSafeRepoIndexPath(value) {
|
|
88
|
+
if (typeof value !== "string" || !value || value.length > 1024) return false;
|
|
89
|
+
if (value.startsWith("/") || value.includes("\\") || /[\u0000-\u001f\u007f]/u.test(value)) return false;
|
|
90
|
+
const segments = value.split("/");
|
|
91
|
+
if (segments.some((segment) => !segment || segment === "." || segment === "..")) return false;
|
|
92
|
+
return !isHardDeniedRepoIndexPath(value);
|
|
93
|
+
}
|
|
94
|
+
var REPO_INDEX_ALGORITHM_VERSION = 1;
|
|
95
|
+
var REPO_INDEX_FILTER_VERSION = 2;
|
|
96
|
+
var REPO_INDEX_MATERIAL_LAYOUT_VERSION = 2;
|
|
97
|
+
var LEGACY_REPO_INDEX_PROVENANCE = Object.freeze({
|
|
98
|
+
algorithmVersion: 1,
|
|
99
|
+
filterVersion: 1,
|
|
100
|
+
materialLayoutVersion: 1
|
|
101
|
+
});
|
|
102
|
+
var CURRENT_REPO_INDEX_PROVENANCE = Object.freeze({
|
|
103
|
+
algorithmVersion: REPO_INDEX_ALGORITHM_VERSION,
|
|
104
|
+
filterVersion: REPO_INDEX_FILTER_VERSION,
|
|
105
|
+
materialLayoutVersion: REPO_INDEX_MATERIAL_LAYOUT_VERSION
|
|
106
|
+
});
|
|
107
|
+
function repoIndexProvenanceToken(provenance = CURRENT_REPO_INDEX_PROVENANCE) {
|
|
108
|
+
const resolved = provenance && typeof provenance === "object" ? provenance : {};
|
|
109
|
+
return `a${resolved.algorithmVersion}-f${resolved.filterVersion}-l${resolved.materialLayoutVersion}`;
|
|
110
|
+
}
|
|
111
|
+
var CURRENT_REPO_INDEX_PROVENANCE_TOKEN = repoIndexProvenanceToken(CURRENT_REPO_INDEX_PROVENANCE);
|
|
112
|
+
var GENERATED_PROJECTION = Object.freeze([
|
|
113
|
+
// Host plugin packages: the assembled skills/hooks/scripts/bin payload and the copied host
|
|
114
|
+
// manifest directory. `packages/<host>-plugin/<file>` at the root stays admitted.
|
|
115
|
+
/^packages\/(?:claude|codex|kimi|cursor|hermes)-plugin\/(?:skills|hooks|scripts|bin)\//,
|
|
116
|
+
/^packages\/(?:claude|codex|kimi|cursor|hermes)-plugin\/\.[A-Za-z0-9-]+-plugin\//,
|
|
117
|
+
// In-repo plugin roots assembled by the same declaration.
|
|
118
|
+
/^\.kilo-plugin\/(?:skills|scripts)\//,
|
|
119
|
+
/^\.pi-plugin\/(?:skills|scripts|extensions)\//,
|
|
120
|
+
// Release metadata regenerated from the tracked tree at every prepare.
|
|
121
|
+
/^distribution-bom\.json$/,
|
|
122
|
+
// Cross-repo generator outputs the estate audit named.
|
|
123
|
+
/^product\/connector\/generated\//,
|
|
124
|
+
/^packages\/jerv-pi\/generated\/roster\//,
|
|
125
|
+
/^docs\/\.release-inbox\//
|
|
126
|
+
]);
|
|
127
|
+
function isGeneratedRepoIndexProjection(value) {
|
|
128
|
+
return typeof value === "string" && GENERATED_PROJECTION.some((pattern) => pattern.test(value));
|
|
129
|
+
}
|
|
130
|
+
function isCanonicalRepoIndexPath(value) {
|
|
131
|
+
return isSafeRepoIndexPath(value) && !isGeneratedRepoIndexProjection(value);
|
|
132
|
+
}
|
|
133
|
+
function readRepoIndexProvenance(manifest) {
|
|
134
|
+
if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) return null;
|
|
135
|
+
const provenance = manifest.indexProvenance;
|
|
136
|
+
if (provenance === void 0) return { ...LEGACY_REPO_INDEX_PROVENANCE };
|
|
137
|
+
if (!provenance || typeof provenance !== "object" || Array.isArray(provenance)) return null;
|
|
138
|
+
const keys = ["algorithmVersion", "filterVersion", "materialLayoutVersion"];
|
|
139
|
+
if (Object.keys(provenance).length !== keys.length) return null;
|
|
140
|
+
for (const key of keys) {
|
|
141
|
+
const value = provenance[key];
|
|
142
|
+
if (!Number.isInteger(value) || value < 1) return null;
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
algorithmVersion: provenance.algorithmVersion,
|
|
146
|
+
filterVersion: provenance.filterVersion,
|
|
147
|
+
materialLayoutVersion: provenance.materialLayoutVersion
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function isRepoIndexDeltaCompatible(manifest) {
|
|
151
|
+
const provenance = readRepoIndexProvenance(manifest);
|
|
152
|
+
return provenance !== null && provenance.algorithmVersion === REPO_INDEX_ALGORITHM_VERSION && provenance.filterVersion === REPO_INDEX_FILTER_VERSION && provenance.materialLayoutVersion === REPO_INDEX_MATERIAL_LAYOUT_VERSION;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// ../infra/repo-index-material-buckets.mjs
|
|
156
|
+
var import_node_crypto = require("node:crypto");
|
|
157
|
+
var REPO_INDEX_MATERIAL_BUCKET_COUNT = 2;
|
|
158
|
+
var REPO_INDEX_MATERIAL_KINDS = Object.freeze(["chunks", "embeddings"]);
|
|
159
|
+
var REPO_INDEX_MATERIAL_PREFIX = "material-v2";
|
|
160
|
+
function canonicalMaterialJson(value) {
|
|
161
|
+
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
162
|
+
if (Array.isArray(value)) return `[${value.map(canonicalMaterialJson).join(",")}]`;
|
|
163
|
+
return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${canonicalMaterialJson(value[key])}`).join(",")}}`;
|
|
164
|
+
}
|
|
165
|
+
function repoIndexMaterialDigest(value) {
|
|
166
|
+
return (0, import_node_crypto.createHash)("sha256").update(canonicalMaterialJson(value)).digest("hex");
|
|
167
|
+
}
|
|
168
|
+
function normalizeRepoIndexMaterialPath(path) {
|
|
169
|
+
return String(path).replace(/^\.\//, "").normalize("NFC");
|
|
170
|
+
}
|
|
171
|
+
function repoIndexMaterialBucket(path) {
|
|
172
|
+
const hash = (0, import_node_crypto.createHash)("sha256").update(normalizeRepoIndexMaterialPath(path), "utf8").digest();
|
|
173
|
+
return hash.readUInt32BE(0) % REPO_INDEX_MATERIAL_BUCKET_COUNT;
|
|
174
|
+
}
|
|
175
|
+
function compareRepoIndexChunks(a, b) {
|
|
176
|
+
const aPath = String(a?.path ?? "");
|
|
177
|
+
const bPath = String(b?.path ?? "");
|
|
178
|
+
if (aPath !== bPath) return aPath < bPath ? -1 : 1;
|
|
179
|
+
const aLine = Number(a?.citations?.[0]?.startLine ?? 0);
|
|
180
|
+
const bLine = Number(b?.citations?.[0]?.startLine ?? 0);
|
|
181
|
+
if (aLine !== bLine) return aLine - bLine;
|
|
182
|
+
const aId = String(a?.id ?? "");
|
|
183
|
+
const bId = String(b?.id ?? "");
|
|
184
|
+
return aId === bId ? 0 : aId < bId ? -1 : 1;
|
|
185
|
+
}
|
|
186
|
+
function compareRepoIndexEmbeddings(a, b) {
|
|
187
|
+
const aId = String(a?.chunkId ?? "");
|
|
188
|
+
const bId = String(b?.chunkId ?? "");
|
|
189
|
+
return aId === bId ? 0 : aId < bId ? -1 : 1;
|
|
190
|
+
}
|
|
191
|
+
function stripRepoIndexChunkCommit(chunk) {
|
|
192
|
+
const citations = Array.isArray(chunk?.citations) ? chunk.citations : [];
|
|
193
|
+
return {
|
|
194
|
+
...chunk,
|
|
195
|
+
citations: citations.map((citation2) => {
|
|
196
|
+
const rest = { ...citation2 };
|
|
197
|
+
delete rest.commit;
|
|
198
|
+
return rest;
|
|
199
|
+
})
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
function repoIndexMaterialIndexKey(repoBase, digest) {
|
|
203
|
+
return `${repoBase}/${REPO_INDEX_MATERIAL_PREFIX}/index/${digest}.json`;
|
|
204
|
+
}
|
|
205
|
+
function repoIndexMaterialIndexUri(repo, digest) {
|
|
206
|
+
return `s3://${repoIndexMaterialIndexKey(`repo-index/v4/${repo}`, digest)}`;
|
|
207
|
+
}
|
|
208
|
+
function repoIndexMaterialBucketBody(kind, bucket, records) {
|
|
209
|
+
return { schemaVersion: 4, materialLayoutVersion: 2, kind, bucket, bucketCount: REPO_INDEX_MATERIAL_BUCKET_COUNT, count: records.length, records };
|
|
210
|
+
}
|
|
211
|
+
var bucketBody = repoIndexMaterialBucketBody;
|
|
212
|
+
function buildRepoIndexMaterialLayout(repo, chunks, embeddings) {
|
|
213
|
+
const chunkList = Array.isArray(chunks) ? chunks : [];
|
|
214
|
+
const embeddingList = Array.isArray(embeddings) ? embeddings : [];
|
|
215
|
+
const pathByChunkId = new Map(chunkList.map((chunk) => [String(chunk?.id), String(chunk?.path)]));
|
|
216
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
217
|
+
for (const kind of REPO_INDEX_MATERIAL_KINDS) {
|
|
218
|
+
for (let bucket = 0; bucket < REPO_INDEX_MATERIAL_BUCKET_COUNT; bucket++) grouped.set(`${kind}:${bucket}`, []);
|
|
219
|
+
}
|
|
220
|
+
for (const chunk of chunkList) {
|
|
221
|
+
grouped.get(`chunks:${repoIndexMaterialBucket(chunk?.path)}`).push(stripRepoIndexChunkCommit(chunk));
|
|
222
|
+
}
|
|
223
|
+
for (const embedding of embeddingList) {
|
|
224
|
+
const path = pathByChunkId.get(String(embedding?.chunkId));
|
|
225
|
+
if (path === void 0) throw new Error("repo-index material embeds a chunk that is not in the corpus");
|
|
226
|
+
grouped.get(`embeddings:${repoIndexMaterialBucket(path)}`).push(embedding);
|
|
227
|
+
}
|
|
228
|
+
const buckets = [];
|
|
229
|
+
for (const kind of REPO_INDEX_MATERIAL_KINDS) {
|
|
230
|
+
for (let bucket = 0; bucket < REPO_INDEX_MATERIAL_BUCKET_COUNT; bucket++) {
|
|
231
|
+
const records = grouped.get(`${kind}:${bucket}`);
|
|
232
|
+
records.sort(kind === "chunks" ? compareRepoIndexChunks : compareRepoIndexEmbeddings);
|
|
233
|
+
const body = bucketBody(kind, bucket, records);
|
|
234
|
+
buckets.push({ kind, bucket, count: records.length, digest: repoIndexMaterialDigest(body), body });
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
const index = {
|
|
238
|
+
schemaVersion: 4,
|
|
239
|
+
materialLayoutVersion: 2,
|
|
240
|
+
repo,
|
|
241
|
+
bucketCount: REPO_INDEX_MATERIAL_BUCKET_COUNT,
|
|
242
|
+
chunkCount: chunkList.length,
|
|
243
|
+
embeddingCount: embeddingList.length,
|
|
244
|
+
// Ordered descriptors: chunks buckets ascending, then embeddings buckets ascending.
|
|
245
|
+
buckets: buckets.map(({ kind, bucket, count, digest }) => ({ kind, bucket, count, digest }))
|
|
246
|
+
};
|
|
247
|
+
return { bucketCount: REPO_INDEX_MATERIAL_BUCKET_COUNT, buckets, index, indexDigest: repoIndexMaterialDigest(index) };
|
|
248
|
+
}
|
|
249
|
+
|
|
57
250
|
// src/doc-refs-core.ts
|
|
58
251
|
var import_node_child_process = require("node:child_process");
|
|
59
252
|
var CHECK_IGNORE_MAX_BUFFER = 32 * 1024 * 1024;
|
|
@@ -85,38 +278,14 @@ function defaultIsIgnored(root, relPaths, exec = import_node_child_process.execF
|
|
|
85
278
|
var import_node_child_process2 = require("node:child_process");
|
|
86
279
|
var import_node_path2 = require("node:path");
|
|
87
280
|
|
|
88
|
-
// ../infra/repo-index-path-policy.mjs
|
|
89
|
-
var HARD_DENY = Object.freeze([
|
|
90
|
-
/(^|\/)\.env(\.|$)/i,
|
|
91
|
-
/(^|\/)\.env\./i,
|
|
92
|
-
/credentials/i,
|
|
93
|
-
/secrets?\.json$/i,
|
|
94
|
-
/\.pem$/i,
|
|
95
|
-
/\.p12$/i,
|
|
96
|
-
/\.key$/i,
|
|
97
|
-
/(^|\/)id_rsa/i,
|
|
98
|
-
/(^|\/)id_ed25519/i,
|
|
99
|
-
/\.keystore$/i
|
|
100
|
-
]);
|
|
101
|
-
function isHardDeniedRepoIndexPath(value) {
|
|
102
|
-
return typeof value !== "string" || HARD_DENY.some((pattern) => pattern.test(value));
|
|
103
|
-
}
|
|
104
|
-
function isSafeRepoIndexPath(value) {
|
|
105
|
-
if (typeof value !== "string" || !value || value.length > 1024) return false;
|
|
106
|
-
if (value.startsWith("/") || value.includes("\\") || /[\u0000-\u001f\u007f]/u.test(value)) return false;
|
|
107
|
-
const segments = value.split("/");
|
|
108
|
-
if (segments.some((segment) => !segment || segment === "." || segment === "..")) return false;
|
|
109
|
-
return !isHardDeniedRepoIndexPath(value);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
281
|
// src/repo-runtime-state.ts
|
|
113
|
-
var
|
|
282
|
+
var import_node_crypto2 = require("node:crypto");
|
|
114
283
|
var import_node_fs = require("node:fs");
|
|
115
284
|
var import_node_os = require("node:os");
|
|
116
285
|
var import_node_path = require("node:path");
|
|
117
286
|
var RUNTIME_DIR = "mmi-runtime";
|
|
118
287
|
function hashPath(path) {
|
|
119
|
-
return (0,
|
|
288
|
+
return (0, import_node_crypto2.createHash)("sha256").update((0, import_node_path.resolve)(path)).digest("hex").slice(0, 16);
|
|
120
289
|
}
|
|
121
290
|
function resolveGitDir(cwd) {
|
|
122
291
|
const dotGit = (0, import_node_path.join)(cwd, ".git");
|
|
@@ -257,7 +426,7 @@ async function parserFor(language) {
|
|
|
257
426
|
return parser;
|
|
258
427
|
}
|
|
259
428
|
function sha256(value) {
|
|
260
|
-
return (0,
|
|
429
|
+
return (0, import_node_crypto3.createHash)("sha256").update(value).digest("hex");
|
|
261
430
|
}
|
|
262
431
|
function pointerId(path, kind, contentHash, start, end, symbol) {
|
|
263
432
|
return sha256(["repo-index-v4", path, kind, contentHash, String(start), String(end), symbol ?? ""].join("\0"));
|
|
@@ -345,12 +514,17 @@ async function structuralChunksForSource(repo, commit, path, source) {
|
|
|
345
514
|
parser?.delete();
|
|
346
515
|
}
|
|
347
516
|
}
|
|
348
|
-
|
|
517
|
+
function canonicalRepoIndexPaths(cwd) {
|
|
349
518
|
const candidates = listCandidatePaths(cwd).filter(isIndexablePath).sort((a, b) => a.localeCompare(b));
|
|
350
519
|
const ignored = defaultIsIgnored(cwd, candidates);
|
|
520
|
+
return candidates.filter((path) => !ignored.has(path) && !isHardDeniedPath(path) && isCanonicalRepoIndexPath(path));
|
|
521
|
+
}
|
|
522
|
+
function compareV4Chunks(a, b) {
|
|
523
|
+
return compareRepoIndexChunks(a, b);
|
|
524
|
+
}
|
|
525
|
+
async function buildStructuralChunksForPaths(cwd, repo, commit, paths) {
|
|
351
526
|
const chunks = [];
|
|
352
|
-
for (const path of
|
|
353
|
-
if (ignored.has(path) || isHardDeniedPath(path)) continue;
|
|
527
|
+
for (const path of paths) {
|
|
354
528
|
const absolute = (0, import_node_path3.join)(cwd, ...path.split("/"));
|
|
355
529
|
if (!(0, import_node_fs2.existsSync)(absolute)) continue;
|
|
356
530
|
let source;
|
|
@@ -361,23 +535,102 @@ async function buildStructuralChunks(cwd, repo, commit) {
|
|
|
361
535
|
}
|
|
362
536
|
chunks.push(...await structuralChunksForSource(repo, commit, path, source));
|
|
363
537
|
}
|
|
364
|
-
return chunks.sort(
|
|
538
|
+
return chunks.sort(compareV4Chunks);
|
|
539
|
+
}
|
|
540
|
+
async function buildStructuralChunks(cwd, repo, commit) {
|
|
541
|
+
return buildStructuralChunksForPaths(cwd, repo, commit, canonicalRepoIndexPaths(cwd));
|
|
365
542
|
}
|
|
366
543
|
|
|
367
544
|
// src/repo-index-v4/types.ts
|
|
368
545
|
var REPO_INDEX_V4_SCHEMA = 4;
|
|
369
546
|
|
|
370
547
|
// src/repo-index-v4/builder.ts
|
|
371
|
-
var
|
|
372
|
-
var
|
|
548
|
+
var import_node_crypto4 = require("node:crypto");
|
|
549
|
+
var import_node_child_process4 = require("node:child_process");
|
|
373
550
|
var import_node_fs3 = require("node:fs");
|
|
374
551
|
var import_node_os2 = require("node:os");
|
|
375
552
|
var import_node_path4 = require("node:path");
|
|
553
|
+
|
|
554
|
+
// src/repo-index-v4/delta.ts
|
|
555
|
+
var import_node_child_process3 = require("node:child_process");
|
|
556
|
+
var COMMIT = /^[a-f0-9]{40}$/;
|
|
557
|
+
var V4_DELTA_DEEPEN_STEPS = [50, 250, 1e3];
|
|
558
|
+
function gitRunner(cwd) {
|
|
559
|
+
return (args) => {
|
|
560
|
+
const result = (0, import_node_child_process3.spawnSync)("git", [...args], { cwd, encoding: "utf8", windowsHide: true, maxBuffer: 64 * 1024 * 1024 });
|
|
561
|
+
if (result.error) return { status: -1, stdout: "" };
|
|
562
|
+
return { status: typeof result.status === "number" ? result.status : -1, stdout: String(result.stdout ?? "") };
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
function parseNameStatusZ(output) {
|
|
566
|
+
const fields = output.split("\0");
|
|
567
|
+
if (fields.length && fields[fields.length - 1] === "") fields.pop();
|
|
568
|
+
const changes = [];
|
|
569
|
+
for (let i = 0; i < fields.length; ) {
|
|
570
|
+
const raw = fields[i++] ?? "";
|
|
571
|
+
const letter = raw[0];
|
|
572
|
+
if (!letter || !/^[AMDTRC]\d*$/.test(raw)) return null;
|
|
573
|
+
if (letter === "R" || letter === "C") {
|
|
574
|
+
const oldPath = fields[i++];
|
|
575
|
+
const path2 = fields[i++];
|
|
576
|
+
if (!oldPath || !path2) return null;
|
|
577
|
+
changes.push(letter === "C" ? { status: "A", path: path2 } : { status: "R", path: path2, oldPath });
|
|
578
|
+
continue;
|
|
579
|
+
}
|
|
580
|
+
const path = fields[i++];
|
|
581
|
+
if (!path) return null;
|
|
582
|
+
changes.push({ status: letter, path });
|
|
583
|
+
}
|
|
584
|
+
return changes;
|
|
585
|
+
}
|
|
586
|
+
function changedPaths(changes) {
|
|
587
|
+
return [...new Set(changes.filter((change) => change.status !== "D").map((change) => change.path))].sort();
|
|
588
|
+
}
|
|
589
|
+
function removedPaths(changes) {
|
|
590
|
+
const removed = changes.flatMap((change) => change.status === "D" ? [change.path] : change.status === "R" && change.oldPath ? [change.oldPath] : []);
|
|
591
|
+
return [...new Set(removed)].sort();
|
|
592
|
+
}
|
|
593
|
+
function commitPresent(git2, commit) {
|
|
594
|
+
return git2(["cat-file", "-e", `${commit}^{commit}`]).status === 0;
|
|
595
|
+
}
|
|
596
|
+
function isAncestor(git2, base, head) {
|
|
597
|
+
return git2(["merge-base", "--is-ancestor", base, head]).status === 0;
|
|
598
|
+
}
|
|
599
|
+
function planRepoIndexV4Delta(opts) {
|
|
600
|
+
const headCommit = opts.headCommit.toLowerCase();
|
|
601
|
+
const baseCommit = opts.baseCommit ? opts.baseCommit.toLowerCase() : null;
|
|
602
|
+
const full = (fallbackReason) => ({ mode: "full", headCommit, fallbackReason, ...baseCommit ? { baseCommit } : {} });
|
|
603
|
+
if (opts.forceFull) return full("explicit-full-rebuild");
|
|
604
|
+
if (!baseCommit || !COMMIT.test(baseCommit) || baseCommit === headCommit) return full("no-active-authority");
|
|
605
|
+
if (opts.basePipelineCompatible === false) return full("incompatible-base-provenance");
|
|
606
|
+
if (opts.hasPriorMaterial === false) return full("no-prior-material");
|
|
607
|
+
const { git: git2 } = opts;
|
|
608
|
+
let usable = commitPresent(git2, baseCommit) && isAncestor(git2, baseCommit, headCommit);
|
|
609
|
+
for (const depth of V4_DELTA_DEEPEN_STEPS) {
|
|
610
|
+
if (usable || !opts.deepen) break;
|
|
611
|
+
try {
|
|
612
|
+
opts.deepen(depth);
|
|
613
|
+
} catch {
|
|
614
|
+
break;
|
|
615
|
+
}
|
|
616
|
+
usable = commitPresent(git2, baseCommit) && isAncestor(git2, baseCommit, headCommit);
|
|
617
|
+
}
|
|
618
|
+
if (!usable) {
|
|
619
|
+
return full(commitPresent(git2, baseCommit) ? "base-not-ancestor" : "base-commit-unavailable");
|
|
620
|
+
}
|
|
621
|
+
const diff = git2(["diff", "--name-status", "-z", "--find-renames", baseCommit, headCommit]);
|
|
622
|
+
if (diff.status !== 0) return full("diff-unreadable");
|
|
623
|
+
const changes = parseNameStatusZ(diff.stdout);
|
|
624
|
+
if (!changes) return full("unsupported-change-status");
|
|
625
|
+
return { mode: "delta", baseCommit, headCommit, changes };
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
// src/repo-index-v4/builder.ts
|
|
376
629
|
var V4_MAX_CHUNKS = 1e4;
|
|
377
630
|
var V4_MAX_ARTIFACT_BYTES = 64 * 1024 * 1024;
|
|
378
631
|
var V4_EMBED_BATCH = 32;
|
|
379
632
|
var V4_VECTOR_DECIMAL_PLACES = 6;
|
|
380
|
-
var
|
|
633
|
+
var COMMIT2 = /^[a-f0-9]{40}$/;
|
|
381
634
|
function canonicalJson(value) {
|
|
382
635
|
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
383
636
|
if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
|
|
@@ -385,7 +638,7 @@ function canonicalJson(value) {
|
|
|
385
638
|
return `{${Object.keys(record).sort().map((k) => `${JSON.stringify(k)}:${canonicalJson(record[k])}`).join(",")}}`;
|
|
386
639
|
}
|
|
387
640
|
function sha2562(value) {
|
|
388
|
-
return (0,
|
|
641
|
+
return (0, import_node_crypto4.createHash)("sha256").update(canonicalJson(value)).digest("hex");
|
|
389
642
|
}
|
|
390
643
|
function quantizeV4Vector(vector) {
|
|
391
644
|
return vector.map((value) => Number(value.toFixed(V4_VECTOR_DECIMAL_PLACES)));
|
|
@@ -394,11 +647,11 @@ function statePath(cwd) {
|
|
|
394
647
|
return repoRuntimeStatePath(cwd, "repo-index", "v4.json");
|
|
395
648
|
}
|
|
396
649
|
function git(cwd, args) {
|
|
397
|
-
return String((0,
|
|
650
|
+
return String((0, import_node_child_process4.execFileSync)("git", args, { cwd, encoding: "utf8", windowsHide: true, stdio: ["ignore", "pipe", "ignore"] })).trim();
|
|
398
651
|
}
|
|
399
652
|
function gitInfo(cwd) {
|
|
400
653
|
const commit = git(cwd, ["rev-parse", "HEAD"]).toLowerCase();
|
|
401
|
-
if (!
|
|
654
|
+
if (!COMMIT2.test(commit)) throw new Error("repo-index v4 requires an exact git HEAD commit");
|
|
402
655
|
let defaultBranch = "main";
|
|
403
656
|
try {
|
|
404
657
|
defaultBranch = git(cwd, ["symbolic-ref", "--short", "refs/remotes/origin/HEAD"]).replace(/^origin\//, "") || defaultBranch;
|
|
@@ -420,6 +673,9 @@ function prior(cwd) {
|
|
|
420
673
|
return null;
|
|
421
674
|
}
|
|
422
675
|
}
|
|
676
|
+
function repoIndexV4DeltaBase(envelope) {
|
|
677
|
+
return envelope && isRepoIndexDeltaCompatible(envelope.manifest) ? envelope : null;
|
|
678
|
+
}
|
|
423
679
|
function tombstone(repo, commit, path, createdAt) {
|
|
424
680
|
const base = { repo, commit, path, reason: "deleted", createdAt };
|
|
425
681
|
return { ...base, id: sha2562(base) };
|
|
@@ -454,7 +710,7 @@ function runEmbedderOnce(cwd, chunks, modelDirectory, createdAt) {
|
|
|
454
710
|
(0, import_node_fs3.writeFileSync)(requestFile, JSON.stringify(request));
|
|
455
711
|
let result;
|
|
456
712
|
try {
|
|
457
|
-
result = (0,
|
|
713
|
+
result = (0, import_node_child_process4.spawnSync)(process.execPath, [file, requestFile], { encoding: "utf8", windowsHide: true, timeout: V4_EMBED_TIMEOUT_MS, maxBuffer: V4_MAX_ARTIFACT_BYTES, env });
|
|
458
714
|
} finally {
|
|
459
715
|
(0, import_node_fs3.rmSync)(requestDir, { recursive: true, force: true });
|
|
460
716
|
}
|
|
@@ -510,23 +766,53 @@ function runEmbedder(cwd, chunks, modelDirectory, createdAt) {
|
|
|
510
766
|
const stderr = runner.stderrTail ? ` stderr=${runner.stderrTail}` : "";
|
|
511
767
|
throw new Error(`repo-index v4 embedding runner failed: ${runner.detail ?? "unknown"}${code}${stdout}${stderr}`);
|
|
512
768
|
}
|
|
769
|
+
function restampCitations(chunk, repo, commit) {
|
|
770
|
+
return { ...chunk, citations: chunk.citations.map((citation2) => ({ ...citation2, repo, commit })) };
|
|
771
|
+
}
|
|
513
772
|
async function buildRepoIndexV4(cwd, repo, opts = {}) {
|
|
773
|
+
return (await buildRepoIndexV4Detailed(cwd, repo, opts)).envelope;
|
|
774
|
+
}
|
|
775
|
+
async function buildRepoIndexV4Detailed(cwd, repo, opts = {}) {
|
|
514
776
|
const { commit, defaultBranch, createdAt } = gitInfo(cwd);
|
|
515
|
-
const
|
|
516
|
-
if (chunks.length > V4_MAX_CHUNKS) throw new Error(`repo-index v4 exceeds ${V4_MAX_CHUNKS} chunk ceiling`);
|
|
777
|
+
const delta = opts.delta;
|
|
517
778
|
const old = prior(cwd);
|
|
779
|
+
const deltaBase = repoIndexV4DeltaBase(old);
|
|
780
|
+
let chunks;
|
|
781
|
+
let carried = 0;
|
|
782
|
+
let built = 0;
|
|
783
|
+
let changedCount = 0;
|
|
784
|
+
let removedCount = 0;
|
|
785
|
+
if (delta) {
|
|
786
|
+
const admitted = new Set(canonicalRepoIndexPaths(cwd));
|
|
787
|
+
const changed = new Set(changedPaths(delta.changes));
|
|
788
|
+
const removed = new Set(removedPaths(delta.changes));
|
|
789
|
+
changedCount = changed.size;
|
|
790
|
+
removedCount = removed.size;
|
|
791
|
+
const rebuilt = await buildStructuralChunksForPaths(cwd, repo, commit, [...changed].filter((path2) => admitted.has(path2)).sort());
|
|
792
|
+
const kept = delta.prior.chunks.filter((chunk) => !changed.has(chunk.path) && !removed.has(chunk.path) && admitted.has(chunk.path)).map((chunk) => restampCitations(chunk, repo, commit));
|
|
793
|
+
carried = kept.length;
|
|
794
|
+
built = rebuilt.length;
|
|
795
|
+
chunks = [...kept, ...rebuilt].sort(compareV4Chunks);
|
|
796
|
+
} else {
|
|
797
|
+
chunks = await buildStructuralChunks(cwd, repo, commit);
|
|
798
|
+
built = chunks.length;
|
|
799
|
+
}
|
|
800
|
+
if (chunks.length > V4_MAX_CHUNKS) throw new Error(`repo-index v4 exceeds ${V4_MAX_CHUNKS} chunk ceiling`);
|
|
518
801
|
const currentPaths = new Set(chunks.map((c) => c.path));
|
|
802
|
+
const priorChunks = delta ? delta.prior.chunks : old?.manifest.chunks ?? [];
|
|
803
|
+
const priorTombstones = delta ? delta.prior.tombstones ?? [] : old?.manifest.tombstones ?? [];
|
|
519
804
|
const tombstonePaths = [
|
|
520
|
-
...
|
|
521
|
-
...
|
|
805
|
+
...priorTombstones.map((t) => t.path),
|
|
806
|
+
...priorChunks.map((c) => c.path).filter((path2) => !currentPaths.has(path2))
|
|
522
807
|
];
|
|
523
808
|
const tombstones = [...new Set(tombstonePaths)].sort().map((path2) => tombstone(repo, commit, path2, createdAt));
|
|
524
|
-
const
|
|
809
|
+
const embeddingSource = delta ? delta.prior : { chunks: deltaBase?.manifest.chunks ?? [], embeddings: deltaBase?.manifest.embeddings ?? [] };
|
|
810
|
+
const oldChunkHashById = new Map(embeddingSource.chunks.map((c) => [c.id, c.contentHash]));
|
|
525
811
|
const reusableEmbedding = (embedding) => {
|
|
526
812
|
const norm = Math.hypot(...embedding.vector);
|
|
527
813
|
return embedding.vector.length === 384 && embedding.vector.every(Number.isFinite) && norm >= 0.98 && norm <= 1.02 && embedding.provenance.provider === "local" && embedding.provenance.modelDigest === "828e1496d7fabb79cfa4dcd84fa38625c0d3d21da474a00f08db0f559940cf35" && embedding.provenance.dimensions === 384 && embedding.provenance.input === "pointer-safe-structural-chunk";
|
|
528
814
|
};
|
|
529
|
-
const oldEmbeddingByHash = new Map(
|
|
815
|
+
const oldEmbeddingByHash = new Map(embeddingSource.embeddings.filter(reusableEmbedding).map((e) => [oldChunkHashById.get(e.chunkId), e]));
|
|
530
816
|
const reusable = chunks.flatMap((chunk) => {
|
|
531
817
|
const priorEmbedding = oldEmbeddingByHash.get(chunk.contentHash);
|
|
532
818
|
return priorEmbedding ? [{ ...priorEmbedding, chunkId: chunk.id }] : [];
|
|
@@ -534,21 +820,21 @@ async function buildRepoIndexV4(cwd, repo, opts = {}) {
|
|
|
534
820
|
const reusableIds = new Set(reusable.map((e) => e.chunkId));
|
|
535
821
|
const missing = chunks.filter((chunk) => !reusableIds.has(chunk.id));
|
|
536
822
|
const generated = missing.length === 0 ? { embeddings: [] } : opts.embed === false ? { embeddings: [], reason: "embeddings-unavailable" } : runEmbedder(cwd, missing, opts.modelDirectory, createdAt);
|
|
537
|
-
const embeddings = [...reusable, ...generated.embeddings].map((embedding) => ({ ...embedding, vector: quantizeV4Vector(embedding.vector) })).sort(
|
|
538
|
-
const
|
|
539
|
-
const
|
|
540
|
-
|
|
541
|
-
const identity2 = { repo, commit, immutable: true, kind, uri: `s3://repo-index/v4/${repo}/${commit}/${digest}.${kind}.json`, sha256: digest, createdAt };
|
|
823
|
+
const embeddings = [...reusable, ...generated.embeddings].map((embedding) => ({ ...embedding, vector: quantizeV4Vector(embedding.vector) })).sort(compareRepoIndexEmbeddings);
|
|
824
|
+
const materialIndexDigest = buildRepoIndexMaterialLayout(repo, chunks, embeddings).indexDigest;
|
|
825
|
+
const artifact = (kind, digest, uri) => {
|
|
826
|
+
const identity2 = { repo, commit, immutable: true, kind, uri, sha256: digest, createdAt };
|
|
542
827
|
return { ...identity2, id: sha2562(identity2) };
|
|
543
828
|
};
|
|
544
|
-
const artifacts = [artifact("
|
|
829
|
+
const artifacts = [artifact("material-index", materialIndexDigest, repoIndexMaterialIndexUri(repo, materialIndexDigest))];
|
|
545
830
|
const grammarProvenance = {
|
|
546
831
|
runtime: { name: "web-tree-sitter", version: "0.26.12", license: "MIT" },
|
|
547
832
|
grammarPack: { name: "tree-sitter-wasm", version: "1.1.4", license: "MIT", digest: "f3089ddf2c9615a423783b645c4dfb23ccda30807bbd059746f583952357c489" },
|
|
548
833
|
languages: ["go", "java", "javascript", "jsx", "kotlin", "python", "rust", "tsx", "typescript"]
|
|
549
834
|
};
|
|
550
835
|
const rrf = { algorithm: "reciprocal-rank-fusion", k: 60, lexicalWeight: 1, semanticWeight: 1 };
|
|
551
|
-
const
|
|
836
|
+
const indexProvenance = { ...CURRENT_REPO_INDEX_PROVENANCE };
|
|
837
|
+
const identity = { repo, commit, defaultBranch, immutable: true, ...delta ? { parentCommit: delta.baseCommit } : {}, createdAt, grammarProvenance, indexProvenance, chunks, embeddings, artifacts, tombstones, rrf };
|
|
552
838
|
const manifest = { ...identity, id: sha2562(identity) };
|
|
553
839
|
const complete = embeddings.length === chunks.length;
|
|
554
840
|
const envelope = {
|
|
@@ -562,7 +848,23 @@ async function buildRepoIndexV4(cwd, repo, opts = {}) {
|
|
|
562
848
|
(0, import_node_fs3.mkdirSync)((0, import_node_path4.dirname)(path), { recursive: true });
|
|
563
849
|
(0, import_node_fs3.writeFileSync)(path, `${JSON.stringify(envelope, null, 2)}
|
|
564
850
|
`, "utf8");
|
|
565
|
-
|
|
851
|
+
const metrics = {
|
|
852
|
+
mode: delta ? "delta" : "full",
|
|
853
|
+
...delta ? { baseCommit: delta.baseCommit } : {},
|
|
854
|
+
changedPaths: changedCount,
|
|
855
|
+
removedPaths: removedCount,
|
|
856
|
+
chunksTotal: chunks.length,
|
|
857
|
+
chunksCarried: carried,
|
|
858
|
+
chunksBuilt: built,
|
|
859
|
+
embeddingsReused: reusable.length,
|
|
860
|
+
embeddingsEmbedded: generated.embeddings.length,
|
|
861
|
+
tombstones: tombstones.length
|
|
862
|
+
};
|
|
863
|
+
return { envelope, metrics };
|
|
864
|
+
}
|
|
865
|
+
function formatV4BuildMetrics(repo, metrics) {
|
|
866
|
+
const base = metrics.baseCommit ? ` base=${metrics.baseCommit.slice(0, 12)}` : "";
|
|
867
|
+
return `${repo}: ${metrics.mode}${base} changed=${metrics.changedPaths} removed=${metrics.removedPaths} chunks=${metrics.chunksTotal} (carried=${metrics.chunksCarried} built=${metrics.chunksBuilt}) embeddings(reused=${metrics.embeddingsReused} new=${metrics.embeddingsEmbedded}) tombstones=${metrics.tombstones}`;
|
|
566
868
|
}
|
|
567
869
|
function repoIndexV4StorePath(cwd) {
|
|
568
870
|
return statePath(cwd);
|
|
@@ -575,12 +877,12 @@ var V4_STAGE_MAX_SHARDS = 128;
|
|
|
575
877
|
function encodedBytes(value) {
|
|
576
878
|
return Buffer.byteLength(JSON.stringify(value));
|
|
577
879
|
}
|
|
578
|
-
function split(kind, records, manifest) {
|
|
880
|
+
function split(kind, records, manifest, bucket) {
|
|
579
881
|
const groups = [];
|
|
580
882
|
let group = [];
|
|
581
883
|
for (const record of records) {
|
|
582
884
|
const next = [...group, record];
|
|
583
|
-
const probe = { repo: manifest.repo, commit: manifest.commit, manifestId: manifest.id, kind, index: 127, total: 128, digest: "0".repeat(64), records: next };
|
|
885
|
+
const probe = { repo: manifest.repo, commit: manifest.commit, manifestId: manifest.id, kind, ...bucket === void 0 ? {} : { bucket }, index: 127, total: 128, digest: "0".repeat(64), records: next };
|
|
584
886
|
if (group.length && (group.length >= V4_STAGE_MAX_RECORDS || encodedBytes(probe) > V4_STAGE_MAX_BODY_BYTES)) {
|
|
585
887
|
groups.push(group);
|
|
586
888
|
group = [record];
|
|
@@ -596,6 +898,7 @@ function split(kind, records, manifest) {
|
|
|
596
898
|
commit: manifest.commit,
|
|
597
899
|
manifestId: manifest.id,
|
|
598
900
|
kind,
|
|
901
|
+
...bucket === void 0 ? {} : { bucket },
|
|
599
902
|
index,
|
|
600
903
|
total: groups.length,
|
|
601
904
|
digest: sha2562(items),
|
|
@@ -605,11 +908,27 @@ function split(kind, records, manifest) {
|
|
|
605
908
|
return request;
|
|
606
909
|
});
|
|
607
910
|
}
|
|
608
|
-
function shardRepoIndexV4(envelope) {
|
|
911
|
+
function shardRepoIndexV4(envelope, opts = {}) {
|
|
609
912
|
const { chunks, embeddings, ...header } = envelope.manifest;
|
|
610
|
-
const
|
|
611
|
-
|
|
612
|
-
|
|
913
|
+
const identity = { repo: header.repo, commit: header.commit, manifestId: header.id, header, status: envelope.status };
|
|
914
|
+
if ((header.indexProvenance?.materialLayoutVersion ?? 1) < 2) {
|
|
915
|
+
const stages2 = [...split("chunks", chunks, envelope.manifest), ...split("embeddings", embeddings ?? [], envelope.manifest)];
|
|
916
|
+
const shards2 = stages2.map(({ kind, index, total, digest, records }) => ({ kind, index, total, digest, count: records.length }));
|
|
917
|
+
return { stages: stages2, finalize: { ...identity, shards: shards2 } };
|
|
918
|
+
}
|
|
919
|
+
const reusable = new Set(opts.priorBucketDigests ?? []);
|
|
920
|
+
const layout = buildRepoIndexMaterialLayout(header.repo, chunks, embeddings ?? []);
|
|
921
|
+
const stages = [];
|
|
922
|
+
const shards = [];
|
|
923
|
+
const buckets = layout.buckets.map((bucket) => {
|
|
924
|
+
if (reusable.has(bucket.digest)) return { kind: bucket.kind, bucket: bucket.bucket, count: bucket.count, digest: bucket.digest, shards: 0 };
|
|
925
|
+
const fragments = split(bucket.kind, bucket.body.records, envelope.manifest, bucket.bucket);
|
|
926
|
+
stages.push(...fragments);
|
|
927
|
+
shards.push(...fragments.map(({ kind, index, total, digest, records }) => ({ kind, bucket: bucket.bucket, index, total, digest, count: records.length })));
|
|
928
|
+
return { kind: bucket.kind, bucket: bucket.bucket, count: bucket.count, digest: bucket.digest, shards: fragments.length };
|
|
929
|
+
});
|
|
930
|
+
if (buckets.length !== 2 * REPO_INDEX_MATERIAL_BUCKET_COUNT) throw new Error("repo-index v4 material layout is incomplete");
|
|
931
|
+
return { stages, finalize: { ...identity, shards, materialLayout: 2, buckets } };
|
|
613
932
|
}
|
|
614
933
|
function encodedStageBytes(stage) {
|
|
615
934
|
return encodedBytes(stage);
|
|
@@ -718,6 +1037,7 @@ function buildGraphEdges(cwd, repo, commit, rosterRepos) {
|
|
|
718
1037
|
// Annotate the CommonJS export names for ESM import in node:
|
|
719
1038
|
0 && (module.exports = {
|
|
720
1039
|
REPO_INDEX_V4_SCHEMA,
|
|
1040
|
+
V4_DELTA_DEEPEN_STEPS,
|
|
721
1041
|
V4_GRAPH_MAX_EDGES,
|
|
722
1042
|
V4_GRAPH_MAX_EDGES_PER_FILE,
|
|
723
1043
|
V4_MAX_ARTIFACT_BYTES,
|
|
@@ -726,10 +1046,23 @@ function buildGraphEdges(cwd, repo, commit, rosterRepos) {
|
|
|
726
1046
|
V4_STAGE_MAX_RECORDS,
|
|
727
1047
|
buildGraphEdges,
|
|
728
1048
|
buildRepoIndexV4,
|
|
1049
|
+
buildRepoIndexV4Detailed,
|
|
729
1050
|
buildStructuralChunks,
|
|
1051
|
+
buildStructuralChunksForPaths,
|
|
1052
|
+
canonicalRepoIndexPaths,
|
|
1053
|
+
changedPaths,
|
|
1054
|
+
compareV4Chunks,
|
|
730
1055
|
encodedStageBytes,
|
|
1056
|
+
formatV4BuildMetrics,
|
|
1057
|
+
gitRunner,
|
|
731
1058
|
graphEdgesForSource,
|
|
1059
|
+
isRepoIndexDeltaCompatible,
|
|
732
1060
|
languageForPath,
|
|
1061
|
+
parseNameStatusZ,
|
|
1062
|
+
planRepoIndexV4Delta,
|
|
1063
|
+
readRepoIndexProvenance,
|
|
1064
|
+
removedPaths,
|
|
1065
|
+
repoIndexV4DeltaBase,
|
|
733
1066
|
repoIndexV4StorePath,
|
|
734
1067
|
shardRepoIndexV4,
|
|
735
1068
|
structuralChunksForSource
|
package/package.json
CHANGED