@gluecharm-lab/easyspecs-cli 0.2.1 → 0.3.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/commands.md +1 -1
- package/dist/main.cjs +379 -292
- package/dist/main.cjs.map +4 -4
- package/error-code.md +1 -1
- package/package.json +1 -1
package/dist/main.cjs
CHANGED
|
@@ -959,7 +959,7 @@ var require_command = __commonJS({
|
|
|
959
959
|
"node_modules/commander/lib/command.js"(exports2) {
|
|
960
960
|
var EventEmitter = require("node:events").EventEmitter;
|
|
961
961
|
var childProcess = require("node:child_process");
|
|
962
|
-
var
|
|
962
|
+
var path62 = require("node:path");
|
|
963
963
|
var fs64 = require("node:fs");
|
|
964
964
|
var process2 = require("node:process");
|
|
965
965
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
@@ -1892,9 +1892,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1892
1892
|
let launchWithNode = false;
|
|
1893
1893
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
1894
1894
|
function findFile(baseDir, baseName) {
|
|
1895
|
-
const localBin =
|
|
1895
|
+
const localBin = path62.resolve(baseDir, baseName);
|
|
1896
1896
|
if (fs64.existsSync(localBin)) return localBin;
|
|
1897
|
-
if (sourceExt.includes(
|
|
1897
|
+
if (sourceExt.includes(path62.extname(baseName))) return void 0;
|
|
1898
1898
|
const foundExt = sourceExt.find(
|
|
1899
1899
|
(ext) => fs64.existsSync(`${localBin}${ext}`)
|
|
1900
1900
|
);
|
|
@@ -1912,17 +1912,17 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1912
1912
|
} catch (err) {
|
|
1913
1913
|
resolvedScriptPath = this._scriptPath;
|
|
1914
1914
|
}
|
|
1915
|
-
executableDir =
|
|
1916
|
-
|
|
1915
|
+
executableDir = path62.resolve(
|
|
1916
|
+
path62.dirname(resolvedScriptPath),
|
|
1917
1917
|
executableDir
|
|
1918
1918
|
);
|
|
1919
1919
|
}
|
|
1920
1920
|
if (executableDir) {
|
|
1921
1921
|
let localFile = findFile(executableDir, executableFile);
|
|
1922
1922
|
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
|
1923
|
-
const legacyName =
|
|
1923
|
+
const legacyName = path62.basename(
|
|
1924
1924
|
this._scriptPath,
|
|
1925
|
-
|
|
1925
|
+
path62.extname(this._scriptPath)
|
|
1926
1926
|
);
|
|
1927
1927
|
if (legacyName !== this._name) {
|
|
1928
1928
|
localFile = findFile(
|
|
@@ -1933,7 +1933,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1933
1933
|
}
|
|
1934
1934
|
executableFile = localFile || executableFile;
|
|
1935
1935
|
}
|
|
1936
|
-
launchWithNode = sourceExt.includes(
|
|
1936
|
+
launchWithNode = sourceExt.includes(path62.extname(executableFile));
|
|
1937
1937
|
let proc;
|
|
1938
1938
|
if (process2.platform !== "win32") {
|
|
1939
1939
|
if (launchWithNode) {
|
|
@@ -2773,7 +2773,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2773
2773
|
* @return {Command}
|
|
2774
2774
|
*/
|
|
2775
2775
|
nameFromFilename(filename) {
|
|
2776
|
-
this._name =
|
|
2776
|
+
this._name = path62.basename(filename, path62.extname(filename));
|
|
2777
2777
|
return this;
|
|
2778
2778
|
}
|
|
2779
2779
|
/**
|
|
@@ -2787,9 +2787,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2787
2787
|
* @param {string} [path]
|
|
2788
2788
|
* @return {(string|null|Command)}
|
|
2789
2789
|
*/
|
|
2790
|
-
executableDir(
|
|
2791
|
-
if (
|
|
2792
|
-
this._executableDir =
|
|
2790
|
+
executableDir(path63) {
|
|
2791
|
+
if (path63 === void 0) return this._executableDir;
|
|
2792
|
+
this._executableDir = path63;
|
|
2793
2793
|
return this;
|
|
2794
2794
|
}
|
|
2795
2795
|
/**
|
|
@@ -5244,8 +5244,8 @@ var require_resolve = __commonJS({
|
|
|
5244
5244
|
}
|
|
5245
5245
|
return count;
|
|
5246
5246
|
}
|
|
5247
|
-
function getFullPath(resolver, id = "",
|
|
5248
|
-
if (
|
|
5247
|
+
function getFullPath(resolver, id = "", normalize9) {
|
|
5248
|
+
if (normalize9 !== false)
|
|
5249
5249
|
id = normalizeId(id);
|
|
5250
5250
|
const p = resolver.parse(id);
|
|
5251
5251
|
return _getFullPath(resolver, p);
|
|
@@ -5993,7 +5993,7 @@ var require_compile = __commonJS({
|
|
|
5993
5993
|
const schOrFunc = root.refs[ref];
|
|
5994
5994
|
if (schOrFunc)
|
|
5995
5995
|
return schOrFunc;
|
|
5996
|
-
let _sch =
|
|
5996
|
+
let _sch = resolve24.call(this, root, ref);
|
|
5997
5997
|
if (_sch === void 0) {
|
|
5998
5998
|
const schema = (_a = root.localRefs) === null || _a === void 0 ? void 0 : _a[ref];
|
|
5999
5999
|
const { schemaId } = this.opts;
|
|
@@ -6020,7 +6020,7 @@ var require_compile = __commonJS({
|
|
|
6020
6020
|
function sameSchemaEnv(s1, s2) {
|
|
6021
6021
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
6022
6022
|
}
|
|
6023
|
-
function
|
|
6023
|
+
function resolve24(root, ref) {
|
|
6024
6024
|
let sch;
|
|
6025
6025
|
while (typeof (sch = this.refs[ref]) == "string")
|
|
6026
6026
|
ref = sch;
|
|
@@ -6235,8 +6235,8 @@ var require_utils = __commonJS({
|
|
|
6235
6235
|
}
|
|
6236
6236
|
return ind;
|
|
6237
6237
|
}
|
|
6238
|
-
function removeDotSegments(
|
|
6239
|
-
let input =
|
|
6238
|
+
function removeDotSegments(path62) {
|
|
6239
|
+
let input = path62;
|
|
6240
6240
|
const output = [];
|
|
6241
6241
|
let nextSlash = -1;
|
|
6242
6242
|
let len = 0;
|
|
@@ -6435,8 +6435,8 @@ var require_schemes = __commonJS({
|
|
|
6435
6435
|
wsComponent.secure = void 0;
|
|
6436
6436
|
}
|
|
6437
6437
|
if (wsComponent.resourceName) {
|
|
6438
|
-
const [
|
|
6439
|
-
wsComponent.path =
|
|
6438
|
+
const [path62, query] = wsComponent.resourceName.split("?");
|
|
6439
|
+
wsComponent.path = path62 && path62 !== "/" ? path62 : void 0;
|
|
6440
6440
|
wsComponent.query = query;
|
|
6441
6441
|
wsComponent.resourceName = void 0;
|
|
6442
6442
|
}
|
|
@@ -6585,7 +6585,7 @@ var require_fast_uri = __commonJS({
|
|
|
6585
6585
|
"use strict";
|
|
6586
6586
|
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizeComponentEncoding, isIPv4, nonSimpleDomain } = require_utils();
|
|
6587
6587
|
var { SCHEMES, getSchemeHandler } = require_schemes();
|
|
6588
|
-
function
|
|
6588
|
+
function normalize9(uri, options) {
|
|
6589
6589
|
if (typeof uri === "string") {
|
|
6590
6590
|
uri = /** @type {T} */
|
|
6591
6591
|
serialize(parse(uri, options), options);
|
|
@@ -6595,7 +6595,7 @@ var require_fast_uri = __commonJS({
|
|
|
6595
6595
|
}
|
|
6596
6596
|
return uri;
|
|
6597
6597
|
}
|
|
6598
|
-
function
|
|
6598
|
+
function resolve24(baseURI, relativeURI, options) {
|
|
6599
6599
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
6600
6600
|
const resolved = resolveComponent(parse(baseURI, schemelessOptions), parse(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
6601
6601
|
schemelessOptions.skipEscape = true;
|
|
@@ -6821,8 +6821,8 @@ var require_fast_uri = __commonJS({
|
|
|
6821
6821
|
}
|
|
6822
6822
|
var fastUri = {
|
|
6823
6823
|
SCHEMES,
|
|
6824
|
-
normalize:
|
|
6825
|
-
resolve:
|
|
6824
|
+
normalize: normalize9,
|
|
6825
|
+
resolve: resolve24,
|
|
6826
6826
|
resolveComponent,
|
|
6827
6827
|
equal,
|
|
6828
6828
|
serialize,
|
|
@@ -10637,7 +10637,7 @@ var require_dist = __commonJS({
|
|
|
10637
10637
|
|
|
10638
10638
|
// src/cli/main.ts
|
|
10639
10639
|
var fs63 = __toESM(require("node:fs"));
|
|
10640
|
-
var
|
|
10640
|
+
var path61 = __toESM(require("node:path"));
|
|
10641
10641
|
|
|
10642
10642
|
// src/cli/exitCodes.ts
|
|
10643
10643
|
var OsExit = {
|
|
@@ -10778,9 +10778,9 @@ function describeExitCode(code) {
|
|
|
10778
10778
|
case OsExit.readinessOpenCodeCredentials:
|
|
10779
10779
|
return "OpenCode credentials not ready for factory run.";
|
|
10780
10780
|
case OsExit.readinessOpenCodeModel:
|
|
10781
|
-
return "OpenCode default model is not configured \u2014 add
|
|
10781
|
+
return "OpenCode default model is not configured \u2014 add `model` (or equivalent) in repo `opencode.json` / `opencode.jsonc`, global `~/.config/opencode/opencode.json`, `OPENCODE_CONFIG` / `OPENCODE_CONFIG_DIR`, managed config (see OpenCode docs), or `easyspecs.openCodeRuntime.providers`.";
|
|
10782
10782
|
case OsExit.readinessOpenCodeMandatoryConfig:
|
|
10783
|
-
return "
|
|
10783
|
+
return "Readiness gate (d) reserved \u2014 repo-root `opencode.json` is optional when OpenCode is installed, credentials are ready, and a model is configured.";
|
|
10784
10784
|
default:
|
|
10785
10785
|
return `Non-zero exit (${String(code)}) \u2014 see stderr and any JSON \`error\` field for detail.`;
|
|
10786
10786
|
}
|
|
@@ -12687,7 +12687,7 @@ function stringifyForSrs13Debug(value) {
|
|
|
12687
12687
|
return truncateForSrs13DebugLog(String(value));
|
|
12688
12688
|
}
|
|
12689
12689
|
}
|
|
12690
|
-
function logSrs13HttpDebug(log,
|
|
12690
|
+
function logSrs13HttpDebug(log, path62, method, requestBody, error) {
|
|
12691
12691
|
if (!log) {
|
|
12692
12692
|
return;
|
|
12693
12693
|
}
|
|
@@ -12697,7 +12697,7 @@ function logSrs13HttpDebug(log, path61, method, requestBody, error) {
|
|
|
12697
12697
|
} catch {
|
|
12698
12698
|
bodyBytes = 0;
|
|
12699
12699
|
}
|
|
12700
|
-
log(`[pipeline:upload] debug ${method} ${
|
|
12700
|
+
log(`[pipeline:upload] debug ${method} ${path62} \u2014 request body ~${bodyBytes} bytes (JSON below):`);
|
|
12701
12701
|
log(stringifyForSrs13Debug(requestBody));
|
|
12702
12702
|
const raw = httpApiResponseBody(error);
|
|
12703
12703
|
const status = error && typeof error === "object" && "status" in error ? Number(error.status) : void 0;
|
|
@@ -14394,9 +14394,9 @@ function parsePsRssDarwinKilobytes(stdout) {
|
|
|
14394
14394
|
return n;
|
|
14395
14395
|
}
|
|
14396
14396
|
function readLinuxPidRssBytes(pid) {
|
|
14397
|
-
const
|
|
14397
|
+
const path62 = `/proc/${pid}/status`;
|
|
14398
14398
|
try {
|
|
14399
|
-
const content = fs18.readFileSync(
|
|
14399
|
+
const content = fs18.readFileSync(path62, "utf8");
|
|
14400
14400
|
const kb = parseVmRssKilobytesFromProcStatus(content);
|
|
14401
14401
|
if (kb === null) {
|
|
14402
14402
|
return { kind: "unknown", reason: "VmRSS_missing" };
|
|
@@ -14497,7 +14497,16 @@ var PROVIDER_ENV_KEYS = [
|
|
|
14497
14497
|
"OPENAI_API_KEY",
|
|
14498
14498
|
"OPENROUTER_API_KEY",
|
|
14499
14499
|
"GOOGLE_API_KEY",
|
|
14500
|
-
"
|
|
14500
|
+
"GEMINI_API_KEY",
|
|
14501
|
+
"GOOGLE_GENERATIVE_AI_API_KEY",
|
|
14502
|
+
"OPENCODE_API_KEY",
|
|
14503
|
+
"MISTRAL_API_KEY",
|
|
14504
|
+
"GROQ_API_KEY",
|
|
14505
|
+
"COHERE_API_KEY",
|
|
14506
|
+
"XAI_API_KEY",
|
|
14507
|
+
"DEEPSEEK_API_KEY",
|
|
14508
|
+
"AZURE_OPENAI_API_KEY",
|
|
14509
|
+
"AWS_BEARER_TOKEN_BEDROCK"
|
|
14501
14510
|
];
|
|
14502
14511
|
function hasProviderEnvConfigured() {
|
|
14503
14512
|
for (const k of PROVIDER_ENV_KEYS) {
|
|
@@ -14584,9 +14593,9 @@ function runOpenCodeAgent(cwd, args, options) {
|
|
|
14584
14593
|
log?.(`${procTag} command: ${formatCliCommandForLog(cmd, args)}`);
|
|
14585
14594
|
log?.(`${procTag} cwd: ${JSON.stringify(cwd)}`);
|
|
14586
14595
|
log?.(`${procTag} argv: ${JSON.stringify(args)}`);
|
|
14587
|
-
return new Promise((
|
|
14596
|
+
return new Promise((resolve24) => {
|
|
14588
14597
|
if (sig?.aborted) {
|
|
14589
|
-
|
|
14598
|
+
resolve24({ ok: false, message: "Stopped by user.", cancelled: true });
|
|
14590
14599
|
return;
|
|
14591
14600
|
}
|
|
14592
14601
|
const spawnEnv = options?.childEnv && Object.keys(options.childEnv).length > 0 ? { ...process.env, ...options.childEnv } : process.env;
|
|
@@ -14681,7 +14690,7 @@ ${truncateForDiag(outBody, DIAG_STDOUT_MAX)}`);
|
|
|
14681
14690
|
if (diag) {
|
|
14682
14691
|
finishDiag(diag.label, diag.code, diag.dumpStreams);
|
|
14683
14692
|
}
|
|
14684
|
-
|
|
14693
|
+
resolve24(result);
|
|
14685
14694
|
};
|
|
14686
14695
|
let onAbort;
|
|
14687
14696
|
const clearAbortHandler = () => {
|
|
@@ -21405,8 +21414,8 @@ async function drainWorkstationPool(p) {
|
|
|
21405
21414
|
const artefactRunId = readArtefactRunSnapshot(storageContext)?.runId ?? "unknown-run";
|
|
21406
21415
|
let active = 0;
|
|
21407
21416
|
let wake;
|
|
21408
|
-
const waitTurn = () => new Promise((
|
|
21409
|
-
wake =
|
|
21417
|
+
const waitTurn = () => new Promise((resolve24) => {
|
|
21418
|
+
wake = resolve24;
|
|
21410
21419
|
});
|
|
21411
21420
|
const persist = async () => {
|
|
21412
21421
|
const items = {};
|
|
@@ -21767,30 +21776,81 @@ var FACTORY_PIPELINE_EXIT_CONDITIONS = {
|
|
|
21767
21776
|
|
|
21768
21777
|
// src/readiness/factoryReadiness.ts
|
|
21769
21778
|
var fs39 = __toESM(require("node:fs"));
|
|
21779
|
+
var path35 = __toESM(require("node:path"));
|
|
21780
|
+
|
|
21781
|
+
// src/readiness/openCodeConfigCandidates.ts
|
|
21770
21782
|
var os6 = __toESM(require("node:os"));
|
|
21771
21783
|
var path34 = __toESM(require("node:path"));
|
|
21772
|
-
|
|
21773
|
-
var READINESS_OPENCODE_NOT_INSTALLED = "READINESS_OPENCODE_NOT_INSTALLED";
|
|
21774
|
-
var READINESS_OPENCODE_CREDENTIALS = "READINESS_OPENCODE_CREDENTIALS";
|
|
21775
|
-
var READINESS_OPENCODE_MODEL = "READINESS_OPENCODE_MODEL";
|
|
21776
|
-
var READINESS_OPENCODE_MANDATORY_CONFIG = "READINESS_OPENCODE_MANDATORY_CONFIG";
|
|
21777
|
-
function userOpenCodeConfigPath() {
|
|
21784
|
+
function openCodeUserConfigDir() {
|
|
21778
21785
|
if (process.platform === "win32") {
|
|
21779
21786
|
const base = process.env.APPDATA || path34.join(os6.homedir(), "AppData", "Roaming");
|
|
21780
|
-
return path34.join(base, "opencode"
|
|
21787
|
+
return path34.join(base, "opencode");
|
|
21781
21788
|
}
|
|
21782
21789
|
const xdg = process.env.XDG_CONFIG_HOME?.trim();
|
|
21783
21790
|
const cfgRoot = xdg && xdg.length > 0 ? xdg : path34.join(os6.homedir(), ".config");
|
|
21784
|
-
return path34.join(cfgRoot, "opencode"
|
|
21791
|
+
return path34.join(cfgRoot, "opencode");
|
|
21785
21792
|
}
|
|
21786
|
-
function
|
|
21793
|
+
function managedOpenCodeConfigDir() {
|
|
21794
|
+
if (process.platform === "darwin") {
|
|
21795
|
+
return "/Library/Application Support/opencode";
|
|
21796
|
+
}
|
|
21797
|
+
if (process.platform === "linux") {
|
|
21798
|
+
return path34.join("/etc", "opencode");
|
|
21799
|
+
}
|
|
21800
|
+
if (process.platform === "win32") {
|
|
21801
|
+
const pd = process.env.ProgramData?.trim() || "C:\\ProgramData";
|
|
21802
|
+
return path34.join(pd, "opencode");
|
|
21803
|
+
}
|
|
21804
|
+
return void 0;
|
|
21805
|
+
}
|
|
21806
|
+
function pushConfigBasenames(out, dir) {
|
|
21807
|
+
const d = path34.normalize(dir);
|
|
21808
|
+
out.push(path34.join(d, "opencode.json"));
|
|
21809
|
+
out.push(path34.join(d, "opencode.jsonc"));
|
|
21810
|
+
out.push(path34.join(d, "config.json"));
|
|
21811
|
+
}
|
|
21812
|
+
function dedupeStablePaths(paths) {
|
|
21813
|
+
const seen = /* @__PURE__ */ new Set();
|
|
21814
|
+
const out = [];
|
|
21815
|
+
for (const p of paths) {
|
|
21816
|
+
const n = path34.normalize(p.trim());
|
|
21817
|
+
if (n.length === 0 || seen.has(n)) {
|
|
21818
|
+
continue;
|
|
21819
|
+
}
|
|
21820
|
+
seen.add(n);
|
|
21821
|
+
out.push(n);
|
|
21822
|
+
}
|
|
21823
|
+
return out;
|
|
21824
|
+
}
|
|
21825
|
+
function openCodeJsonModelFileCandidates(analysisRootAbs) {
|
|
21787
21826
|
const root = path34.resolve(analysisRootAbs);
|
|
21788
|
-
const
|
|
21789
|
-
|
|
21790
|
-
|
|
21791
|
-
|
|
21792
|
-
|
|
21793
|
-
|
|
21827
|
+
const acc = [];
|
|
21828
|
+
const oc = process.env.OPENCODE_CONFIG?.trim();
|
|
21829
|
+
if (oc) {
|
|
21830
|
+
acc.push(path34.resolve(oc));
|
|
21831
|
+
}
|
|
21832
|
+
pushConfigBasenames(acc, root);
|
|
21833
|
+
pushConfigBasenames(acc, path34.join(root, ".opencode"));
|
|
21834
|
+
const ocd = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
21835
|
+
if (ocd) {
|
|
21836
|
+
pushConfigBasenames(acc, path34.resolve(ocd));
|
|
21837
|
+
}
|
|
21838
|
+
pushConfigBasenames(acc, openCodeUserConfigDir());
|
|
21839
|
+
pushConfigBasenames(acc, path34.join(os6.homedir(), ".opencode"));
|
|
21840
|
+
const managed = managedOpenCodeConfigDir();
|
|
21841
|
+
if (managed) {
|
|
21842
|
+
pushConfigBasenames(acc, managed);
|
|
21843
|
+
}
|
|
21844
|
+
return dedupeStablePaths(acc);
|
|
21845
|
+
}
|
|
21846
|
+
|
|
21847
|
+
// src/readiness/factoryReadiness.ts
|
|
21848
|
+
var MANDATORY_OPEN_CODE_CONFIG_REL_PATHS = ["opencode.json"];
|
|
21849
|
+
var READINESS_OPENCODE_NOT_INSTALLED = "READINESS_OPENCODE_NOT_INSTALLED";
|
|
21850
|
+
var READINESS_OPENCODE_CREDENTIALS = "READINESS_OPENCODE_CREDENTIALS";
|
|
21851
|
+
var READINESS_OPENCODE_MODEL = "READINESS_OPENCODE_MODEL";
|
|
21852
|
+
function buildOpenCodeConfigInventory(analysisRootAbs) {
|
|
21853
|
+
return openCodeJsonModelFileCandidates(analysisRootAbs).map((p) => ({ path: p, exists: fs39.existsSync(p) }));
|
|
21794
21854
|
}
|
|
21795
21855
|
function defaultModelFromEasyspecsConfig(cfg) {
|
|
21796
21856
|
const providers = cfg.easyspecs?.openCodeRuntime?.providers;
|
|
@@ -21835,6 +21895,40 @@ function extractModelFromOpenCodeJson(data) {
|
|
|
21835
21895
|
}
|
|
21836
21896
|
return void 0;
|
|
21837
21897
|
}
|
|
21898
|
+
function parseOpenCodeConfigText(raw) {
|
|
21899
|
+
const t = raw.trim();
|
|
21900
|
+
if (!t) {
|
|
21901
|
+
return void 0;
|
|
21902
|
+
}
|
|
21903
|
+
try {
|
|
21904
|
+
return JSON.parse(t);
|
|
21905
|
+
} catch {
|
|
21906
|
+
const noBlock = t.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
21907
|
+
const noLine = noBlock.replace(/^\s*\/\/[^\n\r]*/gm, "");
|
|
21908
|
+
try {
|
|
21909
|
+
return JSON.parse(noLine);
|
|
21910
|
+
} catch {
|
|
21911
|
+
return void 0;
|
|
21912
|
+
}
|
|
21913
|
+
}
|
|
21914
|
+
}
|
|
21915
|
+
function modelFromOpencodeConfigContentEnv() {
|
|
21916
|
+
const v = process.env.OPENCODE_CONFIG_CONTENT?.trim();
|
|
21917
|
+
if (!v) {
|
|
21918
|
+
return void 0;
|
|
21919
|
+
}
|
|
21920
|
+
const data = parseOpenCodeConfigText(v);
|
|
21921
|
+
return data !== void 0 ? extractModelFromOpenCodeJson(data) : void 0;
|
|
21922
|
+
}
|
|
21923
|
+
function tryModelFromConfigFile(absPath) {
|
|
21924
|
+
try {
|
|
21925
|
+
const txt = fs39.readFileSync(absPath, "utf-8");
|
|
21926
|
+
const data = parseOpenCodeConfigText(txt);
|
|
21927
|
+
return data !== void 0 ? extractModelFromOpenCodeJson(data) : void 0;
|
|
21928
|
+
} catch {
|
|
21929
|
+
return void 0;
|
|
21930
|
+
}
|
|
21931
|
+
}
|
|
21838
21932
|
function sanitizeModelSummary(raw) {
|
|
21839
21933
|
const t = raw.trim();
|
|
21840
21934
|
if (!t) {
|
|
@@ -21854,15 +21948,15 @@ function resolveModelFromContext(ctx) {
|
|
|
21854
21948
|
if (fromCfg) {
|
|
21855
21949
|
return { configured: true, summary: sanitizeModelSummary(fromCfg) };
|
|
21856
21950
|
}
|
|
21857
|
-
const
|
|
21858
|
-
|
|
21859
|
-
|
|
21860
|
-
|
|
21861
|
-
|
|
21951
|
+
const fromInline = modelFromOpencodeConfigContentEnv();
|
|
21952
|
+
if (fromInline) {
|
|
21953
|
+
return { configured: true, summary: sanitizeModelSummary(fromInline) };
|
|
21954
|
+
}
|
|
21955
|
+
for (const p of openCodeJsonModelFileCandidates(ctx.analysisRootAbs)) {
|
|
21956
|
+
const m = tryModelFromConfigFile(p);
|
|
21862
21957
|
if (m) {
|
|
21863
21958
|
return { configured: true, summary: sanitizeModelSummary(m) };
|
|
21864
21959
|
}
|
|
21865
|
-
} catch {
|
|
21866
21960
|
}
|
|
21867
21961
|
return { configured: false, summary: "(not configured)" };
|
|
21868
21962
|
}
|
|
@@ -21874,7 +21968,7 @@ function buildReadinessProbeFacts(ctx) {
|
|
|
21874
21968
|
});
|
|
21875
21969
|
const openCodeConfigFiles = buildOpenCodeConfigInventory(ctx.analysisRootAbs);
|
|
21876
21970
|
const mandatoryOk = MANDATORY_OPEN_CODE_CONFIG_REL_PATHS.every((rel) => {
|
|
21877
|
-
const abs =
|
|
21971
|
+
const abs = path35.join(path35.resolve(ctx.analysisRootAbs), rel);
|
|
21878
21972
|
return fs39.existsSync(abs);
|
|
21879
21973
|
});
|
|
21880
21974
|
const model = resolveModelFromContext(ctx);
|
|
@@ -21898,7 +21992,8 @@ function buildReadinessLineBlock(facts, ctx) {
|
|
|
21898
21992
|
`repoRoot=${ctx.repoRootAbs}`,
|
|
21899
21993
|
`apiBaseUrl=${apiDisp}`,
|
|
21900
21994
|
`opencode installed=${String(facts.installed)} credentialsReady=${String(facts.credentialsReady)}`,
|
|
21901
|
-
`opencode modelConfigured=${String(facts.modelConfigured)} modelSummary=${facts.modelSummary}
|
|
21995
|
+
`opencode modelConfigured=${String(facts.modelConfigured)} modelSummary=${facts.modelSummary}`,
|
|
21996
|
+
`mandatoryRepoOpenCodeJsonPathsOk=${String(facts.mandatoryConfigPathsOk)} (informational)`
|
|
21902
21997
|
];
|
|
21903
21998
|
for (const e of facts.openCodeConfigFiles) {
|
|
21904
21999
|
lines.push(`opencodeConfigFile ${e.path} exists=${String(e.exists)}`);
|
|
@@ -21931,14 +22026,6 @@ function evaluateReadinessGates(facts) {
|
|
|
21931
22026
|
readinessReasonCode: READINESS_OPENCODE_MODEL
|
|
21932
22027
|
};
|
|
21933
22028
|
}
|
|
21934
|
-
if (!facts.mandatoryConfigPathsOk) {
|
|
21935
|
-
return {
|
|
21936
|
-
ok: false,
|
|
21937
|
-
gate: "d",
|
|
21938
|
-
exitCode: OsExit.readinessOpenCodeMandatoryConfig,
|
|
21939
|
-
readinessReasonCode: READINESS_OPENCODE_MANDATORY_CONFIG
|
|
21940
|
-
};
|
|
21941
|
-
}
|
|
21942
22029
|
return { ok: true };
|
|
21943
22030
|
}
|
|
21944
22031
|
function buildReadinessJsonFields(facts) {
|
|
@@ -22204,7 +22291,7 @@ function sleepUntilAborted(ms, signal) {
|
|
|
22204
22291
|
if (signal.aborted) {
|
|
22205
22292
|
return Promise.reject(new DOMException("The operation was aborted.", "AbortError"));
|
|
22206
22293
|
}
|
|
22207
|
-
return new Promise((
|
|
22294
|
+
return new Promise((resolve24, reject) => {
|
|
22208
22295
|
const onAbort = () => {
|
|
22209
22296
|
clearTimeout(t);
|
|
22210
22297
|
signal.removeEventListener("abort", onAbort);
|
|
@@ -22212,7 +22299,7 @@ function sleepUntilAborted(ms, signal) {
|
|
|
22212
22299
|
};
|
|
22213
22300
|
const t = setTimeout(() => {
|
|
22214
22301
|
signal.removeEventListener("abort", onAbort);
|
|
22215
|
-
|
|
22302
|
+
resolve24();
|
|
22216
22303
|
}, ms);
|
|
22217
22304
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
22218
22305
|
});
|
|
@@ -22711,7 +22798,7 @@ async function runGenerateContextFactory(deps) {
|
|
|
22711
22798
|
|
|
22712
22799
|
// src/factory/generateContextFactoryHeadlessHost.ts
|
|
22713
22800
|
var fs48 = __toESM(require("node:fs"));
|
|
22714
|
-
var
|
|
22801
|
+
var path45 = __toESM(require("node:path"));
|
|
22715
22802
|
|
|
22716
22803
|
// src/stores/pipelineRunStore.ts
|
|
22717
22804
|
var STORAGE_KEY2 = SRS53_PIPELINE_RUN_KEY_V2;
|
|
@@ -22812,11 +22899,11 @@ async function noteAgentsMaterialized(context) {
|
|
|
22812
22899
|
|
|
22813
22900
|
// src/pipelines/remediation/missingWorkstations.ts
|
|
22814
22901
|
var fs41 = __toESM(require("fs"));
|
|
22815
|
-
var
|
|
22902
|
+
var path37 = __toESM(require("path"));
|
|
22816
22903
|
|
|
22817
22904
|
// src/analysis/analysisDetailMarkdownDiscovery.ts
|
|
22818
22905
|
var fs40 = __toESM(require("fs"));
|
|
22819
|
-
var
|
|
22906
|
+
var path36 = __toESM(require("path"));
|
|
22820
22907
|
var SLUG4 = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
22821
22908
|
var FE2 = /^FE-\d+$/;
|
|
22822
22909
|
var UC2 = /^UC-\d+$/;
|
|
@@ -22878,7 +22965,7 @@ function expectedFeatureDetailBasenameFromRow(row2) {
|
|
|
22878
22965
|
return `${code}-${slug}.md`;
|
|
22879
22966
|
}
|
|
22880
22967
|
function ctxPath(contextDir2, basename17) {
|
|
22881
|
-
return
|
|
22968
|
+
return path36.join(contextDir2, basename17);
|
|
22882
22969
|
}
|
|
22883
22970
|
function pushTarget(targets, stem, outputBasename, taskDescription, contextDir2) {
|
|
22884
22971
|
const meta = STEM_TO_AGENT[stem];
|
|
@@ -22894,7 +22981,7 @@ function pushTarget(targets, stem, outputBasename, taskDescription, contextDir2)
|
|
|
22894
22981
|
function discoverDetailMarkdownGroups(contextDir2) {
|
|
22895
22982
|
const groups = [];
|
|
22896
22983
|
const featureTargets = [];
|
|
22897
|
-
const flPath =
|
|
22984
|
+
const flPath = path36.join(contextDir2, "features-list.json");
|
|
22898
22985
|
const fl = readJson5(flPath);
|
|
22899
22986
|
const features = Array.isArray(fl?.features) ? fl.features : [];
|
|
22900
22987
|
for (const row2 of features) {
|
|
@@ -22924,7 +23011,7 @@ function discoverDetailMarkdownGroups(contextDir2) {
|
|
|
22924
23011
|
if (!FE2.test(feCode)) {
|
|
22925
23012
|
continue;
|
|
22926
23013
|
}
|
|
22927
|
-
const ucListPath =
|
|
23014
|
+
const ucListPath = path36.join(contextDir2, `${feCode}-use-cases-list.json`);
|
|
22928
23015
|
const ucFile = readJson5(ucListPath);
|
|
22929
23016
|
const ucs = Array.isArray(ucFile?.useCases) ? ucFile.useCases : [];
|
|
22930
23017
|
for (const ucRow of ucs) {
|
|
@@ -22944,7 +23031,7 @@ function discoverDetailMarkdownGroups(contextDir2) {
|
|
|
22944
23031
|
Follow bundled agent **agent-md-use-case-detail**: include **## Data inputs and validation** (concrete fields, mandatory vs optional, rules, failure behaviour). **## Code flow** must trace **implementation order** (entrypoint \u2192 validation \u2192 business rules \u2192 persistence \u2192 response) with **real** symbols and files\u2014not generic \u201Cuser does X\u201D. Add a **Mermaid** fenced diagram under Code flow when there are **two or more** implementation stages. **## Evidence index** must cite **each major stage** (validation, persistence, response), not only the outer entrypoint.`,
|
|
22945
23032
|
contextDir2
|
|
22946
23033
|
);
|
|
22947
|
-
const scPath =
|
|
23034
|
+
const scPath = path36.join(contextDir2, `${feCode}_${ucCode}-scenarios-list.json`);
|
|
22948
23035
|
const scFile = readJson5(scPath);
|
|
22949
23036
|
const scs = Array.isArray(scFile?.scenarios) ? scFile.scenarios : [];
|
|
22950
23037
|
for (const scRow of scs) {
|
|
@@ -23015,7 +23102,7 @@ Follow bundled agent **agent-md-use-case-detail**: include **## Data inputs and
|
|
|
23015
23102
|
groups.push({ id: "detail-services", label: "Detail markdown \u2014 Services", targets: svcTargets });
|
|
23016
23103
|
groups.push({ id: "detail-methods", label: "Detail markdown \u2014 Methods", targets: meTargets });
|
|
23017
23104
|
const entTargets = [];
|
|
23018
|
-
const dmPath =
|
|
23105
|
+
const dmPath = path36.join(contextDir2, "data-model-list.json");
|
|
23019
23106
|
const dmFile = readJson5(dmPath);
|
|
23020
23107
|
const ents = Array.isArray(dmFile?.entities) ? dmFile.entities : [];
|
|
23021
23108
|
for (const erow of ents) {
|
|
@@ -23044,7 +23131,7 @@ Follow bundled agent **agent-md-use-case-detail**: include **## Data inputs and
|
|
|
23044
23131
|
if (!DM2.test(dmCode)) {
|
|
23045
23132
|
continue;
|
|
23046
23133
|
}
|
|
23047
|
-
const flPath2 =
|
|
23134
|
+
const flPath2 = path36.join(contextDir2, `${dmCode}-fields-list.json`);
|
|
23048
23135
|
const flFile = readJson5(flPath2);
|
|
23049
23136
|
const flds = Array.isArray(flFile?.fields) ? flFile.fields : [];
|
|
23050
23137
|
for (const frow of flds) {
|
|
@@ -23103,7 +23190,7 @@ function fileAndValidationFromKind(kind) {
|
|
|
23103
23190
|
return { filePresentYesNo: "no", validationYesNo: "na" };
|
|
23104
23191
|
}
|
|
23105
23192
|
function classifyMissingWorkstationOutputFileStatus(row2, contextDir2, worktreeRoot) {
|
|
23106
|
-
const abs =
|
|
23193
|
+
const abs = path37.join(contextDir2, row2.relativePath);
|
|
23107
23194
|
try {
|
|
23108
23195
|
const st = fs41.statSync(abs);
|
|
23109
23196
|
if (!st.isFile()) {
|
|
@@ -23142,7 +23229,7 @@ function classifyMissingWorkstationOutputFileStatus(row2, contextDir2, worktreeR
|
|
|
23142
23229
|
detail: "Unknown coordination list basename \u2014 no JSON Schema mapping."
|
|
23143
23230
|
};
|
|
23144
23231
|
}
|
|
23145
|
-
const schemaAbs =
|
|
23232
|
+
const schemaAbs = path37.join(worktreeRoot, ".opencode", "schemas", "context-lists", schemaBn);
|
|
23146
23233
|
if (!fs41.existsSync(schemaAbs)) {
|
|
23147
23234
|
return {
|
|
23148
23235
|
kind: "invalid",
|
|
@@ -23172,7 +23259,7 @@ function classifyWorkstationOutputOnDisk(item, contextDir2, worktreeRoot) {
|
|
|
23172
23259
|
return classifyMissingWorkstationOutputFileStatus(row2, contextDir2, worktreeRoot).kind;
|
|
23173
23260
|
}
|
|
23174
23261
|
function isWorkstationRunSnapshotForWorktree(snapshot, worktreeRoot) {
|
|
23175
|
-
return !!(snapshot && snapshot.overallStatus !== "running" && snapshot.overallStatus !== "idle" &&
|
|
23262
|
+
return !!(snapshot && snapshot.overallStatus !== "running" && snapshot.overallStatus !== "idle" && path37.resolve(snapshot.analysisRoot) === path37.resolve(worktreeRoot));
|
|
23176
23263
|
}
|
|
23177
23264
|
function expectedBasenameForCoordPayload(p) {
|
|
23178
23265
|
const { step, listTarget } = p;
|
|
@@ -23246,10 +23333,10 @@ function labelContextForCoordPayload(p) {
|
|
|
23246
23333
|
}
|
|
23247
23334
|
function contextPathForWorkItem(item, contextDir2) {
|
|
23248
23335
|
if (item.kind === "markdown") {
|
|
23249
|
-
return
|
|
23336
|
+
return path37.join(contextDir2, item.payload.outputBasename);
|
|
23250
23337
|
}
|
|
23251
23338
|
const bn = expectedBasenameForCoordPayload(item.payload);
|
|
23252
|
-
return bn ?
|
|
23339
|
+
return bn ? path37.join(contextDir2, bn) : null;
|
|
23253
23340
|
}
|
|
23254
23341
|
function syntheticRunnerId(key) {
|
|
23255
23342
|
return `remediation:${key}`;
|
|
@@ -23259,7 +23346,7 @@ function rowFromSkippedItem(item, contextDir2) {
|
|
|
23259
23346
|
return null;
|
|
23260
23347
|
}
|
|
23261
23348
|
const abs = contextPathForWorkItem(item, contextDir2);
|
|
23262
|
-
const rel = abs ?
|
|
23349
|
+
const rel = abs ? path37.basename(abs) : item.kind === "markdown" ? item.payload.outputBasename : item.id;
|
|
23263
23350
|
if (abs && nonEmptyContextFile(abs)) {
|
|
23264
23351
|
return null;
|
|
23265
23352
|
}
|
|
@@ -23434,7 +23521,7 @@ function toMissingWorkstationUiRows(rows, contextDir2, worktreeRoot) {
|
|
|
23434
23521
|
}
|
|
23435
23522
|
|
|
23436
23523
|
// src/pipelines/remediation/missingWorkstationsPool.ts
|
|
23437
|
-
var
|
|
23524
|
+
var path38 = __toESM(require("path"));
|
|
23438
23525
|
function reconcileSkippedWorkItemsWithDisk(byId, contextDir2, worktreeRoot) {
|
|
23439
23526
|
for (const item of byId.values()) {
|
|
23440
23527
|
if (item.status !== "skipped") {
|
|
@@ -23494,7 +23581,7 @@ async function runRemediationPipelineMissingPass(p) {
|
|
|
23494
23581
|
onItemComplete,
|
|
23495
23582
|
sourceBranchAtWorktreeCreation
|
|
23496
23583
|
} = p;
|
|
23497
|
-
const contextDir2 =
|
|
23584
|
+
const contextDir2 = path38.join(worktreeRoot, ".gluecharm", "context");
|
|
23498
23585
|
const snap = readArtefactRunSnapshot(storageContext);
|
|
23499
23586
|
const snapOk = isWorkstationRunSnapshotForWorktree(snap, worktreeRoot);
|
|
23500
23587
|
let byId;
|
|
@@ -23561,17 +23648,17 @@ async function runRemediationPipelineMissingPass(p) {
|
|
|
23561
23648
|
// src/pipelines/coverage/coveragePipeline.ts
|
|
23562
23649
|
var import_child_process5 = require("child_process");
|
|
23563
23650
|
var fs43 = __toESM(require("fs"));
|
|
23564
|
-
var
|
|
23651
|
+
var path40 = __toESM(require("path"));
|
|
23565
23652
|
|
|
23566
23653
|
// src/analysis/coverageReferenceValidationSchemaValidate.ts
|
|
23567
23654
|
var fs42 = __toESM(require("fs"));
|
|
23568
|
-
var
|
|
23655
|
+
var path39 = __toESM(require("path"));
|
|
23569
23656
|
var import__5 = __toESM(require__());
|
|
23570
23657
|
function stripUtf8Bom4(s) {
|
|
23571
23658
|
return s.length > 0 && s.charCodeAt(0) === 65279 ? s.slice(1) : s;
|
|
23572
23659
|
}
|
|
23573
23660
|
function bundledCoverageReferenceValidationSchemaPath() {
|
|
23574
|
-
return
|
|
23661
|
+
return path39.join(
|
|
23575
23662
|
resolveRepoResourcesRoot(),
|
|
23576
23663
|
"schemas",
|
|
23577
23664
|
"context-lists",
|
|
@@ -23651,8 +23738,8 @@ var DEFAULT_IGNORE_DIR_BASENAMES = [
|
|
|
23651
23738
|
];
|
|
23652
23739
|
var GIT_LS_FILES_MAX_BUFFER = 64 * 1024 * 1024;
|
|
23653
23740
|
function tryLoadGitNonIgnoredPathSet(repositoryRootAbs) {
|
|
23654
|
-
const root =
|
|
23655
|
-
if (!fs43.existsSync(
|
|
23741
|
+
const root = path40.resolve(repositoryRootAbs);
|
|
23742
|
+
if (!fs43.existsSync(path40.join(root, ".git"))) {
|
|
23656
23743
|
return null;
|
|
23657
23744
|
}
|
|
23658
23745
|
const env = { ...process.env, GIT_TERMINAL_PROMPT: "0" };
|
|
@@ -23720,12 +23807,12 @@ var REFERENCE_COVERAGE_IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
23720
23807
|
".emf"
|
|
23721
23808
|
]);
|
|
23722
23809
|
function isReferenceCoverageExcludedImagePath(relPosix) {
|
|
23723
|
-
const ext =
|
|
23810
|
+
const ext = path40.extname(relPosix).toLowerCase();
|
|
23724
23811
|
return ext.length > 0 && REFERENCE_COVERAGE_IMAGE_EXTENSIONS.has(ext);
|
|
23725
23812
|
}
|
|
23726
23813
|
var REFERENCE_COVERAGE_EXCLUDED_FILE_BASENAMES = /* @__PURE__ */ new Set([".gitignore"]);
|
|
23727
23814
|
function isReferenceCoverageExcludedDefaultBasename(relPosix) {
|
|
23728
|
-
const base =
|
|
23815
|
+
const base = path40.basename(relPosix.replace(/\\/g, "/")).toLowerCase();
|
|
23729
23816
|
return REFERENCE_COVERAGE_EXCLUDED_FILE_BASENAMES.has(base);
|
|
23730
23817
|
}
|
|
23731
23818
|
function decodeBufferForLineCount(buf) {
|
|
@@ -23762,12 +23849,12 @@ function normalizeRepoRelativePath(repoRoot, raw) {
|
|
|
23762
23849
|
if (!trimmed || trimmed.includes("\0")) {
|
|
23763
23850
|
return null;
|
|
23764
23851
|
}
|
|
23765
|
-
const abs =
|
|
23766
|
-
const rel =
|
|
23767
|
-
if (rel.startsWith("..") ||
|
|
23852
|
+
const abs = path40.resolve(repoRoot, trimmed);
|
|
23853
|
+
const rel = path40.relative(repoRoot, abs);
|
|
23854
|
+
if (rel.startsWith("..") || path40.isAbsolute(rel)) {
|
|
23768
23855
|
return null;
|
|
23769
23856
|
}
|
|
23770
|
-
return rel.split(
|
|
23857
|
+
return rel.split(path40.sep).join("/");
|
|
23771
23858
|
}
|
|
23772
23859
|
function collectJsonSourceReferences(node, out) {
|
|
23773
23860
|
if (node === null || typeof node !== "object") {
|
|
@@ -23812,7 +23899,7 @@ function listContextFilesRecursive(dir, acc) {
|
|
|
23812
23899
|
return;
|
|
23813
23900
|
}
|
|
23814
23901
|
for (const e of entries) {
|
|
23815
|
-
const full =
|
|
23902
|
+
const full = path40.join(dir, e.name);
|
|
23816
23903
|
if (e.isDirectory()) {
|
|
23817
23904
|
listContextFilesRecursive(full, acc);
|
|
23818
23905
|
} else if (e.isFile()) {
|
|
@@ -23833,8 +23920,8 @@ function walkRepositoryFiles(repoRoot, ignoreBasenames, maxBytes, excludedOut, g
|
|
|
23833
23920
|
if (ignoreBasenames.has(e.name)) {
|
|
23834
23921
|
continue;
|
|
23835
23922
|
}
|
|
23836
|
-
const full =
|
|
23837
|
-
const rel =
|
|
23923
|
+
const full = path40.join(dir, e.name);
|
|
23924
|
+
const rel = path40.relative(repoRoot, full).split(path40.sep).join("/");
|
|
23838
23925
|
if (rel.startsWith("..")) {
|
|
23839
23926
|
continue;
|
|
23840
23927
|
}
|
|
@@ -23892,9 +23979,9 @@ function collectReferencesFromContext(contextDirAbs, repositoryRootAbs, warnings
|
|
|
23892
23979
|
const allFiles = [];
|
|
23893
23980
|
listContextFilesRecursive(contextDirAbs, allFiles);
|
|
23894
23981
|
for (const abs of allFiles) {
|
|
23895
|
-
const ext =
|
|
23896
|
-
const base =
|
|
23897
|
-
const sourceArtefact =
|
|
23982
|
+
const ext = path40.extname(abs).toLowerCase();
|
|
23983
|
+
const base = path40.basename(abs);
|
|
23984
|
+
const sourceArtefact = path40.relative(contextDirAbs, abs).split(path40.sep).join("/");
|
|
23898
23985
|
if (ext === ".json") {
|
|
23899
23986
|
if (SKIP_CONTEXT_JSON.has(base)) {
|
|
23900
23987
|
continue;
|
|
@@ -23976,12 +24063,12 @@ function sortReferenceRows(a, b) {
|
|
|
23976
24063
|
return (a.startLine ?? 0) - (b.startLine ?? 0);
|
|
23977
24064
|
}
|
|
23978
24065
|
function buildCoverageReferenceValidationDocument(repositoryRootAbs, contextDirAbs, options) {
|
|
23979
|
-
const repoRoot =
|
|
24066
|
+
const repoRoot = path40.resolve(repositoryRootAbs);
|
|
23980
24067
|
const warnings = [];
|
|
23981
24068
|
const ignoreDirs = [...DEFAULT_IGNORE_DIR_BASENAMES];
|
|
23982
24069
|
const ignoreSet = new Set(ignoreDirs);
|
|
23983
24070
|
const maxBytes = options?.maxFileBytes ?? MAX_FILE_BYTES;
|
|
23984
|
-
const references = collectReferencesFromContext(
|
|
24071
|
+
const references = collectReferencesFromContext(path40.resolve(contextDirAbs), repoRoot, warnings);
|
|
23985
24072
|
references.sort(sortReferenceRows);
|
|
23986
24073
|
const referencedSet = /* @__PURE__ */ new Set();
|
|
23987
24074
|
for (const r of references) {
|
|
@@ -23989,7 +24076,7 @@ function buildCoverageReferenceValidationDocument(repositoryRootAbs, contextDirA
|
|
|
23989
24076
|
}
|
|
23990
24077
|
const excludedFiles = [];
|
|
23991
24078
|
const gitNonIgnoredPaths = tryLoadGitNonIgnoredPathSet(repoRoot);
|
|
23992
|
-
if (fs43.existsSync(
|
|
24079
|
+
if (fs43.existsSync(path40.join(repoRoot, ".git")) && gitNonIgnoredPaths === null) {
|
|
23993
24080
|
warnings.push(
|
|
23994
24081
|
"Repository has .git but git ls-files failed or git is unavailable; .gitignore / exclude-standard not applied."
|
|
23995
24082
|
);
|
|
@@ -24038,8 +24125,8 @@ function buildCoverageReferenceValidationDocument(repositoryRootAbs, contextDirA
|
|
|
24038
24125
|
return { document: doc, warnings };
|
|
24039
24126
|
}
|
|
24040
24127
|
function runCoveragePipeline(opts) {
|
|
24041
|
-
const repoRoot =
|
|
24042
|
-
const contextDir2 =
|
|
24128
|
+
const repoRoot = path40.resolve(opts.repositoryRootAbs);
|
|
24129
|
+
const contextDir2 = path40.resolve(opts.contextDirAbs);
|
|
24043
24130
|
if (!fs43.existsSync(repoRoot)) {
|
|
24044
24131
|
return { ok: false, error: `Repository root does not exist: ${repoRoot}` };
|
|
24045
24132
|
}
|
|
@@ -24061,7 +24148,7 @@ ${schemaCheck.errors.join("\n")}`,
|
|
|
24061
24148
|
warnings
|
|
24062
24149
|
};
|
|
24063
24150
|
}
|
|
24064
|
-
const outPath =
|
|
24151
|
+
const outPath = path40.join(contextDir2, COVERAGE_REFERENCE_VALIDATION_BASENAME);
|
|
24065
24152
|
if (opts.write) {
|
|
24066
24153
|
try {
|
|
24067
24154
|
const payload = stableStringifyCoverageDocument(document);
|
|
@@ -24080,11 +24167,11 @@ ${schemaCheck.errors.join("\n")}`,
|
|
|
24080
24167
|
// src/pipelines/remediation/zeroReferenceWorkstationChain.ts
|
|
24081
24168
|
var crypto = __toESM(require("crypto"));
|
|
24082
24169
|
var fs45 = __toESM(require("fs"));
|
|
24083
|
-
var
|
|
24170
|
+
var path42 = __toESM(require("path"));
|
|
24084
24171
|
|
|
24085
24172
|
// src/analysis/zeroReferenceRemediationSchemaValidate.ts
|
|
24086
24173
|
var fs44 = __toESM(require("fs"));
|
|
24087
|
-
var
|
|
24174
|
+
var path41 = __toESM(require("path"));
|
|
24088
24175
|
var import__6 = __toESM(require__());
|
|
24089
24176
|
function stripUtf8Bom5(s) {
|
|
24090
24177
|
return s.length > 0 && s.charCodeAt(0) === 65279 ? s.slice(1) : s;
|
|
@@ -24104,7 +24191,7 @@ function formatAjvErrors6(errors) {
|
|
|
24104
24191
|
}
|
|
24105
24192
|
var ajv = new import__6.default({ allErrors: true, strict: false });
|
|
24106
24193
|
function compileSchema(basename17) {
|
|
24107
|
-
const schemaPath =
|
|
24194
|
+
const schemaPath = path41.join(schemasDir(), basename17);
|
|
24108
24195
|
const schemaRaw = stripUtf8Bom5(fs44.readFileSync(schemaPath, "utf-8"));
|
|
24109
24196
|
const schema = JSON.parse(schemaRaw);
|
|
24110
24197
|
return ajv.compile(schema);
|
|
@@ -24399,17 +24486,17 @@ function expandArgvTemplate4(template, vars) {
|
|
|
24399
24486
|
});
|
|
24400
24487
|
}
|
|
24401
24488
|
function schemaRef2(worktreeRoot, schemaBasename) {
|
|
24402
|
-
return
|
|
24489
|
+
return path42.join(worktreeRoot, ".opencode", "schemas", "context-lists", schemaBasename);
|
|
24403
24490
|
}
|
|
24404
24491
|
function stagingDir(contextDirAbs) {
|
|
24405
|
-
return
|
|
24492
|
+
return path42.join(contextDirAbs, "_zero-ref-staging");
|
|
24406
24493
|
}
|
|
24407
24494
|
function stagingPathForTarget(contextDirAbs, kind, targetFilePathPosix) {
|
|
24408
24495
|
const h = crypto.createHash("sha256").update(targetFilePathPosix, "utf8").digest("hex").slice(0, 16);
|
|
24409
|
-
return
|
|
24496
|
+
return path42.join(stagingDir(contextDirAbs), `${kind}-${h}.json`);
|
|
24410
24497
|
}
|
|
24411
24498
|
function readNonReferencedFilesFromRepositoryRoot(repositoryRootAbs) {
|
|
24412
|
-
const p =
|
|
24499
|
+
const p = path42.join(repositoryRootAbs, ".gluecharm", "context", "coverage-reference-validation.json");
|
|
24413
24500
|
const r = readAndValidateCoverageReferenceValidationFile(p);
|
|
24414
24501
|
if (!r.ok) {
|
|
24415
24502
|
return { ok: false, error: r.errors.join("; ") };
|
|
@@ -24502,7 +24589,7 @@ function slugifyFeatureLabel(s) {
|
|
|
24502
24589
|
return t.length > 0 ? t : "feature";
|
|
24503
24590
|
}
|
|
24504
24591
|
function lineCountRepoFile(worktreeRootAbs, relPosix) {
|
|
24505
|
-
const abs =
|
|
24592
|
+
const abs = path42.join(worktreeRootAbs, ...relPosix.split("/"));
|
|
24506
24593
|
let buf;
|
|
24507
24594
|
try {
|
|
24508
24595
|
buf = fs45.readFileSync(abs);
|
|
@@ -24557,8 +24644,8 @@ var LIST_STEP_HINT = {
|
|
|
24557
24644
|
};
|
|
24558
24645
|
async function applyCoordinationListTriageMerge(input) {
|
|
24559
24646
|
const cfg = LIST_MERGE_CFG[input.listKind];
|
|
24560
|
-
const listPath =
|
|
24561
|
-
const schemaPath =
|
|
24647
|
+
const listPath = path42.join(input.contextDirAbs, cfg.listBasename);
|
|
24648
|
+
const schemaPath = path42.join(resolveContextListSchemasDir(), cfg.schemaBasename);
|
|
24562
24649
|
if (!fs45.existsSync(listPath)) {
|
|
24563
24650
|
return {
|
|
24564
24651
|
ok: false,
|
|
@@ -24662,10 +24749,10 @@ async function applyCoordinationListTriageMerge(input) {
|
|
|
24662
24749
|
}
|
|
24663
24750
|
async function runClassifierAgent(common, contextDirAbs, targetFilePathPosix, workspaceLabel) {
|
|
24664
24751
|
const outAbs = stagingPathForTarget(contextDirAbs, "classifier", targetFilePathPosix);
|
|
24665
|
-
fs45.mkdirSync(
|
|
24666
|
-
const runDir =
|
|
24752
|
+
fs45.mkdirSync(path42.dirname(outAbs), { recursive: true });
|
|
24753
|
+
const runDir = path42.join(common.worktreeRoot, ".opencode", "_run");
|
|
24667
24754
|
fs45.mkdirSync(runDir, { recursive: true });
|
|
24668
|
-
const outputBasename =
|
|
24755
|
+
const outputBasename = path42.basename(outAbs);
|
|
24669
24756
|
const listTaskDescription = [
|
|
24670
24757
|
`Target file (repo-relative, POSIX): **${targetFilePathPosix}**`,
|
|
24671
24758
|
`Workspace label hint: **${workspaceLabel}**.`,
|
|
@@ -24701,7 +24788,7 @@ async function runClassifierAgent(common, contextDirAbs, targetFilePathPosix, wo
|
|
|
24701
24788
|
parentContextBlock: "",
|
|
24702
24789
|
...repairAppendix ? { repairAppendix } : {}
|
|
24703
24790
|
});
|
|
24704
|
-
const promptPath =
|
|
24791
|
+
const promptPath = path42.join(runDir, `zero-ref-classify-a${attempt}-${Date.now()}.prompt.txt`);
|
|
24705
24792
|
fs45.writeFileSync(promptPath, body, "utf-8");
|
|
24706
24793
|
const argv = expandArgvTemplate4(common.argvTemplate, {
|
|
24707
24794
|
promptFile: promptPath,
|
|
@@ -24833,9 +24920,9 @@ var TRIAGE_SCOPE_META = {
|
|
|
24833
24920
|
};
|
|
24834
24921
|
async function runMarkdownReferenceAgent(common, contextDirAbs, targetFilePathPosix, routingSummary, which) {
|
|
24835
24922
|
const mdBasename = which === "project" ? "project.md" : "architecture.md";
|
|
24836
|
-
const mdAbs =
|
|
24923
|
+
const mdAbs = path42.join(contextDirAbs, mdBasename);
|
|
24837
24924
|
const agentStem = which === "project" ? ZERO_REF_ADD_REF_PROJECT_AGENT_STEM : ZERO_REF_ADD_REF_ARCH_AGENT_STEM;
|
|
24838
|
-
const runDir =
|
|
24925
|
+
const runDir = path42.join(common.worktreeRoot, ".opencode", "_run");
|
|
24839
24926
|
fs45.mkdirSync(runDir, { recursive: true });
|
|
24840
24927
|
const lines = [
|
|
24841
24928
|
`# SRS-30 \u2014 Add reference to ${mdBasename}`,
|
|
@@ -24851,7 +24938,7 @@ async function runMarkdownReferenceAgent(common, contextDirAbs, targetFilePathPo
|
|
|
24851
24938
|
`- If the file is short, \`${targetFilePathPosix}:1-<lastLine>\` is acceptable.`,
|
|
24852
24939
|
`- Do not remove unrelated content; append or extend the most appropriate section.`
|
|
24853
24940
|
];
|
|
24854
|
-
const promptPath =
|
|
24941
|
+
const promptPath = path42.join(runDir, `zero-ref-md-${which}-${Date.now()}.prompt.txt`);
|
|
24855
24942
|
fs45.writeFileSync(promptPath, lines.join("\n"), "utf-8");
|
|
24856
24943
|
const argv = expandArgvTemplate4(common.argvTemplate, {
|
|
24857
24944
|
promptFile: promptPath,
|
|
@@ -24879,10 +24966,10 @@ async function runMarkdownReferenceAgent(common, contextDirAbs, targetFilePathPo
|
|
|
24879
24966
|
async function runCoordinationTriageAgent(common, contextDirAbs, targetFilePathPosix, routingSummary, workspaceLabel, triageScope) {
|
|
24880
24967
|
const meta = TRIAGE_SCOPE_META[triageScope];
|
|
24881
24968
|
const outAbs = stagingPathForTarget(contextDirAbs, "triage", targetFilePathPosix);
|
|
24882
|
-
fs45.mkdirSync(
|
|
24883
|
-
const runDir =
|
|
24969
|
+
fs45.mkdirSync(path42.dirname(outAbs), { recursive: true });
|
|
24970
|
+
const runDir = path42.join(common.worktreeRoot, ".opencode", "_run");
|
|
24884
24971
|
fs45.mkdirSync(runDir, { recursive: true });
|
|
24885
|
-
const outputBasename =
|
|
24972
|
+
const outputBasename = path42.basename(outAbs);
|
|
24886
24973
|
const listTaskDescription = [
|
|
24887
24974
|
`Target file: **${targetFilePathPosix}** (${workspaceLabel})`,
|
|
24888
24975
|
"**Classifier summary:**",
|
|
@@ -24912,7 +24999,7 @@ async function runCoordinationTriageAgent(common, contextDirAbs, targetFilePathP
|
|
|
24912
24999
|
parentContextBlock: "",
|
|
24913
25000
|
...repairAppendix ? { repairAppendix } : {}
|
|
24914
25001
|
});
|
|
24915
|
-
const promptPath =
|
|
25002
|
+
const promptPath = path42.join(runDir, `zero-ref-triage-a${attempt}-${Date.now()}.prompt.txt`);
|
|
24916
25003
|
fs45.writeFileSync(promptPath, body, "utf-8");
|
|
24917
25004
|
const argv = expandArgvTemplate4(common.argvTemplate, {
|
|
24918
25005
|
promptFile: promptPath,
|
|
@@ -25027,8 +25114,8 @@ async function runCoordinationTriageAgent(common, contextDirAbs, targetFilePathP
|
|
|
25027
25114
|
return { ok: false, message: lastFailureMessage, stagingPath: outAbs };
|
|
25028
25115
|
}
|
|
25029
25116
|
async function runOneUnreferencedFilePipeline(p) {
|
|
25030
|
-
const routingAbs =
|
|
25031
|
-
const triageAbs =
|
|
25117
|
+
const routingAbs = path42.join(p.contextDirAbs, ZERO_REF_ROUTING_BASENAME);
|
|
25118
|
+
const triageAbs = path42.join(p.contextDirAbs, ZERO_REF_TRIAGE_BASENAME);
|
|
25032
25119
|
const key = p.targetFilePathPosix;
|
|
25033
25120
|
const cr = await runClassifierAgent(p, p.contextDirAbs, key, p.workspaceLabel);
|
|
25034
25121
|
if (!cr.ok) {
|
|
@@ -25052,7 +25139,7 @@ async function runOneUnreferencedFilePipeline(p) {
|
|
|
25052
25139
|
if (!s.ok) {
|
|
25053
25140
|
throw new Error(s.errors.join("; "));
|
|
25054
25141
|
}
|
|
25055
|
-
fs45.mkdirSync(
|
|
25142
|
+
fs45.mkdirSync(path42.dirname(routingAbs), { recursive: true });
|
|
25056
25143
|
fs45.writeFileSync(routingAbs, s.json, "utf-8");
|
|
25057
25144
|
});
|
|
25058
25145
|
const routing = stagingParsed.routing;
|
|
@@ -25101,7 +25188,7 @@ async function runOneUnreferencedFilePipeline(p) {
|
|
|
25101
25188
|
if (!s.ok) {
|
|
25102
25189
|
throw new Error(s.errors.join("; "));
|
|
25103
25190
|
}
|
|
25104
|
-
fs45.mkdirSync(
|
|
25191
|
+
fs45.mkdirSync(path42.dirname(triageAbs), { recursive: true });
|
|
25105
25192
|
fs45.writeFileSync(triageAbs, s.json, "utf-8");
|
|
25106
25193
|
});
|
|
25107
25194
|
const decision = triageParsed.decision;
|
|
@@ -25129,11 +25216,11 @@ async function runOneUnreferencedFilePipeline(p) {
|
|
|
25129
25216
|
return { ok: true, message: `Triage ${decision}.` };
|
|
25130
25217
|
}
|
|
25131
25218
|
async function runRemediationPipelineZeroRefPass(p) {
|
|
25132
|
-
const contextDirAbs =
|
|
25219
|
+
const contextDirAbs = path42.join(p.worktreeRoot, ".gluecharm", "context");
|
|
25133
25220
|
const covRoot = p.coverageRepositoryRootAbs ?? p.workspaceRootAbs;
|
|
25134
25221
|
const cov = readNonReferencedFilesFromRepositoryRoot(covRoot);
|
|
25135
25222
|
const coverageAt = cov.ok ? cov.generatedAt : void 0;
|
|
25136
|
-
const workspaceLabel =
|
|
25223
|
+
const workspaceLabel = path42.basename(p.worktreeRoot);
|
|
25137
25224
|
const routingMutex = new AsyncMutex();
|
|
25138
25225
|
const triageMutex = new AsyncMutex();
|
|
25139
25226
|
const paths = [...p.paths];
|
|
@@ -25191,7 +25278,7 @@ async function runRemediationPipelineZeroRefPass(p) {
|
|
|
25191
25278
|
|
|
25192
25279
|
// src/pipelines/coverage/coverageExecutionReport.ts
|
|
25193
25280
|
var fs46 = __toESM(require("fs"));
|
|
25194
|
-
var
|
|
25281
|
+
var path43 = __toESM(require("path"));
|
|
25195
25282
|
var REFERENCE_COVERAGE_EXECUTION_REPORT_BASENAME = "reference-coverage-execution-report.md";
|
|
25196
25283
|
function inlineMdText(s) {
|
|
25197
25284
|
const t = s.replace(/\r\n/g, "\n").replace(/\n/g, " ").trim();
|
|
@@ -25315,10 +25402,10 @@ async function runCoverageExecutionReport(p) {
|
|
|
25315
25402
|
if (p.abortSignal?.aborted) {
|
|
25316
25403
|
return { ok: false, error: "Stopped.", cancelled: true };
|
|
25317
25404
|
}
|
|
25318
|
-
const contextDirAbs =
|
|
25319
|
-
const coverageAbs =
|
|
25320
|
-
const routingAbs =
|
|
25321
|
-
const outAbs =
|
|
25405
|
+
const contextDirAbs = path43.join(p.repositoryRootAbs, ".gluecharm", "context");
|
|
25406
|
+
const coverageAbs = path43.join(contextDirAbs, "coverage-reference-validation.json");
|
|
25407
|
+
const routingAbs = path43.join(contextDirAbs, "zero-reference-routing.json");
|
|
25408
|
+
const outAbs = path43.join(contextDirAbs, REFERENCE_COVERAGE_EXECUTION_REPORT_BASENAME);
|
|
25322
25409
|
const cov = readAndValidateCoverageReferenceValidationFile(coverageAbs);
|
|
25323
25410
|
if (!cov.ok) {
|
|
25324
25411
|
return { ok: false, error: `Coverage JSON: ${cov.errors.join("; ")}` };
|
|
@@ -25342,7 +25429,7 @@ async function runCoverageExecutionReport(p) {
|
|
|
25342
25429
|
previous = void 0;
|
|
25343
25430
|
}
|
|
25344
25431
|
try {
|
|
25345
|
-
fs46.mkdirSync(
|
|
25432
|
+
fs46.mkdirSync(path43.dirname(outAbs), { recursive: true });
|
|
25346
25433
|
fs46.writeFileSync(outAbs, md, "utf-8");
|
|
25347
25434
|
} catch (e) {
|
|
25348
25435
|
const msg = e instanceof Error ? e.message : String(e);
|
|
@@ -25360,7 +25447,7 @@ async function runCoverageExecutionReport(p) {
|
|
|
25360
25447
|
|
|
25361
25448
|
// src/gluecharm/minimalGluecharmLayout.ts
|
|
25362
25449
|
var fs47 = __toESM(require("node:fs"));
|
|
25363
|
-
var
|
|
25450
|
+
var path44 = __toESM(require("node:path"));
|
|
25364
25451
|
var MINIMAL_GLUECHARM_RELATIVE_DIRS = [
|
|
25365
25452
|
[".gluecharm", "docs", "srs"],
|
|
25366
25453
|
[".gluecharm", "content"],
|
|
@@ -25368,9 +25455,9 @@ var MINIMAL_GLUECHARM_RELATIVE_DIRS = [
|
|
|
25368
25455
|
[".gluecharm", "context"]
|
|
25369
25456
|
];
|
|
25370
25457
|
function ensureMinimalGluecharmLayoutNode(repoRootAbs) {
|
|
25371
|
-
const root =
|
|
25458
|
+
const root = path44.resolve(repoRootAbs);
|
|
25372
25459
|
for (const segments of MINIMAL_GLUECHARM_RELATIVE_DIRS) {
|
|
25373
|
-
const dir =
|
|
25460
|
+
const dir = path44.join(root, ...segments);
|
|
25374
25461
|
try {
|
|
25375
25462
|
fs47.mkdirSync(dir, { recursive: true });
|
|
25376
25463
|
} catch (e) {
|
|
@@ -25502,7 +25589,7 @@ function buildFactoryDepsHeadless(input) {
|
|
|
25502
25589
|
if (!layout.ok) {
|
|
25503
25590
|
return { ok: false, error: layout.error };
|
|
25504
25591
|
}
|
|
25505
|
-
const ctxDir =
|
|
25592
|
+
const ctxDir = path45.join(ar, ".gluecharm", "context");
|
|
25506
25593
|
const snap = readArtefactRunSnapshot(storageContext);
|
|
25507
25594
|
const rows = listMissingWorkstations(ctxDir, ar, snap);
|
|
25508
25595
|
if (rows.length === 0) {
|
|
@@ -25516,7 +25603,7 @@ function buildFactoryDepsHeadless(input) {
|
|
|
25516
25603
|
storageContext,
|
|
25517
25604
|
repositoryRoot: repoRoot,
|
|
25518
25605
|
worktreeRoot: ar,
|
|
25519
|
-
workspaceLabel:
|
|
25606
|
+
workspaceLabel: path45.basename(ar),
|
|
25520
25607
|
oc: {
|
|
25521
25608
|
...oc,
|
|
25522
25609
|
aceEnabled: getAceAnalysisEnabledForCheckout(ar),
|
|
@@ -25544,7 +25631,7 @@ function buildFactoryDepsHeadless(input) {
|
|
|
25544
25631
|
}
|
|
25545
25632
|
try {
|
|
25546
25633
|
await startPipelineRun(storageContext, repoRoot);
|
|
25547
|
-
const folderName =
|
|
25634
|
+
const folderName = path45.basename(repoRoot);
|
|
25548
25635
|
const oc = buildOpenCodeOptions(handle.path);
|
|
25549
25636
|
const result = await runSynthesisPipelineDrainFromPreparedWorktree(
|
|
25550
25637
|
storageContext,
|
|
@@ -25601,7 +25688,7 @@ function buildFactoryDepsHeadless(input) {
|
|
|
25601
25688
|
if (!ar) {
|
|
25602
25689
|
return 0;
|
|
25603
25690
|
}
|
|
25604
|
-
const ctxDir =
|
|
25691
|
+
const ctxDir = path45.join(ar, ".gluecharm", "context");
|
|
25605
25692
|
const snap = readArtefactRunSnapshot(storageContext);
|
|
25606
25693
|
return listMissingWorkstations(ctxDir, ar, snap).length;
|
|
25607
25694
|
};
|
|
@@ -25614,7 +25701,7 @@ function buildFactoryDepsHeadless(input) {
|
|
|
25614
25701
|
if (!layout.ok) {
|
|
25615
25702
|
return { ok: false, message: layout.error };
|
|
25616
25703
|
}
|
|
25617
|
-
const contextDir2 =
|
|
25704
|
+
const contextDir2 = path45.join(ar, ".gluecharm", "context");
|
|
25618
25705
|
log(`[factory] reference coverage (worktree) \u2014 ${ar}`);
|
|
25619
25706
|
const res = runCoveragePipeline({
|
|
25620
25707
|
repositoryRootAbs: ar,
|
|
@@ -25674,7 +25761,7 @@ function buildFactoryDepsHeadless(input) {
|
|
|
25674
25761
|
diagnosticLog: log
|
|
25675
25762
|
});
|
|
25676
25763
|
if (res.ok) {
|
|
25677
|
-
return { ok: true, message: `Report: ${
|
|
25764
|
+
return { ok: true, message: `Report: ${path45.basename(res.outputAbsolutePath)}` };
|
|
25678
25765
|
}
|
|
25679
25766
|
if (res.cancelled) {
|
|
25680
25767
|
return { ok: false, cancelled: true, message: "Report generation stopped." };
|
|
@@ -25690,7 +25777,7 @@ function buildFactoryDepsHeadless(input) {
|
|
|
25690
25777
|
if (!lmLayout.ok) {
|
|
25691
25778
|
return { ok: false, message: lmLayout.error };
|
|
25692
25779
|
}
|
|
25693
|
-
const contextDir2 =
|
|
25780
|
+
const contextDir2 = path45.join(snap.adHocWorktreePath, ".gluecharm", "context");
|
|
25694
25781
|
const linkGraph = runLinkMappingPipeline(contextDir2, { log });
|
|
25695
25782
|
if (!linkGraph.ok) {
|
|
25696
25783
|
return { ok: false, message: linkGraph.error };
|
|
@@ -25706,7 +25793,7 @@ function buildFactoryDepsHeadless(input) {
|
|
|
25706
25793
|
if (!idxLayout.ok) {
|
|
25707
25794
|
return { ok: false, message: idxLayout.error };
|
|
25708
25795
|
}
|
|
25709
|
-
const contextDir2 =
|
|
25796
|
+
const contextDir2 = path45.join(snap.adHocWorktreePath, ".gluecharm", "context");
|
|
25710
25797
|
try {
|
|
25711
25798
|
writeIndexApplicationContext(contextDir2, void 0, {
|
|
25712
25799
|
sourceBranchAtWorktreeCreation: snap.adHocSourceBranchAtCreation
|
|
@@ -25761,13 +25848,13 @@ function buildFactoryDepsHeadless(input) {
|
|
|
25761
25848
|
},
|
|
25762
25849
|
runPrepareAnalysisWorktree: async (resume) => {
|
|
25763
25850
|
if (resume) {
|
|
25764
|
-
if (adHocWorktree && fs48.existsSync(
|
|
25851
|
+
if (adHocWorktree && fs48.existsSync(path45.join(adHocWorktree.path, ".git"))) {
|
|
25765
25852
|
return { ok: true };
|
|
25766
25853
|
}
|
|
25767
25854
|
const snap = readAnalysisWorkspaceSnapshot(storageContext);
|
|
25768
25855
|
const wtPath = snap?.adHocWorktreePath?.trim();
|
|
25769
25856
|
const repo = snap?.adHocRepositoryRoot?.trim() || repoRoot;
|
|
25770
|
-
if (wtPath && fs48.existsSync(
|
|
25857
|
+
if (wtPath && fs48.existsSync(path45.join(wtPath, ".git"))) {
|
|
25771
25858
|
adHocWorktree = resolveAnalysisCheckoutHandle(wtPath, repo);
|
|
25772
25859
|
macroSourceBranch = snap?.adHocSourceBranchAtCreation;
|
|
25773
25860
|
macroFinalize = () => {
|
|
@@ -25985,11 +26072,11 @@ function stderrLinesForFactoryFailures(failures, exitCode) {
|
|
|
25985
26072
|
}
|
|
25986
26073
|
|
|
25987
26074
|
// src/factory/updateContext/runUpdateContextFactory.ts
|
|
25988
|
-
var
|
|
26075
|
+
var path50 = __toESM(require("node:path"));
|
|
25989
26076
|
|
|
25990
26077
|
// src/factory/updateContext/updateContextBaseline.ts
|
|
25991
26078
|
var fs49 = __toESM(require("node:fs"));
|
|
25992
|
-
var
|
|
26079
|
+
var path46 = __toESM(require("node:path"));
|
|
25993
26080
|
function isValidIso(s) {
|
|
25994
26081
|
const t = Date.parse(s);
|
|
25995
26082
|
return Number.isFinite(t);
|
|
@@ -26004,7 +26091,7 @@ function maxMtimeRegularFilesUnderDir(dirAbs) {
|
|
|
26004
26091
|
return;
|
|
26005
26092
|
}
|
|
26006
26093
|
for (const e of entries) {
|
|
26007
|
-
const p =
|
|
26094
|
+
const p = path46.join(d, e.name);
|
|
26008
26095
|
if (e.isDirectory()) {
|
|
26009
26096
|
walk(p);
|
|
26010
26097
|
} else if (e.isFile()) {
|
|
@@ -26030,7 +26117,7 @@ function resolveUpdateContextBaseline(repoRootAbs, repoConfig) {
|
|
|
26030
26117
|
if (last.length > 0 && isValidIso(last)) {
|
|
26031
26118
|
return { baselineIsoUtc: new Date(last).toISOString(), source: "lastRunAt" };
|
|
26032
26119
|
}
|
|
26033
|
-
const ctxDir =
|
|
26120
|
+
const ctxDir = path46.join(repoRootAbs, ".gluecharm", "context");
|
|
26034
26121
|
if (!fs49.existsSync(ctxDir)) {
|
|
26035
26122
|
return null;
|
|
26036
26123
|
}
|
|
@@ -26055,7 +26142,7 @@ function persistUpdateContextLastRunAt(repoRootAbs, isoUtc) {
|
|
|
26055
26142
|
// src/factory/updateContext/updateContextGitWindow.ts
|
|
26056
26143
|
var import_node_child_process3 = require("node:child_process");
|
|
26057
26144
|
var fs50 = __toESM(require("node:fs"));
|
|
26058
|
-
var
|
|
26145
|
+
var path47 = __toESM(require("node:path"));
|
|
26059
26146
|
var GIT_ENV = { ...process.env, GIT_TERMINAL_PROMPT: "0" };
|
|
26060
26147
|
function gitLines(repoRootAbs, args) {
|
|
26061
26148
|
const r = (0, import_node_child_process3.execFileSync)("git", ["-c", "core.quotepath=false", ...args], {
|
|
@@ -26079,8 +26166,8 @@ function parseGitLogIso(line) {
|
|
|
26079
26166
|
return { hash, iso };
|
|
26080
26167
|
}
|
|
26081
26168
|
function discoverCommitWindowAndTouchedPaths(repoRootAbs, baselineIsoUtc) {
|
|
26082
|
-
const root =
|
|
26083
|
-
if (!fs50.existsSync(
|
|
26169
|
+
const root = path47.resolve(repoRootAbs);
|
|
26170
|
+
if (!fs50.existsSync(path47.join(root, ".git"))) {
|
|
26084
26171
|
return { ok: false, error: "Not a git repository (missing .git)." };
|
|
26085
26172
|
}
|
|
26086
26173
|
const baselineMs = Date.parse(baselineIsoUtc);
|
|
@@ -26139,11 +26226,11 @@ function discoverCommitWindowAndTouchedPaths(repoRootAbs, baselineIsoUtc) {
|
|
|
26139
26226
|
};
|
|
26140
26227
|
}
|
|
26141
26228
|
function filterPathsExistingInWorktree(worktreeRootAbs, pathsPosix) {
|
|
26142
|
-
const root =
|
|
26229
|
+
const root = path47.resolve(worktreeRootAbs);
|
|
26143
26230
|
const out = [];
|
|
26144
26231
|
for (const p of pathsPosix) {
|
|
26145
26232
|
const rel = p.replace(/\\/g, "/");
|
|
26146
|
-
const abs =
|
|
26233
|
+
const abs = path47.join(root, ...rel.split("/"));
|
|
26147
26234
|
try {
|
|
26148
26235
|
if (fs50.existsSync(abs) && fs50.statSync(abs).isFile()) {
|
|
26149
26236
|
out.push(rel);
|
|
@@ -26156,7 +26243,7 @@ function filterPathsExistingInWorktree(worktreeRootAbs, pathsPosix) {
|
|
|
26156
26243
|
|
|
26157
26244
|
// src/factory/updateContext/updateContextReport.ts
|
|
26158
26245
|
var fs51 = __toESM(require("node:fs"));
|
|
26159
|
-
var
|
|
26246
|
+
var path48 = __toESM(require("node:path"));
|
|
26160
26247
|
var CHANGES_SINCE_DATE_BASENAME = "changes-since-date.md";
|
|
26161
26248
|
function renderChangesSinceDateMarkdown(p) {
|
|
26162
26249
|
const lines = [
|
|
@@ -26198,7 +26285,7 @@ function renderChangesSinceDateMarkdown(p) {
|
|
|
26198
26285
|
function writeChangesSinceDateReport(contextDirAbs, body) {
|
|
26199
26286
|
try {
|
|
26200
26287
|
fs51.mkdirSync(contextDirAbs, { recursive: true });
|
|
26201
|
-
const target =
|
|
26288
|
+
const target = path48.join(contextDirAbs, CHANGES_SINCE_DATE_BASENAME);
|
|
26202
26289
|
fs51.writeFileSync(target, body, "utf-8");
|
|
26203
26290
|
return { ok: true };
|
|
26204
26291
|
} catch (e) {
|
|
@@ -26208,7 +26295,7 @@ function writeChangesSinceDateReport(contextDirAbs, body) {
|
|
|
26208
26295
|
|
|
26209
26296
|
// src/factory/updateContext/updateContextSeedCheck.ts
|
|
26210
26297
|
var fs52 = __toESM(require("node:fs"));
|
|
26211
|
-
var
|
|
26298
|
+
var path49 = __toESM(require("node:path"));
|
|
26212
26299
|
var INDEX_BASENAME = "index-application-context.json";
|
|
26213
26300
|
var CHANGES_REPORT = "changes-since-date.md";
|
|
26214
26301
|
function tryParseJsonFile(abs) {
|
|
@@ -26224,7 +26311,7 @@ function isWorktreeContextSeeded(contextDirAbs) {
|
|
|
26224
26311
|
if (!fs52.existsSync(contextDirAbs)) {
|
|
26225
26312
|
return false;
|
|
26226
26313
|
}
|
|
26227
|
-
const indexAbs =
|
|
26314
|
+
const indexAbs = path49.join(contextDirAbs, INDEX_BASENAME);
|
|
26228
26315
|
if (fs52.existsSync(indexAbs) && fs52.statSync(indexAbs).isFile() && tryParseJsonFile(indexAbs)) {
|
|
26229
26316
|
return true;
|
|
26230
26317
|
}
|
|
@@ -26242,7 +26329,7 @@ function isWorktreeContextSeeded(contextDirAbs) {
|
|
|
26242
26329
|
if (!name.endsWith(".md") && !name.endsWith(".json")) {
|
|
26243
26330
|
continue;
|
|
26244
26331
|
}
|
|
26245
|
-
const p =
|
|
26332
|
+
const p = path49.join(contextDirAbs, name);
|
|
26246
26333
|
try {
|
|
26247
26334
|
if (fs52.statSync(p).isFile()) {
|
|
26248
26335
|
distinct.add(name);
|
|
@@ -26256,7 +26343,7 @@ function isWorktreeContextSeeded(contextDirAbs) {
|
|
|
26256
26343
|
// src/factory/updateContext/runUpdateContextFactory.ts
|
|
26257
26344
|
var REMEDIATION_CHUNK_MAX = 40;
|
|
26258
26345
|
function contextDirUnderRoot(wtRoot) {
|
|
26259
|
-
return
|
|
26346
|
+
return path50.join(wtRoot, ".gluecharm", "context");
|
|
26260
26347
|
}
|
|
26261
26348
|
async function runUpdateContextFactory(deps) {
|
|
26262
26349
|
const inPlace = deps.inPlace === true;
|
|
@@ -26587,11 +26674,11 @@ async function runUpdateContextFactory(deps) {
|
|
|
26587
26674
|
|
|
26588
26675
|
// src/factory/contextDrift/runContextDriftFactory.ts
|
|
26589
26676
|
var fs58 = __toESM(require("node:fs"));
|
|
26590
|
-
var
|
|
26677
|
+
var path55 = __toESM(require("node:path"));
|
|
26591
26678
|
|
|
26592
26679
|
// src/factory/contextDrift/contextDriftManifest.ts
|
|
26593
26680
|
var fs53 = __toESM(require("node:fs"));
|
|
26594
|
-
var
|
|
26681
|
+
var path51 = __toESM(require("node:path"));
|
|
26595
26682
|
var MAX_REFERENCE_BYTES = 256 * 1024;
|
|
26596
26683
|
var MAX_EVIDENCE_FILES = 300;
|
|
26597
26684
|
var MAX_EVIDENCE_READ = 512 * 1024;
|
|
@@ -26611,16 +26698,16 @@ function collectEvidencePaths(repoRoot) {
|
|
|
26611
26698
|
const out = [];
|
|
26612
26699
|
const roots = ["src", "test", "tests", "packages", ".gluecharm", "scripts"];
|
|
26613
26700
|
for (const rel of roots) {
|
|
26614
|
-
const abs =
|
|
26701
|
+
const abs = path51.join(repoRoot, rel);
|
|
26615
26702
|
if (!fs53.existsSync(abs)) {
|
|
26616
26703
|
continue;
|
|
26617
26704
|
}
|
|
26618
26705
|
walkFiles(abs, repoRoot, out, 0);
|
|
26619
26706
|
}
|
|
26620
26707
|
for (const leaf of ["package.json", "tsconfig.json"]) {
|
|
26621
|
-
const abs =
|
|
26708
|
+
const abs = path51.join(repoRoot, leaf);
|
|
26622
26709
|
if (fs53.existsSync(abs) && fs53.statSync(abs).isFile()) {
|
|
26623
|
-
const r =
|
|
26710
|
+
const r = path51.relative(repoRoot, abs).split(path51.sep).join("/");
|
|
26624
26711
|
out.push(r);
|
|
26625
26712
|
}
|
|
26626
26713
|
}
|
|
@@ -26645,13 +26732,13 @@ function walkFiles(dir, repoRoot, out, depth) {
|
|
|
26645
26732
|
if (e.name === "node_modules" || e.name === ".git" || e.name === "dist" || e.name === "out") {
|
|
26646
26733
|
continue;
|
|
26647
26734
|
}
|
|
26648
|
-
const full =
|
|
26735
|
+
const full = path51.join(dir, e.name);
|
|
26649
26736
|
if (e.isDirectory()) {
|
|
26650
26737
|
walkFiles(full, repoRoot, out, depth + 1);
|
|
26651
26738
|
} else if (e.isFile()) {
|
|
26652
|
-
const ext =
|
|
26739
|
+
const ext = path51.extname(e.name).toLowerCase();
|
|
26653
26740
|
if ([".ts", ".tsx", ".js", ".mjs", ".cjs", ".json", ".md", ".yaml", ".yml"].includes(ext) || e.name === "Dockerfile") {
|
|
26654
|
-
const rel =
|
|
26741
|
+
const rel = path51.relative(repoRoot, full).split(path51.sep).join("/");
|
|
26655
26742
|
out.push(rel);
|
|
26656
26743
|
}
|
|
26657
26744
|
}
|
|
@@ -26661,7 +26748,7 @@ function buildComparisonManifest(args) {
|
|
|
26661
26748
|
const references = [];
|
|
26662
26749
|
let referenceTruncated = false;
|
|
26663
26750
|
for (const abs of args.bundleAbsFiles) {
|
|
26664
|
-
const rel =
|
|
26751
|
+
const rel = path51.relative(args.worktreeRoot, abs).split(path51.sep).join("/");
|
|
26665
26752
|
const { text, truncated } = readFileLimited(abs, MAX_REFERENCE_BYTES);
|
|
26666
26753
|
references.push({ path: rel, content: text, truncated });
|
|
26667
26754
|
if (truncated) {
|
|
@@ -26673,7 +26760,7 @@ function buildComparisonManifest(args) {
|
|
|
26673
26760
|
const omitted = Math.max(0, allEvidence.length - evidencePathsTrimmed.length);
|
|
26674
26761
|
const evidenceFiles = [];
|
|
26675
26762
|
for (const rel of evidencePathsTrimmed) {
|
|
26676
|
-
const abs =
|
|
26763
|
+
const abs = path51.join(args.worktreeRoot, ...rel.split("/"));
|
|
26677
26764
|
const st = fs53.existsSync(abs) ? fs53.statSync(abs) : null;
|
|
26678
26765
|
const size = st && st.isFile() ? st.size : 0;
|
|
26679
26766
|
const { text, truncated } = readFileLimited(abs, MAX_EVIDENCE_READ);
|
|
@@ -26684,7 +26771,7 @@ function buildComparisonManifest(args) {
|
|
|
26684
26771
|
}
|
|
26685
26772
|
return {
|
|
26686
26773
|
runDate: args.runDate,
|
|
26687
|
-
referenceRelPaths: args.bundleAbsFiles.map((a) =>
|
|
26774
|
+
referenceRelPaths: args.bundleAbsFiles.map((a) => path51.relative(args.worktreeRoot, a).split(path51.sep).join("/")),
|
|
26688
26775
|
references,
|
|
26689
26776
|
evidenceFiles,
|
|
26690
26777
|
evidencePathsOnly: [],
|
|
@@ -26697,7 +26784,7 @@ function buildComparisonManifest(args) {
|
|
|
26697
26784
|
|
|
26698
26785
|
// src/factory/contextDrift/contextDriftAgent.ts
|
|
26699
26786
|
var fs54 = __toESM(require("node:fs"));
|
|
26700
|
-
var
|
|
26787
|
+
var path52 = __toESM(require("node:path"));
|
|
26701
26788
|
|
|
26702
26789
|
// src/factory/contextDrift/contextDriftPayload.ts
|
|
26703
26790
|
function isNonEmptyString2(v) {
|
|
@@ -26842,16 +26929,16 @@ function buildDriftPrompt(args) {
|
|
|
26842
26929
|
].join("\n");
|
|
26843
26930
|
}
|
|
26844
26931
|
async function runDriftComparisonOpenCode(args) {
|
|
26845
|
-
const runDir =
|
|
26932
|
+
const runDir = path52.join(args.worktreeRoot, ".opencode", "_run");
|
|
26846
26933
|
fs54.mkdirSync(runDir, { recursive: true });
|
|
26847
|
-
const manifestPath =
|
|
26848
|
-
const outputPath =
|
|
26934
|
+
const manifestPath = path52.join(runDir, "context-drift-manifest.json");
|
|
26935
|
+
const outputPath = path52.join(runDir, "context-drift-payload.json");
|
|
26849
26936
|
fs54.writeFileSync(manifestPath, `${JSON.stringify(args.manifestObject, null, 2)}
|
|
26850
26937
|
`, "utf8");
|
|
26851
26938
|
if (fs54.existsSync(outputPath)) {
|
|
26852
26939
|
fs54.unlinkSync(outputPath);
|
|
26853
26940
|
}
|
|
26854
|
-
const promptPath =
|
|
26941
|
+
const promptPath = path52.join(runDir, `context-drift-${Date.now()}.prompt.txt`);
|
|
26855
26942
|
fs54.writeFileSync(
|
|
26856
26943
|
promptPath,
|
|
26857
26944
|
buildDriftPrompt({
|
|
@@ -26869,7 +26956,7 @@ async function runDriftComparisonOpenCode(args) {
|
|
|
26869
26956
|
});
|
|
26870
26957
|
const title = buildOpenCodeSessionTitle({
|
|
26871
26958
|
runId: "context-drift",
|
|
26872
|
-
workItemId:
|
|
26959
|
+
workItemId: path52.basename(args.worktreeRoot).slice(0, 24) || "wt",
|
|
26873
26960
|
stepLabel: "context-drift"
|
|
26874
26961
|
});
|
|
26875
26962
|
const argv = injectPrimaryOpenCodeSessionArgv(expanded, title);
|
|
@@ -26912,8 +26999,8 @@ async function runDriftComparisonOpenCode(args) {
|
|
|
26912
26999
|
// src/factory/contextDrift/contextDriftPaths.ts
|
|
26913
27000
|
var crypto2 = __toESM(require("node:crypto"));
|
|
26914
27001
|
var fs55 = __toESM(require("node:fs"));
|
|
26915
|
-
var
|
|
26916
|
-
var DRIFT_CONTEXT_SUBDIR =
|
|
27002
|
+
var path53 = __toESM(require("node:path"));
|
|
27003
|
+
var DRIFT_CONTEXT_SUBDIR = path53.join(".gluecharm", "context", "drift");
|
|
26917
27004
|
function sanitizeSlug(raw) {
|
|
26918
27005
|
const s = raw.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64);
|
|
26919
27006
|
return s.length > 0 ? s : "drift";
|
|
@@ -26922,9 +27009,9 @@ function utcDateString(d) {
|
|
|
26922
27009
|
return d.toISOString().slice(0, 10);
|
|
26923
27010
|
}
|
|
26924
27011
|
function resolveInsideRepo(repoRootAbs, userPath) {
|
|
26925
|
-
const abs =
|
|
26926
|
-
const rel =
|
|
26927
|
-
if (rel.startsWith("..") ||
|
|
27012
|
+
const abs = path53.isAbsolute(userPath) ? path53.normalize(userPath) : path53.resolve(repoRootAbs, userPath);
|
|
27013
|
+
const rel = path53.relative(repoRootAbs, abs);
|
|
27014
|
+
if (rel.startsWith("..") || path53.isAbsolute(rel)) {
|
|
26928
27015
|
return { ok: false };
|
|
26929
27016
|
}
|
|
26930
27017
|
return { ok: true, abs };
|
|
@@ -26934,7 +27021,7 @@ function computeSlug(args) {
|
|
|
26934
27021
|
return sanitizeSlug(args.label.trim());
|
|
26935
27022
|
}
|
|
26936
27023
|
const r = resolveInsideRepo(args.repoRootAbs, args.referencePath);
|
|
26937
|
-
const base = r.ok ?
|
|
27024
|
+
const base = r.ok ? path53.basename(r.abs) : path53.basename(args.referencePath);
|
|
26938
27025
|
return sanitizeSlug(base);
|
|
26939
27026
|
}
|
|
26940
27027
|
function driftFilename(slug, runDate) {
|
|
@@ -26976,7 +27063,7 @@ function discoverReferenceBundle(worktreeRoot, referenceAbsInWorktree) {
|
|
|
26976
27063
|
return;
|
|
26977
27064
|
}
|
|
26978
27065
|
for (const e of entries) {
|
|
26979
|
-
const full =
|
|
27066
|
+
const full = path53.join(dir, e.name);
|
|
26980
27067
|
if (e.isDirectory()) {
|
|
26981
27068
|
if (e.name === "node_modules" || e.name === ".git") {
|
|
26982
27069
|
continue;
|
|
@@ -27006,7 +27093,7 @@ function pickReferenceRootDocument(args) {
|
|
|
27006
27093
|
}
|
|
27007
27094
|
const dir = args.referenceAbsInWorktree;
|
|
27008
27095
|
for (const name of ["index.md", "README.md"]) {
|
|
27009
|
-
const p =
|
|
27096
|
+
const p = path53.join(dir, name);
|
|
27010
27097
|
if (fs55.existsSync(p) && fs55.statSync(p).isFile()) {
|
|
27011
27098
|
return { ok: true, path: p };
|
|
27012
27099
|
}
|
|
@@ -27017,10 +27104,10 @@ function pickReferenceRootDocument(args) {
|
|
|
27017
27104
|
};
|
|
27018
27105
|
}
|
|
27019
27106
|
function toWorktreeRelative(worktreeRoot, absolute) {
|
|
27020
|
-
return
|
|
27107
|
+
return path53.relative(worktreeRoot, absolute).split(path53.sep).join("/");
|
|
27021
27108
|
}
|
|
27022
27109
|
function toPosixPath(p) {
|
|
27023
|
-
return p.split(
|
|
27110
|
+
return p.split(path53.sep).join("/");
|
|
27024
27111
|
}
|
|
27025
27112
|
|
|
27026
27113
|
// src/factory/contextDrift/contextDriftIndex.ts
|
|
@@ -27063,19 +27150,19 @@ function escapeRe(s) {
|
|
|
27063
27150
|
|
|
27064
27151
|
// src/factory/contextDrift/contextDriftPromote.ts
|
|
27065
27152
|
var fs57 = __toESM(require("node:fs"));
|
|
27066
|
-
var
|
|
27153
|
+
var path54 = __toESM(require("node:path"));
|
|
27067
27154
|
function copyWorktreeFileToWorkspace(args) {
|
|
27068
|
-
const wt =
|
|
27069
|
-
const ws =
|
|
27155
|
+
const wt = path54.resolve(args.worktreeRoot);
|
|
27156
|
+
const ws = path54.resolve(args.workspaceRoot);
|
|
27070
27157
|
if (wt === ws) {
|
|
27071
27158
|
return;
|
|
27072
27159
|
}
|
|
27073
|
-
const src =
|
|
27074
|
-
const dest =
|
|
27075
|
-
if (
|
|
27160
|
+
const src = path54.join(args.worktreeRoot, ...args.relativePosix.split("/"));
|
|
27161
|
+
const dest = path54.join(args.workspaceRoot, ...args.relativePosix.split("/"));
|
|
27162
|
+
if (path54.resolve(src) === path54.resolve(dest)) {
|
|
27076
27163
|
return;
|
|
27077
27164
|
}
|
|
27078
|
-
fs57.mkdirSync(
|
|
27165
|
+
fs57.mkdirSync(path54.dirname(dest), { recursive: true });
|
|
27079
27166
|
fs57.copyFileSync(src, dest);
|
|
27080
27167
|
}
|
|
27081
27168
|
|
|
@@ -27131,7 +27218,7 @@ async function runContextDriftFactory(deps) {
|
|
|
27131
27218
|
ok: true,
|
|
27132
27219
|
code: "DRY_RUN",
|
|
27133
27220
|
...baseMeta,
|
|
27134
|
-
referenceRootDocument: toPosixPath(
|
|
27221
|
+
referenceRootDocument: toPosixPath(path55.relative(deps.repoRootAbs, refAbsWorkspace)) + (fs58.statSync(refAbsWorkspace).isDirectory() ? "/" : ""),
|
|
27135
27222
|
driftReportPath: null,
|
|
27136
27223
|
analysisWorktreeRoot: "",
|
|
27137
27224
|
promoted: false,
|
|
@@ -27188,8 +27275,8 @@ async function runContextDriftFactory(deps) {
|
|
|
27188
27275
|
const handle = prep.handle;
|
|
27189
27276
|
const finalizeWt = prep.finalize;
|
|
27190
27277
|
const wt = handle.path;
|
|
27191
|
-
const refRel =
|
|
27192
|
-
const refAbsWt =
|
|
27278
|
+
const refRel = path55.relative(deps.repoRootAbs, refAbsWorkspace).split(path55.sep).join("/");
|
|
27279
|
+
const refAbsWt = path55.join(wt, ...refRel.split("/"));
|
|
27193
27280
|
try {
|
|
27194
27281
|
materializeOpenCodeAgentsWithAce(deps.agentsDirFs, wt, {
|
|
27195
27282
|
enabled: getAceAnalysisEnabledForCheckout(wt),
|
|
@@ -27228,7 +27315,7 @@ async function runContextDriftFactory(deps) {
|
|
|
27228
27315
|
...baseMeta
|
|
27229
27316
|
};
|
|
27230
27317
|
}
|
|
27231
|
-
const indexWt = indexOverrideAbsWorkspace ?
|
|
27318
|
+
const indexWt = indexOverrideAbsWorkspace ? path55.join(wt, ...path55.relative(deps.repoRootAbs, indexOverrideAbsWorkspace).split(path55.sep)) : void 0;
|
|
27232
27319
|
const rootPick = pickReferenceRootDocument({
|
|
27233
27320
|
referencePathIsFile: fs58.statSync(refAbsWt).isFile(),
|
|
27234
27321
|
referenceAbsInWorktree: refAbsWt,
|
|
@@ -27256,9 +27343,9 @@ async function runContextDriftFactory(deps) {
|
|
|
27256
27343
|
let slug = computeSlug({ label: deps.label, referencePath: deps.referencePathArg, repoRootAbs: deps.repoRootAbs });
|
|
27257
27344
|
slug = maybeDedupeSlug(slug, refRel);
|
|
27258
27345
|
const driftBase = driftFilename(slug, runDate);
|
|
27259
|
-
const driftDirWt =
|
|
27346
|
+
const driftDirWt = path55.join(wt, DRIFT_CONTEXT_SUBDIR);
|
|
27260
27347
|
fs58.mkdirSync(driftDirWt, { recursive: true });
|
|
27261
|
-
const driftAbsWt =
|
|
27348
|
+
const driftAbsWt = path55.join(driftDirWt, driftBase);
|
|
27262
27349
|
let payload;
|
|
27263
27350
|
if (deps.testOnlyFixturePayload) {
|
|
27264
27351
|
payload = deps.testOnlyFixturePayload;
|
|
@@ -27307,7 +27394,7 @@ async function runContextDriftFactory(deps) {
|
|
|
27307
27394
|
...baseMeta
|
|
27308
27395
|
};
|
|
27309
27396
|
}
|
|
27310
|
-
const driftRelFromRootDir =
|
|
27397
|
+
const driftRelFromRootDir = path55.relative(path55.dirname(refRootAbsWt), driftAbsWt).split(path55.sep).join("/");
|
|
27311
27398
|
const linkRes = patchReferenceIndexWithDriftLink({
|
|
27312
27399
|
referenceRootAbsolute: refRootAbsWt,
|
|
27313
27400
|
relativeLinkFromRootToDrift: driftRelFromRootDir,
|
|
@@ -27326,8 +27413,8 @@ async function runContextDriftFactory(deps) {
|
|
|
27326
27413
|
...baseMeta
|
|
27327
27414
|
};
|
|
27328
27415
|
}
|
|
27329
|
-
const driftRelPosix = toPosixPath(
|
|
27330
|
-
const rootRelPosix = toPosixPath(
|
|
27416
|
+
const driftRelPosix = toPosixPath(path55.relative(wt, driftAbsWt));
|
|
27417
|
+
const rootRelPosix = toPosixPath(path55.relative(wt, refRootAbsWt));
|
|
27331
27418
|
const promoteEffective = deps.merged.promoteContextToWorkspace !== false;
|
|
27332
27419
|
if (promoteEffective && !inPlace) {
|
|
27333
27420
|
try {
|
|
@@ -27357,7 +27444,7 @@ async function runContextDriftFactory(deps) {
|
|
|
27357
27444
|
} else if (promoteEffective && inPlace) {
|
|
27358
27445
|
deps.log("[context-drift] in-place analysis \u2014 promote skipped (artefacts already under repository root)");
|
|
27359
27446
|
}
|
|
27360
|
-
const driftReportPathFs = promoteEffective ?
|
|
27447
|
+
const driftReportPathFs = promoteEffective ? path55.join(deps.repoRootAbs, ...driftRelPosix.split("/")) : driftAbsWt;
|
|
27361
27448
|
return {
|
|
27362
27449
|
exitOk: true,
|
|
27363
27450
|
ok: true,
|
|
@@ -27376,7 +27463,7 @@ async function runContextDriftFactory(deps) {
|
|
|
27376
27463
|
|
|
27377
27464
|
// src/analysis/coordinationDuplicatesDiagnosis.ts
|
|
27378
27465
|
var fs59 = __toESM(require("fs"));
|
|
27379
|
-
var
|
|
27466
|
+
var path56 = __toESM(require("path"));
|
|
27380
27467
|
var import__7 = __toESM(require__());
|
|
27381
27468
|
var COORDINATION_DUPLICATES_REPORT_BASENAME = "coordination-duplicates-report.json";
|
|
27382
27469
|
var COORDINATION_LIST_SCAN_ENTRIES = [
|
|
@@ -27402,7 +27489,7 @@ var RE_MD_DM_FD = /^DM-\d+_FD-\d+-.+\.md$/i;
|
|
|
27402
27489
|
var RE_MD_DM = /^DM-\d+-.+\.md$/i;
|
|
27403
27490
|
var RE_MD_TS = /^TS-\d+-.+\.md$/i;
|
|
27404
27491
|
function looksLikeCoordinationDetailMarkdownBasename(basename17) {
|
|
27405
|
-
if (!basename17 || basename17 !==
|
|
27492
|
+
if (!basename17 || basename17 !== path56.basename(basename17) || !/\.md$/i.test(basename17)) {
|
|
27406
27493
|
return false;
|
|
27407
27494
|
}
|
|
27408
27495
|
if (STAPLE_CONTEXT_MARKDOWN_BASENAMES.has(basename17)) {
|
|
@@ -27411,7 +27498,7 @@ function looksLikeCoordinationDetailMarkdownBasename(basename17) {
|
|
|
27411
27498
|
return RE_MD_FE_UC_SC.test(basename17) || RE_MD_FE_UC_SLUG.test(basename17) || RE_MD_FE_UC_PLAIN.test(basename17) || RE_MD_FE_FEATURE.test(basename17) || RE_MD_XP_BH.test(basename17) || RE_MD_XP_VIEW.test(basename17) || RE_MD_SV_ME.test(basename17) || RE_MD_SV.test(basename17) || RE_MD_DM_FD.test(basename17) || RE_MD_DM.test(basename17) || RE_MD_TS.test(basename17);
|
|
27412
27499
|
}
|
|
27413
27500
|
function loadRawFeatureRows(contextDirAbs) {
|
|
27414
|
-
const p =
|
|
27501
|
+
const p = path56.join(contextDirAbs, "features-list.json");
|
|
27415
27502
|
if (!fs59.existsSync(p)) {
|
|
27416
27503
|
return [];
|
|
27417
27504
|
}
|
|
@@ -27704,7 +27791,7 @@ function buildCoordinationDuplicatesReport(input) {
|
|
|
27704
27791
|
const lists = [];
|
|
27705
27792
|
const duplicateGroups = [];
|
|
27706
27793
|
for (const entry of COORDINATION_LIST_SCAN_ENTRIES) {
|
|
27707
|
-
const filePath =
|
|
27794
|
+
const filePath = path56.join(input.contextDirAbsolute, entry.basename);
|
|
27708
27795
|
if (!fs59.existsSync(filePath)) {
|
|
27709
27796
|
lists.push({ basename: entry.basename, status: "missing" });
|
|
27710
27797
|
continue;
|
|
@@ -27759,7 +27846,7 @@ var validateReportCompiled;
|
|
|
27759
27846
|
function validateReportData(data) {
|
|
27760
27847
|
if (!validateReportCompiled) {
|
|
27761
27848
|
const ajv2 = new import__7.default({ allErrors: true, strict: false });
|
|
27762
|
-
const schemaPath =
|
|
27849
|
+
const schemaPath = path56.join(resolveContextListSchemasDir(), "coordination-duplicates-report.schema.json");
|
|
27763
27850
|
const schemaRaw = stripUtf8Bom6(fs59.readFileSync(schemaPath, "utf-8"));
|
|
27764
27851
|
validateReportCompiled = ajv2.compile(JSON.parse(schemaRaw));
|
|
27765
27852
|
}
|
|
@@ -27778,7 +27865,7 @@ function runCoordinationDuplicatesDiagnosis(input) {
|
|
|
27778
27865
|
if (!v.ok) {
|
|
27779
27866
|
return { ok: false, message: `Report validation failed: ${v.errors.join("; ")}` };
|
|
27780
27867
|
}
|
|
27781
|
-
const outPath =
|
|
27868
|
+
const outPath = path56.join(input.contextDirAbsolute, COORDINATION_DUPLICATES_REPORT_BASENAME);
|
|
27782
27869
|
const payload = `${JSON.stringify(report, null, 2)}
|
|
27783
27870
|
`;
|
|
27784
27871
|
const tmp = `${outPath}.tmp.${process.pid}`;
|
|
@@ -27826,7 +27913,7 @@ function runCoordinationDuplicatesDiagnosis(input) {
|
|
|
27826
27913
|
|
|
27827
27914
|
// src/pipelines/download/downloadPipeline.ts
|
|
27828
27915
|
var fs60 = __toESM(require("node:fs"));
|
|
27829
|
-
var
|
|
27916
|
+
var path57 = __toESM(require("node:path"));
|
|
27830
27917
|
var SRS_DISCOVERY_BATCH_GET_CHUNK_SIZE = 200;
|
|
27831
27918
|
function isRecord7(v) {
|
|
27832
27919
|
return Boolean(v) && typeof v === "object" && !Array.isArray(v);
|
|
@@ -27916,9 +28003,9 @@ function resolveSafeContextOutputPath(contextDirAbs, nameRaw) {
|
|
|
27916
28003
|
return null;
|
|
27917
28004
|
}
|
|
27918
28005
|
}
|
|
27919
|
-
const resolved =
|
|
27920
|
-
const rel =
|
|
27921
|
-
if (rel.startsWith("..") ||
|
|
28006
|
+
const resolved = path57.resolve(contextDirAbs, ...segments);
|
|
28007
|
+
const rel = path57.relative(contextDirAbs, resolved);
|
|
28008
|
+
if (rel.startsWith("..") || path57.isAbsolute(rel)) {
|
|
27922
28009
|
return null;
|
|
27923
28010
|
}
|
|
27924
28011
|
return resolved;
|
|
@@ -27934,7 +28021,7 @@ function clearContextDirectoryForCloudReplace(contextDirAbs) {
|
|
|
27934
28021
|
if (!fs60.existsSync(contextDirAbs) || !fs60.statSync(contextDirAbs).isDirectory()) {
|
|
27935
28022
|
return { filesRemoved: 0 };
|
|
27936
28023
|
}
|
|
27937
|
-
const preserveAbs =
|
|
28024
|
+
const preserveAbs = path57.resolve(contextDirAbs, UPLOAD_TARGET_FILENAME);
|
|
27938
28025
|
const preserveSet = /* @__PURE__ */ new Set();
|
|
27939
28026
|
if (fs60.existsSync(preserveAbs) && fs60.statSync(preserveAbs).isFile()) {
|
|
27940
28027
|
preserveSet.add(preserveAbs);
|
|
@@ -27948,7 +28035,7 @@ function clearContextDirectoryForCloudReplace(contextDirAbs) {
|
|
|
27948
28035
|
return;
|
|
27949
28036
|
}
|
|
27950
28037
|
for (const e of entries) {
|
|
27951
|
-
const full =
|
|
28038
|
+
const full = path57.join(dir, e.name);
|
|
27952
28039
|
if (e.isDirectory()) {
|
|
27953
28040
|
walkRm(full);
|
|
27954
28041
|
try {
|
|
@@ -27956,7 +28043,7 @@ function clearContextDirectoryForCloudReplace(contextDirAbs) {
|
|
|
27956
28043
|
} catch {
|
|
27957
28044
|
}
|
|
27958
28045
|
} else if (e.isFile()) {
|
|
27959
|
-
const abs =
|
|
28046
|
+
const abs = path57.resolve(full);
|
|
27960
28047
|
if (preserveSet.has(abs)) {
|
|
27961
28048
|
continue;
|
|
27962
28049
|
}
|
|
@@ -28029,7 +28116,7 @@ async function runDownloadPipeline(opts) {
|
|
|
28029
28116
|
failed.push({ id, message: "Missing name on srs_discovery node." });
|
|
28030
28117
|
continue;
|
|
28031
28118
|
}
|
|
28032
|
-
if (name === UPLOAD_TARGET_FILENAME ||
|
|
28119
|
+
if (name === UPLOAD_TARGET_FILENAME || path57.basename(name) === UPLOAD_TARGET_FILENAME) {
|
|
28033
28120
|
skipped += 1;
|
|
28034
28121
|
log?.(`[pipeline:download] skip ${name} (upload target row).`);
|
|
28035
28122
|
continue;
|
|
@@ -28040,7 +28127,7 @@ async function runDownloadPipeline(opts) {
|
|
|
28040
28127
|
failed.push({ id, name, message: "Unsafe or invalid name for local path." });
|
|
28041
28128
|
continue;
|
|
28042
28129
|
}
|
|
28043
|
-
fs60.mkdirSync(
|
|
28130
|
+
fs60.mkdirSync(path57.dirname(outAbs), { recursive: true });
|
|
28044
28131
|
const exists = fs60.existsSync(outAbs);
|
|
28045
28132
|
if (exists && !opts.force && !opts.replaceFromCloud) {
|
|
28046
28133
|
skipped += 1;
|
|
@@ -28123,12 +28210,12 @@ function toFetchErrorMessage(e) {
|
|
|
28123
28210
|
|
|
28124
28211
|
// src/auth/gluecharmContentNegotiation.ts
|
|
28125
28212
|
var GLUECHARM_WS_LEGACY_JSON = "application/vnd.gluecharm.v1.ws-legacy+json";
|
|
28126
|
-
function pathWithoutQuery(
|
|
28127
|
-
const q =
|
|
28128
|
-
return q === -1 ?
|
|
28213
|
+
function pathWithoutQuery(path62) {
|
|
28214
|
+
const q = path62.indexOf("?");
|
|
28215
|
+
return q === -1 ? path62 : path62.slice(0, q);
|
|
28129
28216
|
}
|
|
28130
|
-
function isGluecharmContentApiPath(
|
|
28131
|
-
const p = pathWithoutQuery(
|
|
28217
|
+
function isGluecharmContentApiPath(path62) {
|
|
28218
|
+
const p = pathWithoutQuery(path62);
|
|
28132
28219
|
return p.startsWith("/api/content/") || p.startsWith("/api/batch/content/");
|
|
28133
28220
|
}
|
|
28134
28221
|
function gluecharmContentHeaders(method) {
|
|
@@ -28166,7 +28253,7 @@ async function fetchWithTimeout2(url, init, fetchImpl, timeoutMs, externalSignal
|
|
|
28166
28253
|
}
|
|
28167
28254
|
function createAuthenticatedRequestJson(deps) {
|
|
28168
28255
|
const fetchImpl = deps.fetchImpl ?? fetch;
|
|
28169
|
-
async function requestJson(
|
|
28256
|
+
async function requestJson(path62, options = {}) {
|
|
28170
28257
|
const base = deps.getApiBaseUrl();
|
|
28171
28258
|
if (!base) {
|
|
28172
28259
|
const err = { status: 0, message: "easyspecs.apiBaseUrl is not configured." };
|
|
@@ -28174,7 +28261,7 @@ function createAuthenticatedRequestJson(deps) {
|
|
|
28174
28261
|
}
|
|
28175
28262
|
const method = options.method ?? "GET";
|
|
28176
28263
|
const headers = { ...options.headers };
|
|
28177
|
-
if (isGluecharmContentApiPath(
|
|
28264
|
+
if (isGluecharmContentApiPath(path62)) {
|
|
28178
28265
|
Object.assign(headers, gluecharmContentHeaders(method));
|
|
28179
28266
|
} else {
|
|
28180
28267
|
if (!headers.Accept) {
|
|
@@ -28188,7 +28275,7 @@ function createAuthenticatedRequestJson(deps) {
|
|
|
28188
28275
|
if (options.withAuth !== false && access) {
|
|
28189
28276
|
headers.Authorization = `Bearer ${access}`;
|
|
28190
28277
|
}
|
|
28191
|
-
const url = `${base}${
|
|
28278
|
+
const url = `${base}${path62}`;
|
|
28192
28279
|
const timeoutMs = options.timeoutMs ?? API_TIMEOUT_MS;
|
|
28193
28280
|
const response = await fetchWithTimeout2(
|
|
28194
28281
|
url,
|
|
@@ -28209,7 +28296,7 @@ function createAuthenticatedRequestJson(deps) {
|
|
|
28209
28296
|
if (shouldRetryUnauthorized) {
|
|
28210
28297
|
const refreshed = await deps.refreshSession();
|
|
28211
28298
|
if (refreshed) {
|
|
28212
|
-
return requestJson(
|
|
28299
|
+
return requestJson(path62, { ...options, retryOnUnauthorized: false });
|
|
28213
28300
|
}
|
|
28214
28301
|
}
|
|
28215
28302
|
const fallback = payload == null ? `${response.statusText || "HTTP error"} (response body empty or not JSON)` : "Request failed.";
|
|
@@ -28221,13 +28308,13 @@ function createAuthenticatedRequestJson(deps) {
|
|
|
28221
28308
|
// src/cli/cliSession.ts
|
|
28222
28309
|
var fs61 = __toESM(require("node:fs"));
|
|
28223
28310
|
var os7 = __toESM(require("node:os"));
|
|
28224
|
-
var
|
|
28311
|
+
var path58 = __toESM(require("node:path"));
|
|
28225
28312
|
function defaultSessionPath() {
|
|
28226
|
-
return
|
|
28313
|
+
return path58.join(os7.homedir(), ".easyspecs", "cli-session.json");
|
|
28227
28314
|
}
|
|
28228
28315
|
var configSessionPath;
|
|
28229
28316
|
function setCliSessionPathFromConfig(absPath) {
|
|
28230
|
-
configSessionPath = absPath?.trim() ?
|
|
28317
|
+
configSessionPath = absPath?.trim() ? path58.resolve(absPath) : void 0;
|
|
28231
28318
|
}
|
|
28232
28319
|
function applyCliSessionPathFromRepoConfig(repoRoot, cfg) {
|
|
28233
28320
|
const raw = cfg.easyspecs?.cliSessionPath?.trim();
|
|
@@ -28235,7 +28322,7 @@ function applyCliSessionPathFromRepoConfig(repoRoot, cfg) {
|
|
|
28235
28322
|
setCliSessionPathFromConfig(void 0);
|
|
28236
28323
|
return;
|
|
28237
28324
|
}
|
|
28238
|
-
const abs =
|
|
28325
|
+
const abs = path58.isAbsolute(raw) ? raw : path58.join(repoRoot, raw);
|
|
28239
28326
|
setCliSessionPathFromConfig(abs);
|
|
28240
28327
|
}
|
|
28241
28328
|
function normalizeCliSessionPathForConfig(repoRoot, raw) {
|
|
@@ -28243,15 +28330,15 @@ function normalizeCliSessionPathForConfig(repoRoot, raw) {
|
|
|
28243
28330
|
if (!t) {
|
|
28244
28331
|
return "";
|
|
28245
28332
|
}
|
|
28246
|
-
const resolvedRepo =
|
|
28247
|
-
const abs =
|
|
28248
|
-
const rel =
|
|
28333
|
+
const resolvedRepo = path58.resolve(repoRoot);
|
|
28334
|
+
const abs = path58.isAbsolute(t) ? path58.normalize(t) : path58.resolve(resolvedRepo, t);
|
|
28335
|
+
const rel = path58.relative(resolvedRepo, abs);
|
|
28249
28336
|
if (rel === "") {
|
|
28250
28337
|
return abs;
|
|
28251
28338
|
}
|
|
28252
|
-
const underRepo = !rel.startsWith("..") && !
|
|
28339
|
+
const underRepo = !rel.startsWith("..") && !path58.isAbsolute(rel);
|
|
28253
28340
|
if (underRepo) {
|
|
28254
|
-
return rel.split(
|
|
28341
|
+
return rel.split(path58.sep).join("/");
|
|
28255
28342
|
}
|
|
28256
28343
|
return abs;
|
|
28257
28344
|
}
|
|
@@ -28281,7 +28368,7 @@ function readCliSession() {
|
|
|
28281
28368
|
}
|
|
28282
28369
|
function writeCliSession(s) {
|
|
28283
28370
|
const p = effectiveCliSessionPath();
|
|
28284
|
-
fs61.mkdirSync(
|
|
28371
|
+
fs61.mkdirSync(path58.dirname(p), { recursive: true });
|
|
28285
28372
|
fs61.writeFileSync(p, `${JSON.stringify(s, null, 2)}
|
|
28286
28373
|
`, "utf8");
|
|
28287
28374
|
}
|
|
@@ -28295,7 +28382,7 @@ function clearCliSession() {
|
|
|
28295
28382
|
|
|
28296
28383
|
// src/analysis/acePendingTraces.ts
|
|
28297
28384
|
var fs62 = __toESM(require("fs"));
|
|
28298
|
-
var
|
|
28385
|
+
var path59 = __toESM(require("path"));
|
|
28299
28386
|
function normalizeAceTraceRelativePath(rel) {
|
|
28300
28387
|
return rel.split(/[/\\]/).join("/");
|
|
28301
28388
|
}
|
|
@@ -28345,7 +28432,7 @@ function listPendingAceTraceFiles(contextDir2, worktreeRoot) {
|
|
|
28345
28432
|
const allAbs = listAceTraceFiles(contextDir2);
|
|
28346
28433
|
const pending = [];
|
|
28347
28434
|
for (const abs of allAbs) {
|
|
28348
|
-
const rel = normalizeAceTraceRelativePath(
|
|
28435
|
+
const rel = normalizeAceTraceRelativePath(path59.relative(contextDir2, abs));
|
|
28349
28436
|
const v = validateAceJsonFile(abs, traceSchema);
|
|
28350
28437
|
if (!v.ok) {
|
|
28351
28438
|
continue;
|
|
@@ -28360,7 +28447,7 @@ function listPendingAceTraceFiles(contextDir2, worktreeRoot) {
|
|
|
28360
28447
|
}
|
|
28361
28448
|
|
|
28362
28449
|
// src/analysis/aceAutoLearnPool.ts
|
|
28363
|
-
var
|
|
28450
|
+
var path60 = __toESM(require("path"));
|
|
28364
28451
|
function clampConcurrency2(n) {
|
|
28365
28452
|
if (!Number.isFinite(n)) {
|
|
28366
28453
|
return DEFAULT_MAX_CONCURRENT_AI;
|
|
@@ -28395,8 +28482,8 @@ async function runAceAutoLearnPool(p) {
|
|
|
28395
28482
|
};
|
|
28396
28483
|
const currentCap = () => Math.min(staticMaxC, adaptiveMax);
|
|
28397
28484
|
let wake;
|
|
28398
|
-
const waitTurn = () => new Promise((
|
|
28399
|
-
wake =
|
|
28485
|
+
const waitTurn = () => new Promise((resolve24) => {
|
|
28486
|
+
wake = resolve24;
|
|
28400
28487
|
});
|
|
28401
28488
|
const pump = () => {
|
|
28402
28489
|
wake?.();
|
|
@@ -28418,7 +28505,7 @@ async function runAceAutoLearnPool(p) {
|
|
|
28418
28505
|
poolAbortListenerRegistered = true;
|
|
28419
28506
|
}
|
|
28420
28507
|
}
|
|
28421
|
-
const traceRel = (abs) =>
|
|
28508
|
+
const traceRel = (abs) => path60.relative(contextDir2, abs).split(path60.sep).join("/");
|
|
28422
28509
|
const runOne = async (traceAbs) => {
|
|
28423
28510
|
if (abortSignal?.aborted) {
|
|
28424
28511
|
active -= 1;
|
|
@@ -28949,7 +29036,7 @@ function formatCliStderrLine(line, useAnsi) {
|
|
|
28949
29036
|
}
|
|
28950
29037
|
|
|
28951
29038
|
// src/cli/main.ts
|
|
28952
|
-
var PKG_VERSION = "0.
|
|
29039
|
+
var PKG_VERSION = "0.3.0";
|
|
28953
29040
|
function isNonEmptyFactoryFailureArray(x) {
|
|
28954
29041
|
if (!Array.isArray(x) || x.length === 0) {
|
|
28955
29042
|
return false;
|
|
@@ -29091,23 +29178,23 @@ function resolveAnalysisRoot(repoRoot, rootKind, worktreePath) {
|
|
|
29091
29178
|
return repoRoot;
|
|
29092
29179
|
}
|
|
29093
29180
|
const wt = worktreePath?.trim();
|
|
29094
|
-
if (wt && fs63.existsSync(
|
|
29095
|
-
return
|
|
29181
|
+
if (wt && fs63.existsSync(path61.join(wt, ".git"))) {
|
|
29182
|
+
return path61.resolve(wt);
|
|
29096
29183
|
}
|
|
29097
29184
|
throw new Error("worktree mode requires --worktree <path> to an existing analysis checkout.");
|
|
29098
29185
|
}
|
|
29099
29186
|
function resolveAdHocCheckoutRoot(_repoRoot, storage, worktreeFlag) {
|
|
29100
29187
|
const w = worktreeFlag?.trim();
|
|
29101
29188
|
if (w) {
|
|
29102
|
-
const abs =
|
|
29103
|
-
if (fs63.existsSync(
|
|
29189
|
+
const abs = path61.resolve(w);
|
|
29190
|
+
if (fs63.existsSync(path61.join(abs, ".git"))) {
|
|
29104
29191
|
return abs;
|
|
29105
29192
|
}
|
|
29106
29193
|
throw new Error(`Invalid --worktree (not a git checkout): ${abs}`);
|
|
29107
29194
|
}
|
|
29108
29195
|
const snap = readAnalysisWorkspaceSnapshot(storage);
|
|
29109
29196
|
const p = snap?.adHocWorktreePath?.trim();
|
|
29110
|
-
if (p && fs63.existsSync(
|
|
29197
|
+
if (p && fs63.existsSync(path61.join(p, ".git"))) {
|
|
29111
29198
|
return p;
|
|
29112
29199
|
}
|
|
29113
29200
|
throw new Error("No analysis checkout: run `easyspecs-cli run synthesis` first or pass `--worktree <path>`.");
|
|
@@ -29134,7 +29221,7 @@ async function runResumeRemediationPool(storage, repoRoot, analysisRoot, merged,
|
|
|
29134
29221
|
requireOpenCode(merged, flags);
|
|
29135
29222
|
const agentsDir = resolveOpenCodeAgentsDir(repoRoot, repoConfig);
|
|
29136
29223
|
assertAgentsDirExists(agentsDir);
|
|
29137
|
-
const ctxDir =
|
|
29224
|
+
const ctxDir = path61.join(analysisRoot, ".gluecharm", "context");
|
|
29138
29225
|
const snap = readArtefactRunSnapshot(storage);
|
|
29139
29226
|
const rows = listMissingWorkstations(ctxDir, analysisRoot, snap);
|
|
29140
29227
|
if (rows.length === 0) {
|
|
@@ -29152,7 +29239,7 @@ async function runResumeRemediationPool(storage, repoRoot, analysisRoot, merged,
|
|
|
29152
29239
|
storageContext: storage,
|
|
29153
29240
|
repositoryRoot: repoRoot,
|
|
29154
29241
|
worktreeRoot: analysisRoot,
|
|
29155
|
-
workspaceLabel:
|
|
29242
|
+
workspaceLabel: path61.basename(analysisRoot),
|
|
29156
29243
|
oc,
|
|
29157
29244
|
log: (line) => logErr(flags, line),
|
|
29158
29245
|
abortSignal: void 0,
|
|
@@ -29329,17 +29416,17 @@ async function main() {
|
|
|
29329
29416
|
{ easyspecs: { defaultGitRemoteUrl: url } },
|
|
29330
29417
|
{ warnMigration: (m) => logErr(flags, `[EasySpecs] ${m}`) }
|
|
29331
29418
|
);
|
|
29332
|
-
const
|
|
29419
|
+
const path62 = easyspecsConfigPath(repoRoot);
|
|
29333
29420
|
if (flags.json) {
|
|
29334
29421
|
printJsonLine({
|
|
29335
29422
|
command: "config set-git-remote",
|
|
29336
29423
|
durationMs: Date.now() - t0,
|
|
29337
29424
|
ok: true,
|
|
29338
|
-
path:
|
|
29425
|
+
path: path62,
|
|
29339
29426
|
defaultGitRemoteUrl: cfg.easyspecs?.defaultGitRemoteUrl ?? ""
|
|
29340
29427
|
});
|
|
29341
29428
|
} else {
|
|
29342
|
-
console.log(`Updated ${
|
|
29429
|
+
console.log(`Updated ${path62} \u2014 easyspecs.defaultGitRemoteUrl`);
|
|
29343
29430
|
}
|
|
29344
29431
|
process.exit(ExitCode.ok);
|
|
29345
29432
|
} catch (e) {
|
|
@@ -29372,7 +29459,7 @@ async function main() {
|
|
|
29372
29459
|
applyCliSessionPathFromRepoConfig(repoRoot, repoConfig);
|
|
29373
29460
|
if (flags.sessionPath?.trim()) {
|
|
29374
29461
|
const sp = flags.sessionPath.trim();
|
|
29375
|
-
const abs =
|
|
29462
|
+
const abs = path61.isAbsolute(sp) ? path61.normalize(sp) : path61.resolve(repoRoot, sp);
|
|
29376
29463
|
setCliSessionPathFromConfig(abs);
|
|
29377
29464
|
}
|
|
29378
29465
|
const apiResolved = initApiBaseUrlForCli(repoRoot, flags, repoConfig);
|
|
@@ -29613,7 +29700,7 @@ async function main() {
|
|
|
29613
29700
|
const result = await runSynthesisPipeline(
|
|
29614
29701
|
storage,
|
|
29615
29702
|
repoRoot,
|
|
29616
|
-
|
|
29703
|
+
path61.basename(repoRoot),
|
|
29617
29704
|
agentsDir,
|
|
29618
29705
|
{
|
|
29619
29706
|
...merged.pipelineOpenCode
|
|
@@ -29668,7 +29755,7 @@ async function main() {
|
|
|
29668
29755
|
if (sub === "reference-coverage") {
|
|
29669
29756
|
const rootAbs = resolveAnalysisRoot(repoRoot, rootKind, worktree);
|
|
29670
29757
|
requireMinimalGluecharmLayoutAt(rootAbs);
|
|
29671
|
-
const contextDir2 =
|
|
29758
|
+
const contextDir2 = path61.join(rootAbs, ".gluecharm", "context");
|
|
29672
29759
|
const res = runCoveragePipeline({
|
|
29673
29760
|
repositoryRootAbs: rootAbs,
|
|
29674
29761
|
contextDirAbs: contextDir2,
|
|
@@ -29691,7 +29778,7 @@ async function main() {
|
|
|
29691
29778
|
if (sub === "coordination-duplicates") {
|
|
29692
29779
|
const rootAbs = resolveAnalysisRoot(repoRoot, rootKind, worktree);
|
|
29693
29780
|
requireMinimalGluecharmLayoutAt(rootAbs);
|
|
29694
|
-
const contextDir2 =
|
|
29781
|
+
const contextDir2 = path61.join(rootAbs, ".gluecharm", "context");
|
|
29695
29782
|
const res = runCoordinationDuplicatesDiagnosis({
|
|
29696
29783
|
contextDirAbsolute: contextDir2,
|
|
29697
29784
|
sourceRoot: rootKind === "worktree" ? "worktree" : "workspace"
|
|
@@ -29727,7 +29814,7 @@ async function main() {
|
|
|
29727
29814
|
if (sub === "missing-artefacts") {
|
|
29728
29815
|
const rootAbs = resolveAnalysisRoot(repoRoot, rootKind, worktree);
|
|
29729
29816
|
requireMinimalGluecharmLayoutAt(rootAbs);
|
|
29730
|
-
const ctxDir =
|
|
29817
|
+
const ctxDir = path61.join(rootAbs, ".gluecharm", "context");
|
|
29731
29818
|
const storage = createFileBackedWorkspaceState(repoRoot);
|
|
29732
29819
|
const snap = readArtefactRunSnapshot(storage);
|
|
29733
29820
|
const rows = listMissingWorkstations(ctxDir, rootAbs, snap);
|
|
@@ -29777,7 +29864,7 @@ async function main() {
|
|
|
29777
29864
|
});
|
|
29778
29865
|
const bad = poolRes.cancelled || poolRes.failures > 0;
|
|
29779
29866
|
if (!bad) {
|
|
29780
|
-
const ctxDir =
|
|
29867
|
+
const ctxDir = path61.join(analysisRoot, ".gluecharm", "context");
|
|
29781
29868
|
const lg = runLinkMappingPipeline(ctxDir, { log: (line) => logErr(flags, line) });
|
|
29782
29869
|
if (!lg.ok) {
|
|
29783
29870
|
finish(OsExit.diagnoseZeroReferenceLinkMapping, {
|
|
@@ -29807,7 +29894,7 @@ async function main() {
|
|
|
29807
29894
|
const worktree = wtExplicit ?? wtFromRoot;
|
|
29808
29895
|
const rootAbs = resolveAnalysisRoot(repoRoot, rootKind, worktree);
|
|
29809
29896
|
requireMinimalGluecharmLayoutAt(rootAbs);
|
|
29810
|
-
const contextDir2 =
|
|
29897
|
+
const contextDir2 = path61.join(rootAbs, ".gluecharm", "context");
|
|
29811
29898
|
const res = runLinkMappingPipeline(contextDir2, {
|
|
29812
29899
|
log: (line) => logErr(flags, line)
|
|
29813
29900
|
});
|
|
@@ -29985,8 +30072,8 @@ async function main() {
|
|
|
29985
30072
|
const snap = readAnalysisWorkspaceSnapshot(storage);
|
|
29986
30073
|
const wt = snap?.adHocWorktreePath?.trim();
|
|
29987
30074
|
if (wt) {
|
|
29988
|
-
const sourceCtx =
|
|
29989
|
-
if (
|
|
30075
|
+
const sourceCtx = path61.join(wt, ".gluecharm", "context");
|
|
30076
|
+
if (path61.resolve(wt) === path61.resolve(repoRoot)) {
|
|
29990
30077
|
logErr(
|
|
29991
30078
|
flags,
|
|
29992
30079
|
"[pipeline:analysis] promote skipped (in-place: analysis checkout is the repository root)"
|
|
@@ -30088,10 +30175,10 @@ async function main() {
|
|
|
30088
30175
|
finish(ExitCode.usage, { ok: false, error: `unknown download context flag: ${a}` });
|
|
30089
30176
|
}
|
|
30090
30177
|
requireMinimalGluecharmLayoutAt(repoRoot);
|
|
30091
|
-
const ctxDir =
|
|
30092
|
-
const gluecharmParent =
|
|
30093
|
-
if (
|
|
30094
|
-
requireMinimalGluecharmLayoutAt(
|
|
30178
|
+
const ctxDir = path61.resolve(path61.join(repoRoot, ".gluecharm", "context"));
|
|
30179
|
+
const gluecharmParent = path61.dirname(ctxDir);
|
|
30180
|
+
if (path61.basename(gluecharmParent) === ".gluecharm" && path61.basename(ctxDir) === "context") {
|
|
30181
|
+
requireMinimalGluecharmLayoutAt(path61.dirname(gluecharmParent));
|
|
30095
30182
|
}
|
|
30096
30183
|
const appIdRaw = getEasyspecsProjectIdFromRepoConfig(repoConfig)?.trim();
|
|
30097
30184
|
if (!appIdRaw) {
|
|
@@ -30174,16 +30261,16 @@ async function main() {
|
|
|
30174
30261
|
}
|
|
30175
30262
|
const sess = sessRaw;
|
|
30176
30263
|
requireMinimalGluecharmLayoutAt(repoRoot);
|
|
30177
|
-
let ctxDir =
|
|
30264
|
+
let ctxDir = path61.join(repoRoot, ".gluecharm", "context");
|
|
30178
30265
|
if (pos[1] === "republish") {
|
|
30179
30266
|
const fromCfg = repoConfig.easyspecs?.upload?.contextDirectory?.trim();
|
|
30180
|
-
const resolvedOverride = fromCfg && fromCfg.length > 0 ?
|
|
30181
|
-
if (resolvedOverride && fs63.existsSync(
|
|
30267
|
+
const resolvedOverride = fromCfg && fromCfg.length > 0 ? path61.isAbsolute(fromCfg) ? path61.normalize(fromCfg) : path61.resolve(repoRoot, fromCfg) : "";
|
|
30268
|
+
if (resolvedOverride && fs63.existsSync(path61.join(resolvedOverride, ".."))) {
|
|
30182
30269
|
ctxDir = resolvedOverride;
|
|
30183
30270
|
} else {
|
|
30184
30271
|
const storage = createFileBackedWorkspaceState(repoRoot);
|
|
30185
30272
|
const snap = readAnalysisWorkspaceSnapshot(storage);
|
|
30186
|
-
const wt = snap?.adHocWorktreePath && fs63.existsSync(
|
|
30273
|
+
const wt = snap?.adHocWorktreePath && fs63.existsSync(path61.join(snap.adHocWorktreePath, ".gluecharm", "context")) ? path61.join(snap.adHocWorktreePath, ".gluecharm", "context") : "";
|
|
30187
30274
|
if (!wt) {
|
|
30188
30275
|
finish(ExitCode.misconfiguration, {
|
|
30189
30276
|
ok: false,
|
|
@@ -30193,10 +30280,10 @@ async function main() {
|
|
|
30193
30280
|
ctxDir = wt;
|
|
30194
30281
|
}
|
|
30195
30282
|
}
|
|
30196
|
-
const ctxResolved =
|
|
30197
|
-
const gluecharmParent =
|
|
30198
|
-
if (
|
|
30199
|
-
requireMinimalGluecharmLayoutAt(
|
|
30283
|
+
const ctxResolved = path61.resolve(ctxDir);
|
|
30284
|
+
const gluecharmParent = path61.dirname(ctxResolved);
|
|
30285
|
+
if (path61.basename(gluecharmParent) === ".gluecharm" && path61.basename(ctxResolved) === "context") {
|
|
30286
|
+
requireMinimalGluecharmLayoutAt(path61.dirname(gluecharmParent));
|
|
30200
30287
|
}
|
|
30201
30288
|
const appIdRaw = getEasyspecsProjectIdFromRepoConfig(repoConfig)?.trim();
|
|
30202
30289
|
if (!appIdRaw) {
|
|
@@ -30300,7 +30387,7 @@ async function main() {
|
|
|
30300
30387
|
finish(failed ? ExitCode.upload : ExitCode.ok, primary);
|
|
30301
30388
|
}
|
|
30302
30389
|
if (pos[0] === "ace" && pos[1] === "clear") {
|
|
30303
|
-
const learnings =
|
|
30390
|
+
const learnings = path61.join(repoRoot, ".gluecharm", "context", "learnings");
|
|
30304
30391
|
if (!fs63.existsSync(learnings)) {
|
|
30305
30392
|
finish(ExitCode.ok, { ok: true, message: "nothing to clear" });
|
|
30306
30393
|
}
|
|
@@ -30310,8 +30397,8 @@ async function main() {
|
|
|
30310
30397
|
if (pos[0] === "ace" && pos[1] === "learn") {
|
|
30311
30398
|
requireOpenCode(merged, flags);
|
|
30312
30399
|
const { worktree } = parseWorktreeFlag(pos.slice(2));
|
|
30313
|
-
const root = worktree && fs63.existsSync(
|
|
30314
|
-
const contextDir2 =
|
|
30400
|
+
const root = worktree && fs63.existsSync(path61.join(worktree, ".opencode", "schemas", "ace")) ? worktree : repoRoot;
|
|
30401
|
+
const contextDir2 = path61.join(root, ".gluecharm", "context");
|
|
30315
30402
|
const traces = listAceTraceFiles(contextDir2);
|
|
30316
30403
|
if (traces.length === 0) {
|
|
30317
30404
|
finish(ExitCode.ok, { ok: true, message: "no traces", traceCount: 0 });
|
|
@@ -30335,8 +30422,8 @@ async function main() {
|
|
|
30335
30422
|
if (pos[0] === "ace" && pos[1] === "auto-learn") {
|
|
30336
30423
|
requireOpenCode(merged, flags);
|
|
30337
30424
|
const { worktree } = parseWorktreeFlag(pos.slice(2));
|
|
30338
|
-
const root = worktree && fs63.existsSync(
|
|
30339
|
-
const contextDir2 =
|
|
30425
|
+
const root = worktree && fs63.existsSync(path61.join(worktree, ".git")) ? worktree : repoRoot;
|
|
30426
|
+
const contextDir2 = path61.join(root, ".gluecharm", "context");
|
|
30340
30427
|
const pending = listPendingAceTraceFiles(contextDir2, root);
|
|
30341
30428
|
if (pending.length === 0) {
|
|
30342
30429
|
finish(ExitCode.ok, { ok: true, pending: 0 });
|