github-router 0.3.257 → 0.3.261
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/{attribution-settings-Bf_bD4RA.js → attribution-settings-Bl0HHJQF.js} +9 -9
- package/dist/attribution-settings-Bl0HHJQF.js.map +1 -0
- package/dist/{auth-CP4q2CjO.js → auth-I8k2OOvA.js} +3 -3
- package/dist/{auth-CP4q2CjO.js.map → auth-I8k2OOvA.js.map} +1 -1
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/{check-usage-6PB5IUFb.js → check-usage-SOn7-cWc.js} +4 -4
- package/dist/{check-usage-6PB5IUFb.js.map → check-usage-SOn7-cWc.js.map} +1 -1
- package/dist/{claude-DAG4HtaH.js → claude-CEaI47j7.js} +17 -14
- package/dist/claude-CEaI47j7.js.map +1 -0
- package/dist/{codex-DKyJuUiO.js → codex-C6Eyz3EV.js} +9 -6
- package/dist/codex-C6Eyz3EV.js.map +1 -0
- package/dist/{debug-CjmE9sgG.js → debug-vshv4nIv.js} +2 -2
- package/dist/{debug-CjmE9sgG.js.map → debug-vshv4nIv.js.map} +1 -1
- package/dist/engine-B4Ohhv5i.js +2 -0
- package/dist/{file-log-reporter-IFQcL5IK.js → file-log-reporter-vI8qCFNM.js} +2 -2
- package/dist/{file-log-reporter-IFQcL5IK.js.map → file-log-reporter-vI8qCFNM.js.map} +1 -1
- package/dist/{gate-discovery-B86ByhEG.js → gate-discovery-BnPhH_AC.js} +5 -5
- package/dist/{gate-discovery-B86ByhEG.js.map → gate-discovery-BnPhH_AC.js.map} +1 -1
- package/dist/{get-copilot-usage-DD1N0Xlh.js → get-copilot-usage-CYpAsYrM.js} +2 -2
- package/dist/{get-copilot-usage-DD1N0Xlh.js.map → get-copilot-usage-CYpAsYrM.js.map} +1 -1
- package/dist/{internal-artifact-open-D2cQ2QCw.js → internal-artifact-open-CZGO831M.js} +2 -2
- package/dist/{internal-artifact-open-D2cQ2QCw.js.map → internal-artifact-open-CZGO831M.js.map} +1 -1
- package/dist/{internal-plan-review-ipnT3bhj.js → internal-plan-review-6gkcOAjT.js} +3 -3
- package/dist/{internal-plan-review-ipnT3bhj.js.map → internal-plan-review-6gkcOAjT.js.map} +1 -1
- package/dist/{internal-prompt-submit-DOj75_hh.js → internal-prompt-submit-CSJR24-y.js} +4 -4
- package/dist/{internal-prompt-submit-DOj75_hh.js.map → internal-prompt-submit-CSJR24-y.js.map} +1 -1
- package/dist/{internal-session-bind-DwK2iGW0.js → internal-session-bind-DtSBTkQe.js} +2 -2
- package/dist/{internal-session-bind-DwK2iGW0.js.map → internal-session-bind-DtSBTkQe.js.map} +1 -1
- package/dist/{internal-stop-hook-B8huizZ1.js → internal-stop-hook-CiflCJO-.js} +5 -5
- package/dist/{internal-stop-hook-B8huizZ1.js.map → internal-stop-hook-CiflCJO-.js.map} +1 -1
- package/dist/{internal-stop-review-AUcFssrW.js → internal-stop-review-_1Mqz7eT.js} +2 -2
- package/dist/{internal-stop-review-AUcFssrW.js.map → internal-stop-review-_1Mqz7eT.js.map} +1 -1
- package/dist/{lifecycle-Byw5s1G8.js → lifecycle-Bd1Fyf4B.js} +100 -3
- package/dist/lifecycle-Bd1Fyf4B.js.map +1 -0
- package/dist/lifecycle-CRTWEbiP.js +2 -0
- package/dist/lifecycle-DUPXAOQS.js +2 -0
- package/dist/{lifecycle-DD88ka3f.js → lifecycle-DjC9tC1A.js} +2 -2
- package/dist/{lifecycle-DD88ka3f.js.map → lifecycle-DjC9tC1A.js.map} +1 -1
- package/dist/main.js +14 -14
- package/dist/{models-B6UnGyRo.js → models-uQgsKNNC.js} +3 -3
- package/dist/{models-B6UnGyRo.js.map → models-uQgsKNNC.js.map} +1 -1
- package/dist/{orchestration-hRU4TdWr.js → orchestration-BiZviyam.js} +2 -2
- package/dist/{orchestration-hRU4TdWr.js.map → orchestration-BiZviyam.js.map} +1 -1
- package/dist/{paths-C1cLZ7Ga.js → paths-BXrbboAS.js} +3 -3
- package/dist/{paths-C1cLZ7Ga.js.map → paths-BXrbboAS.js.map} +1 -1
- package/dist/paths-Dz1WyRJG.js +2 -0
- package/dist/{peer-mcp-personas-ByulAXNm.js → peer-mcp-personas-V4AXhm9B.js} +414 -59
- package/dist/peer-mcp-personas-V4AXhm9B.js.map +1 -0
- package/dist/{plan-review-hook-C8x0uKPf.js → plan-review-hook-Bo4y1r3j.js} +2 -2
- package/dist/{plan-review-hook-C8x0uKPf.js.map → plan-review-hook-Bo4y1r3j.js.map} +1 -1
- package/dist/{prompt-submit-hook-BrkkLAAB.js → prompt-submit-hook-BFRFLSk5.js} +2 -2
- package/dist/{prompt-submit-hook-BrkkLAAB.js.map → prompt-submit-hook-BFRFLSk5.js.map} +1 -1
- package/dist/{provision-BztATDo4.js → provision-BLwsOFCI.js} +4 -4
- package/dist/{provision-BztATDo4.js.map → provision-BLwsOFCI.js.map} +1 -1
- package/dist/{serve-CkBOQXvt.js → serve-De-kqWXM.js} +10 -10
- package/dist/{serve-CkBOQXvt.js.map → serve-De-kqWXM.js.map} +1 -1
- package/dist/{server-setup-CA0ZT-nq.js → server-setup-BeeT8m-w.js} +99 -13
- package/dist/server-setup-BeeT8m-w.js.map +1 -0
- package/dist/{start-DGiyI4Pm.js → start-DEC0M8UH.js} +8 -5
- package/dist/start-DEC0M8UH.js.map +1 -0
- package/dist/{stop-gate-hook-DQc2KV7B.js → stop-gate-hook-DoYD9Wt8.js} +2 -2
- package/dist/{stop-gate-hook-DQc2KV7B.js.map → stop-gate-hook-DoYD9Wt8.js.map} +1 -1
- package/dist/{stop-gate-policy-CHwWbuF_.js → stop-gate-policy-CoMKWSsS.js} +2 -2
- package/dist/{stop-gate-policy-CHwWbuF_.js.map → stop-gate-policy-CoMKWSsS.js.map} +1 -1
- package/dist/{token-R2ocFC3M.js → token-DWknHe9M.js} +23 -2
- package/dist/token-DWknHe9M.js.map +1 -0
- package/package.json +1 -1
- package/dist/attribution-settings-Bf_bD4RA.js.map +0 -1
- package/dist/claude-DAG4HtaH.js.map +0 -1
- package/dist/codex-DKyJuUiO.js.map +0 -1
- package/dist/engine-BpTP4Mex.js +0 -2
- package/dist/lifecycle-Byw5s1G8.js.map +0 -1
- package/dist/lifecycle-D80CaWie.js +0 -2
- package/dist/lifecycle-DzqCqDlM.js +0 -2
- package/dist/paths-CwKwc2pi.js +0 -2
- package/dist/peer-mcp-personas-ByulAXNm.js.map +0 -1
- package/dist/server-setup-CA0ZT-nq.js.map +0 -1
- package/dist/start-DGiyI4Pm.js.map +0 -1
- package/dist/token-R2ocFC3M.js.map +0 -1
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { t as getPackageVersion } from "./version-_Q1WpsQp.js";
|
|
2
|
-
import { t as PATHS } from "./paths-
|
|
3
|
-
import { C as copilotHeaders, E as githubAgentHeaders, O as state, S as copilotBaseUrl, T as githubAgentGraphQLHeaders, _ as withTransientRetry, b as GITHUB_API_BASE_URL, d as resolveModel, f as sleep$2, g as fetchWithTransientRetry, h as isAllowedCopilotHost, i as tryRefreshAndRetry, v as HTTPError, w as copilotVersion, x as GITHUB_GRAPHQL_URL } from "./token-
|
|
2
|
+
import { t as PATHS } from "./paths-BXrbboAS.js";
|
|
3
|
+
import { C as copilotHeaders, E as githubAgentHeaders, O as state, S as copilotBaseUrl, T as githubAgentGraphQLHeaders, _ as withTransientRetry, b as GITHUB_API_BASE_URL, d as resolveModel, f as sleep$2, g as fetchWithTransientRetry, h as isAllowedCopilotHost, i as tryRefreshAndRetry, v as HTTPError, w as copilotVersion, x as GITHUB_GRAPHQL_URL } from "./token-DWknHe9M.js";
|
|
4
4
|
import { a as resolveExecutable, c as runManagedExeCapture, i as parseIntEnv, r as parseBoolEnv } from "./exec-DTO2oin0.js";
|
|
5
|
-
import { i as registerExitHandlers$1, n as getInstanceUuid, r as recordWorkerRepo, t as WorktreeRegistry } from "./lifecycle-
|
|
5
|
+
import { i as registerExitHandlers$1, n as getInstanceUuid, r as recordWorkerRepo, t as WorktreeRegistry } from "./lifecycle-DjC9tC1A.js";
|
|
6
6
|
import { t as MCP_WORKSPACE_HEADER } from "./mcp-workspace-header-CGJbNeHb.js";
|
|
7
7
|
import { n as ArtifactError, r as applyInsecureTls, t as ArtifactClient } from "./client-CQMfroGV.js";
|
|
8
|
-
import { n as isPidAlive,
|
|
9
|
-
import { h as runGateChecks, m as sealedGateIds, p as resolveSealedGate } from "./stop-gate-hook-
|
|
10
|
-
import { t as liveExec } from "./orchestration-
|
|
8
|
+
import { n as isPidAlive, r as registerColbertExitHandlers, s as trackChild, t as getColbertInstanceUuid } from "./lifecycle-Bd1Fyf4B.js";
|
|
9
|
+
import { h as runGateChecks, m as sealedGateIds, p as resolveSealedGate } from "./stop-gate-hook-DoYD9Wt8.js";
|
|
10
|
+
import { t as liveExec } from "./orchestration-BiZviyam.js";
|
|
11
11
|
import { createRequire } from "node:module";
|
|
12
12
|
import consola from "consola";
|
|
13
13
|
import { chmodSync, closeSync, constants, cpSync, existsSync, mkdirSync, openSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync, writeSync } from "node:fs";
|
|
@@ -95,6 +95,74 @@ async function tryCreateLock(p) {
|
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
//#endregion
|
|
98
|
+
//#region src/lib/one-m-context.ts
|
|
99
|
+
/**
|
|
100
|
+
* Context-window threshold at which Claude Code's `[1m]` accounting unlock is
|
|
101
|
+
* worth requesting. Shared by `pickClaudeDefault` (`./port`), the gateway
|
|
102
|
+
* picker-row seed (`./server-setup`), and the native-subagent frontmatter
|
|
103
|
+
* builder (`./codex-mcp-config`) so the three cannot drift apart.
|
|
104
|
+
*/
|
|
105
|
+
const ONE_M_TOKENS = 1e6;
|
|
106
|
+
/**
|
|
107
|
+
* Whether the live Copilot catalog advertises a >=1M context window for this
|
|
108
|
+
* exact model id.
|
|
109
|
+
*
|
|
110
|
+
* Exact-id match only — no slug translation, no family inference. Every caller
|
|
111
|
+
* already holds a concrete catalog id (the seeded picker rows and the resolved
|
|
112
|
+
* per-agent models both come from a catalog walk), and an inferred match could
|
|
113
|
+
* silently attach `[1m]` to a sibling that does not serve 1M. `pickClaudeDefault`
|
|
114
|
+
* keeps its own version-anchored regex scan because it resolves a FAMILY
|
|
115
|
+
* (`opus-4.7` may ship as a `-1m` sibling slug), which is a different question.
|
|
116
|
+
*
|
|
117
|
+
* Returns false when the catalog is unavailable, so a thin or not-yet-populated
|
|
118
|
+
* catalog degrades to bare ids (Claude Code then accounts at its 200K default —
|
|
119
|
+
* under-accounting, never overflow).
|
|
120
|
+
*/
|
|
121
|
+
function catalogAdvertises1M(id) {
|
|
122
|
+
const models = state.models?.data;
|
|
123
|
+
if (!models) return false;
|
|
124
|
+
return (models.find((m) => m.id === id)?.capabilities?.limits?.max_context_window_tokens ?? 0) >= ONE_M_TOKENS;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* True when the user has opted out of 1M context accounting (HIPAA and similar
|
|
128
|
+
* data-retention regimes).
|
|
129
|
+
*
|
|
130
|
+
* Deliberately PRESENCE-based rather than parsed as a boolean, because this
|
|
131
|
+
* mirrors Claude Code's own gate verbatim — its `has1mContext` helper is
|
|
132
|
+
* `if (process.env.CLAUDE_CODE_DISABLE_1M_CONTEXT) return false` over a raw env
|
|
133
|
+
* read, so a literal `"0"` disables 1M there. Parsing it as a boolean here would
|
|
134
|
+
* make the proxy attach a bracket that Claude Code then ignores: the decoration
|
|
135
|
+
* and the accounting must agree in every case, so we match the quirk instead of
|
|
136
|
+
* fixing it on one side only. An empty string is falsy in both.
|
|
137
|
+
*/
|
|
138
|
+
function oneMContextDisabled() {
|
|
139
|
+
return (process.env.CLAUDE_CODE_DISABLE_1M_CONTEXT ?? "") !== "";
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Decorate a model id with the `[1m]` literal-bracket suffix iff the catalog
|
|
143
|
+
* says the model serves >=1M context and the user has not opted out.
|
|
144
|
+
*
|
|
145
|
+
* The bracket is Claude Code's local context-accounting unlock. Its detector is
|
|
146
|
+
* `/\[1m\]/i` applied to the model id with NO vendor gate, so it works for the
|
|
147
|
+
* non-Claude gateway models exactly as it does for Opus — verified against the
|
|
148
|
+
* installed 2.1.222 build, where the window resolver returns `1e6` on a bracket
|
|
149
|
+
* match and otherwise falls through to a 200K default. Without the bracket a
|
|
150
|
+
* 1M-context model like `gpt-5.6-sol` (1,050,000) is budgeted at 200K and
|
|
151
|
+
* auto-compacts at roughly a fifth of its real window.
|
|
152
|
+
*
|
|
153
|
+
* The bracket never reaches Copilot: `resolveModel` (`./utils`) strips it before
|
|
154
|
+
* the upstream call, and because the catalog window is >=1M its `resolvedIs1M`
|
|
155
|
+
* check passes, so no spurious downgrade warning fires.
|
|
156
|
+
*
|
|
157
|
+
* Catalog-gating is what keeps this honest for sub-1M models: `gpt-5.3-codex`
|
|
158
|
+
* (400K) and `gpt-5.4-mini` (400K) are left bare, so they keep Claude Code's
|
|
159
|
+
* conservative 200K accounting rather than being over-budgeted into an overflow.
|
|
160
|
+
*/
|
|
161
|
+
function withOneMSuffix(id) {
|
|
162
|
+
if (oneMContextDisabled()) return id;
|
|
163
|
+
return catalogAdvertises1M(id) ? `${id}[1m]` : id;
|
|
164
|
+
}
|
|
165
|
+
//#endregion
|
|
98
166
|
//#region src/lib/port.ts
|
|
99
167
|
const DEFAULT_PORT = 8787;
|
|
100
168
|
const DEFAULT_CLAUDE_MODEL_FALLBACKS = [
|
|
@@ -152,7 +220,6 @@ const DEFAULT_CLAUDE_MODEL_FALLBACKS = [
|
|
|
152
220
|
* variant" — defaulting safe-side preserves the pre-change behavior).
|
|
153
221
|
*/
|
|
154
222
|
const DEFAULT_OPUS_FAMILY = "5";
|
|
155
|
-
const ONE_M_TOKENS = 1e6;
|
|
156
223
|
function pickClaudeDefault(opusFamily = DEFAULT_OPUS_FAMILY) {
|
|
157
224
|
const dotted = opusFamily.replace(/-/g, ".");
|
|
158
225
|
const bareSlug = `claude-opus-${dotted.replace(/\./g, "-")}`;
|
|
@@ -15238,7 +15305,7 @@ const BUILD_SPAWN_GRACE_MS = 3e4;
|
|
|
15238
15305
|
* route). A stable sha256-prefix of the canonical path is sufficient.
|
|
15239
15306
|
*/
|
|
15240
15307
|
function metaHashForWorkspace(workspace) {
|
|
15241
|
-
const canonical =
|
|
15308
|
+
const canonical = canonicalWorkspace(workspace);
|
|
15242
15309
|
let h = 2166136261;
|
|
15243
15310
|
for (let i = 0; i < canonical.length; i++) {
|
|
15244
15311
|
h ^= canonical.charCodeAt(i);
|
|
@@ -15250,11 +15317,79 @@ function metaPath(workspace) {
|
|
|
15250
15317
|
return path.join(PATHS.COLBERT_META_DIR, `${metaHashForWorkspace(workspace)}.json`);
|
|
15251
15318
|
}
|
|
15252
15319
|
/** Read the sidecar metadata for a workspace (null if none yet). */
|
|
15320
|
+
/**
|
|
15321
|
+
* Bump this when a router-side bug could have written a failure verdict that
|
|
15322
|
+
* was never the workspace's fault. A sidecar stamped with an older epoch gets
|
|
15323
|
+
* its watchdog-attributed streak cleared ONCE, then is stamped forward.
|
|
15324
|
+
*
|
|
15325
|
+
* Epoch 1: the fail-safe-probe fix. Before it, `indexDirSignature` could not
|
|
15326
|
+
* match colgrep's Windows extended-length `project_path`, so the inactivity
|
|
15327
|
+
* watchdog killed healthy builds and recorded `stuck` — which is refused
|
|
15328
|
+
* forever at a cap of 2. Those users are still capped after upgrading,
|
|
15329
|
+
* because the existing reset triggers on git/model/engine inputs and none of
|
|
15330
|
+
* those changed. This is the only thing that un-sticks them.
|
|
15331
|
+
* Epoch 2: widened to include `corrupt`, once it became clear the identity
|
|
15332
|
+
* bug MANUFACTURED corrupt verdicts (a null project-dir lookup was recorded
|
|
15333
|
+
* as corruption).
|
|
15334
|
+
*
|
|
15335
|
+
* Epoch 3: clearing the streak was not enough — `freshnessVerdict` returns
|
|
15336
|
+
* `failed` straight off `meta.status`, before it looks at the disk, so a
|
|
15337
|
+
* zeroed counter still short-circuited every query. The reset now drops the
|
|
15338
|
+
* status as well.
|
|
15339
|
+
*/
|
|
15340
|
+
const WATCHDOG_EPOCH = 3;
|
|
15341
|
+
/**
|
|
15342
|
+
* Failure classes the router-side bugs could have manufactured.
|
|
15343
|
+
*
|
|
15344
|
+
* `stuck`/`crashed` came from the blind watchdog. `corrupt` belongs here too,
|
|
15345
|
+
* which is not obvious: `repairCorruptIndex` recorded `failureClass:"corrupt"`
|
|
15346
|
+
* whenever `colbertProjectDir` returned null, and a null lookup is exactly
|
|
15347
|
+
* what the identity bug produced for a perfectly healthy index. So a stored
|
|
15348
|
+
* `corrupt` is not reliable evidence about the workspace — it may be evidence
|
|
15349
|
+
* about us. Observed on the machine where this was diagnosed: a `corrupt`
|
|
15350
|
+
* marker sitting next to an index that validates as coherent with 15 shards
|
|
15351
|
+
* and 1.24M embeddings.
|
|
15352
|
+
*
|
|
15353
|
+
* Clearing it is safe because it only resets the STREAK. The next query still
|
|
15354
|
+
* re-derives the verdict from the shards on disk, so an index that really is
|
|
15355
|
+
* corrupt is re-detected immediately and quarantined as before.
|
|
15356
|
+
*
|
|
15357
|
+
* `launch` stays excluded: a spawn failure (missing binary, unrunnable ORT)
|
|
15358
|
+
* is genuinely about the environment, and the existing engine-sha reset
|
|
15359
|
+
* already covers the case where an upgrade fixes it.
|
|
15360
|
+
*/
|
|
15361
|
+
const EPOCH_CLEARABLE = /* @__PURE__ */ new Set([
|
|
15362
|
+
"stuck",
|
|
15363
|
+
"crashed",
|
|
15364
|
+
"corrupt"
|
|
15365
|
+
]);
|
|
15366
|
+
/**
|
|
15367
|
+
* Clear a stale failure streak that a router-side bug produced.
|
|
15368
|
+
*
|
|
15369
|
+
* Bounded by construction: it fires only while the stored epoch is behind,
|
|
15370
|
+
* and the caller stamps the current epoch on the next write, so it is one
|
|
15371
|
+
* reset per epoch bump rather than a reset loop.
|
|
15372
|
+
*/
|
|
15373
|
+
function applyWatchdogEpoch(meta) {
|
|
15374
|
+
if ((meta.watchdogEpoch ?? 0) >= WATCHDOG_EPOCH) return meta;
|
|
15375
|
+
if (!(meta.status === "failed" && meta.failureClass !== void 0 && EPOCH_CLEARABLE.has(meta.failureClass))) return {
|
|
15376
|
+
...meta,
|
|
15377
|
+
watchdogEpoch: WATCHDOG_EPOCH
|
|
15378
|
+
};
|
|
15379
|
+
return {
|
|
15380
|
+
...meta,
|
|
15381
|
+
watchdogEpoch: WATCHDOG_EPOCH,
|
|
15382
|
+
status: "ready",
|
|
15383
|
+
failureClass: void 0,
|
|
15384
|
+
failedAttempts: 0,
|
|
15385
|
+
failedAt: void 0
|
|
15386
|
+
};
|
|
15387
|
+
}
|
|
15253
15388
|
async function readColbertMeta(workspace) {
|
|
15254
15389
|
try {
|
|
15255
15390
|
const raw = await fs$1.readFile(metaPath(workspace), "utf8");
|
|
15256
15391
|
const parsed = JSON.parse(raw);
|
|
15257
|
-
if (parsed && typeof parsed === "object" && typeof parsed.status === "string") return parsed;
|
|
15392
|
+
if (parsed && typeof parsed === "object" && typeof parsed.status === "string") return applyWatchdogEpoch(parsed);
|
|
15258
15393
|
return null;
|
|
15259
15394
|
} catch {
|
|
15260
15395
|
return null;
|
|
@@ -15279,9 +15414,13 @@ async function writeColbertMeta(meta) {
|
|
|
15279
15414
|
async function writeColbertMetaUnchained(meta) {
|
|
15280
15415
|
await fs$1.mkdir(PATHS.COLBERT_META_DIR, { recursive: true });
|
|
15281
15416
|
const dest = metaPath(meta.workspace);
|
|
15417
|
+
const stamped = {
|
|
15418
|
+
...meta,
|
|
15419
|
+
watchdogEpoch: WATCHDOG_EPOCH
|
|
15420
|
+
};
|
|
15282
15421
|
const tmp = `${dest}.${process$1.pid}.${Math.random().toString(16).slice(2, 10)}.tmp`;
|
|
15283
15422
|
try {
|
|
15284
|
-
await fs$1.writeFile(tmp, JSON.stringify(
|
|
15423
|
+
await fs$1.writeFile(tmp, JSON.stringify(stamped, null, 2));
|
|
15285
15424
|
await fs$1.rename(tmp, dest);
|
|
15286
15425
|
} catch (err) {
|
|
15287
15426
|
await fs$1.rm(tmp, { force: true }).catch(() => {});
|
|
@@ -15380,17 +15519,112 @@ async function completedIndexOnDisk(workspace) {
|
|
|
15380
15519
|
if (!projectDir) return false;
|
|
15381
15520
|
return validateIndexIntegrity(path.join(projectDir, "index")).verdict !== "not-built";
|
|
15382
15521
|
}
|
|
15383
|
-
|
|
15384
|
-
|
|
15522
|
+
/**
|
|
15523
|
+
* Strip a Windows extended-length prefix.
|
|
15524
|
+
*
|
|
15525
|
+
* `\\?\Q:\dir` → `Q:\dir`, and `\\?\UNC\server\share` → `\\server\share`
|
|
15526
|
+
* (naively slicing 4 there would yield the relative `UNC\server\share`).
|
|
15527
|
+
* colgrep stores `project_path` in this form — 50 of 53 dirs on the machine
|
|
15528
|
+
* where this was diagnosed — so every comparison against its `project.json`
|
|
15529
|
+
* has to account for it.
|
|
15530
|
+
*/
|
|
15531
|
+
function stripExtendedPrefix(p) {
|
|
15532
|
+
if (p.startsWith("\\\\?\\UNC\\")) return `\\\\${p.slice(8)}`;
|
|
15533
|
+
if (p.startsWith("\\\\?\\")) return p.slice(4);
|
|
15534
|
+
return p;
|
|
15385
15535
|
}
|
|
15386
|
-
/**
|
|
15387
|
-
*
|
|
15388
|
-
|
|
15536
|
+
/**
|
|
15537
|
+
* Is the volume holding `p` case-insensitive?
|
|
15538
|
+
*
|
|
15539
|
+
* Probed at runtime rather than inferred from `process.platform`, because
|
|
15540
|
+
* the platform is wrong in both directions: APFS can be formatted
|
|
15541
|
+
* case-SENSITIVE (folding there merges two genuinely distinct workspaces),
|
|
15542
|
+
* and Linux routinely mounts case-INSENSITIVE volumes such as exfat/NTFS
|
|
15543
|
+
* (not folding there splits one workspace into two identities).
|
|
15544
|
+
*
|
|
15545
|
+
* Cheap and memoized per filesystem root: stat the path back through a
|
|
15546
|
+
* case-flipped spelling of its own basename. Falls back to the platform
|
|
15547
|
+
* default only when the probe itself cannot run.
|
|
15548
|
+
*/
|
|
15549
|
+
const _caseInsensitiveByRoot = /* @__PURE__ */ new Map();
|
|
15550
|
+
function volumeIsCaseInsensitive(p) {
|
|
15551
|
+
const root = path.parse(path.resolve(p)).root || path.sep;
|
|
15552
|
+
const cached = _caseInsensitiveByRoot.get(root);
|
|
15553
|
+
if (cached !== void 0) return cached;
|
|
15554
|
+
let result = process$1.platform === "win32" || process$1.platform === "darwin";
|
|
15555
|
+
try {
|
|
15556
|
+
let probe = path.resolve(p);
|
|
15557
|
+
for (let i = 0; i < 64 && !existsSync(probe); i++) {
|
|
15558
|
+
const parent = path.dirname(probe);
|
|
15559
|
+
if (parent === probe) break;
|
|
15560
|
+
probe = parent;
|
|
15561
|
+
}
|
|
15562
|
+
const base = path.basename(probe);
|
|
15563
|
+
if (base && /[a-z]/i.test(base)) {
|
|
15564
|
+
const flipped = base === base.toLowerCase() ? base.toUpperCase() : base.toLowerCase();
|
|
15565
|
+
const sibling = path.join(path.dirname(probe), flipped);
|
|
15566
|
+
result = existsSync(sibling);
|
|
15567
|
+
}
|
|
15568
|
+
} catch {}
|
|
15569
|
+
_caseInsensitiveByRoot.set(root, result);
|
|
15570
|
+
return result;
|
|
15571
|
+
}
|
|
15572
|
+
/**
|
|
15573
|
+
* THE canonical identity for a workspace. Every surface that answers "is this
|
|
15574
|
+
* the same workspace?" — the meta sidecar key, the colgrep project-dir lookup,
|
|
15575
|
+
* the watchdog signature, the init/search locks, and the argument handed to
|
|
15576
|
+
* colgrep — must go through this and nothing else.
|
|
15577
|
+
*
|
|
15578
|
+
* They previously disagreed four different ways, and the disagreement is what
|
|
15579
|
+
* made a healthy index invisible: colgrep writes `\\?\Q:\...`, the lookup
|
|
15580
|
+
* normalized it to `//?/q:/...`, and nothing ever matched.
|
|
15581
|
+
*
|
|
15582
|
+
* Order matters: realpath FIRST (it resolves symlinks — the macOS
|
|
15583
|
+
* `/var`→`/private/var` and `/tmp`→`/private/tmp` shapes — expands 8.3 short
|
|
15584
|
+
* names, and returns the true on-disk casing), THEN strip any extended-length
|
|
15585
|
+
* prefix from the *result*. `realpathSync.native` was measured to already
|
|
15586
|
+
* return a clean `Q:\Software\github-router` for all input spellings, so the
|
|
15587
|
+
* strip is belt-and-braces rather than load-bearing; it costs nothing and
|
|
15588
|
+
* covers the fallback path where realpath could not run at all.
|
|
15589
|
+
*/
|
|
15590
|
+
function canonicalWorkspace(p) {
|
|
15591
|
+
let out = stripExtendedPrefix(p);
|
|
15389
15592
|
try {
|
|
15390
|
-
|
|
15593
|
+
out = stripExtendedPrefix(realpathSync.native(out));
|
|
15594
|
+
} catch {
|
|
15595
|
+
out = resolveThroughExistingAncestor(out);
|
|
15596
|
+
}
|
|
15597
|
+
out = path.resolve(out);
|
|
15598
|
+
if (volumeIsCaseInsensitive(out)) out = out.toLowerCase();
|
|
15599
|
+
return process$1.platform === "win32" ? out.replaceAll("\\", "/") : out;
|
|
15600
|
+
}
|
|
15601
|
+
/**
|
|
15602
|
+
* Realpath as much of `p` as exists, then re-append the missing tail. Keeps a
|
|
15603
|
+
* not-yet-created or just-deleted path on the same canonical root as its live
|
|
15604
|
+
* self.
|
|
15605
|
+
*/
|
|
15606
|
+
function resolveThroughExistingAncestor(p) {
|
|
15607
|
+
const abs = path.resolve(p);
|
|
15608
|
+
const tail = [];
|
|
15609
|
+
let cur = abs;
|
|
15610
|
+
for (let i = 0; i < 64; i++) try {
|
|
15611
|
+
const real = stripExtendedPrefix(realpathSync.native(cur));
|
|
15612
|
+
return tail.length > 0 ? path.join(real, ...tail.reverse()) : real;
|
|
15391
15613
|
} catch {
|
|
15392
|
-
|
|
15614
|
+
const parent = path.dirname(cur);
|
|
15615
|
+
if (parent === cur) break;
|
|
15616
|
+
tail.push(path.basename(cur));
|
|
15617
|
+
cur = parent;
|
|
15393
15618
|
}
|
|
15619
|
+
return abs;
|
|
15620
|
+
}
|
|
15621
|
+
function canonicalForCompare(p) {
|
|
15622
|
+
return canonicalWorkspace(p);
|
|
15623
|
+
}
|
|
15624
|
+
/** Sync realpath-aware canonicalization. Retained as a named alias so call
|
|
15625
|
+
* sites read intentionally; `canonicalWorkspace` already realpaths. */
|
|
15626
|
+
function canonicalRealpathSync(p) {
|
|
15627
|
+
return canonicalWorkspace(p);
|
|
15394
15628
|
}
|
|
15395
15629
|
/** Recursive (bytes, fileCount) of a directory; sync + best-effort. A
|
|
15396
15630
|
* colgrep index is a bounded set of shards so the walk stays small. */
|
|
@@ -15416,23 +15650,13 @@ function dirSizeSync(dir) {
|
|
|
15416
15650
|
}
|
|
15417
15651
|
return [bytes, count];
|
|
15418
15652
|
}
|
|
15419
|
-
/**
|
|
15420
|
-
* (sync) Progress signature of a workspace's colgrep index dir for the init
|
|
15421
|
-
* inactivity watchdog: `${totalBytes}:${fileCount}` of the project dir, or
|
|
15422
|
-
* `null` if it isn't on disk yet. colgrep is SILENT on a non-TTY pipe
|
|
15423
|
-
* during the (potentially multi-hour) encode phase, so output is useless as
|
|
15424
|
-
* a progress signal — but it writes index shards incrementally, so a
|
|
15425
|
-
* changing signature means "still progressing" and a frozen one means
|
|
15426
|
-
* "hung". Successive signatures drive the watchdog: change ⇒ re-arm, frozen
|
|
15427
|
-
* ⇒ kill. Sync because it's called from a `setTimeout` (not awaited).
|
|
15428
|
-
*/
|
|
15429
15653
|
function indexDirSignature(workspace) {
|
|
15430
15654
|
const indicesDir = PATHS.COLBERT_INDICES_DIR;
|
|
15431
15655
|
let names;
|
|
15432
15656
|
try {
|
|
15433
15657
|
names = readdirSync(indicesDir);
|
|
15434
15658
|
} catch {
|
|
15435
|
-
return
|
|
15659
|
+
return { kind: "unknown" };
|
|
15436
15660
|
}
|
|
15437
15661
|
const want = canonicalRealpathSync(workspace);
|
|
15438
15662
|
for (const name of names) {
|
|
@@ -15447,10 +15671,14 @@ function indexDirSignature(workspace) {
|
|
|
15447
15671
|
}
|
|
15448
15672
|
const projPath = proj.path ?? proj.project_path;
|
|
15449
15673
|
if (!projPath || canonicalRealpathSync(projPath) !== want) continue;
|
|
15674
|
+
if (proj.model !== canonicalColbertModelDir()) continue;
|
|
15450
15675
|
const [bytes, count] = dirSizeSync(dir);
|
|
15451
|
-
return
|
|
15676
|
+
return {
|
|
15677
|
+
kind: "observed",
|
|
15678
|
+
signature: `${bytes}:${count}`
|
|
15679
|
+
};
|
|
15452
15680
|
}
|
|
15453
|
-
return
|
|
15681
|
+
return { kind: "not-created" };
|
|
15454
15682
|
}
|
|
15455
15683
|
/**
|
|
15456
15684
|
* Realpath-aware canonicalization for matching a workspace against
|
|
@@ -15460,11 +15688,7 @@ function indexDirSignature(workspace) {
|
|
|
15460
15688
|
* when realpath fails (path doesn't exist yet).
|
|
15461
15689
|
*/
|
|
15462
15690
|
async function realpathForCompare(p) {
|
|
15463
|
-
|
|
15464
|
-
return canonicalForCompare(await fs$1.realpath(p));
|
|
15465
|
-
} catch {
|
|
15466
|
-
return canonicalForCompare(p);
|
|
15467
|
-
}
|
|
15691
|
+
return canonicalWorkspace(p);
|
|
15468
15692
|
}
|
|
15469
15693
|
/**
|
|
15470
15694
|
* Compute the freshness verdict for a query against a workspace.
|
|
@@ -15680,18 +15904,13 @@ function envIntMs(name, fallback) {
|
|
|
15680
15904
|
*/
|
|
15681
15905
|
function makeIndexProgressProbe(workspace) {
|
|
15682
15906
|
let lastSig;
|
|
15683
|
-
let nullStreak = 0;
|
|
15684
15907
|
return () => {
|
|
15685
|
-
const
|
|
15686
|
-
if (
|
|
15687
|
-
nullStreak += 1;
|
|
15688
|
-
return nullStreak <= 1;
|
|
15689
|
-
}
|
|
15690
|
-
nullStreak = 0;
|
|
15908
|
+
const p = indexDirSignature(workspace);
|
|
15909
|
+
if (p.kind !== "observed") return true;
|
|
15691
15910
|
const prev = lastSig;
|
|
15692
|
-
lastSig =
|
|
15911
|
+
lastSig = p.signature;
|
|
15693
15912
|
if (prev === void 0) return true;
|
|
15694
|
-
return
|
|
15913
|
+
return p.signature !== prev;
|
|
15695
15914
|
};
|
|
15696
15915
|
}
|
|
15697
15916
|
/** Workspaces with a DETACHED indexing search in flight. A new search for
|
|
@@ -15742,10 +15961,18 @@ async function runSemanticSearch(opts) {
|
|
|
15742
15961
|
case "failed": return handleFailure(workspace, fresh.meta, false);
|
|
15743
15962
|
case "crashed": return handleFailure(workspace, fresh.meta, true);
|
|
15744
15963
|
case "corrupt": return repairCorruptIndex(workspace, fresh.meta);
|
|
15745
|
-
case "building":
|
|
15746
|
-
|
|
15747
|
-
|
|
15748
|
-
|
|
15964
|
+
case "building":
|
|
15965
|
+
if (!isInitInFlight(workspace) && !await completedIndexOnDisk(workspace)) {
|
|
15966
|
+
kickBackgroundInit(workspace);
|
|
15967
|
+
return {
|
|
15968
|
+
status: "building",
|
|
15969
|
+
notice: "semantic index build was interrupted; a rebuild was started — retry shortly (or use code_search now)"
|
|
15970
|
+
};
|
|
15971
|
+
}
|
|
15972
|
+
return {
|
|
15973
|
+
status: "building",
|
|
15974
|
+
notice: "semantic index is being built for this workspace; retry shortly (or use code_search now)"
|
|
15975
|
+
};
|
|
15749
15976
|
case "stale":
|
|
15750
15977
|
kickBackgroundInit(workspace);
|
|
15751
15978
|
return {
|
|
@@ -15804,6 +16031,13 @@ async function repairCorruptIndex(workspace, meta) {
|
|
|
15804
16031
|
status: "failed",
|
|
15805
16032
|
failureClass: "corrupt",
|
|
15806
16033
|
failedAttempts: attempts,
|
|
16034
|
+
failedAt: {
|
|
16035
|
+
head: meta?.lastIndexedHead,
|
|
16036
|
+
dirty: meta?.lastIndexedDirty,
|
|
16037
|
+
binarySha: colgrepBinAsset()?.sha256,
|
|
16038
|
+
ortSha: ortLibAsset()?.sha256,
|
|
16039
|
+
modelRev: MODEL_REVISION
|
|
16040
|
+
},
|
|
15807
16041
|
lastIndexedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
15808
16042
|
lastIndexedHead: meta?.lastIndexedHead,
|
|
15809
16043
|
lastIndexedDirty: meta?.lastIndexedDirty,
|
|
@@ -15814,7 +16048,14 @@ async function repairCorruptIndex(workspace, meta) {
|
|
|
15814
16048
|
notice: "semantic index was found corrupt but a writer is still active; returned results are disabled until it exits"
|
|
15815
16049
|
};
|
|
15816
16050
|
const projectDir = await colbertProjectDir(workspace);
|
|
15817
|
-
if (!projectDir)
|
|
16051
|
+
if (!projectDir) {
|
|
16052
|
+
kickBackgroundInit(workspace);
|
|
16053
|
+
return {
|
|
16054
|
+
status: "unavailable",
|
|
16055
|
+
isError: true,
|
|
16056
|
+
notice: "no semantic index for this workspace yet — a background index was started; retry shortly or use code_search"
|
|
16057
|
+
};
|
|
16058
|
+
}
|
|
15818
16059
|
if (!await quarantineProjectDir(projectDir)) {
|
|
15819
16060
|
await writeColbertMeta(failedMeta).catch(() => {});
|
|
15820
16061
|
return {
|
|
@@ -15831,10 +16072,69 @@ async function repairCorruptIndex(workspace, meta) {
|
|
|
15831
16072
|
notice: attempts < 2 ? "semantic index was found corrupt and quarantined; a clean rebuild was started — retry mode:\"semantic\" shortly" : "semantic index repeatedly failed integrity checks; automatic rebuild is capped — do NOT retry mode:\"semantic\", use lexical search with specific symbol/keyword terms and see proxy logs"
|
|
15832
16073
|
};
|
|
15833
16074
|
}
|
|
16075
|
+
/**
|
|
16076
|
+
* True when the inputs that produced the recorded failure streak differ from
|
|
16077
|
+
* the inputs in effect now — i.e. the streak is stale evidence and must not
|
|
16078
|
+
* veto a fresh attempt.
|
|
16079
|
+
*
|
|
16080
|
+
* Each signal answers "could this plausibly have fixed the cause?":
|
|
16081
|
+
* - engine/runtime sha: a colgrep or ONNX-runtime upgrade may fix the exact
|
|
16082
|
+
* bug that failed. Precedent: `freshnessVerdict` already forces a rebuild
|
|
16083
|
+
* on an engine-sha change for the same reason.
|
|
16084
|
+
* - model revision: a different embedding model is a different build.
|
|
16085
|
+
* - corpus identity: HEAD moved OR the working tree's dirty-state changed.
|
|
16086
|
+
* BOTH are needed — HEAD-only misses the most common local recovery
|
|
16087
|
+
* (fixing a malformed file without committing), and dirty-only misses a
|
|
16088
|
+
* branch switch.
|
|
16089
|
+
*
|
|
16090
|
+
* A legacy entry with no `failedAt` (written before this field existed) has no
|
|
16091
|
+
* baseline to compare, so it does NOT reset — it keeps today's behavior until
|
|
16092
|
+
* its next failure stamps one. That is the conservative direction: a missing
|
|
16093
|
+
* baseline must not read as "everything changed".
|
|
16094
|
+
*/
|
|
16095
|
+
function failureInputsChanged(meta, git) {
|
|
16096
|
+
const at = meta?.failedAt;
|
|
16097
|
+
if (!at) return false;
|
|
16098
|
+
const binarySha = colgrepBinAsset()?.sha256;
|
|
16099
|
+
const ortSha = ortLibAsset()?.sha256;
|
|
16100
|
+
if (at.binarySha !== void 0 && binarySha !== void 0 && at.binarySha !== binarySha) return true;
|
|
16101
|
+
if (at.ortSha !== void 0 && ortSha !== void 0 && at.ortSha !== ortSha) return true;
|
|
16102
|
+
if (at.modelRev !== void 0 && at.modelRev !== "07ef20f406c86badca122464808f4cac2f6e4b25") return true;
|
|
16103
|
+
if (at.head !== void 0 && git.head !== void 0 && at.head !== git.head) return true;
|
|
16104
|
+
if (at.dirty !== void 0 && git.dirty !== void 0 && at.dirty !== git.dirty) return true;
|
|
16105
|
+
return false;
|
|
16106
|
+
}
|
|
15834
16107
|
async function handleFailure(workspace, meta, crashedVerdict) {
|
|
15835
16108
|
const cls = crashedVerdict ? "crashed" : meta?.failureClass ?? "error";
|
|
15836
|
-
const attempts = crashedVerdict ? (meta?.failedAttempts ?? 0) + 1 : meta?.failedAttempts ?? 1;
|
|
15837
16109
|
const lastAt = meta?.lastIndexedAt;
|
|
16110
|
+
const lastMs = lastAt ? Date.parse(lastAt) : NaN;
|
|
16111
|
+
const backoffElapsed = !Number.isFinite(lastMs) || Date.now() - lastMs >= FAILED_RETRY_BACKOFF_MS;
|
|
16112
|
+
const at = meta?.failedAt;
|
|
16113
|
+
if (failureInputsChanged(meta, at?.head !== void 0 || at?.dirty !== void 0 ? await gitState(workspace).catch(() => ({})) : {})) {
|
|
16114
|
+
consola.warn(`colbert: index inputs changed since the last failure (class=${cls}); clearing the failure streak${backoffElapsed ? " and retrying" : ""} for ${workspace}`);
|
|
16115
|
+
await writeColbertMeta({
|
|
16116
|
+
workspace,
|
|
16117
|
+
model: meta?.model ?? "LateOn-Code-edge",
|
|
16118
|
+
modelRev: meta?.modelRev ?? "07ef20f406c86badca122464808f4cac2f6e4b25",
|
|
16119
|
+
binarySha: meta?.binarySha,
|
|
16120
|
+
ortSha: meta?.ortSha,
|
|
16121
|
+
status: "failed",
|
|
16122
|
+
failureClass: meta?.failureClass,
|
|
16123
|
+
failedAttempts: 0,
|
|
16124
|
+
failedAt: void 0,
|
|
16125
|
+
lastIndexedAt: meta?.lastIndexedAt,
|
|
16126
|
+
lastIndexedHead: meta?.lastIndexedHead,
|
|
16127
|
+
lastIndexedDirty: meta?.lastIndexedDirty,
|
|
16128
|
+
ownerInstanceId: getColbertInstanceUuid()
|
|
16129
|
+
}).catch(() => {});
|
|
16130
|
+
if (backoffElapsed) kickBackgroundInit(workspace);
|
|
16131
|
+
return {
|
|
16132
|
+
status: "failed",
|
|
16133
|
+
isError: true,
|
|
16134
|
+
notice: backoffElapsed ? "semantic index unavailable; inputs changed since the last failure so a rebuild was started — retry mode:\"semantic\" shortly, or use code_search with specific symbol/keyword terms now" : "semantic index unavailable (recent build failure); a rebuild is pending — retry mode:\"semantic\" shortly, or use code_search with specific symbol/keyword terms now"
|
|
16135
|
+
};
|
|
16136
|
+
}
|
|
16137
|
+
const attempts = crashedVerdict ? (meta?.failedAttempts ?? 0) + 1 : meta?.failedAttempts ?? 1;
|
|
15838
16138
|
if (crashedVerdict) await writeColbertMeta({
|
|
15839
16139
|
workspace,
|
|
15840
16140
|
model: meta?.model ?? "LateOn-Code-edge",
|
|
@@ -15842,14 +16142,19 @@ async function handleFailure(workspace, meta, crashedVerdict) {
|
|
|
15842
16142
|
status: "failed",
|
|
15843
16143
|
failureClass: "crashed",
|
|
15844
16144
|
failedAttempts: attempts,
|
|
16145
|
+
failedAt: {
|
|
16146
|
+
head: meta?.lastIndexedHead,
|
|
16147
|
+
dirty: meta?.lastIndexedDirty,
|
|
16148
|
+
binarySha: meta?.binarySha ?? colgrepBinAsset()?.sha256,
|
|
16149
|
+
ortSha: meta?.ortSha ?? ortLibAsset()?.sha256,
|
|
16150
|
+
modelRev: MODEL_REVISION
|
|
16151
|
+
},
|
|
15845
16152
|
lastIndexedAt: lastAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
15846
16153
|
lastIndexedHead: meta?.lastIndexedHead,
|
|
15847
16154
|
lastIndexedDirty: meta?.lastIndexedDirty,
|
|
15848
16155
|
ownerInstanceId: getColbertInstanceUuid()
|
|
15849
16156
|
}).catch(() => {});
|
|
15850
16157
|
const cap = cls === "stuck" || cls === "corrupt" ? 2 : MAX_FAILED_ATTEMPTS;
|
|
15851
|
-
const lastMs = lastAt ? Date.parse(lastAt) : NaN;
|
|
15852
|
-
const backoffElapsed = !Number.isFinite(lastMs) || Date.now() - lastMs >= FAILED_RETRY_BACKOFF_MS;
|
|
15853
16158
|
if (attempts < cap && backoffElapsed) {
|
|
15854
16159
|
kickBackgroundInit(workspace);
|
|
15855
16160
|
consola.debug(`colbert: re-kicking index (class=${cls}, attempt=${attempts}/${cap})`);
|
|
@@ -15864,11 +16169,11 @@ async function handleFailure(workspace, meta, crashedVerdict) {
|
|
|
15864
16169
|
isError: true,
|
|
15865
16170
|
notice: "semantic index unavailable (recent build failure); retry mode:\"semantic\" shortly, or use code_search with specific symbol/keyword terms now"
|
|
15866
16171
|
};
|
|
15867
|
-
consola.
|
|
16172
|
+
consola.warn(`colbert: index ${cls}, giving up (attempts=${attempts}) for ${workspace}`);
|
|
15868
16173
|
return {
|
|
15869
16174
|
status: "failed",
|
|
15870
16175
|
isError: true,
|
|
15871
|
-
notice: `semantic index
|
|
16176
|
+
notice: `semantic index unavailable (${cls}); use code_search with specific symbol/keyword terms`
|
|
15872
16177
|
};
|
|
15873
16178
|
}
|
|
15874
16179
|
async function spawnSearch(opts) {
|
|
@@ -16070,6 +16375,10 @@ function kickBackgroundInit(workspace) {
|
|
|
16070
16375
|
releaseInit(workspace);
|
|
16071
16376
|
consola.error("colbert: background init failed:", err);
|
|
16072
16377
|
const prior = await readColbertMeta(workspace);
|
|
16378
|
+
const g = await gitState(workspace).catch(() => ({
|
|
16379
|
+
head: void 0,
|
|
16380
|
+
dirty: void 0
|
|
16381
|
+
}));
|
|
16073
16382
|
await writeColbertMeta({
|
|
16074
16383
|
workspace,
|
|
16075
16384
|
model: prior?.model ?? "LateOn-Code-edge",
|
|
@@ -16079,6 +16388,13 @@ function kickBackgroundInit(workspace) {
|
|
|
16079
16388
|
status: "failed",
|
|
16080
16389
|
failureClass: "launch",
|
|
16081
16390
|
failedAttempts: (prior?.failedAttempts ?? 0) + 1,
|
|
16391
|
+
failedAt: {
|
|
16392
|
+
head: g.head,
|
|
16393
|
+
dirty: g.dirty,
|
|
16394
|
+
binarySha: colgrepBinAsset()?.sha256,
|
|
16395
|
+
ortSha: ortLibAsset()?.sha256,
|
|
16396
|
+
modelRev: MODEL_REVISION
|
|
16397
|
+
},
|
|
16082
16398
|
lastIndexedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
16083
16399
|
lastIndexedHead: prior?.lastIndexedHead,
|
|
16084
16400
|
lastIndexedDirty: prior?.lastIndexedDirty,
|
|
@@ -16172,7 +16488,8 @@ async function runInit(workspace) {
|
|
|
16172
16488
|
buildPid: void 0,
|
|
16173
16489
|
ownerInstanceId: getColbertInstanceUuid(),
|
|
16174
16490
|
lastIndexedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
16175
|
-
failedAttempts: prior?.failedAttempts ?? 0
|
|
16491
|
+
failedAttempts: prior?.failedAttempts ?? 0,
|
|
16492
|
+
failedAt: prior?.failedAt
|
|
16176
16493
|
};
|
|
16177
16494
|
try {
|
|
16178
16495
|
const g = await gitState(workspace);
|
|
@@ -16244,10 +16561,18 @@ async function runInit(workspace) {
|
|
|
16244
16561
|
if (ok) {
|
|
16245
16562
|
finalMeta.failedAttempts = 0;
|
|
16246
16563
|
finalMeta.failureClass = void 0;
|
|
16564
|
+
finalMeta.failedAt = void 0;
|
|
16247
16565
|
} else {
|
|
16248
16566
|
finalMeta.failureClass = failureClass;
|
|
16249
16567
|
finalMeta.failedAttempts = (prior?.failedAttempts ?? 0) + 1;
|
|
16250
|
-
|
|
16568
|
+
finalMeta.failedAt = {
|
|
16569
|
+
head: finalMeta.lastIndexedHead,
|
|
16570
|
+
dirty: finalMeta.lastIndexedDirty,
|
|
16571
|
+
binarySha: finalMeta.binarySha,
|
|
16572
|
+
ortSha: finalMeta.ortSha,
|
|
16573
|
+
modelRev: finalMeta.modelRev
|
|
16574
|
+
};
|
|
16575
|
+
consola.warn(`colbert: init ${failureClass} after ${Math.round(elapsedMs / 1e3)}s (attempt ${finalMeta.failedAttempts}) for ${workspace}`);
|
|
16251
16576
|
}
|
|
16252
16577
|
await writeColbertMeta(finalMeta).catch(() => {});
|
|
16253
16578
|
}
|
|
@@ -16324,6 +16649,36 @@ async function provisionAndIndexColbert(opts = {}) {
|
|
|
16324
16649
|
consola.debug("colbert: cwd git-detect skipped:", err);
|
|
16325
16650
|
}
|
|
16326
16651
|
}
|
|
16652
|
+
/**
|
|
16653
|
+
* One-line operator warning when this workspace's semantic index is sitting in
|
|
16654
|
+
* a terminal `failed` state, or `null` when there is nothing to say.
|
|
16655
|
+
*
|
|
16656
|
+
* This exists because the failure mode that motivated it was SILENCE: semantic
|
|
16657
|
+
* search degraded to lexical on a real repo for an unknown period — possibly
|
|
16658
|
+
* weeks — and nobody noticed, because the only signals were a `notice` string
|
|
16659
|
+
* the model reads and a `consola.debug` the file logger drops. Neither reaches
|
|
16660
|
+
* a human. The launcher writes this to stderr next to the readiness line so a
|
|
16661
|
+
* degraded capability is visible at the moment the user starts a session.
|
|
16662
|
+
*
|
|
16663
|
+
* `logsToFile` says where the failure detail actually went. `claude` and
|
|
16664
|
+
* `codex` call `enableFileLogging()`, which redirects warnings to
|
|
16665
|
+
* ERROR_LOG_PATH; `start` does not, so its warnings stay on the terminal and
|
|
16666
|
+
* pointing at the file would send the operator to a stale or absent one.
|
|
16667
|
+
*
|
|
16668
|
+
* Deliberately advisory and best-effort: lexical search still works, so this
|
|
16669
|
+
* must never block or fail a launch.
|
|
16670
|
+
*/
|
|
16671
|
+
async function colbertDegradedWarning(cwd, opts = {}) {
|
|
16672
|
+
if (!semanticSearchOptedIn()) return null;
|
|
16673
|
+
try {
|
|
16674
|
+
const meta = await readColbertMeta(cwd ?? process$1.cwd());
|
|
16675
|
+
if (!meta || meta.status !== "failed") return null;
|
|
16676
|
+
const cls = meta.failureClass ?? "error";
|
|
16677
|
+
return `Semantic search DEGRADED for this workspace (colbert: ${cls}) — lexical code search still works. ${opts.logsToFile ? `See ${PATHS.ERROR_LOG_PATH}` : "See the proxy log output"}.${cls === "stuck" ? " For a very large repo, raise GH_ROUTER_COLBERT_INIT_STALL_MS / GH_ROUTER_COLBERT_INIT_TIMEOUT_MS." : ""}`;
|
|
16678
|
+
} catch {
|
|
16679
|
+
return null;
|
|
16680
|
+
}
|
|
16681
|
+
}
|
|
16327
16682
|
//#endregion
|
|
16328
16683
|
//#region src/lib/unified-code-search.ts
|
|
16329
16684
|
/**
|
|
@@ -18005,7 +18360,7 @@ function logAudit$1(record) {
|
|
|
18005
18360
|
try {
|
|
18006
18361
|
const fs = await import("node:fs/promises");
|
|
18007
18362
|
const path = await import("node:path");
|
|
18008
|
-
const { PATHS } = await import("./paths-
|
|
18363
|
+
const { PATHS } = await import("./paths-Dz1WyRJG.js");
|
|
18009
18364
|
const dir = path.join(PATHS.APP_DIR, "browser-mcp");
|
|
18010
18365
|
await fs.mkdir(dir, { recursive: true });
|
|
18011
18366
|
const line = JSON.stringify({
|
|
@@ -33788,6 +34143,6 @@ function enumerateInjectedMcpToolNames(groupKeys, opts = {}) {
|
|
|
33788
34143
|
return [...new Set(names)];
|
|
33789
34144
|
}
|
|
33790
34145
|
//#endregion
|
|
33791
|
-
export { reviewerModel as $, searchWeb as A,
|
|
34146
|
+
export { reviewerModel as $, searchWeb as A, DEFAULT_CODEX_MODEL_FALLBACKS as At, readIteratorWithTimeout as B, buildToolbeltAwareness as C, CONDENSED_OPERATING_SEQUENCE as Ct, TOOLBELT_TOOLS$1 as D, toolbeltPathOverride as Dt, vscodeRipgrepPath as E, collapsePathKeys as Et, isAdvisorRequested as F, pickClaudeDefault as Ft, artifactToolsEnabled as G, handleMcpDelete as H, buildAnthropicErrorEvent as I, withOneMSuffix as It, browserCompoundToolsEnabled as J, brainstormModel as K, buildOpenAIErrorEvent as L, withInstallLock as Lt, ADVISOR_TOOL_INSTRUCTIONS as M, UPSTREAM_FETCH_TIMEOUT_MS as Mt, buildAdvisorStream as N, UPSTREAM_INACTIVITY_TIMEOUT_MS as Nt, assetFor as O, DEFAULT_CLAUDE_MODEL_FALLBACKS as Ot, injectAdvisorTool as P, generateRandomPort as Pt, nativeSubagentModel as Q, isControllerClosedError as R, availableToolCommands as S, warmTreeSitterPool as St, toolbeltSkipSet as T, shouldUseInsecureTls as Tt, handleMcpPost as U, relayAnthropicStream as V, agentToolsEnabled as W, fleetToolsEnabled as X, browserToolsEnabled as Y, geminiAvailable as Z, appendPlanReminder as _, hasSupportedBrowserInstalled as _t, buildPeerAwarenessSnippet as a, countTokens as at, runWorkerAgent as b, extractTarGzMember as bt, personasFor as c, assembleResponsesPayload as ct, EXPLORE_DEFAULT_MODEL as d, createResponses as dt, scoutModel as et, EXPLORE_DEFAULT_THINKING as f, createChatCompletions as ft, TEST_DEFAULT_MODEL as g, provisionBrowserAssets as gt, REVIEW_DEFAULT_MODEL as h, parseJsonOrDiagnose as ht, buildAgentPrompt as i, shimDefaultsToXhigh as it, ADVISOR_INTERNAL_TOOL_NAME as j, DEFAULT_PORT as jt, satisfiesMinVersion as k, DEFAULT_CODEX_MODEL as kt, BROWSE_DEFAULT_MODEL as l, resolveMcpToolTimeoutMs as lt, PLAN_DEFAULT_MODEL as m, readResponseBodyCapped as mt, MCP_GROUPS as n, standInToolEnabled as nt, buildPeerAwarenessSummary as o, createMessages as ot, IMPLEMENT_DEFAULT_MODEL as p, MAX_RESPONSE_BODY_BYTES as pt, browseAgentEnabled as q, assertMcpToolSurfaceConsistent as r, workerToolsEnabled as rt, enumerateInjectedMcpToolNames as s, getTokenCount as st, GROUP_META as t, scribeModel as tt, DEFAULT_MODEL as u, pickEndpoint as ut, resolveModeDefaults as v, colbertDegradedWarning as vt, toolbeltEnabled as w, DEFINITION_OF_GREATNESS as wt, buildEnv as x, extractZipMember as xt, resolveWorkerRunOpts as y, provisionAndIndexColbert as yt, logStreamError as z };
|
|
33792
34147
|
|
|
33793
|
-
//# sourceMappingURL=peer-mcp-personas-
|
|
34148
|
+
//# sourceMappingURL=peer-mcp-personas-V4AXhm9B.js.map
|