@mutmutco/cli 3.139.2 → 3.139.4
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 +138 -95
- package/dist/repo-index-v4.cjs +18 -6
- package/package.json +1 -1
package/dist/main.cjs
CHANGED
|
@@ -10746,10 +10746,10 @@ var rollout_plan_default = {
|
|
|
10746
10746
|
note: "The v4.0.0 stamp happens at cut time (D6e #4463); until then the candidate is the origin/development head artifacts (built cli/dist + npm pack), identity proven by dist content hash (D6a)."
|
|
10747
10747
|
},
|
|
10748
10748
|
baseline: {
|
|
10749
|
-
version: "3.139.
|
|
10750
|
-
tag: "v3.139.
|
|
10751
|
-
commit: "
|
|
10752
|
-
npm: "@mutmutco/cli@3.139.
|
|
10749
|
+
version: "3.139.4",
|
|
10750
|
+
tag: "v3.139.4",
|
|
10751
|
+
commit: "ec2807c7a293",
|
|
10752
|
+
npm: "@mutmutco/cli@3.139.4"
|
|
10753
10753
|
},
|
|
10754
10754
|
exitCriterion: "fleet-n-of-n",
|
|
10755
10755
|
hubOnlyShortcut: "forbidden",
|
|
@@ -10766,14 +10766,14 @@ var rollout_plan_default = {
|
|
|
10766
10766
|
repo: "mutmutco/mmi-hub",
|
|
10767
10767
|
role: "canary",
|
|
10768
10768
|
schedule: "train",
|
|
10769
|
-
v3Target: "v3.139.
|
|
10769
|
+
v3Target: "v3.139.4"
|
|
10770
10770
|
}
|
|
10771
10771
|
],
|
|
10772
10772
|
rollbackTrigger: "Any red inside the post-cut soak window: `devops train gate` FAIL attributable to the v4 doors, Hub endpoint health probe failure, a v3 client refused while the compat window must still admit it (SUPPORTED_MINOR_WINDOW=2, MIN_CLIENT_VERSION 0.0.0 \u2014 D6a), or npm consumer install/doctor failure on the v4 dist.",
|
|
10773
10773
|
rollback: {
|
|
10774
10774
|
independent: true,
|
|
10775
|
-
mechanism: "npm dist-tag latest -> 3.139.
|
|
10776
|
-
v3Target: "v3.139.
|
|
10775
|
+
mechanism: "npm dist-tag latest -> 3.139.4 and redeploy the Hub Lambda from tag v3.139.4 (ec2807c7a293); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
|
|
10776
|
+
v3Target: "v3.139.4 (@mutmutco/cli@3.139.4, tag commit ec2807c7a293 \u2014 the preserved latest-v3 distribution, D6b)"
|
|
10777
10777
|
}
|
|
10778
10778
|
},
|
|
10779
10779
|
{
|
|
@@ -23042,8 +23042,12 @@ var import_node_path22 = require("node:path");
|
|
|
23042
23042
|
// src/repo-index-v4/language.ts
|
|
23043
23043
|
var LANGUAGE_BY_EXTENSION = {
|
|
23044
23044
|
".ts": { name: "typescript", parserName: "typescript" },
|
|
23045
|
+
".mts": { name: "typescript", parserName: "typescript" },
|
|
23046
|
+
".cts": { name: "typescript", parserName: "typescript" },
|
|
23045
23047
|
".tsx": { name: "tsx", parserName: "tsx" },
|
|
23046
23048
|
".js": { name: "javascript", parserName: "javascript" },
|
|
23049
|
+
".mjs": { name: "javascript", parserName: "javascript" },
|
|
23050
|
+
".cjs": { name: "javascript", parserName: "javascript" },
|
|
23047
23051
|
".jsx": { name: "jsx", parserName: "javascript" },
|
|
23048
23052
|
".py": { name: "python", parserName: "python" },
|
|
23049
23053
|
".go": { name: "go", parserName: "go" },
|
|
@@ -23209,6 +23213,7 @@ async function buildStructuralChunks(cwd, repo, commit) {
|
|
|
23209
23213
|
var V4_MAX_CHUNKS = 1e4;
|
|
23210
23214
|
var V4_MAX_ARTIFACT_BYTES = 64 * 1024 * 1024;
|
|
23211
23215
|
var V4_EMBED_BATCH = 32;
|
|
23216
|
+
var V4_VECTOR_DECIMAL_PLACES = 6;
|
|
23212
23217
|
var COMMIT = /^[a-f0-9]{40}$/;
|
|
23213
23218
|
function canonicalJson(value) {
|
|
23214
23219
|
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
@@ -23219,6 +23224,9 @@ function canonicalJson(value) {
|
|
|
23219
23224
|
function sha2562(value) {
|
|
23220
23225
|
return (0, import_node_crypto7.createHash)("sha256").update(canonicalJson(value)).digest("hex");
|
|
23221
23226
|
}
|
|
23227
|
+
function quantizeV4Vector(vector) {
|
|
23228
|
+
return vector.map((value) => Number(value.toFixed(V4_VECTOR_DECIMAL_PLACES)));
|
|
23229
|
+
}
|
|
23222
23230
|
function statePath(cwd) {
|
|
23223
23231
|
return repoRuntimeStatePath(cwd, "repo-index", "v4.json");
|
|
23224
23232
|
}
|
|
@@ -23268,16 +23276,20 @@ ${chunk.symbol ?? ""}
|
|
|
23268
23276
|
${chunk.blurb ?? ""}`;
|
|
23269
23277
|
}
|
|
23270
23278
|
}
|
|
23279
|
+
var V4_EMBED_TIMEOUT_MS = 15 * 6e4;
|
|
23271
23280
|
function runEmbedder(cwd, chunks, modelDirectory, createdAt) {
|
|
23272
23281
|
if (!chunks.length) return { embeddings: [] };
|
|
23273
|
-
const
|
|
23274
|
-
const
|
|
23275
|
-
const file = (0, import_node_fs25.existsSync)(
|
|
23282
|
+
const orchestratorRunner = (0, import_node_path23.join)(process.cwd(), "repo-indexer", "src", "batch.mjs");
|
|
23283
|
+
const targetRunner = (0, import_node_path23.join)(cwd, "repo-indexer", "src", "batch.mjs");
|
|
23284
|
+
const file = (0, import_node_fs25.existsSync)(orchestratorRunner) ? orchestratorRunner : targetRunner;
|
|
23276
23285
|
if (!(0, import_node_fs25.existsSync)(file)) return { embeddings: [], reason: "embeddings-unavailable" };
|
|
23277
23286
|
const request = { texts: chunks.map((chunk) => ({ id: chunk.id, text: embeddingInput(cwd, chunk) })), maxBatch: V4_EMBED_BATCH };
|
|
23278
23287
|
const env = { ...process.env, ...modelDirectory ? { MMI_REPO_INDEXER_MODEL_DIR: modelDirectory } : {} };
|
|
23279
|
-
const result = (0, import_node_child_process13.spawnSync)(process.execPath, [file], { input: JSON.stringify(request), encoding: "utf8", windowsHide: true, timeout:
|
|
23280
|
-
if (result.error || result.status !== 0)
|
|
23288
|
+
const result = (0, import_node_child_process13.spawnSync)(process.execPath, [file], { input: JSON.stringify(request), encoding: "utf8", windowsHide: true, timeout: V4_EMBED_TIMEOUT_MS, maxBuffer: V4_MAX_ARTIFACT_BYTES, env });
|
|
23289
|
+
if (result.error || result.status !== 0) {
|
|
23290
|
+
const detail = result.error?.message ?? result.signal ?? `exit status ${result.status ?? "unknown"}`;
|
|
23291
|
+
throw new Error(`repo-index v4 embedding runner failed: ${detail}`);
|
|
23292
|
+
}
|
|
23281
23293
|
try {
|
|
23282
23294
|
const response = JSON.parse(result.stdout);
|
|
23283
23295
|
if (!response.ok || !response.provenance || !Array.isArray(response.embeddings)) return { embeddings: [], reason: "embeddings-unavailable" };
|
|
@@ -23320,7 +23332,7 @@ async function buildRepoIndexV4(cwd, repo, opts = {}) {
|
|
|
23320
23332
|
const reusableIds = new Set(reusable.map((e) => e.chunkId));
|
|
23321
23333
|
const missing = chunks.filter((chunk) => !reusableIds.has(chunk.id));
|
|
23322
23334
|
const generated = missing.length === 0 ? { embeddings: [] } : opts.embed === false ? { embeddings: [], reason: "embeddings-unavailable" } : runEmbedder(cwd, missing, opts.modelDirectory, createdAt);
|
|
23323
|
-
const embeddings = [...reusable, ...generated.embeddings].sort((a, b) => a.chunkId.localeCompare(b.chunkId));
|
|
23335
|
+
const embeddings = [...reusable, ...generated.embeddings].map((embedding) => ({ ...embedding, vector: quantizeV4Vector(embedding.vector) })).sort((a, b) => a.chunkId.localeCompare(b.chunkId));
|
|
23324
23336
|
const chunksDigest = sha2562(chunks);
|
|
23325
23337
|
const embeddingsDigest = sha2562(embeddings);
|
|
23326
23338
|
const artifact = (kind, digest) => {
|
|
@@ -23350,6 +23362,9 @@ async function buildRepoIndexV4(cwd, repo, opts = {}) {
|
|
|
23350
23362
|
`, "utf8");
|
|
23351
23363
|
return envelope;
|
|
23352
23364
|
}
|
|
23365
|
+
function repoIndexV4StorePath(cwd) {
|
|
23366
|
+
return statePath(cwd);
|
|
23367
|
+
}
|
|
23353
23368
|
|
|
23354
23369
|
// src/repo-index-v4/shards.ts
|
|
23355
23370
|
var V4_STAGE_MAX_BODY_BYTES = 750 * 1024;
|
|
@@ -23645,6 +23660,41 @@ var import_node_os12 = require("node:os");
|
|
|
23645
23660
|
var import_node_path25 = require("node:path");
|
|
23646
23661
|
var import_node_child_process14 = require("node:child_process");
|
|
23647
23662
|
|
|
23663
|
+
// ../infra/src/repo-index-roster.ts
|
|
23664
|
+
var ORG2 = "mutmutco";
|
|
23665
|
+
function normalizeRepoIndexRepo(raw) {
|
|
23666
|
+
if (typeof raw !== "string") return null;
|
|
23667
|
+
const value = raw.trim().replace(/\.git$/, "");
|
|
23668
|
+
if (!value) return null;
|
|
23669
|
+
if (value.includes("/")) {
|
|
23670
|
+
const [owner, name, ...rest] = value.split("/");
|
|
23671
|
+
if (!owner || !name || rest.length) return null;
|
|
23672
|
+
return `${owner.toLowerCase()}/${name.toLowerCase()}`;
|
|
23673
|
+
}
|
|
23674
|
+
if (!/^[A-Za-z0-9._-]+$/.test(value)) return null;
|
|
23675
|
+
return `${ORG2}/${value.toLowerCase()}`;
|
|
23676
|
+
}
|
|
23677
|
+
function repoIndexRepoIsEligible(project2, repo) {
|
|
23678
|
+
const normalized = normalizeRepoIndexRepo(repo);
|
|
23679
|
+
if (!normalized || project2.class === "content") return false;
|
|
23680
|
+
return !(project2.repoIndexExcludedRepos ?? []).some(
|
|
23681
|
+
(excluded) => normalizeRepoIndexRepo(excluded) === normalized
|
|
23682
|
+
);
|
|
23683
|
+
}
|
|
23684
|
+
function repoIndexRoster(projects) {
|
|
23685
|
+
const excluded = new Set(
|
|
23686
|
+
projects.flatMap((project2) => project2.repoIndexExcludedRepos ?? []).map(normalizeRepoIndexRepo).filter((repo) => repo !== null)
|
|
23687
|
+
);
|
|
23688
|
+
const roster = /* @__PURE__ */ new Set();
|
|
23689
|
+
for (const project2 of projects) {
|
|
23690
|
+
for (const repo of project2.repos ?? []) {
|
|
23691
|
+
const normalized = normalizeRepoIndexRepo(repo);
|
|
23692
|
+
if (normalized && repoIndexRepoIsEligible(project2, normalized) && !excluded.has(normalized)) roster.add(normalized);
|
|
23693
|
+
}
|
|
23694
|
+
}
|
|
23695
|
+
return roster;
|
|
23696
|
+
}
|
|
23697
|
+
|
|
23648
23698
|
// src/repo-index-v4/edges.ts
|
|
23649
23699
|
var import_node_fs26 = require("node:fs");
|
|
23650
23700
|
var import_node_path24 = require("node:path");
|
|
@@ -23749,20 +23799,12 @@ function buildGraphEdges(cwd, repo, commit, rosterRepos2) {
|
|
|
23749
23799
|
// src/repo-index-sync.ts
|
|
23750
23800
|
var MAX_EMBED_BACKFILL_ROUNDS = 40;
|
|
23751
23801
|
function normalizeRepo(raw) {
|
|
23752
|
-
const
|
|
23753
|
-
if (
|
|
23754
|
-
|
|
23755
|
-
return `${(owner || "").toLowerCase()}/${(name || "").toLowerCase()}`;
|
|
23756
|
-
}
|
|
23757
|
-
return `mutmutco/${t.toLowerCase()}`;
|
|
23802
|
+
const normalized = normalizeRepoIndexRepo(raw);
|
|
23803
|
+
if (!normalized) throw new Error(`invalid repository: ${raw}`);
|
|
23804
|
+
return normalized;
|
|
23758
23805
|
}
|
|
23759
23806
|
function rosterRepos(projects) {
|
|
23760
|
-
|
|
23761
|
-
for (const p of projects) {
|
|
23762
|
-
if (p.class === "content") continue;
|
|
23763
|
-
for (const r of p.repos ?? []) set.add(normalizeRepo(r));
|
|
23764
|
-
}
|
|
23765
|
-
return [...set].sort((a, b) => a.localeCompare(b));
|
|
23807
|
+
return [...repoIndexRoster(projects)].sort((a, b) => a.localeCompare(b));
|
|
23766
23808
|
}
|
|
23767
23809
|
function shallowClone(repo, dest, token) {
|
|
23768
23810
|
const basic = Buffer.from(`x-access-token:${token}`, "utf8").toString("base64");
|
|
@@ -24595,7 +24637,7 @@ async function syncProjectInfo(plan, client, apply) {
|
|
|
24595
24637
|
}
|
|
24596
24638
|
|
|
24597
24639
|
// src/project-set.ts
|
|
24598
|
-
var UNSET_KEYS = ["oauth", "requiredRuntimeSecrets", "requiredBuildSecrets", "tenantTasks", "secrets", "edgeDomains", "requiredGcpApis", "publishRequired", "publishDir", "dsManifestPath", "fofuEnabled", "consumesDesignSystem", "ci", "requiredChecks", "ciExemptReason", "gate", "seedCanary"];
|
|
24640
|
+
var UNSET_KEYS = ["oauth", "requiredRuntimeSecrets", "requiredBuildSecrets", "tenantTasks", "secrets", "edgeDomains", "requiredGcpApis", "publishRequired", "publishDir", "dsManifestPath", "fofuEnabled", "consumesDesignSystem", "ci", "requiredChecks", "ciExemptReason", "gate", "seedCanary", "repoIndexExcludedRepos"];
|
|
24599
24641
|
var UNSET_KEY_SET = new Set(UNSET_KEYS);
|
|
24600
24642
|
var RUNTIME_SECRET_STAGES = ["dev", "rc", "main"];
|
|
24601
24643
|
var SECRET_CONSUMERS = ["runtime", "build", "lambda", "actions", "agent", "box"];
|
|
@@ -24966,6 +25008,7 @@ var SETTABLE_VAR_KEYS = [
|
|
|
24966
25008
|
"branch",
|
|
24967
25009
|
"vaultPath",
|
|
24968
25010
|
"repos",
|
|
25011
|
+
"repoIndexExcludedRepos",
|
|
24969
25012
|
"oauth",
|
|
24970
25013
|
"publishRequired",
|
|
24971
25014
|
"publishDir",
|
|
@@ -25001,6 +25044,7 @@ var SETTABLE_VAR_HINTS = {
|
|
|
25001
25044
|
runtimeVaultOnly: "true|false",
|
|
25002
25045
|
seedCanary: "true|false",
|
|
25003
25046
|
repos: 'JSON array, e.g. ["mutmutco/mm-foo"]',
|
|
25047
|
+
repoIndexExcludedRepos: "JSON array; excludes only these registered repos from repo-index",
|
|
25004
25048
|
oauth: "JSON {subdomains,domains,callbackPath,fofuSubdomain}",
|
|
25005
25049
|
requiredGcpApis: "comma-string",
|
|
25006
25050
|
requiredRuntimeSecrets: 'JSON stage map, e.g. {"dev":["KEY"],"rc":["KEY"],"main":["KEY"]}',
|
|
@@ -25092,7 +25136,7 @@ function buildProjectSetPatch(input) {
|
|
|
25092
25136
|
patch[key] = parsePortRangeVar(raw);
|
|
25093
25137
|
} else if (key === "oauth") {
|
|
25094
25138
|
patch[key] = parseOauthVar(raw);
|
|
25095
|
-
} else if (key === "repos") {
|
|
25139
|
+
} else if (key === "repos" || key === "repoIndexExcludedRepos") {
|
|
25096
25140
|
patch[key] = parseReposVar(raw);
|
|
25097
25141
|
} else if (key === "publishRequired") {
|
|
25098
25142
|
patch[key] = parsePublishRequiredVar(raw);
|
|
@@ -32424,7 +32468,7 @@ var surfaces_default = {
|
|
|
32424
32468
|
ownership: {
|
|
32425
32469
|
trust: "host",
|
|
32426
32470
|
cache: "host",
|
|
32427
|
-
repair: "mmi-
|
|
32471
|
+
repair: "mmi-hub"
|
|
32428
32472
|
},
|
|
32429
32473
|
certification: {
|
|
32430
32474
|
hostCommand: "claude",
|
|
@@ -32559,7 +32603,7 @@ var surfaces_default = {
|
|
|
32559
32603
|
ownership: {
|
|
32560
32604
|
trust: "operator",
|
|
32561
32605
|
cache: "host",
|
|
32562
|
-
repair: "mmi-
|
|
32606
|
+
repair: "mmi-hub"
|
|
32563
32607
|
},
|
|
32564
32608
|
certification: {
|
|
32565
32609
|
hostCommand: "codex",
|
|
@@ -32820,8 +32864,8 @@ var surfaces_default = {
|
|
|
32820
32864
|
},
|
|
32821
32865
|
ownership: {
|
|
32822
32866
|
trust: "host",
|
|
32823
|
-
cache: "mmi-
|
|
32824
|
-
repair: "mmi-
|
|
32867
|
+
cache: "mmi-hub",
|
|
32868
|
+
repair: "mmi-hub"
|
|
32825
32869
|
},
|
|
32826
32870
|
certification: {
|
|
32827
32871
|
hostCommand: "cursor-agent",
|
|
@@ -32932,7 +32976,7 @@ var surfaces_default = {
|
|
|
32932
32976
|
ownership: {
|
|
32933
32977
|
trust: "host",
|
|
32934
32978
|
cache: "host",
|
|
32935
|
-
repair: "mmi-
|
|
32979
|
+
repair: "mmi-hub"
|
|
32936
32980
|
},
|
|
32937
32981
|
certification: {
|
|
32938
32982
|
hostCommand: "kilo",
|
|
@@ -33050,7 +33094,7 @@ var surfaces_default = {
|
|
|
33050
33094
|
ownership: {
|
|
33051
33095
|
trust: "host",
|
|
33052
33096
|
cache: "host",
|
|
33053
|
-
repair: "mmi-
|
|
33097
|
+
repair: "mmi-hub"
|
|
33054
33098
|
},
|
|
33055
33099
|
certification: {
|
|
33056
33100
|
hostCommand: "jervcode",
|
|
@@ -34178,19 +34222,14 @@ function checkPluginCache(input) {
|
|
|
34178
34222
|
parts.push(`${input.staging.length} orphaned staging dir(s)${size}`);
|
|
34179
34223
|
}
|
|
34180
34224
|
return {
|
|
34181
|
-
ok:
|
|
34225
|
+
ok: true,
|
|
34226
|
+
warn: true,
|
|
34182
34227
|
id: "plugin-cache",
|
|
34183
34228
|
label: "plugin cache",
|
|
34184
|
-
//
|
|
34185
|
-
//
|
|
34186
|
-
// `mmi-cli plugin prune --apply` clears it in one command and a re-run goes green, so this is an
|
|
34187
|
-
// ordinary red the operator is expected to act on. "The doctor cannot heal it automatically" was never
|
|
34188
|
-
// the bar — see the contract for why report-only is a per-row ruling rather than a rule you can apply
|
|
34189
|
-
// from here.
|
|
34190
|
-
// Lead with the versioned-cache framing when there are stale versions; otherwise report the staging litter
|
|
34191
|
-
// on its own so a cache with zero versioned dirs still gets an honest ✗.
|
|
34229
|
+
// Installed-surface convergence belongs to mmi-hub; the host owns its cache lifecycle. Doctor
|
|
34230
|
+
// reports old generations but never races either writer by deleting them.
|
|
34192
34231
|
detail: input.stale.length ? `${input.cached} versions cached (${parts.join("; ")})` : parts.join("; "),
|
|
34193
|
-
fix: "run `mmi-
|
|
34232
|
+
fix: "run `mmi-hub status` and `mmi-hub update`; if only superseded cache remains, let the host retire it after all older sessions close",
|
|
34194
34233
|
verbose: evidence
|
|
34195
34234
|
};
|
|
34196
34235
|
}
|
|
@@ -34295,24 +34334,34 @@ function checkRepoIndexCloud(probe) {
|
|
|
34295
34334
|
probe.builtAt ? `builtAt: ${probe.builtAt}` : "builtAt: n/a",
|
|
34296
34335
|
typeof probe.fileCount === "number" ? `fileCount: ${probe.fileCount}` : "fileCount: n/a",
|
|
34297
34336
|
typeof probe.embCount === "number" ? `embCount: ${probe.embCount}` : "embCount: n/a",
|
|
34298
|
-
typeof probe.localPresent === "boolean" ? `local cache: ${probe.localPresent ? "present" : "absent"}` : "local cache: n/a"
|
|
34337
|
+
typeof probe.localPresent === "boolean" ? `local v3 cache: ${probe.localPresent ? "present" : "absent"}` : "local v3 cache: n/a",
|
|
34338
|
+
`local v4: ${probe.localV4State ?? "unknown"}${probe.localV4Commit ? ` @ ${probe.localV4Commit.slice(0, 12)}` : ""}${typeof probe.localV4EmbeddingCoverage === "number" ? ` (${Math.round(probe.localV4EmbeddingCoverage * 100)}% embeddings)` : ""}`,
|
|
34339
|
+
`cloud v4: ${probe.cloudV4State ?? "unknown"}${probe.cloudV4Commit ? ` @ ${probe.cloudV4Commit.slice(0, 12)}` : ""}`,
|
|
34340
|
+
`v4 cohort: ${probe.v4ReadPercent ?? 0}%`,
|
|
34341
|
+
`v4 shadows: ${probe.v4ShadowComparisons ?? 0}/${probe.v4ShadowMinimum ?? 50} \u2014 ${probe.v4ShadowCutoverReady ? "cutover-ready" : "not ready"}`,
|
|
34342
|
+
...Object.entries(probe.v4ShadowErrors ?? {}).map(([kind, count]) => `v4 shadow error ${kind}: ${count}`)
|
|
34299
34343
|
];
|
|
34300
34344
|
switch (probe.kind) {
|
|
34301
|
-
case "healthy":
|
|
34345
|
+
case "healthy": {
|
|
34346
|
+
const v4Unready = probe.cloudV4State === "invalid" || probe.cloudV4State === "tombstoned" || probe.cloudV4State === "degraded" && (probe.localV4EmbeddingCoverage ?? 1) < 0.95;
|
|
34347
|
+
const detail = probe.detail ?? `cloud v3 ok${typeof probe.fileCount === "number" ? ` \u2014 ${probe.fileCount} files` : ""}; v4 ${probe.cloudV4State ?? "absent"}, cohort ${probe.v4ReadPercent ?? 0}%`;
|
|
34302
34348
|
return {
|
|
34303
|
-
ok:
|
|
34349
|
+
ok: !v4Unready || (probe.v4ReadPercent ?? 0) === 0,
|
|
34350
|
+
...v4Unready && (probe.v4ReadPercent ?? 0) === 0 ? { warn: true, verified: false } : {},
|
|
34304
34351
|
id: "repo-index",
|
|
34305
34352
|
label: "repo-index",
|
|
34306
|
-
detail
|
|
34353
|
+
detail,
|
|
34354
|
+
...v4Unready ? { fix: "run `mmi-hub update`, then dispatch `mmi-cli harbour org schedules run MMI-Hub/repo-index-reconcile`; keep the v4 cohort at 0 until shadows pass" } : {},
|
|
34307
34355
|
verbose: evidence
|
|
34308
34356
|
};
|
|
34357
|
+
}
|
|
34309
34358
|
case "command-absent":
|
|
34310
34359
|
return {
|
|
34311
34360
|
ok: false,
|
|
34312
34361
|
id: "repo-index",
|
|
34313
34362
|
label: "repo-index",
|
|
34314
34363
|
detail: "this mmi-cli build has no repo-index command",
|
|
34315
|
-
fix: "run `mmi-
|
|
34364
|
+
fix: "run `mmi-hub status`, then `mmi-hub update` to converge the CLI and installed host surfaces",
|
|
34316
34365
|
verbose: evidence
|
|
34317
34366
|
};
|
|
34318
34367
|
case "deploy-lag":
|
|
@@ -34331,7 +34380,7 @@ function checkRepoIndexCloud(probe) {
|
|
|
34331
34380
|
id: "repo-index",
|
|
34332
34381
|
label: "repo-index",
|
|
34333
34382
|
detail: probe.detail ?? "no cloud projection for this repo",
|
|
34334
|
-
fix: "
|
|
34383
|
+
fix: "dispatch `mmi-cli harbour org schedules run MMI-Hub/repo-index-reconcile` or run the authenticated per-repo sync",
|
|
34335
34384
|
verbose: evidence
|
|
34336
34385
|
};
|
|
34337
34386
|
case "stale":
|
|
@@ -34340,7 +34389,7 @@ function checkRepoIndexCloud(probe) {
|
|
|
34340
34389
|
id: "repo-index",
|
|
34341
34390
|
label: "repo-index",
|
|
34342
34391
|
detail: probe.detail ?? "cloud projection looks stale vs recent pushes",
|
|
34343
|
-
fix: "
|
|
34392
|
+
fix: "dispatch `mmi-cli harbour org schedules run MMI-Hub/repo-index-reconcile` or wait for the registered 6h schedule",
|
|
34344
34393
|
verbose: evidence
|
|
34345
34394
|
};
|
|
34346
34395
|
case "auth":
|
|
@@ -34358,7 +34407,7 @@ function checkRepoIndexCloud(probe) {
|
|
|
34358
34407
|
id: "repo-index",
|
|
34359
34408
|
label: "repo-index",
|
|
34360
34409
|
detail: probe.detail ?? "Hub API URL not configured",
|
|
34361
|
-
fix: "run `mmi-
|
|
34410
|
+
fix: "run `mmi-hub status` and `mmi-hub update`; Hub URL wiring is installer-owned",
|
|
34362
34411
|
verbose: evidence
|
|
34363
34412
|
};
|
|
34364
34413
|
case "network":
|
|
@@ -34578,42 +34627,6 @@ async function runDoctorClean(opts, io, deps) {
|
|
|
34578
34627
|
}
|
|
34579
34628
|
}
|
|
34580
34629
|
async function runPluginCacheRow() {
|
|
34581
|
-
if (applyEnv && deps.prunePluginCache && spendOnce("cache-prune")) {
|
|
34582
|
-
const cache = deps.pluginCache();
|
|
34583
|
-
if (cache.stale.length === 0 && cache.staging.length === 0) {
|
|
34584
|
-
emitNow(checkPluginCache(cache));
|
|
34585
|
-
return;
|
|
34586
|
-
}
|
|
34587
|
-
healIntent(`plugin cache \u2014 pruning ${cache.stale.length} superseded version(s) (guarded)`);
|
|
34588
|
-
traceHeal("cache-prune");
|
|
34589
|
-
const outcome = deps.prunePluginCache();
|
|
34590
|
-
if (outcome.removed.length) markHealChanged();
|
|
34591
|
-
const evidence = [
|
|
34592
|
-
...outcome.removed.map((v) => `pruned: ${v}`),
|
|
34593
|
-
...outcome.held.map((h) => `still held: ${h.version} (${h.error}) \u2014 never forced`),
|
|
34594
|
-
...outcome.kept.map((k) => `kept: ${k.version} \u2014 ${k.reason}`)
|
|
34595
|
-
];
|
|
34596
|
-
if (outcome.held.length === 0) {
|
|
34597
|
-
emitNow({
|
|
34598
|
-
id: "plugin-cache",
|
|
34599
|
-
ok: true,
|
|
34600
|
-
label: "plugin cache",
|
|
34601
|
-
detail: outcome.removed.length ? `pruned ${outcome.removed.length} superseded version(s)` : "nothing provably superseded (guards kept every candidate)",
|
|
34602
|
-
verbose: evidence
|
|
34603
|
-
});
|
|
34604
|
-
} else {
|
|
34605
|
-
emitNow({
|
|
34606
|
-
id: "plugin-cache",
|
|
34607
|
-
ok: false,
|
|
34608
|
-
reportOnly: true,
|
|
34609
|
-
label: "plugin cache",
|
|
34610
|
-
detail: `${outcome.removed.length} pruned; ${outcome.held.length} still held by a live session`,
|
|
34611
|
-
fix: "close the session holding it and re-run `mmi-cli doctor`",
|
|
34612
|
-
verbose: evidence
|
|
34613
|
-
});
|
|
34614
|
-
}
|
|
34615
|
-
return;
|
|
34616
|
-
}
|
|
34617
34630
|
emitNow(checkPluginCache(deps.pluginCache()));
|
|
34618
34631
|
}
|
|
34619
34632
|
async function runClaudeBinaryRow() {
|
|
@@ -35627,6 +35640,21 @@ function mmiDoctorDeps(opts = {}) {
|
|
|
35627
35640
|
// #4156: short-timeout Hub status for the current repo. Fail-soft — never throws to doctor.
|
|
35628
35641
|
repoIndexCloudState: async (root) => {
|
|
35629
35642
|
const local = repoIndexStatus(root);
|
|
35643
|
+
let localV4 = { state: "absent" };
|
|
35644
|
+
try {
|
|
35645
|
+
const parsed = JSON.parse((0, import_node_fs42.readFileSync)(repoIndexV4StorePath(root), "utf8"));
|
|
35646
|
+
const state = parsed.status?.state;
|
|
35647
|
+
if (parsed.schemaVersion === 4 && (state === "ready" || state === "degraded")) {
|
|
35648
|
+
const chunks = parsed.manifest?.chunks?.length ?? 0;
|
|
35649
|
+
localV4 = {
|
|
35650
|
+
state,
|
|
35651
|
+
...typeof parsed.manifest?.commit === "string" ? { commit: parsed.manifest.commit } : {},
|
|
35652
|
+
embeddingCoverage: chunks ? (parsed.manifest?.embeddings?.length ?? 0) / chunks : 1
|
|
35653
|
+
};
|
|
35654
|
+
} else localV4 = { state: "invalid" };
|
|
35655
|
+
} catch {
|
|
35656
|
+
}
|
|
35657
|
+
const localFields = { localPresent: local.present, localV4State: localV4.state, localV4Commit: localV4.commit, localV4EmbeddingCoverage: localV4.embeddingCoverage };
|
|
35630
35658
|
try {
|
|
35631
35659
|
const cfg = await loadConfig();
|
|
35632
35660
|
const repo = inferRepoSlug(root);
|
|
@@ -35635,17 +35663,32 @@ function mmiDoctorDeps(opts = {}) {
|
|
|
35635
35663
|
timeoutMs: 4e3
|
|
35636
35664
|
});
|
|
35637
35665
|
if (isRepoIndexStatusError(st)) {
|
|
35638
|
-
if (st.code === "deploy-lag") return { kind: "deploy-lag", repo,
|
|
35639
|
-
if (st.code === "auth") return { kind: "auth", repo,
|
|
35640
|
-
if (st.code === "config") return { kind: "config", repo, detail: st.error,
|
|
35641
|
-
return { kind: "network", repo, detail: st.error,
|
|
35666
|
+
if (st.code === "deploy-lag") return { kind: "deploy-lag", repo, ...localFields };
|
|
35667
|
+
if (st.code === "auth") return { kind: "auth", repo, ...localFields };
|
|
35668
|
+
if (st.code === "config") return { kind: "config", repo, detail: st.error, ...localFields };
|
|
35669
|
+
return { kind: "network", repo, detail: st.error, ...localFields };
|
|
35642
35670
|
}
|
|
35643
35671
|
const present = st.present;
|
|
35644
35672
|
const builtAt = typeof st.builtAt === "string" ? st.builtAt : void 0;
|
|
35645
35673
|
const fileCount = typeof st.fileCount === "number" ? st.fileCount : void 0;
|
|
35646
35674
|
const embCount = typeof st.embCount === "number" ? st.embCount : void 0;
|
|
35675
|
+
const v4 = st.v4;
|
|
35676
|
+
const migration = st.v4Migration;
|
|
35677
|
+
const shadow = st.v4Shadow;
|
|
35678
|
+
const shadowThresholds = shadow?.thresholds;
|
|
35679
|
+
const cloudV4State = typeof v4?.state === "string" && ["ready", "degraded", "invalid", "tombstoned"].includes(v4.state) ? v4.state : "absent";
|
|
35680
|
+
const v4Fields = {
|
|
35681
|
+
...localFields,
|
|
35682
|
+
cloudV4State,
|
|
35683
|
+
...typeof v4?.commit === "string" ? { cloudV4Commit: v4.commit } : {},
|
|
35684
|
+
v4ReadPercent: typeof migration?.readPercent === "number" ? migration.readPercent : 0,
|
|
35685
|
+
v4ShadowComparisons: typeof shadow?.comparisonCount === "number" ? shadow.comparisonCount : 0,
|
|
35686
|
+
v4ShadowMinimum: typeof shadowThresholds?.minimumComparisons === "number" ? shadowThresholds.minimumComparisons : 50,
|
|
35687
|
+
v4ShadowCutoverReady: shadow?.cutoverReady === true,
|
|
35688
|
+
v4ShadowErrors: shadow?.errors && typeof shadow.errors === "object" ? shadow.errors : {}
|
|
35689
|
+
};
|
|
35647
35690
|
if (present === false) {
|
|
35648
|
-
return { kind: "missing-projection", repo,
|
|
35691
|
+
return { kind: "missing-projection", repo, ...v4Fields, fileCount: 0, embCount: 0 };
|
|
35649
35692
|
}
|
|
35650
35693
|
if (builtAt) {
|
|
35651
35694
|
const ageMs = Date.now() - Date.parse(builtAt);
|
|
@@ -35656,7 +35699,7 @@ function mmiDoctorDeps(opts = {}) {
|
|
|
35656
35699
|
builtAt,
|
|
35657
35700
|
fileCount,
|
|
35658
35701
|
embCount,
|
|
35659
|
-
|
|
35702
|
+
...v4Fields,
|
|
35660
35703
|
detail: `projection builtAt ${builtAt} (>48h old)`
|
|
35661
35704
|
};
|
|
35662
35705
|
}
|
|
@@ -35667,13 +35710,13 @@ function mmiDoctorDeps(opts = {}) {
|
|
|
35667
35710
|
builtAt,
|
|
35668
35711
|
fileCount,
|
|
35669
35712
|
embCount,
|
|
35670
|
-
|
|
35713
|
+
...v4Fields
|
|
35671
35714
|
};
|
|
35672
35715
|
} catch (e) {
|
|
35673
35716
|
return {
|
|
35674
35717
|
kind: "network",
|
|
35675
35718
|
detail: e instanceof Error ? e.message : String(e),
|
|
35676
|
-
|
|
35719
|
+
...localFields
|
|
35677
35720
|
};
|
|
35678
35721
|
}
|
|
35679
35722
|
}
|
package/dist/repo-index-v4.cjs
CHANGED
|
@@ -197,8 +197,12 @@ function listCandidatePaths(cwd, exec = import_node_child_process2.execFileSync)
|
|
|
197
197
|
// src/repo-index-v4/language.ts
|
|
198
198
|
var LANGUAGE_BY_EXTENSION = {
|
|
199
199
|
".ts": { name: "typescript", parserName: "typescript" },
|
|
200
|
+
".mts": { name: "typescript", parserName: "typescript" },
|
|
201
|
+
".cts": { name: "typescript", parserName: "typescript" },
|
|
200
202
|
".tsx": { name: "tsx", parserName: "tsx" },
|
|
201
203
|
".js": { name: "javascript", parserName: "javascript" },
|
|
204
|
+
".mjs": { name: "javascript", parserName: "javascript" },
|
|
205
|
+
".cjs": { name: "javascript", parserName: "javascript" },
|
|
202
206
|
".jsx": { name: "jsx", parserName: "javascript" },
|
|
203
207
|
".py": { name: "python", parserName: "python" },
|
|
204
208
|
".go": { name: "go", parserName: "go" },
|
|
@@ -371,6 +375,7 @@ var import_node_path4 = require("node:path");
|
|
|
371
375
|
var V4_MAX_CHUNKS = 1e4;
|
|
372
376
|
var V4_MAX_ARTIFACT_BYTES = 64 * 1024 * 1024;
|
|
373
377
|
var V4_EMBED_BATCH = 32;
|
|
378
|
+
var V4_VECTOR_DECIMAL_PLACES = 6;
|
|
374
379
|
var COMMIT = /^[a-f0-9]{40}$/;
|
|
375
380
|
function canonicalJson(value) {
|
|
376
381
|
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
@@ -381,6 +386,9 @@ function canonicalJson(value) {
|
|
|
381
386
|
function sha2562(value) {
|
|
382
387
|
return (0, import_node_crypto3.createHash)("sha256").update(canonicalJson(value)).digest("hex");
|
|
383
388
|
}
|
|
389
|
+
function quantizeV4Vector(vector) {
|
|
390
|
+
return vector.map((value) => Number(value.toFixed(V4_VECTOR_DECIMAL_PLACES)));
|
|
391
|
+
}
|
|
384
392
|
function statePath(cwd) {
|
|
385
393
|
return repoRuntimeStatePath(cwd, "repo-index", "v4.json");
|
|
386
394
|
}
|
|
@@ -430,16 +438,20 @@ ${chunk.symbol ?? ""}
|
|
|
430
438
|
${chunk.blurb ?? ""}`;
|
|
431
439
|
}
|
|
432
440
|
}
|
|
441
|
+
var V4_EMBED_TIMEOUT_MS = 15 * 6e4;
|
|
433
442
|
function runEmbedder(cwd, chunks, modelDirectory, createdAt) {
|
|
434
443
|
if (!chunks.length) return { embeddings: [] };
|
|
435
|
-
const
|
|
436
|
-
const
|
|
437
|
-
const file = (0, import_node_fs3.existsSync)(
|
|
444
|
+
const orchestratorRunner = (0, import_node_path4.join)(process.cwd(), "repo-indexer", "src", "batch.mjs");
|
|
445
|
+
const targetRunner = (0, import_node_path4.join)(cwd, "repo-indexer", "src", "batch.mjs");
|
|
446
|
+
const file = (0, import_node_fs3.existsSync)(orchestratorRunner) ? orchestratorRunner : targetRunner;
|
|
438
447
|
if (!(0, import_node_fs3.existsSync)(file)) return { embeddings: [], reason: "embeddings-unavailable" };
|
|
439
448
|
const request = { texts: chunks.map((chunk) => ({ id: chunk.id, text: embeddingInput(cwd, chunk) })), maxBatch: V4_EMBED_BATCH };
|
|
440
449
|
const env = { ...process.env, ...modelDirectory ? { MMI_REPO_INDEXER_MODEL_DIR: modelDirectory } : {} };
|
|
441
|
-
const result = (0, import_node_child_process3.spawnSync)(process.execPath, [file], { input: JSON.stringify(request), encoding: "utf8", windowsHide: true, timeout:
|
|
442
|
-
if (result.error || result.status !== 0)
|
|
450
|
+
const result = (0, import_node_child_process3.spawnSync)(process.execPath, [file], { input: JSON.stringify(request), encoding: "utf8", windowsHide: true, timeout: V4_EMBED_TIMEOUT_MS, maxBuffer: V4_MAX_ARTIFACT_BYTES, env });
|
|
451
|
+
if (result.error || result.status !== 0) {
|
|
452
|
+
const detail = result.error?.message ?? result.signal ?? `exit status ${result.status ?? "unknown"}`;
|
|
453
|
+
throw new Error(`repo-index v4 embedding runner failed: ${detail}`);
|
|
454
|
+
}
|
|
443
455
|
try {
|
|
444
456
|
const response = JSON.parse(result.stdout);
|
|
445
457
|
if (!response.ok || !response.provenance || !Array.isArray(response.embeddings)) return { embeddings: [], reason: "embeddings-unavailable" };
|
|
@@ -482,7 +494,7 @@ async function buildRepoIndexV4(cwd, repo, opts = {}) {
|
|
|
482
494
|
const reusableIds = new Set(reusable.map((e) => e.chunkId));
|
|
483
495
|
const missing = chunks.filter((chunk) => !reusableIds.has(chunk.id));
|
|
484
496
|
const generated = missing.length === 0 ? { embeddings: [] } : opts.embed === false ? { embeddings: [], reason: "embeddings-unavailable" } : runEmbedder(cwd, missing, opts.modelDirectory, createdAt);
|
|
485
|
-
const embeddings = [...reusable, ...generated.embeddings].sort((a, b) => a.chunkId.localeCompare(b.chunkId));
|
|
497
|
+
const embeddings = [...reusable, ...generated.embeddings].map((embedding) => ({ ...embedding, vector: quantizeV4Vector(embedding.vector) })).sort((a, b) => a.chunkId.localeCompare(b.chunkId));
|
|
486
498
|
const chunksDigest = sha2562(chunks);
|
|
487
499
|
const embeddingsDigest = sha2562(embeddings);
|
|
488
500
|
const artifact = (kind, digest) => {
|
package/package.json
CHANGED