@c4a/context-cli 0.6.5 → 0.6.7
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/cli.js +1022 -724
- package/package.json +2 -2
- package/plugins/VERSION +1 -1
- package/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/plugins/codex/.codex-plugin/plugin.json +2 -2
- package/plugins/cursor/.cursor-plugin/plugin.json +1 -1
- package/providers/context/manifest.json +3 -3
- package/providers/context/provider.yaml +1 -1
package/cli.js
CHANGED
|
@@ -17720,17 +17720,17 @@ var init_writeLock = __esm(() => {
|
|
|
17720
17720
|
|
|
17721
17721
|
// src/project/packageTemplateReview.ts
|
|
17722
17722
|
import { createHash as createHash12 } from "node:crypto";
|
|
17723
|
-
import { existsSync as
|
|
17723
|
+
import { existsSync as existsSync15 } from "node:fs";
|
|
17724
17724
|
import { mkdir as mkdir13, readFile as readFile20, readdir as readdir8, writeFile as writeFile9 } from "node:fs/promises";
|
|
17725
|
-
import { dirname as
|
|
17725
|
+
import { dirname as dirname18, join as join25, relative as relative10, resolve as resolve14 } from "node:path";
|
|
17726
17726
|
async function templateFiles(root) {
|
|
17727
|
-
if (!
|
|
17727
|
+
if (!existsSync15(root))
|
|
17728
17728
|
return [];
|
|
17729
17729
|
const files = [];
|
|
17730
17730
|
const visit2 = async (dir) => {
|
|
17731
17731
|
const entries = await readdir8(dir, { withFileTypes: true });
|
|
17732
17732
|
for (const entry of entries) {
|
|
17733
|
-
const absolutePath =
|
|
17733
|
+
const absolutePath = join25(dir, entry.name);
|
|
17734
17734
|
if (entry.isDirectory()) {
|
|
17735
17735
|
await visit2(absolutePath);
|
|
17736
17736
|
continue;
|
|
@@ -17757,8 +17757,8 @@ function isMarker(value) {
|
|
|
17757
17757
|
return marker.schema === PACKAGE_TEMPLATE_REVIEW_SCHEMA && /^sha256:[a-f0-9]{64}$/u.test(marker.starter_digest ?? "") && (marker.disposition === "review-required" || marker.disposition === "starter-accepted");
|
|
17758
17758
|
}
|
|
17759
17759
|
async function readMarker(templateRoot) {
|
|
17760
|
-
const markerPath =
|
|
17761
|
-
if (!
|
|
17760
|
+
const markerPath = join25(templateRoot, PACKAGE_TEMPLATE_REVIEW_FILE);
|
|
17761
|
+
if (!existsSync15(markerPath))
|
|
17762
17762
|
return null;
|
|
17763
17763
|
try {
|
|
17764
17764
|
const parsed = JSON.parse(await readFile20(markerPath, "utf8"));
|
|
@@ -17768,15 +17768,15 @@ async function readMarker(templateRoot) {
|
|
|
17768
17768
|
}
|
|
17769
17769
|
}
|
|
17770
17770
|
async function writeStarterTemplateReviewMarker(templateRoot) {
|
|
17771
|
-
const markerPath =
|
|
17772
|
-
if (
|
|
17771
|
+
const markerPath = join25(templateRoot, PACKAGE_TEMPLATE_REVIEW_FILE);
|
|
17772
|
+
if (existsSync15(markerPath))
|
|
17773
17773
|
return false;
|
|
17774
17774
|
const marker = {
|
|
17775
17775
|
schema: PACKAGE_TEMPLATE_REVIEW_SCHEMA,
|
|
17776
17776
|
starter_digest: await templateDigest(templateRoot),
|
|
17777
17777
|
disposition: "review-required"
|
|
17778
17778
|
};
|
|
17779
|
-
await mkdir13(
|
|
17779
|
+
await mkdir13(dirname18(markerPath), { recursive: true });
|
|
17780
17780
|
await writeFile9(markerPath, `${JSON.stringify(marker, null, 2)}
|
|
17781
17781
|
`, "utf8");
|
|
17782
17782
|
return true;
|
|
@@ -17796,7 +17796,7 @@ async function inspectPackageTemplateReview(projectRoot, pkg) {
|
|
|
17796
17796
|
packageName: pkg.name,
|
|
17797
17797
|
templatePath: pkg.template.path,
|
|
17798
17798
|
state: "invalid",
|
|
17799
|
-
diagnostic: `${
|
|
17799
|
+
diagnostic: `${join25(pkg.template.path, PACKAGE_TEMPLATE_REVIEW_FILE)} is invalid`
|
|
17800
17800
|
};
|
|
17801
17801
|
}
|
|
17802
17802
|
const currentDigest = await templateDigest(templateRoot);
|
|
@@ -17837,8 +17837,8 @@ async function acceptStarterPackageTemplates(input) {
|
|
|
17837
17837
|
alreadyResolved.push(pkg.name);
|
|
17838
17838
|
continue;
|
|
17839
17839
|
}
|
|
17840
|
-
const markerPath =
|
|
17841
|
-
const marker = await readMarker(
|
|
17840
|
+
const markerPath = join25(input.projectRoot, pkg.template.path, PACKAGE_TEMPLATE_REVIEW_FILE);
|
|
17841
|
+
const marker = await readMarker(join25(input.projectRoot, pkg.template.path));
|
|
17842
17842
|
if (marker === null || marker === "invalid") {
|
|
17843
17843
|
throw new ContextError(ExitCode.WorkspaceStateError, "package template review marker changed before acceptance", {
|
|
17844
17844
|
category: ErrorCategory.WorkspaceStateInvalid,
|
|
@@ -17866,6 +17866,7 @@ var init_packageTemplateReview = __esm(() => {
|
|
|
17866
17866
|
// src/project/workspace.ts
|
|
17867
17867
|
var exports_workspace = {};
|
|
17868
17868
|
__export(exports_workspace, {
|
|
17869
|
+
resolveContextProjectInitTarget: () => resolveContextProjectInitTarget,
|
|
17869
17870
|
projectLanguage: () => projectLanguage,
|
|
17870
17871
|
loadContextProjectModule: () => loadContextProjectModule,
|
|
17871
17872
|
isContextProjectRoot: () => isContextProjectRoot,
|
|
@@ -17876,30 +17877,30 @@ __export(exports_workspace, {
|
|
|
17876
17877
|
assertContextStatusWorkspaceAllowed: () => assertContextStatusWorkspaceAllowed,
|
|
17877
17878
|
PROJECT_LANGUAGES: () => PROJECT_LANGUAGES
|
|
17878
17879
|
});
|
|
17879
|
-
import { existsSync as
|
|
17880
|
+
import { existsSync as existsSync16, readFileSync as readFileSync6 } from "node:fs";
|
|
17880
17881
|
import { mkdir as mkdir14, readFile as readFile21, readdir as readdir9, writeFile as writeFile10 } from "node:fs/promises";
|
|
17881
17882
|
import { createRequire as createRequire3 } from "node:module";
|
|
17882
|
-
import { basename as basename5, dirname as
|
|
17883
|
-
import { fileURLToPath as
|
|
17883
|
+
import { basename as basename5, dirname as dirname19, isAbsolute as isAbsolute6, join as join26, parse as parse6, relative as relative11, resolve as resolve15 } from "node:path";
|
|
17884
|
+
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
17884
17885
|
import { createJiti } from "jiti";
|
|
17885
|
-
function
|
|
17886
|
+
function isRecord13(value) {
|
|
17886
17887
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
17887
17888
|
}
|
|
17888
17889
|
function readPackageJson(root) {
|
|
17889
|
-
const packagePath =
|
|
17890
|
-
if (!
|
|
17890
|
+
const packagePath = join26(root, "package.json");
|
|
17891
|
+
if (!existsSync16(packagePath))
|
|
17891
17892
|
return null;
|
|
17892
17893
|
try {
|
|
17893
|
-
const parsed = JSON.parse(
|
|
17894
|
-
return
|
|
17894
|
+
const parsed = JSON.parse(readFileSync6(packagePath, "utf8"));
|
|
17895
|
+
return isRecord13(parsed) ? parsed : null;
|
|
17895
17896
|
} catch {
|
|
17896
17897
|
return null;
|
|
17897
17898
|
}
|
|
17898
17899
|
}
|
|
17899
17900
|
function readPackageJsonFile(packageJsonPath) {
|
|
17900
17901
|
try {
|
|
17901
|
-
const parsed = JSON.parse(
|
|
17902
|
-
return
|
|
17902
|
+
const parsed = JSON.parse(readFileSync6(packageJsonPath, "utf8"));
|
|
17903
|
+
return isRecord13(parsed) ? parsed : null;
|
|
17903
17904
|
} catch {
|
|
17904
17905
|
return null;
|
|
17905
17906
|
}
|
|
@@ -17910,22 +17911,22 @@ function resolveExportImportTarget(packageJsonPath) {
|
|
|
17910
17911
|
return null;
|
|
17911
17912
|
const exportsField = parsed.exports;
|
|
17912
17913
|
if (typeof exportsField === "string") {
|
|
17913
|
-
return
|
|
17914
|
+
return join26(dirname19(packageJsonPath), exportsField);
|
|
17914
17915
|
}
|
|
17915
|
-
if (
|
|
17916
|
+
if (isRecord13(exportsField)) {
|
|
17916
17917
|
const rootExport = exportsField["."];
|
|
17917
17918
|
if (typeof rootExport === "string") {
|
|
17918
|
-
return
|
|
17919
|
+
return join26(dirname19(packageJsonPath), rootExport);
|
|
17919
17920
|
}
|
|
17920
|
-
if (
|
|
17921
|
-
return
|
|
17921
|
+
if (isRecord13(rootExport) && typeof rootExport.import === "string") {
|
|
17922
|
+
return join26(dirname19(packageJsonPath), rootExport.import);
|
|
17922
17923
|
}
|
|
17923
17924
|
}
|
|
17924
17925
|
if (typeof parsed.module === "string") {
|
|
17925
|
-
return
|
|
17926
|
+
return join26(dirname19(packageJsonPath), parsed.module);
|
|
17926
17927
|
}
|
|
17927
17928
|
if (typeof parsed.main === "string") {
|
|
17928
|
-
return
|
|
17929
|
+
return join26(dirname19(packageJsonPath), parsed.main);
|
|
17929
17930
|
}
|
|
17930
17931
|
return null;
|
|
17931
17932
|
}
|
|
@@ -17941,16 +17942,16 @@ function resolveContextSdkImportAlias(entryPath) {
|
|
|
17941
17942
|
return "@c4a/context";
|
|
17942
17943
|
}
|
|
17943
17944
|
function readCurrentPackageVersion() {
|
|
17944
|
-
let dir =
|
|
17945
|
+
let dir = dirname19(fileURLToPath6(import.meta.url));
|
|
17945
17946
|
for (let index2 = 0;index2 < 8; index2++) {
|
|
17946
|
-
const packagePath =
|
|
17947
|
-
if (
|
|
17947
|
+
const packagePath = join26(dir, "package.json");
|
|
17948
|
+
if (existsSync16(packagePath)) {
|
|
17948
17949
|
const parsed = readPackageJson(dir);
|
|
17949
17950
|
if (typeof parsed?.version === "string" && parsed.version.trim().length > 0) {
|
|
17950
17951
|
return parsed.version;
|
|
17951
17952
|
}
|
|
17952
17953
|
}
|
|
17953
|
-
const parent =
|
|
17954
|
+
const parent = dirname19(dir);
|
|
17954
17955
|
if (parent === dir)
|
|
17955
17956
|
break;
|
|
17956
17957
|
dir = parent;
|
|
@@ -17959,7 +17960,7 @@ function readCurrentPackageVersion() {
|
|
|
17959
17960
|
}
|
|
17960
17961
|
function readContextProjectPackage(root) {
|
|
17961
17962
|
const parsed = readPackageJson(root);
|
|
17962
|
-
const context =
|
|
17963
|
+
const context = isRecord13(parsed?.context) ? parsed.context : null;
|
|
17963
17964
|
if (context?.project !== true || typeof context.entry !== "string" || context.entry.trim().length === 0) {
|
|
17964
17965
|
return null;
|
|
17965
17966
|
}
|
|
@@ -17970,7 +17971,7 @@ function readContextProjectPackage(root) {
|
|
|
17970
17971
|
}
|
|
17971
17972
|
function readContextWorkspaceDir(root) {
|
|
17972
17973
|
const parsed = readPackageJson(root);
|
|
17973
|
-
const context =
|
|
17974
|
+
const context = isRecord13(parsed?.context) ? parsed.context : null;
|
|
17974
17975
|
const workspaceDir = context?.workspaceDir;
|
|
17975
17976
|
if (typeof workspaceDir !== "string" || workspaceDir.trim().length === 0)
|
|
17976
17977
|
return null;
|
|
@@ -17978,7 +17979,7 @@ function readContextWorkspaceDir(root) {
|
|
|
17978
17979
|
}
|
|
17979
17980
|
function readContextProjectLanguage(root) {
|
|
17980
17981
|
const parsed = readPackageJson(root);
|
|
17981
|
-
const context =
|
|
17982
|
+
const context = isRecord13(parsed?.context) ? parsed.context : null;
|
|
17982
17983
|
return context?.language === "en" || context?.language === "zh-CN" ? context.language : undefined;
|
|
17983
17984
|
}
|
|
17984
17985
|
function isSameOrChildPath(path3, parent) {
|
|
@@ -17999,13 +18000,13 @@ function findContextWorkspaceExpectation(startDir = process.cwd()) {
|
|
|
17999
18000
|
workspaceDir,
|
|
18000
18001
|
workspaceRoot,
|
|
18001
18002
|
cwd,
|
|
18002
|
-
exists:
|
|
18003
|
+
exists: existsSync16(workspaceRoot)
|
|
18003
18004
|
};
|
|
18004
18005
|
}
|
|
18005
18006
|
}
|
|
18006
18007
|
if (dir === root)
|
|
18007
18008
|
return null;
|
|
18008
|
-
const parent =
|
|
18009
|
+
const parent = dirname19(dir);
|
|
18009
18010
|
if (parent === dir)
|
|
18010
18011
|
return null;
|
|
18011
18012
|
dir = parent;
|
|
@@ -18039,7 +18040,7 @@ function findContextProjectRoot(startDir = process.cwd()) {
|
|
|
18039
18040
|
return { projectRoot: dir };
|
|
18040
18041
|
if (dir === root)
|
|
18041
18042
|
return null;
|
|
18042
|
-
const parent =
|
|
18043
|
+
const parent = dirname19(dir);
|
|
18043
18044
|
if (parent === dir)
|
|
18044
18045
|
return null;
|
|
18045
18046
|
dir = parent;
|
|
@@ -18049,6 +18050,9 @@ function normalizeProjectDir(cwd, projectDir) {
|
|
|
18049
18050
|
const raw = projectDir?.trim() || DEFAULT_PROJECT_DIR;
|
|
18050
18051
|
return raw === "." ? resolve15(cwd) : resolve15(cwd, raw);
|
|
18051
18052
|
}
|
|
18053
|
+
function resolveContextProjectInitTarget(cwd, projectDir) {
|
|
18054
|
+
return normalizeProjectDir(cwd, projectDir);
|
|
18055
|
+
}
|
|
18052
18056
|
function slugifyName(value) {
|
|
18053
18057
|
const slug = value.trim().toLowerCase().replace(/[^a-z0-9._-]+/gu, "-").replace(/^-+|-+$/gu, "");
|
|
18054
18058
|
return slug.length > 0 ? slug : "context";
|
|
@@ -18078,7 +18082,7 @@ function initCommand(input, allowNonempty) {
|
|
|
18078
18082
|
return args.map(shellQuote3).join(" ");
|
|
18079
18083
|
}
|
|
18080
18084
|
async function assertInitTargetAllowed(input, projectRoot) {
|
|
18081
|
-
if (!
|
|
18085
|
+
if (!existsSync16(projectRoot) || isContextProjectRoot(projectRoot) || input.allowNonempty === true)
|
|
18082
18086
|
return;
|
|
18083
18087
|
const entries = (await readdir9(projectRoot)).sort();
|
|
18084
18088
|
if (entries.length === 0)
|
|
@@ -18102,11 +18106,11 @@ async function assertInitTargetAllowed(input, projectRoot) {
|
|
|
18102
18106
|
});
|
|
18103
18107
|
}
|
|
18104
18108
|
async function writeIfMissing(path3, content3, result) {
|
|
18105
|
-
if (
|
|
18109
|
+
if (existsSync16(path3)) {
|
|
18106
18110
|
result.kept.push(path3);
|
|
18107
18111
|
return;
|
|
18108
18112
|
}
|
|
18109
|
-
await mkdir14(
|
|
18113
|
+
await mkdir14(dirname19(path3), { recursive: true });
|
|
18110
18114
|
await writeFile10(path3, content3, "utf8");
|
|
18111
18115
|
result.created.push(path3);
|
|
18112
18116
|
}
|
|
@@ -18114,7 +18118,7 @@ async function listStaticTemplateFiles(root, dir = root) {
|
|
|
18114
18118
|
const entries = await readdir9(dir, { withFileTypes: true });
|
|
18115
18119
|
const files = [];
|
|
18116
18120
|
for (const entry of entries) {
|
|
18117
|
-
const absolutePath =
|
|
18121
|
+
const absolutePath = join26(dir, entry.name);
|
|
18118
18122
|
if (entry.isDirectory()) {
|
|
18119
18123
|
files.push(...await listStaticTemplateFiles(root, absolutePath));
|
|
18120
18124
|
continue;
|
|
@@ -18131,8 +18135,8 @@ async function listStaticTemplateFiles(root, dir = root) {
|
|
|
18131
18135
|
function resolveContextPackageTemplatesRoot() {
|
|
18132
18136
|
try {
|
|
18133
18137
|
const packageJsonPath = createRequire3(import.meta.url).resolve("@c4a/context/package.json");
|
|
18134
|
-
const templateRoot =
|
|
18135
|
-
if (
|
|
18138
|
+
const templateRoot = join26(dirname19(packageJsonPath), "templates", "package-templates");
|
|
18139
|
+
if (existsSync16(templateRoot))
|
|
18136
18140
|
return templateRoot;
|
|
18137
18141
|
} catch {}
|
|
18138
18142
|
throw new ContextError(ExitCode.WorkspaceStateError, "missing @c4a/context package templates", {
|
|
@@ -18143,8 +18147,8 @@ function resolveContextPackageTemplatesRoot() {
|
|
|
18143
18147
|
}
|
|
18144
18148
|
async function writeDefaultPackageTemplates(projectRoot, result, language) {
|
|
18145
18149
|
const defaultRoot = resolveContextPackageTemplatesRoot();
|
|
18146
|
-
const templateRoot = language === "zh-CN" ?
|
|
18147
|
-
if (!
|
|
18150
|
+
const templateRoot = language === "zh-CN" ? join26(dirname19(defaultRoot), "package-templates.zh-CN") : defaultRoot;
|
|
18151
|
+
if (!existsSync16(templateRoot)) {
|
|
18148
18152
|
throw new ContextError(ExitCode.WorkspaceStateError, `missing ${language} @c4a/context package templates`, {
|
|
18149
18153
|
category: ErrorCategory.WorkspaceStateInvalid,
|
|
18150
18154
|
path: templateRoot,
|
|
@@ -18153,21 +18157,21 @@ async function writeDefaultPackageTemplates(projectRoot, result, language) {
|
|
|
18153
18157
|
}
|
|
18154
18158
|
const files = await listStaticTemplateFiles(templateRoot);
|
|
18155
18159
|
for (const file of files) {
|
|
18156
|
-
await writeIfMissing(
|
|
18160
|
+
await writeIfMissing(join26(projectRoot, "src", "package-templates", ...file.relativePath.split("/")), await readFile21(file.absolutePath, "utf8"), result);
|
|
18157
18161
|
}
|
|
18158
18162
|
const templateKinds = [...new Set(files.map((file) => file.relativePath.split("/")[0]).filter((value) => value !== undefined && value.length > 0))];
|
|
18159
18163
|
for (const templateKind of templateKinds) {
|
|
18160
|
-
const root =
|
|
18164
|
+
const root = join26(projectRoot, "src", "package-templates", templateKind);
|
|
18161
18165
|
if (await writeStarterTemplateReviewMarker(root)) {
|
|
18162
|
-
result.created.push(
|
|
18166
|
+
result.created.push(join26(root, PACKAGE_TEMPLATE_REVIEW_FILE));
|
|
18163
18167
|
} else {
|
|
18164
|
-
result.kept.push(
|
|
18168
|
+
result.kept.push(join26(root, PACKAGE_TEMPLATE_REVIEW_FILE));
|
|
18165
18169
|
}
|
|
18166
18170
|
}
|
|
18167
18171
|
}
|
|
18168
18172
|
function resolveLocalSdkDependency() {
|
|
18169
18173
|
const packageJsonPath = createRequire3(import.meta.url).resolve("@c4a/context/package.json");
|
|
18170
|
-
return `file:${
|
|
18174
|
+
return `file:${dirname19(packageJsonPath)}`;
|
|
18171
18175
|
}
|
|
18172
18176
|
function resolveSdkDependency(dev, version3) {
|
|
18173
18177
|
return dev === true ? resolveLocalSdkDependency() : version3;
|
|
@@ -18465,20 +18469,20 @@ async function initContextProject(input) {
|
|
|
18465
18469
|
kept: []
|
|
18466
18470
|
};
|
|
18467
18471
|
for (const dir of PROJECT_DIRS) {
|
|
18468
|
-
await mkdir14(
|
|
18472
|
+
await mkdir14(join26(projectRoot, dir), { recursive: true });
|
|
18469
18473
|
}
|
|
18470
|
-
await mkdir14(
|
|
18471
|
-
await mkdir14(
|
|
18472
|
-
await mkdir14(
|
|
18473
|
-
await writeIfMissing(
|
|
18474
|
-
await writeIfMissing(
|
|
18474
|
+
await mkdir14(join26(projectRoot, "sources", "repo"), { recursive: true });
|
|
18475
|
+
await mkdir14(join26(projectRoot, "sources", "file"), { recursive: true });
|
|
18476
|
+
await mkdir14(join26(projectRoot, "sources", "lark"), { recursive: true });
|
|
18477
|
+
await writeIfMissing(join26(projectRoot, "package.json"), renderPackageJson(projectName, readCurrentPackageVersion(), input.dev, language, input.debug), result);
|
|
18478
|
+
await writeIfMissing(join26(projectRoot, "src", "index.ts"), renderProjectEntry(language), result);
|
|
18475
18479
|
await writeDefaultPackageTemplates(projectRoot, result, language);
|
|
18476
|
-
await writeIfMissing(
|
|
18477
|
-
await writeIfMissing(
|
|
18478
|
-
await writeIfMissing(
|
|
18479
|
-
await writeIfMissing(
|
|
18480
|
-
await writeIfMissing(
|
|
18481
|
-
await writeIfMissing(
|
|
18480
|
+
await writeIfMissing(join26(projectRoot, "sources", "repo", "index.yaml"), renderRepoIndex(), result);
|
|
18481
|
+
await writeIfMissing(join26(projectRoot, "sources", "file", "index.yaml"), renderFileIndex(), result);
|
|
18482
|
+
await writeIfMissing(join26(projectRoot, "sources", "lark", "index.yaml"), renderLarkIndex(), result);
|
|
18483
|
+
await writeIfMissing(join26(projectRoot, ".gitignore"), renderGitignore(), result);
|
|
18484
|
+
await writeIfMissing(join26(projectRoot, "README.md"), renderReadme(projectName, language), result);
|
|
18485
|
+
await writeIfMissing(join26(projectRoot, "AGENTS.md"), renderAgents(projectName, language), result);
|
|
18482
18486
|
if (input.debug === true)
|
|
18483
18487
|
await enableContextDebug(projectRoot, "init");
|
|
18484
18488
|
return result;
|
|
@@ -18492,7 +18496,7 @@ async function loadContextProjectModule(root) {
|
|
|
18492
18496
|
next: "Ensure package.json declares context.project=true and context.entry points to src/index.ts, then rerun the command."
|
|
18493
18497
|
});
|
|
18494
18498
|
}
|
|
18495
|
-
const entryPath =
|
|
18499
|
+
const entryPath = join26(root, projectConfig.entry);
|
|
18496
18500
|
const jiti = createJiti(entryPath, {
|
|
18497
18501
|
alias: {
|
|
18498
18502
|
"@c4a/context": resolveContextSdkImportAlias(entryPath)
|
|
@@ -18502,7 +18506,7 @@ async function loadContextProjectModule(root) {
|
|
|
18502
18506
|
moduleCache: false
|
|
18503
18507
|
});
|
|
18504
18508
|
const loadedProject = await jiti.import(entryPath, { default: true });
|
|
18505
|
-
if (!
|
|
18509
|
+
if (!isRecord13(loadedProject) || loadedProject.kind !== "context.project") {
|
|
18506
18510
|
throw new ContextError(ExitCode.WorkspaceStateError, "src/index.ts default export must be a @c4a/context project module", {
|
|
18507
18511
|
category: ErrorCategory.SchemaInvalid,
|
|
18508
18512
|
path: projectConfig.entry,
|
|
@@ -21518,7 +21522,7 @@ var require_util2 = __commonJS((exports) => {
|
|
|
21518
21522
|
return path4;
|
|
21519
21523
|
}
|
|
21520
21524
|
exports.normalize = normalize;
|
|
21521
|
-
function
|
|
21525
|
+
function join47(aRoot, aPath) {
|
|
21522
21526
|
if (aRoot === "") {
|
|
21523
21527
|
aRoot = ".";
|
|
21524
21528
|
}
|
|
@@ -21550,7 +21554,7 @@ var require_util2 = __commonJS((exports) => {
|
|
|
21550
21554
|
}
|
|
21551
21555
|
return joined;
|
|
21552
21556
|
}
|
|
21553
|
-
exports.join =
|
|
21557
|
+
exports.join = join47;
|
|
21554
21558
|
exports.isAbsolute = function(aPath) {
|
|
21555
21559
|
return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
|
|
21556
21560
|
};
|
|
@@ -21723,7 +21727,7 @@ var require_util2 = __commonJS((exports) => {
|
|
|
21723
21727
|
parsed.path = parsed.path.substring(0, index2 + 1);
|
|
21724
21728
|
}
|
|
21725
21729
|
}
|
|
21726
|
-
sourceURL =
|
|
21730
|
+
sourceURL = join47(urlGenerate(parsed), sourceURL);
|
|
21727
21731
|
}
|
|
21728
21732
|
return normalize(sourceURL);
|
|
21729
21733
|
}
|
|
@@ -24123,9 +24127,9 @@ var require_lib = __commonJS((exports, module) => {
|
|
|
24123
24127
|
});
|
|
24124
24128
|
|
|
24125
24129
|
// src/cli.ts
|
|
24126
|
-
import { existsSync as
|
|
24127
|
-
import { dirname as
|
|
24128
|
-
import { fileURLToPath as
|
|
24130
|
+
import { existsSync as existsSync47, readFileSync as readFileSync10, realpathSync } from "node:fs";
|
|
24131
|
+
import { dirname as dirname43, join as join74 } from "node:path";
|
|
24132
|
+
import { fileURLToPath as fileURLToPath10, pathToFileURL as pathToFileURL4 } from "node:url";
|
|
24129
24133
|
|
|
24130
24134
|
// ../../node_modules/.bun/commander@11.1.0/node_modules/commander/esm.mjs
|
|
24131
24135
|
var import__ = __toESM(require_commander(), 1);
|
|
@@ -24189,7 +24193,7 @@ function mergedWorkflowAuthorities(...values) {
|
|
|
24189
24193
|
}
|
|
24190
24194
|
|
|
24191
24195
|
// src/project/workflow/workflowResource.ts
|
|
24192
|
-
import { join as
|
|
24196
|
+
import { join as join56 } from "node:path";
|
|
24193
24197
|
|
|
24194
24198
|
// ../../node_modules/.bun/@c4a+agent-graph@0.2.5/node_modules/@c4a/agent-graph/dist/index.js
|
|
24195
24199
|
import { createRequire as createRequire2 } from "node:module";
|
|
@@ -40402,7 +40406,7 @@ init_errors();
|
|
|
40402
40406
|
init_exitCode();
|
|
40403
40407
|
|
|
40404
40408
|
// src/project/status.ts
|
|
40405
|
-
import { join as
|
|
40409
|
+
import { join as join55 } from "node:path";
|
|
40406
40410
|
|
|
40407
40411
|
// ../context/src/contracts.ts
|
|
40408
40412
|
var DEFAULT_PACKAGE_NAVIGATION = {
|
|
@@ -45289,9 +45293,9 @@ function resolveStructureCompileRoute(input) {
|
|
|
45289
45293
|
// src/project/statusReaders.ts
|
|
45290
45294
|
init_errors();
|
|
45291
45295
|
var import_yaml29 = __toESM(require_dist3(), 1);
|
|
45292
|
-
import { existsSync as
|
|
45296
|
+
import { existsSync as existsSync36, readFileSync as readFileSync8 } from "node:fs";
|
|
45293
45297
|
import { readdir as readdir16 } from "node:fs/promises";
|
|
45294
|
-
import { join as
|
|
45298
|
+
import { join as join53 } from "node:path";
|
|
45295
45299
|
|
|
45296
45300
|
// src/project/documentCapture.ts
|
|
45297
45301
|
import { createHash as createHash4 } from "node:crypto";
|
|
@@ -68944,20 +68948,235 @@ async function readApprovedCodegraphPages(input) {
|
|
|
68944
68948
|
// src/project/close.ts
|
|
68945
68949
|
init_cliFeedback();
|
|
68946
68950
|
init_errors();
|
|
68947
|
-
init_exitCode();
|
|
68948
68951
|
var import_yaml14 = __toESM(require_dist3(), 1);
|
|
68949
|
-
import { existsSync as
|
|
68952
|
+
import { existsSync as existsSync22 } from "node:fs";
|
|
68950
68953
|
import { mkdir as mkdir17, readdir as readdir11, readFile as readFile27, writeFile as writeFile13 } from "node:fs/promises";
|
|
68951
|
-
import { dirname as
|
|
68954
|
+
import { dirname as dirname22, join as join33, relative as relative13 } from "node:path";
|
|
68955
|
+
|
|
68956
|
+
// src/runtimeEvents.ts
|
|
68957
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
68958
|
+
import {
|
|
68959
|
+
existsSync as existsSync8,
|
|
68960
|
+
mkdirSync,
|
|
68961
|
+
readFileSync as readFileSync4,
|
|
68962
|
+
renameSync,
|
|
68963
|
+
writeFileSync
|
|
68964
|
+
} from "node:fs";
|
|
68965
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
68966
|
+
import { dirname as dirname15, join as join17 } from "node:path";
|
|
68967
|
+
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
68968
|
+
var CONTEXT_RUNTIME_EVENT_BATCH_SCHEMA = "context.runtime-event-batch.v1";
|
|
68969
|
+
var CONTEXT_RUNTIME_EVENT_SINK_SCHEMA = "context.runtime-event-sink.v1";
|
|
68970
|
+
var CONTEXT_RUNTIME_EVENT_DELIVERY_TIMEOUT_MS = 3000;
|
|
68971
|
+
var CONTEXT_WORKSPACE_ACTIVE_THROTTLE_MS = 60 * 60 * 1000;
|
|
68972
|
+
var RUNTIME_EVENT_STATE_SCHEMA = "context.runtime-event-state.v1";
|
|
68973
|
+
var RUNTIME_EVENT_STATE_FILE = "runtime-event-state.json";
|
|
68974
|
+
var activeScope;
|
|
68975
|
+
function isRecord8(value) {
|
|
68976
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
68977
|
+
}
|
|
68978
|
+
function parseContextRuntimeEventSink(value) {
|
|
68979
|
+
if (!isRecord8(value))
|
|
68980
|
+
return null;
|
|
68981
|
+
if (value.schema !== CONTEXT_RUNTIME_EVENT_SINK_SCHEMA || value.transport !== "command")
|
|
68982
|
+
return null;
|
|
68983
|
+
if (typeof value.command !== "string" || value.command.trim().length === 0)
|
|
68984
|
+
return null;
|
|
68985
|
+
if (!Array.isArray(value.args) || !value.args.every((arg) => typeof arg === "string"))
|
|
68986
|
+
return null;
|
|
68987
|
+
return {
|
|
68988
|
+
schema: CONTEXT_RUNTIME_EVENT_SINK_SCHEMA,
|
|
68989
|
+
transport: "command",
|
|
68990
|
+
command: value.command,
|
|
68991
|
+
args: [...value.args]
|
|
68992
|
+
};
|
|
68993
|
+
}
|
|
68994
|
+
function readRuntimePackageMetadata() {
|
|
68995
|
+
try {
|
|
68996
|
+
let dir = dirname15(fileURLToPath4(import.meta.url));
|
|
68997
|
+
for (let index2 = 0;index2 < 8; index2++) {
|
|
68998
|
+
const packagePath = join17(dir, "package.json");
|
|
68999
|
+
if (existsSync8(packagePath)) {
|
|
69000
|
+
const parsed = JSON.parse(readFileSync4(packagePath, "utf8"));
|
|
69001
|
+
if (isRecord8(parsed)) {
|
|
69002
|
+
return {
|
|
69003
|
+
contextVersion: typeof parsed.version === "string" ? parsed.version : "unknown",
|
|
69004
|
+
sink: parseContextRuntimeEventSink(parsed.contextRuntimeEventSink)
|
|
69005
|
+
};
|
|
69006
|
+
}
|
|
69007
|
+
}
|
|
69008
|
+
const parent = dirname15(dir);
|
|
69009
|
+
if (parent === dir)
|
|
69010
|
+
break;
|
|
69011
|
+
dir = parent;
|
|
69012
|
+
}
|
|
69013
|
+
} catch {}
|
|
69014
|
+
return { contextVersion: "unknown", sink: null };
|
|
69015
|
+
}
|
|
69016
|
+
function dispatchCommand(sink, batch, cwd) {
|
|
69017
|
+
return new Promise((resolve8) => {
|
|
69018
|
+
let settled = false;
|
|
69019
|
+
let timer;
|
|
69020
|
+
const finish = (delivered) => {
|
|
69021
|
+
if (settled)
|
|
69022
|
+
return;
|
|
69023
|
+
settled = true;
|
|
69024
|
+
if (timer !== undefined)
|
|
69025
|
+
clearTimeout(timer);
|
|
69026
|
+
resolve8(delivered);
|
|
69027
|
+
};
|
|
69028
|
+
try {
|
|
69029
|
+
const child = spawn2(sink.command, sink.args, {
|
|
69030
|
+
cwd,
|
|
69031
|
+
env: process.env,
|
|
69032
|
+
shell: false,
|
|
69033
|
+
stdio: ["pipe", "ignore", "ignore"]
|
|
69034
|
+
});
|
|
69035
|
+
child.once("error", () => finish(false));
|
|
69036
|
+
child.once("exit", (code) => finish(code === 0));
|
|
69037
|
+
child.stdin.once("error", () => {
|
|
69038
|
+
child.kill();
|
|
69039
|
+
finish(false);
|
|
69040
|
+
});
|
|
69041
|
+
child.stdin.end(JSON.stringify(batch));
|
|
69042
|
+
timer = setTimeout(() => {
|
|
69043
|
+
child.kill();
|
|
69044
|
+
finish(false);
|
|
69045
|
+
}, CONTEXT_RUNTIME_EVENT_DELIVERY_TIMEOUT_MS);
|
|
69046
|
+
} catch {
|
|
69047
|
+
finish(false);
|
|
69048
|
+
}
|
|
69049
|
+
});
|
|
69050
|
+
}
|
|
69051
|
+
function runtimeEventStatePath(cwd) {
|
|
69052
|
+
return join17(cwd, ".tmp", "context-runtime", RUNTIME_EVENT_STATE_FILE);
|
|
69053
|
+
}
|
|
69054
|
+
function readRuntimeEventState(cwd) {
|
|
69055
|
+
try {
|
|
69056
|
+
const parsed = JSON.parse(readFileSync4(runtimeEventStatePath(cwd), "utf8"));
|
|
69057
|
+
if (!isRecord8(parsed) || parsed.schema !== RUNTIME_EVENT_STATE_SCHEMA)
|
|
69058
|
+
return null;
|
|
69059
|
+
const active = parsed.workspace_active;
|
|
69060
|
+
if (active === undefined)
|
|
69061
|
+
return { schema: RUNTIME_EVENT_STATE_SCHEMA };
|
|
69062
|
+
if (!isRecord8(active) || typeof active.workflow_status !== "string" || typeof active.delivered_at !== "number" || !Number.isFinite(active.delivered_at)) {
|
|
69063
|
+
return null;
|
|
69064
|
+
}
|
|
69065
|
+
return {
|
|
69066
|
+
schema: RUNTIME_EVENT_STATE_SCHEMA,
|
|
69067
|
+
workspace_active: {
|
|
69068
|
+
workflow_status: active.workflow_status,
|
|
69069
|
+
delivered_at: active.delivered_at
|
|
69070
|
+
}
|
|
69071
|
+
};
|
|
69072
|
+
} catch {
|
|
69073
|
+
return null;
|
|
69074
|
+
}
|
|
69075
|
+
}
|
|
69076
|
+
function shouldDeliverWorkspaceActive(event, state) {
|
|
69077
|
+
const workflowStatus = event.properties.workflow_status;
|
|
69078
|
+
if (typeof workflowStatus !== "string")
|
|
69079
|
+
return true;
|
|
69080
|
+
const previous2 = state?.workspace_active;
|
|
69081
|
+
if (previous2 === undefined || previous2.workflow_status !== workflowStatus)
|
|
69082
|
+
return true;
|
|
69083
|
+
return event.event_time - previous2.delivered_at >= CONTEXT_WORKSPACE_ACTIVE_THROTTLE_MS;
|
|
69084
|
+
}
|
|
69085
|
+
function selectRuntimeEventsForDelivery(events, state) {
|
|
69086
|
+
return events.filter((event) => event.kind !== "workspace.active" || shouldDeliverWorkspaceActive(event, state));
|
|
69087
|
+
}
|
|
69088
|
+
function persistDeliveredWorkspaceActive(cwd, events) {
|
|
69089
|
+
const delivered = [...events].reverse().find((event) => event.kind === "workspace.active");
|
|
69090
|
+
const workflowStatus = delivered?.properties.workflow_status;
|
|
69091
|
+
if (delivered === undefined || typeof workflowStatus !== "string")
|
|
69092
|
+
return;
|
|
69093
|
+
try {
|
|
69094
|
+
const statePath = runtimeEventStatePath(cwd);
|
|
69095
|
+
const stateDir = dirname15(statePath);
|
|
69096
|
+
const temporaryPath = `${statePath}.${process.pid}.tmp`;
|
|
69097
|
+
mkdirSync(stateDir, { recursive: true });
|
|
69098
|
+
writeFileSync(temporaryPath, `${JSON.stringify({
|
|
69099
|
+
schema: RUNTIME_EVENT_STATE_SCHEMA,
|
|
69100
|
+
workspace_active: {
|
|
69101
|
+
workflow_status: workflowStatus,
|
|
69102
|
+
delivered_at: delivered.event_time
|
|
69103
|
+
}
|
|
69104
|
+
})}
|
|
69105
|
+
`, "utf8");
|
|
69106
|
+
renameSync(temporaryPath, statePath);
|
|
69107
|
+
} catch {}
|
|
69108
|
+
}
|
|
69109
|
+
async function flushRuntimeEvents(scope) {
|
|
69110
|
+
const grouped = new Map;
|
|
69111
|
+
for (const queued of scope.events) {
|
|
69112
|
+
const events = grouped.get(queued.cwd) ?? [];
|
|
69113
|
+
events.push(queued.event);
|
|
69114
|
+
grouped.set(queued.cwd, events);
|
|
69115
|
+
}
|
|
69116
|
+
await Promise.all([...grouped.entries()].map(async ([cwd, events]) => {
|
|
69117
|
+
try {
|
|
69118
|
+
const selectedEvents = selectRuntimeEventsForDelivery(events, readRuntimeEventState(cwd));
|
|
69119
|
+
if (selectedEvents.length === 0)
|
|
69120
|
+
return;
|
|
69121
|
+
try {
|
|
69122
|
+
await scope.dispatch(scope.sink, {
|
|
69123
|
+
schema: CONTEXT_RUNTIME_EVENT_BATCH_SCHEMA,
|
|
69124
|
+
context_version: scope.contextVersion,
|
|
69125
|
+
events: selectedEvents
|
|
69126
|
+
}, cwd);
|
|
69127
|
+
} finally {
|
|
69128
|
+
persistDeliveredWorkspaceActive(cwd, selectedEvents);
|
|
69129
|
+
}
|
|
69130
|
+
} catch {}
|
|
69131
|
+
}));
|
|
69132
|
+
}
|
|
69133
|
+
function queueContextRuntimeEvent(input) {
|
|
69134
|
+
if (activeScope === undefined)
|
|
69135
|
+
return;
|
|
69136
|
+
activeScope.events.push({
|
|
69137
|
+
cwd: input.cwd,
|
|
69138
|
+
event: {
|
|
69139
|
+
event_id: randomUUID2(),
|
|
69140
|
+
event_time: Date.now(),
|
|
69141
|
+
kind: input.kind,
|
|
69142
|
+
properties: input.properties ?? {}
|
|
69143
|
+
}
|
|
69144
|
+
});
|
|
69145
|
+
}
|
|
69146
|
+
async function withContextRuntimeEventDelivery(work, options = {}) {
|
|
69147
|
+
if (activeScope !== undefined || process.env.CONTEXT_RUNTIME_EVENTS_DISABLED === "1" && options.forceDelivery !== true) {
|
|
69148
|
+
return work();
|
|
69149
|
+
}
|
|
69150
|
+
const metadata = readRuntimePackageMetadata();
|
|
69151
|
+
const sink = options.sink === undefined ? metadata.sink : options.sink;
|
|
69152
|
+
if (sink === null)
|
|
69153
|
+
return work();
|
|
69154
|
+
const scope = {
|
|
69155
|
+
contextVersion: options.contextVersion ?? metadata.contextVersion,
|
|
69156
|
+
dispatch: options.dispatch ?? dispatchCommand,
|
|
69157
|
+
events: [],
|
|
69158
|
+
sink
|
|
69159
|
+
};
|
|
69160
|
+
activeScope = scope;
|
|
69161
|
+
try {
|
|
69162
|
+
return await work();
|
|
69163
|
+
} finally {
|
|
69164
|
+
activeScope = undefined;
|
|
69165
|
+
await flushRuntimeEvents(scope);
|
|
69166
|
+
}
|
|
69167
|
+
}
|
|
69168
|
+
|
|
69169
|
+
// src/project/close.ts
|
|
69170
|
+
init_exitCode();
|
|
68952
69171
|
|
|
68953
69172
|
// src/project/approvedStructureEdges.ts
|
|
68954
69173
|
init_cliFeedback();
|
|
68955
69174
|
init_errors();
|
|
68956
69175
|
init_exitCode();
|
|
68957
69176
|
var import_yaml10 = __toESM(require_dist3(), 1);
|
|
68958
|
-
import { existsSync as
|
|
69177
|
+
import { existsSync as existsSync11 } from "node:fs";
|
|
68959
69178
|
import { readFile as readFile17 } from "node:fs/promises";
|
|
68960
|
-
import { join as
|
|
69179
|
+
import { join as join20 } from "node:path";
|
|
68961
69180
|
|
|
68962
69181
|
// src/project/proseAlignTypes.ts
|
|
68963
69182
|
import { createHash as createHash9 } from "node:crypto";
|
|
@@ -69014,21 +69233,21 @@ function slugify2(input, maxLen = 60) {
|
|
|
69014
69233
|
// src/project/semanticRules.ts
|
|
69015
69234
|
var import_yaml8 = __toESM(require_dist3(), 1);
|
|
69016
69235
|
import { createHash as createHash8 } from "node:crypto";
|
|
69017
|
-
import { existsSync as
|
|
69018
|
-
import { basename as basename4, dirname as
|
|
69019
|
-
import { fileURLToPath as
|
|
69236
|
+
import { existsSync as existsSync9, readFileSync as readFileSync5, readdirSync } from "node:fs";
|
|
69237
|
+
import { basename as basename4, dirname as dirname16, join as join18 } from "node:path";
|
|
69238
|
+
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
69020
69239
|
function sha256(value) {
|
|
69021
69240
|
return `sha256:${createHash8("sha256").update(value).digest("hex")}`;
|
|
69022
69241
|
}
|
|
69023
69242
|
function workflowRootCandidates() {
|
|
69024
|
-
const runtimeDir =
|
|
69243
|
+
const runtimeDir = dirname16(fileURLToPath5(import.meta.url));
|
|
69025
69244
|
return [
|
|
69026
|
-
|
|
69027
|
-
|
|
69245
|
+
join18(runtimeDir, "providers", "context"),
|
|
69246
|
+
join18(runtimeDir, "..", "..", "context-workflow")
|
|
69028
69247
|
];
|
|
69029
69248
|
}
|
|
69030
69249
|
function semanticRuleMetadata(scope, filePath) {
|
|
69031
|
-
const content3 =
|
|
69250
|
+
const content3 = readFileSync5(filePath, "utf8").replaceAll(`\r
|
|
69032
69251
|
`, `
|
|
69033
69252
|
`);
|
|
69034
69253
|
const end = content3.indexOf(`
|
|
@@ -69059,19 +69278,19 @@ function semanticRuleMetadata(scope, filePath) {
|
|
|
69059
69278
|
}
|
|
69060
69279
|
function semanticRuleDescriptors(scope) {
|
|
69061
69280
|
for (const root of workflowRootCandidates()) {
|
|
69062
|
-
const directory =
|
|
69063
|
-
if (!
|
|
69281
|
+
const directory = join18(root, "resources", "semantic", scope);
|
|
69282
|
+
if (!existsSync9(directory))
|
|
69064
69283
|
continue;
|
|
69065
|
-
return readdirSync(directory, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".md")).sort((left, right) => left.name.localeCompare(right.name)).map((entry) => semanticRuleMetadata(scope,
|
|
69284
|
+
return readdirSync(directory, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".md")).sort((left, right) => left.name.localeCompare(right.name)).map((entry) => semanticRuleMetadata(scope, join18(directory, entry.name)));
|
|
69066
69285
|
}
|
|
69067
69286
|
throw new Error(`Context ${scope} semantic workflow resources are missing. Rebuild or reinstall @c4a/context-cli.`);
|
|
69068
69287
|
}
|
|
69069
69288
|
function ruleContent(rulePath) {
|
|
69070
69289
|
for (const root of workflowRootCandidates()) {
|
|
69071
|
-
const absolute =
|
|
69072
|
-
if (
|
|
69290
|
+
const absolute = join18(root, rulePath);
|
|
69291
|
+
if (existsSync9(absolute)) {
|
|
69073
69292
|
return {
|
|
69074
|
-
content:
|
|
69293
|
+
content: readFileSync5(absolute, "utf8"),
|
|
69075
69294
|
available: true,
|
|
69076
69295
|
filePath: absolute
|
|
69077
69296
|
};
|
|
@@ -69484,15 +69703,15 @@ init_cliFeedback();
|
|
|
69484
69703
|
init_errors();
|
|
69485
69704
|
init_exitCode();
|
|
69486
69705
|
var import_yaml9 = __toESM(require_dist3(), 1);
|
|
69487
|
-
import { existsSync as
|
|
69706
|
+
import { existsSync as existsSync10 } from "node:fs";
|
|
69488
69707
|
import { mkdir as mkdir12, readFile as readFile16, writeFile as writeFile8 } from "node:fs/promises";
|
|
69489
|
-
import { dirname as
|
|
69708
|
+
import { dirname as dirname17, join as join19 } from "node:path";
|
|
69490
69709
|
|
|
69491
69710
|
// src/project/proseAlignPayloadParse.ts
|
|
69492
69711
|
import { createHash as createHash10 } from "node:crypto";
|
|
69493
69712
|
|
|
69494
69713
|
// src/project/proseAlignSchemaUtils.ts
|
|
69495
|
-
function
|
|
69714
|
+
function isRecord9(value) {
|
|
69496
69715
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
69497
69716
|
}
|
|
69498
69717
|
function stringValue2(record, field) {
|
|
@@ -69559,7 +69778,7 @@ function parsePreferredNodes(value, diagnostics) {
|
|
|
69559
69778
|
}
|
|
69560
69779
|
const nodes = [];
|
|
69561
69780
|
for (const [index2, rawNode] of value.entries()) {
|
|
69562
|
-
if (!
|
|
69781
|
+
if (!isRecord9(rawNode)) {
|
|
69563
69782
|
diagnostics.push(diagnostic("error", "schema.preferred_node_object", "schema", "preferred_nodes item must be an object.", `user_or_agent_hints.preferred_nodes[${index2}]`));
|
|
69564
69783
|
continue;
|
|
69565
69784
|
}
|
|
@@ -69584,7 +69803,7 @@ function parsePreferredNodes(value, diagnostics) {
|
|
|
69584
69803
|
function parseUserOrAgentHints(value, diagnostics) {
|
|
69585
69804
|
if (value === undefined)
|
|
69586
69805
|
return;
|
|
69587
|
-
if (!
|
|
69806
|
+
if (!isRecord9(value)) {
|
|
69588
69807
|
diagnostics.push(diagnostic("error", "schema.user_or_agent_hints_object", "schema", "user_or_agent_hints must be an object.", "user_or_agent_hints"));
|
|
69589
69808
|
return;
|
|
69590
69809
|
}
|
|
@@ -69787,7 +70006,7 @@ function parseNodes(value, diagnostics) {
|
|
|
69787
70006
|
diagnostics.push(diagnostic("error", "schema.nodes_missing", "schema", "Payload must include at least one node.", "nodes"));
|
|
69788
70007
|
const nodes = [];
|
|
69789
70008
|
for (const [index2, rawNode] of value.entries()) {
|
|
69790
|
-
if (!
|
|
70009
|
+
if (!isRecord9(rawNode)) {
|
|
69791
70010
|
diagnostics.push(diagnostic("error", "schema.node_object", "schema", `Node ${index2 + 1} must be an object.`, `nodes[${index2}]`));
|
|
69792
70011
|
continue;
|
|
69793
70012
|
}
|
|
@@ -69824,7 +70043,7 @@ function parseSections(input) {
|
|
|
69824
70043
|
const sectionIds = new Set;
|
|
69825
70044
|
for (const [sectionIndex, rawSection] of input.value.entries()) {
|
|
69826
70045
|
const field = `views[${input.viewIndex}].sections[${sectionIndex}]`;
|
|
69827
|
-
if (!
|
|
70046
|
+
if (!isRecord9(rawSection)) {
|
|
69828
70047
|
input.diagnostics.push(diagnostic("error", "schema.section_object", "schema", "Section must be an object.", field));
|
|
69829
70048
|
continue;
|
|
69830
70049
|
}
|
|
@@ -69926,7 +70145,7 @@ function parseViews(value, nodes, diagnostics) {
|
|
|
69926
70145
|
const nodeByRef = new Map(nodes.map((node3) => [node3.node_ref, node3]));
|
|
69927
70146
|
const views = [];
|
|
69928
70147
|
for (const [index2, rawView] of value.entries()) {
|
|
69929
|
-
if (!
|
|
70148
|
+
if (!isRecord9(rawView)) {
|
|
69930
70149
|
diagnostics.push(diagnostic("error", "schema.view_object", "schema", `View ${index2 + 1} must be an object.`, `views[${index2}]`));
|
|
69931
70150
|
continue;
|
|
69932
70151
|
}
|
|
@@ -69945,7 +70164,7 @@ function parseEdges(value, diagnostics) {
|
|
|
69945
70164
|
}
|
|
69946
70165
|
const edges = [];
|
|
69947
70166
|
for (const [index2, rawEdge] of value.entries()) {
|
|
69948
|
-
if (!
|
|
70167
|
+
if (!isRecord9(rawEdge)) {
|
|
69949
70168
|
diagnostics.push(diagnostic("error", "schema.edge_object", "schema", `Edge ${index2 + 1} must be an object.`, `edges[${index2}]`));
|
|
69950
70169
|
continue;
|
|
69951
70170
|
}
|
|
@@ -69992,7 +70211,7 @@ function parseUnresolved(value, diagnostics) {
|
|
|
69992
70211
|
}
|
|
69993
70212
|
const unresolved = [];
|
|
69994
70213
|
for (const [index2, rawIssue] of value.entries()) {
|
|
69995
|
-
if (!
|
|
70214
|
+
if (!isRecord9(rawIssue)) {
|
|
69996
70215
|
diagnostics.push(diagnostic("error", "schema.unresolved_object", "schema", `Unresolved issue ${index2 + 1} must be an object.`, `unresolved[${index2}]`));
|
|
69997
70216
|
continue;
|
|
69998
70217
|
}
|
|
@@ -70015,7 +70234,7 @@ function parseUnresolved(value, diagnostics) {
|
|
|
70015
70234
|
function parseLifecycle(value, diagnostics) {
|
|
70016
70235
|
if (value === undefined)
|
|
70017
70236
|
return { state: "draft" };
|
|
70018
|
-
if (!
|
|
70237
|
+
if (!isRecord9(value)) {
|
|
70019
70238
|
diagnostics.push(diagnostic("error", "schema.lifecycle_object", "schema", "Payload lifecycle must be an object.", "lifecycle"));
|
|
70020
70239
|
return { state: "draft" };
|
|
70021
70240
|
}
|
|
@@ -70073,7 +70292,7 @@ function structureBody(input) {
|
|
|
70073
70292
|
}
|
|
70074
70293
|
function parseAlignPayload(value) {
|
|
70075
70294
|
const diagnostics = [];
|
|
70076
|
-
if (!
|
|
70295
|
+
if (!isRecord9(value)) {
|
|
70077
70296
|
return {
|
|
70078
70297
|
diagnostics: [diagnostic("error", "schema.payload_object", "schema", "Payload must be a YAML/JSON object.", "schema")]
|
|
70079
70298
|
};
|
|
@@ -70158,7 +70377,7 @@ function snapshotPath(projectRoot, structureDigest) {
|
|
|
70158
70377
|
structure_digest: structureDigest
|
|
70159
70378
|
});
|
|
70160
70379
|
}
|
|
70161
|
-
return
|
|
70380
|
+
return join19(projectRoot, STRUCTURE_SNAPSHOT_ROOT, `${match[1]}.yaml`);
|
|
70162
70381
|
}
|
|
70163
70382
|
function normalizedSnapshot(payload) {
|
|
70164
70383
|
const { user_or_agent_hints: _hints, ...body } = payload;
|
|
@@ -70174,8 +70393,8 @@ function normalizedSnapshot(payload) {
|
|
|
70174
70393
|
});
|
|
70175
70394
|
}
|
|
70176
70395
|
async function readSlots(projectRoot) {
|
|
70177
|
-
const path3 =
|
|
70178
|
-
if (!
|
|
70396
|
+
const path3 = join19(projectRoot, STRUCTURE_SLOT_FILE);
|
|
70397
|
+
if (!existsSync10(path3))
|
|
70179
70398
|
return [];
|
|
70180
70399
|
const parsed = import_yaml9.default.parse(await readFile16(path3, "utf8"));
|
|
70181
70400
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
@@ -70223,8 +70442,8 @@ async function updateSlots(projectRoot, payload) {
|
|
|
70223
70442
|
...current2.filter((slot) => !replacements.has(`${slot.source}\x00${slot.collection}`)),
|
|
70224
70443
|
...replacements.values()
|
|
70225
70444
|
].sort((left, right) => left.source.localeCompare(right.source) || left.collection.localeCompare(right.collection));
|
|
70226
|
-
const path3 =
|
|
70227
|
-
await mkdir12(
|
|
70445
|
+
const path3 = join19(projectRoot, STRUCTURE_SLOT_FILE);
|
|
70446
|
+
await mkdir12(dirname17(path3), { recursive: true });
|
|
70228
70447
|
await writeFile8(path3, import_yaml9.default.stringify({ schema_version: STRUCTURE_SLOT_SCHEMA_VERSION, slots }), "utf8");
|
|
70229
70448
|
}
|
|
70230
70449
|
async function writeStructureSnapshot(projectRoot, payload) {
|
|
@@ -70239,7 +70458,7 @@ async function writeStructureSnapshot(projectRoot, payload) {
|
|
|
70239
70458
|
});
|
|
70240
70459
|
}
|
|
70241
70460
|
const content3 = import_yaml9.default.stringify(normalized);
|
|
70242
|
-
if (
|
|
70461
|
+
if (existsSync10(path3)) {
|
|
70243
70462
|
const current2 = await readFile16(path3, "utf8");
|
|
70244
70463
|
const existing = parseAlignPayload(import_yaml9.default.parse(current2)).payload;
|
|
70245
70464
|
if (existing?.structure_digest !== payload.structure_digest) {
|
|
@@ -70255,14 +70474,14 @@ async function writeStructureSnapshot(projectRoot, payload) {
|
|
|
70255
70474
|
await updateSlots(projectRoot, payload);
|
|
70256
70475
|
return path3;
|
|
70257
70476
|
}
|
|
70258
|
-
await mkdir12(
|
|
70477
|
+
await mkdir12(dirname17(path3), { recursive: true });
|
|
70259
70478
|
await writeFile8(path3, content3, "utf8");
|
|
70260
70479
|
await updateSlots(projectRoot, payload);
|
|
70261
70480
|
return path3;
|
|
70262
70481
|
}
|
|
70263
70482
|
async function readStructureSnapshot(projectRoot, structureDigest) {
|
|
70264
70483
|
const path3 = snapshotPath(projectRoot, structureDigest);
|
|
70265
|
-
if (!
|
|
70484
|
+
if (!existsSync10(path3))
|
|
70266
70485
|
return null;
|
|
70267
70486
|
try {
|
|
70268
70487
|
return import_yaml9.default.parse(await readFile16(path3, "utf8"));
|
|
@@ -70290,8 +70509,8 @@ async function readStructureSnapshotPayload(projectRoot, structureDigest) {
|
|
|
70290
70509
|
return { ...record, structure_digest: structureDigest };
|
|
70291
70510
|
}
|
|
70292
70511
|
async function archiveActiveStructure(projectRoot) {
|
|
70293
|
-
const path3 =
|
|
70294
|
-
if (!
|
|
70512
|
+
const path3 = join19(projectRoot, LIFECYCLE_STRUCTURE_FILE);
|
|
70513
|
+
if (!existsSync10(path3))
|
|
70295
70514
|
return null;
|
|
70296
70515
|
let parsed;
|
|
70297
70516
|
try {
|
|
@@ -70319,7 +70538,7 @@ function structureSnapshotRelativePath(structureDigest) {
|
|
|
70319
70538
|
const match = STRUCTURE_DIGEST_PATTERN.exec(structureDigest);
|
|
70320
70539
|
if (match?.[1] === undefined)
|
|
70321
70540
|
return STRUCTURE_SNAPSHOT_ROOT;
|
|
70322
|
-
return
|
|
70541
|
+
return join19(STRUCTURE_SNAPSHOT_ROOT, `${match[1]}.yaml`);
|
|
70323
70542
|
}
|
|
70324
70543
|
async function currentStructureSlotDigest(projectRoot, source2, collection) {
|
|
70325
70544
|
return (await readSlots(projectRoot)).find((slot) => slot.source === source2 && slot.collection === collection)?.structure_digest;
|
|
@@ -70334,9 +70553,9 @@ async function activeStructureSlots(projectRoot, collection) {
|
|
|
70334
70553
|
|
|
70335
70554
|
// src/project/approvedStructureEdges.ts
|
|
70336
70555
|
var KNOWLEDGE_ROOT = "knowledge";
|
|
70337
|
-
var APPROVED_STRUCTURE_PATH =
|
|
70556
|
+
var APPROVED_STRUCTURE_PATH = join20(KNOWLEDGE_ROOT, "structure.yaml");
|
|
70338
70557
|
var STRUCTURE_EDGE_CONFIDENCE_SET = new Set(STRUCTURE_EDGE_CONFIDENCES);
|
|
70339
|
-
function
|
|
70558
|
+
function isRecord10(value) {
|
|
70340
70559
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
70341
70560
|
}
|
|
70342
70561
|
function readEdgeArray(structure) {
|
|
@@ -70346,7 +70565,7 @@ function normalizeApprovedEdges(input) {
|
|
|
70346
70565
|
const allowed = new Set(STRUCTURE_EDGE_TYPES);
|
|
70347
70566
|
const edges = [];
|
|
70348
70567
|
for (const [index2, rawEdge] of input.rawEdges.entries()) {
|
|
70349
|
-
if (!
|
|
70568
|
+
if (!isRecord10(rawEdge)) {
|
|
70350
70569
|
throw new ContextError(ExitCode.WorkspaceStateError, "structure edge must be an object", {
|
|
70351
70570
|
category: ErrorCategory.WorkspaceStateInvalid,
|
|
70352
70571
|
path: input.path,
|
|
@@ -70437,20 +70656,20 @@ function structureEndpointRefs(structure) {
|
|
|
70437
70656
|
const refs = [];
|
|
70438
70657
|
if (Array.isArray(structure.nodes)) {
|
|
70439
70658
|
for (const node3 of structure.nodes) {
|
|
70440
|
-
if (
|
|
70659
|
+
if (isRecord10(node3) && typeof node3.node_ref === "string")
|
|
70441
70660
|
refs.push(node3.node_ref);
|
|
70442
70661
|
}
|
|
70443
70662
|
}
|
|
70444
70663
|
if (Array.isArray(structure.views)) {
|
|
70445
70664
|
for (const view of structure.views) {
|
|
70446
|
-
if (!
|
|
70665
|
+
if (!isRecord10(view))
|
|
70447
70666
|
continue;
|
|
70448
70667
|
if (typeof view.view_ref === "string")
|
|
70449
70668
|
refs.push(view.view_ref);
|
|
70450
70669
|
if (!Array.isArray(view.sections))
|
|
70451
70670
|
continue;
|
|
70452
70671
|
for (const section of view.sections) {
|
|
70453
|
-
if (
|
|
70672
|
+
if (isRecord10(section) && typeof section.section_ref === "string")
|
|
70454
70673
|
refs.push(section.section_ref);
|
|
70455
70674
|
}
|
|
70456
70675
|
}
|
|
@@ -70458,12 +70677,12 @@ function structureEndpointRefs(structure) {
|
|
|
70458
70677
|
return refs;
|
|
70459
70678
|
}
|
|
70460
70679
|
async function readYamlRecord(projectRoot, relPath) {
|
|
70461
|
-
const absPath =
|
|
70462
|
-
if (!
|
|
70680
|
+
const absPath = join20(projectRoot, relPath);
|
|
70681
|
+
if (!existsSync11(absPath))
|
|
70463
70682
|
return null;
|
|
70464
70683
|
try {
|
|
70465
70684
|
const parsed = import_yaml10.default.parse(await readFile17(absPath, "utf8"));
|
|
70466
|
-
return
|
|
70685
|
+
return isRecord10(parsed) ? parsed : null;
|
|
70467
70686
|
} catch (error) {
|
|
70468
70687
|
throw new ContextError(ExitCode.WorkspaceStateError, `${relPath} is invalid YAML`, {
|
|
70469
70688
|
category: ErrorCategory.WorkspaceStateInvalid,
|
|
@@ -70502,7 +70721,7 @@ async function readConfirmedStructureEdgeProjection(projectRoot, approvedEndpoin
|
|
|
70502
70721
|
const snapshotEdges = [];
|
|
70503
70722
|
for (const structureDigest of [...new Set(slots.map((slot) => slot.structureDigest))].sort()) {
|
|
70504
70723
|
const structure2 = await readStructureSnapshot(projectRoot, structureDigest);
|
|
70505
|
-
if (!
|
|
70724
|
+
if (!isRecord10(structure2)) {
|
|
70506
70725
|
throw new ContextError(ExitCode.WorkspaceStateError, "active structure snapshot is missing", {
|
|
70507
70726
|
category: ErrorCategory.WorkspaceStateInvalid,
|
|
70508
70727
|
structure_digest: structureDigest,
|
|
@@ -70543,7 +70762,7 @@ async function readConfirmedStructureEdgeProjection(projectRoot, approvedEndpoin
|
|
|
70543
70762
|
}
|
|
70544
70763
|
if (structure === null)
|
|
70545
70764
|
return null;
|
|
70546
|
-
const lifecycle =
|
|
70765
|
+
const lifecycle = isRecord10(structure.lifecycle) ? structure.lifecycle : {};
|
|
70547
70766
|
if (lifecycle.state !== "confirmed" && lifecycle.state !== "frozen")
|
|
70548
70767
|
return null;
|
|
70549
70768
|
return normalizeApprovedEdges({
|
|
@@ -70559,15 +70778,15 @@ async function readConfirmedStructureEdgeProjection(projectRoot, approvedEndpoin
|
|
|
70559
70778
|
init_cliFeedback();
|
|
70560
70779
|
init_errors();
|
|
70561
70780
|
init_exitCode();
|
|
70562
|
-
import { existsSync as
|
|
70781
|
+
import { existsSync as existsSync18 } from "node:fs";
|
|
70563
70782
|
import { readFile as readFile23 } from "node:fs/promises";
|
|
70564
|
-
import { join as
|
|
70783
|
+
import { join as join28 } from "node:path";
|
|
70565
70784
|
|
|
70566
70785
|
// src/project/verifyApprovedStructure.ts
|
|
70567
70786
|
var import_yaml12 = __toESM(require_dist3(), 1);
|
|
70568
|
-
import { existsSync as
|
|
70787
|
+
import { existsSync as existsSync14 } from "node:fs";
|
|
70569
70788
|
import { readFile as readFile19 } from "node:fs/promises";
|
|
70570
|
-
import { join as
|
|
70789
|
+
import { join as join24 } from "node:path";
|
|
70571
70790
|
|
|
70572
70791
|
// src/project/approvedStructureInputHash.ts
|
|
70573
70792
|
import { createHash as createHash11 } from "node:crypto";
|
|
@@ -70608,11 +70827,11 @@ function approvedStructureInputHash(input) {
|
|
|
70608
70827
|
}
|
|
70609
70828
|
|
|
70610
70829
|
// src/project/verifyApprovedStructureEdges.ts
|
|
70611
|
-
import { join as
|
|
70830
|
+
import { join as join22 } from "node:path";
|
|
70612
70831
|
|
|
70613
70832
|
// src/project/verifyCanonicalSourceRefs.ts
|
|
70614
|
-
import { existsSync as
|
|
70615
|
-
import { join as
|
|
70833
|
+
import { existsSync as existsSync12 } from "node:fs";
|
|
70834
|
+
import { join as join21 } from "node:path";
|
|
70616
70835
|
var CANONICAL_SOURCE_REF = /^repo:([^#]+)#symbol:(.+):([^:@]+):([^:@]+)@([a-f0-9]+)$/iu;
|
|
70617
70836
|
function validateCanonicalSourceRef(input) {
|
|
70618
70837
|
const path3 = input.path ?? ".tmp/context-runtime/lifecycle/candidates.jsonl";
|
|
@@ -70668,7 +70887,7 @@ async function validateCanonicalEvidenceSourceRef(input) {
|
|
|
70668
70887
|
const registryEntry = input.sourceRegistry.loaded ? registeredDocumentSource(input.sourceRegistry, locator.sourceType, locator.sourceName) : undefined;
|
|
70669
70888
|
const materializedAt = registryEntry?.materializedAt ?? defaultDocumentMaterializedAt(locator.sourceType, locator.sourceName);
|
|
70670
70889
|
const manifestPath = registryEntry?.snapshot?.manifest ?? defaultDocumentManifest(materializedAt);
|
|
70671
|
-
if (!
|
|
70890
|
+
if (!existsSync12(join21(input.projectRoot, manifestPath)) && !snapshotRootExists(input.projectRoot, materializedAt)) {
|
|
70672
70891
|
input.issues.push({
|
|
70673
70892
|
severity: unresolvedSeverity,
|
|
70674
70893
|
code: "approved-evidence-unavailable",
|
|
@@ -70741,7 +70960,7 @@ async function validateCanonicalEvidenceSourceRef(input) {
|
|
|
70741
70960
|
}
|
|
70742
70961
|
|
|
70743
70962
|
// src/project/verifyApprovedStructureEdges.ts
|
|
70744
|
-
var APPROVED_STRUCTURE_PATH2 =
|
|
70963
|
+
var APPROVED_STRUCTURE_PATH2 = join22("knowledge", "structure.yaml");
|
|
70745
70964
|
function approvedStructureEdgeRecords(parsed, issues) {
|
|
70746
70965
|
if (parsed.edges === undefined)
|
|
70747
70966
|
return [];
|
|
@@ -70874,7 +71093,7 @@ async function validateApprovedStructureEdgeRecords(input) {
|
|
|
70874
71093
|
init_cliFeedback();
|
|
70875
71094
|
init_errors();
|
|
70876
71095
|
init_exitCode();
|
|
70877
|
-
function
|
|
71096
|
+
function isRecord11(value) {
|
|
70878
71097
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
70879
71098
|
}
|
|
70880
71099
|
function codegraphEdgesFromFrontmatter(frontmatter, path3) {
|
|
@@ -70887,7 +71106,7 @@ function codegraphEdgesFromFrontmatter(frontmatter, path3) {
|
|
|
70887
71106
|
});
|
|
70888
71107
|
}
|
|
70889
71108
|
return frontmatter.code_edges.map((rawEdge, index2) => {
|
|
70890
|
-
if (!
|
|
71109
|
+
if (!isRecord11(rawEdge)) {
|
|
70891
71110
|
throw new ContextError(ExitCode.WorkspaceStateError, "approved code edge must be an object", {
|
|
70892
71111
|
category: ErrorCategory.WorkspaceStateInvalid,
|
|
70893
71112
|
path: path3,
|
|
@@ -70947,17 +71166,17 @@ function codegraphRelationshipCoverage(input) {
|
|
|
70947
71166
|
}
|
|
70948
71167
|
|
|
70949
71168
|
// src/project/approvedStructureInputs.ts
|
|
70950
|
-
import { existsSync as
|
|
71169
|
+
import { existsSync as existsSync13 } from "node:fs";
|
|
70951
71170
|
import { readFile as readFile18 } from "node:fs/promises";
|
|
70952
|
-
import { join as
|
|
71171
|
+
import { join as join23 } from "node:path";
|
|
70953
71172
|
init_cliFeedback();
|
|
70954
71173
|
init_errors();
|
|
70955
71174
|
init_exitCode();
|
|
70956
71175
|
var import_yaml11 = __toESM(require_dist3(), 1);
|
|
70957
|
-
var APPROVED_STRUCTURE_FILE =
|
|
71176
|
+
var APPROVED_STRUCTURE_FILE = join23("knowledge", "structure.yaml");
|
|
70958
71177
|
var COLLECTIONS = new Set(KNOWLEDGE_COLLECTIONS);
|
|
70959
71178
|
var SNAPSHOT_HASH_PATTERN = /^sha256:[a-f0-9]{64}$/u;
|
|
70960
|
-
function
|
|
71179
|
+
function isRecord12(value) {
|
|
70961
71180
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
70962
71181
|
}
|
|
70963
71182
|
function invalidSourceInputs(reason) {
|
|
@@ -70976,14 +71195,14 @@ function sortedSourceInputs(values2) {
|
|
|
70976
71195
|
function parseApprovedStructureSourceInputs(structure) {
|
|
70977
71196
|
if (structure.source_inputs === undefined)
|
|
70978
71197
|
return [];
|
|
70979
|
-
if (!
|
|
71198
|
+
if (!isRecord12(structure.source_inputs)) {
|
|
70980
71199
|
throw invalidSourceInputs("source_inputs must be an object when present");
|
|
70981
71200
|
}
|
|
70982
71201
|
const inputs = new Map;
|
|
70983
71202
|
for (const [source2, collections] of Object.entries(structure.source_inputs)) {
|
|
70984
71203
|
if (source2.trim().length === 0)
|
|
70985
71204
|
throw invalidSourceInputs("source_inputs source key must not be empty");
|
|
70986
|
-
if (!
|
|
71205
|
+
if (!isRecord12(collections)) {
|
|
70987
71206
|
throw invalidSourceInputs(`source_inputs.${source2} must be an object`);
|
|
70988
71207
|
}
|
|
70989
71208
|
for (const [collection, snapshotHash] of Object.entries(collections)) {
|
|
@@ -71008,8 +71227,8 @@ function approvedStructureSourceInputsRecord(inputs) {
|
|
|
71008
71227
|
return result;
|
|
71009
71228
|
}
|
|
71010
71229
|
async function readApprovedStructureSourceInputs(projectRoot) {
|
|
71011
|
-
const path3 =
|
|
71012
|
-
if (!
|
|
71230
|
+
const path3 = join23(projectRoot, APPROVED_STRUCTURE_FILE);
|
|
71231
|
+
if (!existsSync13(path3))
|
|
71013
71232
|
return [];
|
|
71014
71233
|
let parsed;
|
|
71015
71234
|
try {
|
|
@@ -71017,7 +71236,7 @@ async function readApprovedStructureSourceInputs(projectRoot) {
|
|
|
71017
71236
|
} catch {
|
|
71018
71237
|
return [];
|
|
71019
71238
|
}
|
|
71020
|
-
if (!
|
|
71239
|
+
if (!isRecord12(parsed))
|
|
71021
71240
|
return [];
|
|
71022
71241
|
return parseApprovedStructureSourceInputs(parsed);
|
|
71023
71242
|
}
|
|
@@ -71046,14 +71265,14 @@ function approvedStructureSourceInputKey(input) {
|
|
|
71046
71265
|
}
|
|
71047
71266
|
|
|
71048
71267
|
// src/project/verifyApprovedStructure.ts
|
|
71049
|
-
var APPROVED_STRUCTURE_PATH3 =
|
|
71268
|
+
var APPROVED_STRUCTURE_PATH3 = join24("knowledge", "structure.yaml");
|
|
71050
71269
|
var APPROVED_STRUCTURE_SCHEMA_VERSION = "context.approved-structure.v1";
|
|
71051
71270
|
var LOCAL_REF = /^src-(\d+)(#(?:span|symbol):.+)$/u;
|
|
71052
71271
|
async function readApprovedStructureForVerify(input) {
|
|
71053
71272
|
if (input.structureOverride !== undefined)
|
|
71054
71273
|
return input.structureOverride;
|
|
71055
|
-
const structurePath =
|
|
71056
|
-
if (!
|
|
71274
|
+
const structurePath = join24(input.projectRoot, APPROVED_STRUCTURE_PATH3);
|
|
71275
|
+
if (!existsSync14(structurePath))
|
|
71057
71276
|
return;
|
|
71058
71277
|
let rawParsed;
|
|
71059
71278
|
try {
|
|
@@ -71278,7 +71497,7 @@ async function approvedStructureProjection(projectRoot) {
|
|
|
71278
71497
|
const views = [];
|
|
71279
71498
|
const parentIndexes = [];
|
|
71280
71499
|
const codeEdges = [];
|
|
71281
|
-
for (const file of await walkMarkdown(
|
|
71500
|
+
for (const file of await walkMarkdown(join24(projectRoot, "knowledge"))) {
|
|
71282
71501
|
if (isKnowledgeAssetPath(file.relPath))
|
|
71283
71502
|
continue;
|
|
71284
71503
|
const content3 = await readFile19(file.absPath, "utf8");
|
|
@@ -71692,13 +71911,13 @@ async function validateApprovedStructureEdges(input) {
|
|
|
71692
71911
|
init_workspace();
|
|
71693
71912
|
|
|
71694
71913
|
// src/project/reviewDecisions.ts
|
|
71695
|
-
import { existsSync as
|
|
71914
|
+
import { existsSync as existsSync17 } from "node:fs";
|
|
71696
71915
|
import { mkdir as mkdir15, readFile as readFile22, rename as rename3, rm as rm8, writeFile as writeFile11 } from "node:fs/promises";
|
|
71697
|
-
import { dirname as
|
|
71916
|
+
import { dirname as dirname20, join as join27 } from "node:path";
|
|
71698
71917
|
init_cliFeedback();
|
|
71699
71918
|
init_errors();
|
|
71700
71919
|
init_exitCode();
|
|
71701
|
-
var REVIEW_DECISIONS_FILE =
|
|
71920
|
+
var REVIEW_DECISIONS_FILE = join27("knowledge", "decisions.json");
|
|
71702
71921
|
var FINGERPRINT_PATTERN = /^sha256:[a-f0-9]{64}$/u;
|
|
71703
71922
|
var COLLECTIONS2 = new Set(KNOWLEDGE_COLLECTIONS);
|
|
71704
71923
|
function isCandidateId(value) {
|
|
@@ -71713,8 +71932,8 @@ function invalidDecisions(reason) {
|
|
|
71713
71932
|
});
|
|
71714
71933
|
}
|
|
71715
71934
|
async function readRejectedDecisions(projectRoot) {
|
|
71716
|
-
const path3 =
|
|
71717
|
-
if (!
|
|
71935
|
+
const path3 = join27(projectRoot, REVIEW_DECISIONS_FILE);
|
|
71936
|
+
if (!existsSync17(path3))
|
|
71718
71937
|
return new Map;
|
|
71719
71938
|
let parsed;
|
|
71720
71939
|
try {
|
|
@@ -71738,14 +71957,14 @@ async function readRejectedDecisions(projectRoot) {
|
|
|
71738
71957
|
return decisions;
|
|
71739
71958
|
}
|
|
71740
71959
|
async function writeRejectedDecisions(projectRoot, decisions) {
|
|
71741
|
-
const path3 =
|
|
71960
|
+
const path3 = join27(projectRoot, REVIEW_DECISIONS_FILE);
|
|
71742
71961
|
if (decisions.size === 0) {
|
|
71743
71962
|
await rm8(path3, { force: true });
|
|
71744
71963
|
return;
|
|
71745
71964
|
}
|
|
71746
71965
|
const rejected = Object.fromEntries([...decisions.entries()].sort(([left], [right]) => left.localeCompare(right)));
|
|
71747
71966
|
const tempPath = `${path3}.${process.pid}.tmp`;
|
|
71748
|
-
await mkdir15(
|
|
71967
|
+
await mkdir15(dirname20(path3), { recursive: true });
|
|
71749
71968
|
await writeFile11(tempPath, `${JSON.stringify(rejected, null, 2)}
|
|
71750
71969
|
`, "utf8");
|
|
71751
71970
|
await rename3(tempPath, path3);
|
|
@@ -71922,7 +72141,7 @@ async function verifyProjectWorkspace(projectRoot, options = {}) {
|
|
|
71922
72141
|
issues
|
|
71923
72142
|
});
|
|
71924
72143
|
const seenViewRefs = new Set;
|
|
71925
|
-
for (const file of await walkMarkdown(
|
|
72144
|
+
for (const file of await walkMarkdown(join28(projectRoot, "knowledge"))) {
|
|
71926
72145
|
if (isKnowledgeAssetPath(file.relPath))
|
|
71927
72146
|
continue;
|
|
71928
72147
|
const content3 = await readFile23(file.absPath, "utf8");
|
|
@@ -71945,7 +72164,7 @@ async function verifyProjectWorkspace(projectRoot, options = {}) {
|
|
|
71945
72164
|
pageRelPath: `knowledge/${file.relPath}`,
|
|
71946
72165
|
content: content3
|
|
71947
72166
|
})) {
|
|
71948
|
-
if (!
|
|
72167
|
+
if (!existsSync18(join28(projectRoot, assetPath))) {
|
|
71949
72168
|
issues.push({
|
|
71950
72169
|
severity: "error",
|
|
71951
72170
|
code: "approved-resource-missing",
|
|
@@ -72131,9 +72350,9 @@ init_writeLock();
|
|
|
72131
72350
|
|
|
72132
72351
|
// src/project/proseCompileBatch.ts
|
|
72133
72352
|
var import_yaml13 = __toESM(require_dist3(), 1);
|
|
72134
|
-
import { existsSync as
|
|
72353
|
+
import { existsSync as existsSync20 } from "node:fs";
|
|
72135
72354
|
import { readFile as readFile25 } from "node:fs/promises";
|
|
72136
|
-
import { join as
|
|
72355
|
+
import { join as join30 } from "node:path";
|
|
72137
72356
|
init_cliFeedback();
|
|
72138
72357
|
init_errors();
|
|
72139
72358
|
init_exitCode();
|
|
@@ -72142,9 +72361,9 @@ init_exitCode();
|
|
|
72142
72361
|
init_cliFeedback();
|
|
72143
72362
|
init_errors();
|
|
72144
72363
|
init_exitCode();
|
|
72145
|
-
import { existsSync as
|
|
72364
|
+
import { existsSync as existsSync19 } from "node:fs";
|
|
72146
72365
|
import { readFile as readFile24, readdir as readdir10 } from "node:fs/promises";
|
|
72147
|
-
import { basename as basename6, join as
|
|
72366
|
+
import { basename as basename6, join as join29, relative as relative12 } from "node:path";
|
|
72148
72367
|
init_writeLock();
|
|
72149
72368
|
function candidateSourceKey(record) {
|
|
72150
72369
|
return record.source === undefined ? undefined : `${record.source.type}:${record.source.name}`;
|
|
@@ -72156,11 +72375,11 @@ function toPosixPath8(value) {
|
|
|
72156
72375
|
return value.split(/[\\/]+/u).join("/");
|
|
72157
72376
|
}
|
|
72158
72377
|
async function approvedPageIdentities(projectRoot) {
|
|
72159
|
-
const root =
|
|
72378
|
+
const root = join29(projectRoot, "knowledge");
|
|
72160
72379
|
const identities = [];
|
|
72161
72380
|
const visit2 = async (directory) => {
|
|
72162
72381
|
for (const entry of await readdir10(directory, { withFileTypes: true })) {
|
|
72163
|
-
const absolutePath =
|
|
72382
|
+
const absolutePath = join29(directory, entry.name);
|
|
72164
72383
|
if (entry.isDirectory()) {
|
|
72165
72384
|
await visit2(absolutePath);
|
|
72166
72385
|
continue;
|
|
@@ -72178,7 +72397,7 @@ async function approvedPageIdentities(projectRoot) {
|
|
|
72178
72397
|
});
|
|
72179
72398
|
}
|
|
72180
72399
|
};
|
|
72181
|
-
if (
|
|
72400
|
+
if (existsSync19(root))
|
|
72182
72401
|
await visit2(root);
|
|
72183
72402
|
return {
|
|
72184
72403
|
byPath: new Map(identities.map((identity) => [identity.path, identity])),
|
|
@@ -72407,7 +72626,7 @@ async function preserveApprovedPathIdentities(input) {
|
|
|
72407
72626
|
}
|
|
72408
72627
|
|
|
72409
72628
|
// src/project/proseCompileBatch.ts
|
|
72410
|
-
function
|
|
72629
|
+
function isRecord14(value) {
|
|
72411
72630
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
72412
72631
|
}
|
|
72413
72632
|
function stringField2(value, field) {
|
|
@@ -72415,11 +72634,11 @@ function stringField2(value, field) {
|
|
|
72415
72634
|
return typeof candidate === "string" && candidate.trim().length > 0 ? candidate.trim() : undefined;
|
|
72416
72635
|
}
|
|
72417
72636
|
async function readConfirmedStructure(projectRoot) {
|
|
72418
|
-
const path3 =
|
|
72419
|
-
if (!
|
|
72637
|
+
const path3 = join30(projectRoot, LIFECYCLE_STRUCTURE_FILE);
|
|
72638
|
+
if (!existsSync20(path3))
|
|
72420
72639
|
return;
|
|
72421
72640
|
const parsed = import_yaml13.default.parse(await readFile25(path3, "utf8"));
|
|
72422
|
-
if (!
|
|
72641
|
+
if (!isRecord14(parsed) || !isRecord14(parsed.lifecycle))
|
|
72423
72642
|
return;
|
|
72424
72643
|
if (parsed.lifecycle.state !== "confirmed" && parsed.lifecycle.state !== "frozen")
|
|
72425
72644
|
return;
|
|
@@ -72434,7 +72653,7 @@ async function readCurrentSnapshotHashes(projectRoot) {
|
|
|
72434
72653
|
}
|
|
72435
72654
|
async function approvedViewRefs(projectRoot, planned) {
|
|
72436
72655
|
const approved = [];
|
|
72437
|
-
for (const file of await walkMarkdown(
|
|
72656
|
+
for (const file of await walkMarkdown(join30(projectRoot, "knowledge"))) {
|
|
72438
72657
|
if (isKnowledgeAssetPath(file.relPath))
|
|
72439
72658
|
continue;
|
|
72440
72659
|
const content3 = await readFile25(file.absPath, "utf8");
|
|
@@ -72702,7 +72921,7 @@ function proseCompileBatchNextAction(input) {
|
|
|
72702
72921
|
|
|
72703
72922
|
// src/project/lifecycleCleanup.ts
|
|
72704
72923
|
import { rm as rm9 } from "node:fs/promises";
|
|
72705
|
-
import { join as
|
|
72924
|
+
import { join as join31 } from "node:path";
|
|
72706
72925
|
var COMPLETED_RUNTIME_PATHS = [
|
|
72707
72926
|
LIFECYCLE_ROOT,
|
|
72708
72927
|
REVIEW_RUNTIME_ROOT,
|
|
@@ -72711,13 +72930,13 @@ var COMPLETED_RUNTIME_PATHS = [
|
|
|
72711
72930
|
CANDIDATE_SNAPSHOT_ROOT
|
|
72712
72931
|
];
|
|
72713
72932
|
async function clearCompletedLifecycle(projectRoot) {
|
|
72714
|
-
await Promise.all(COMPLETED_RUNTIME_PATHS.map((path3) => rm9(
|
|
72933
|
+
await Promise.all(COMPLETED_RUNTIME_PATHS.map((path3) => rm9(join31(projectRoot, path3), { recursive: true, force: true })));
|
|
72715
72934
|
}
|
|
72716
72935
|
|
|
72717
72936
|
// src/project/knowledgeAssetRepair.ts
|
|
72718
|
-
import { existsSync as
|
|
72937
|
+
import { existsSync as existsSync21 } from "node:fs";
|
|
72719
72938
|
import { mkdir as mkdir16, readFile as readFile26, writeFile as writeFile12 } from "node:fs/promises";
|
|
72720
|
-
import { dirname as
|
|
72939
|
+
import { dirname as dirname21, join as join32 } from "node:path";
|
|
72721
72940
|
init_cliFeedback();
|
|
72722
72941
|
init_errors();
|
|
72723
72942
|
init_exitCode();
|
|
@@ -72728,14 +72947,14 @@ function sourceLocators(frontmatter) {
|
|
|
72728
72947
|
])];
|
|
72729
72948
|
}
|
|
72730
72949
|
async function bytesEqual(path3, expected) {
|
|
72731
|
-
if (!
|
|
72950
|
+
if (!existsSync21(path3))
|
|
72732
72951
|
return false;
|
|
72733
72952
|
const actual = await readFile26(path3);
|
|
72734
72953
|
return actual.length === expected.length && actual.equals(Buffer.from(expected));
|
|
72735
72954
|
}
|
|
72736
72955
|
async function repairApprovedKnowledgeAssetProjections(projectRoot) {
|
|
72737
72956
|
const affected = [];
|
|
72738
|
-
for (const file of await walkMarkdown(
|
|
72957
|
+
for (const file of await walkMarkdown(join32(projectRoot, "knowledge"))) {
|
|
72739
72958
|
if (isKnowledgeAssetPath(file.relPath))
|
|
72740
72959
|
continue;
|
|
72741
72960
|
const content3 = await readFile26(file.absPath, "utf8");
|
|
@@ -72809,7 +73028,7 @@ async function repairApprovedKnowledgeAssetProjections(projectRoot) {
|
|
|
72809
73028
|
for (const asset of assets.values()) {
|
|
72810
73029
|
if (await bytesEqual(asset.absPath, asset.bytes))
|
|
72811
73030
|
continue;
|
|
72812
|
-
await mkdir16(
|
|
73031
|
+
await mkdir16(dirname21(asset.absPath), { recursive: true });
|
|
72813
73032
|
await writeFile12(asset.absPath, asset.bytes);
|
|
72814
73033
|
writtenAssets.push(asset.relPath);
|
|
72815
73034
|
}
|
|
@@ -72825,7 +73044,7 @@ async function repairApprovedKnowledgeAssetProjections(projectRoot) {
|
|
|
72825
73044
|
|
|
72826
73045
|
// src/project/close.ts
|
|
72827
73046
|
var KNOWLEDGE_ROOT2 = "knowledge";
|
|
72828
|
-
var STRUCTURE_PATH =
|
|
73047
|
+
var STRUCTURE_PATH = join33(KNOWLEDGE_ROOT2, "structure.yaml");
|
|
72829
73048
|
var STRUCTURE_SCHEMA_VERSION2 = "context.approved-structure.v1";
|
|
72830
73049
|
var LOCAL_REF2 = /^src-(\d+)(#(?:span|symbol):.+)$/u;
|
|
72831
73050
|
var APPROVED_NODE_TYPES2 = new Set(["entity", "domain", "action"]);
|
|
@@ -72855,13 +73074,13 @@ function requiredFrontmatterString(frontmatter, field, relPath) {
|
|
|
72855
73074
|
});
|
|
72856
73075
|
}
|
|
72857
73076
|
async function walkFiles2(root) {
|
|
72858
|
-
if (!
|
|
73077
|
+
if (!existsSync22(root))
|
|
72859
73078
|
return [];
|
|
72860
73079
|
const files = [];
|
|
72861
73080
|
const visit2 = async (dir) => {
|
|
72862
73081
|
const entries = await readdir11(dir, { withFileTypes: true });
|
|
72863
73082
|
for (const entry of entries) {
|
|
72864
|
-
const absPath =
|
|
73083
|
+
const absPath = join33(dir, entry.name);
|
|
72865
73084
|
if (entry.isDirectory()) {
|
|
72866
73085
|
await visit2(absPath);
|
|
72867
73086
|
continue;
|
|
@@ -72886,7 +73105,7 @@ function isDeprecated(content3) {
|
|
|
72886
73105
|
return parseFrontmatter3(content3).deprecated === true;
|
|
72887
73106
|
}
|
|
72888
73107
|
async function approvedKnowledgeFiles(projectRoot) {
|
|
72889
|
-
const files = await walkFiles2(
|
|
73108
|
+
const files = await walkFiles2(join33(projectRoot, KNOWLEDGE_ROOT2));
|
|
72890
73109
|
const markdown = await Promise.all(files.filter((file) => file.relPath.endsWith(".md") && !isKnowledgeAssetPath(file.relPath)).map(async (file) => ({
|
|
72891
73110
|
...file,
|
|
72892
73111
|
content: await readFile27(file.absPath, "utf8")
|
|
@@ -73156,11 +73375,11 @@ function referencesReceipt() {
|
|
|
73156
73375
|
}
|
|
73157
73376
|
async function readProjectCloseStatus(projectRoot) {
|
|
73158
73377
|
const approved = await approvedKnowledgeFiles(projectRoot);
|
|
73159
|
-
const structurePath =
|
|
73160
|
-
if (approved.length === 0 && !
|
|
73378
|
+
const structurePath = join33(projectRoot, STRUCTURE_PATH);
|
|
73379
|
+
if (approved.length === 0 && !existsSync22(structurePath))
|
|
73161
73380
|
return { state: "missing", diagnostics: [] };
|
|
73162
73381
|
const inputHash = await approvedKnowledgeInputHash(projectRoot);
|
|
73163
|
-
if (!
|
|
73382
|
+
if (!existsSync22(structurePath))
|
|
73164
73383
|
return { state: "missing", inputHash, diagnostics: [`close structure is missing: ${STRUCTURE_PATH}`] };
|
|
73165
73384
|
try {
|
|
73166
73385
|
const parsed = import_yaml14.default.parse(await readFile27(structurePath, "utf8"));
|
|
@@ -73229,8 +73448,8 @@ async function closeProjectWorkspace(projectRoot) {
|
|
|
73229
73448
|
next: "Fix context verify errors, then rerun context close --format json."
|
|
73230
73449
|
});
|
|
73231
73450
|
}
|
|
73232
|
-
const outputPath =
|
|
73233
|
-
await mkdir17(
|
|
73451
|
+
const outputPath = join33(projectRoot, STRUCTURE_PATH);
|
|
73452
|
+
await mkdir17(dirname22(outputPath), { recursive: true });
|
|
73234
73453
|
await writeFile13(outputPath, `${import_yaml14.default.stringify(structure)}`, "utf8");
|
|
73235
73454
|
await clearCompletedLifecycle(projectRoot);
|
|
73236
73455
|
return {
|
|
@@ -73279,22 +73498,33 @@ async function runProjectCloseCommand(input) {
|
|
|
73279
73498
|
].join(`
|
|
73280
73499
|
`));
|
|
73281
73500
|
}
|
|
73501
|
+
queueContextRuntimeEvent({
|
|
73502
|
+
cwd: result.projectRoot,
|
|
73503
|
+
kind: "knowledge.closed",
|
|
73504
|
+
properties: {
|
|
73505
|
+
node_count: result.nodes,
|
|
73506
|
+
view_count: result.views,
|
|
73507
|
+
edge_count: result.edges,
|
|
73508
|
+
verify_warning_count: result.verifyWarnings,
|
|
73509
|
+
relationship_coverage: result.relationshipCoverage.state
|
|
73510
|
+
}
|
|
73511
|
+
});
|
|
73282
73512
|
return true;
|
|
73283
73513
|
}
|
|
73284
73514
|
|
|
73285
73515
|
// src/project/reviewApply.ts
|
|
73286
|
-
import { existsSync as
|
|
73516
|
+
import { existsSync as existsSync27 } from "node:fs";
|
|
73287
73517
|
import { mkdir as mkdir22, readFile as readFile34, rm as rm11, writeFile as writeFile18 } from "node:fs/promises";
|
|
73288
|
-
import { dirname as
|
|
73518
|
+
import { dirname as dirname27, join as join42 } from "node:path";
|
|
73289
73519
|
init_cliFeedback();
|
|
73290
73520
|
init_errors();
|
|
73291
73521
|
init_exitCode();
|
|
73292
73522
|
|
|
73293
73523
|
// src/project/proseCompileStructure.ts
|
|
73294
73524
|
import { createHash as createHash15 } from "node:crypto";
|
|
73295
|
-
import { existsSync as
|
|
73525
|
+
import { existsSync as existsSync25 } from "node:fs";
|
|
73296
73526
|
import { mkdir as mkdir20, readFile as readFile32, writeFile as writeFile16 } from "node:fs/promises";
|
|
73297
|
-
import { dirname as
|
|
73527
|
+
import { dirname as dirname25, join as join40 } from "node:path";
|
|
73298
73528
|
init_cliFeedback();
|
|
73299
73529
|
init_errors();
|
|
73300
73530
|
init_exitCode();
|
|
@@ -73303,7 +73533,7 @@ var import_yaml20 = __toESM(require_dist3(), 1);
|
|
|
73303
73533
|
// src/project/proseAlignEvidence.ts
|
|
73304
73534
|
import { createHash as createHash13 } from "node:crypto";
|
|
73305
73535
|
import { readFile as readFile28 } from "node:fs/promises";
|
|
73306
|
-
import { join as
|
|
73536
|
+
import { join as join34 } from "node:path";
|
|
73307
73537
|
|
|
73308
73538
|
// src/incremental/rawBlocks.ts
|
|
73309
73539
|
var import_yaml15 = __toESM(require_dist3(), 1);
|
|
@@ -77198,7 +77428,7 @@ async function loadProseEvidence(input) {
|
|
|
77198
77428
|
const documents = [];
|
|
77199
77429
|
const chunks = [];
|
|
77200
77430
|
for (const [documentIndex, document4] of indexResult.index.documents.entries()) {
|
|
77201
|
-
const markdown = await readFile28(
|
|
77431
|
+
const markdown = await readFile28(join34(input.projectRoot, indexResult.index.materialized_at, document4.path), "utf8");
|
|
77202
77432
|
const locator = locatorFor({
|
|
77203
77433
|
sourceType: resolved.sourceType,
|
|
77204
77434
|
sourceName: resolved.sourceName,
|
|
@@ -77673,19 +77903,19 @@ function repairHints(diagnostics, phaseId) {
|
|
|
77673
77903
|
|
|
77674
77904
|
// src/project/proseAlignStructureSummary.ts
|
|
77675
77905
|
import { mkdir as mkdir18, writeFile as writeFile14 } from "node:fs/promises";
|
|
77676
|
-
import { dirname as
|
|
77906
|
+
import { dirname as dirname23, join as join37 } from "node:path";
|
|
77677
77907
|
|
|
77678
77908
|
// src/project/proseAlignExistingApprovedStructure.ts
|
|
77679
77909
|
var import_yaml16 = __toESM(require_dist3(), 1);
|
|
77680
|
-
import { existsSync as
|
|
77910
|
+
import { existsSync as existsSync23 } from "node:fs";
|
|
77681
77911
|
import { readFile as readFile29, readdir as readdir12 } from "node:fs/promises";
|
|
77682
|
-
import { basename as basename7, join as
|
|
77683
|
-
var APPROVED_STRUCTURE_PATH4 =
|
|
77912
|
+
import { basename as basename7, join as join35, relative as relative14 } from "node:path";
|
|
77913
|
+
var APPROVED_STRUCTURE_PATH4 = join35("knowledge", "structure.yaml");
|
|
77684
77914
|
var KNOWLEDGE_ROOT3 = "knowledge";
|
|
77685
77915
|
function uniqueRefs(refs) {
|
|
77686
77916
|
return [...new Set(refs)].sort();
|
|
77687
77917
|
}
|
|
77688
|
-
function
|
|
77918
|
+
function isRecord15(value) {
|
|
77689
77919
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
77690
77920
|
}
|
|
77691
77921
|
function stringField3(record, key) {
|
|
@@ -77702,14 +77932,14 @@ function toPosixPath10(path4) {
|
|
|
77702
77932
|
return path4.split(/[\\/]+/u).join("/");
|
|
77703
77933
|
}
|
|
77704
77934
|
async function approvedMarkdownFiles(projectRoot) {
|
|
77705
|
-
const root2 =
|
|
77706
|
-
if (!
|
|
77935
|
+
const root2 = join35(projectRoot, KNOWLEDGE_ROOT3);
|
|
77936
|
+
if (!existsSync23(root2))
|
|
77707
77937
|
return [];
|
|
77708
77938
|
const files = [];
|
|
77709
77939
|
const visit3 = async (directory) => {
|
|
77710
77940
|
const entries = await readdir12(directory, { withFileTypes: true });
|
|
77711
77941
|
for (const entry of entries) {
|
|
77712
|
-
const absolutePath =
|
|
77942
|
+
const absolutePath = join35(directory, entry.name);
|
|
77713
77943
|
if (entry.isDirectory()) {
|
|
77714
77944
|
await visit3(absolutePath);
|
|
77715
77945
|
continue;
|
|
@@ -77726,7 +77956,7 @@ function frontmatterRecord(markdown) {
|
|
|
77726
77956
|
if (match === null)
|
|
77727
77957
|
return;
|
|
77728
77958
|
const parsed = import_yaml16.default.parse(match[1] ?? "");
|
|
77729
|
-
return
|
|
77959
|
+
return isRecord15(parsed) ? parsed : undefined;
|
|
77730
77960
|
}
|
|
77731
77961
|
function isDeprecatedApprovedPage(markdown) {
|
|
77732
77962
|
return /^deprecated:\s*true\s*$/mu.test(markdown);
|
|
@@ -77775,7 +78005,7 @@ async function parseExistingApprovedMarkdown(projectRoot) {
|
|
|
77775
78005
|
node_type: existingNode?.node_type ?? nodeType,
|
|
77776
78006
|
tags: uniqueRefs([...existingNode?.tags ?? [], ...nodeTags])
|
|
77777
78007
|
});
|
|
77778
|
-
const relPath = toPosixPath10(relative14(
|
|
78008
|
+
const relPath = toPosixPath10(relative14(join35(projectRoot, KNOWLEDGE_ROOT3), filePath));
|
|
77779
78009
|
const location = pathLocation(relPath);
|
|
77780
78010
|
const collection = viewRef.split(":", 1)[0] ?? location.collection;
|
|
77781
78011
|
views.set(viewRef, {
|
|
@@ -77804,8 +78034,8 @@ async function parseExistingApprovedMarkdown(projectRoot) {
|
|
|
77804
78034
|
return { nodes, views, sections, edges: [], diagnostics: [] };
|
|
77805
78035
|
}
|
|
77806
78036
|
async function readFreshApprovedStructureEdges(projectRoot) {
|
|
77807
|
-
const absolutePath =
|
|
77808
|
-
if (!
|
|
78037
|
+
const absolutePath = join35(projectRoot, APPROVED_STRUCTURE_PATH4);
|
|
78038
|
+
if (!existsSync23(absolutePath))
|
|
77809
78039
|
return { edges: [], diagnostics: [] };
|
|
77810
78040
|
let raw;
|
|
77811
78041
|
try {
|
|
@@ -77814,7 +78044,7 @@ async function readFreshApprovedStructureEdges(projectRoot) {
|
|
|
77814
78044
|
const message = error instanceof Error ? error.message : String(error);
|
|
77815
78045
|
return { edges: [], diagnostics: [`knowledge/structure.yaml could not be parsed: ${message}`] };
|
|
77816
78046
|
}
|
|
77817
|
-
if (!
|
|
78047
|
+
if (!isRecord15(raw) || raw.schema_version !== "context.approved-structure.v1") {
|
|
77818
78048
|
return { edges: [], diagnostics: ["knowledge/structure.yaml schema is not current; approved summary uses Markdown projection only."] };
|
|
77819
78049
|
}
|
|
77820
78050
|
const expectedInputHash = await approvedKnowledgeInputHash(projectRoot).catch(() => {
|
|
@@ -77848,7 +78078,7 @@ function emptyExistingApprovedStructureSummary(diagnostics = []) {
|
|
|
77848
78078
|
function parseApprovedEdges(raw) {
|
|
77849
78079
|
const edges = [];
|
|
77850
78080
|
for (const rawEdge of Array.isArray(raw.edges) ? raw.edges : []) {
|
|
77851
|
-
if (!
|
|
78081
|
+
if (!isRecord15(rawEdge))
|
|
77852
78082
|
continue;
|
|
77853
78083
|
const type = stringField3(rawEdge, "type");
|
|
77854
78084
|
const from = stringField3(rawEdge, "from");
|
|
@@ -77918,7 +78148,7 @@ async function readExistingApprovedStructureSummary(input) {
|
|
|
77918
78148
|
const freshStructure = await readFreshApprovedStructureEdges(input.projectRoot);
|
|
77919
78149
|
approved.edges = freshStructure.edges;
|
|
77920
78150
|
approved.diagnostics.push(...freshStructure.diagnostics);
|
|
77921
|
-
if (approved.nodes.size === 0 && approved.views.size === 0 && approved.sections.size === 0 && !
|
|
78151
|
+
if (approved.nodes.size === 0 && approved.views.size === 0 && approved.sections.size === 0 && !existsSync23(join35(input.projectRoot, APPROVED_STRUCTURE_PATH4))) {
|
|
77922
78152
|
return emptyExistingApprovedStructureSummary();
|
|
77923
78153
|
}
|
|
77924
78154
|
const endpointRefs = new Set([
|
|
@@ -79026,12 +79256,12 @@ function renderStructureSummaryHtml(input) {
|
|
|
79026
79256
|
|
|
79027
79257
|
// src/project/localHtmlReport.ts
|
|
79028
79258
|
import { execFile as execFile3 } from "node:child_process";
|
|
79029
|
-
import { isAbsolute as isAbsolute7, join as
|
|
79259
|
+
import { isAbsolute as isAbsolute7, join as join36 } from "node:path";
|
|
79030
79260
|
import { pathToFileURL } from "node:url";
|
|
79031
79261
|
import { promisify as promisify3 } from "node:util";
|
|
79032
79262
|
var execFileAsync3 = promisify3(execFile3);
|
|
79033
79263
|
function htmlReportReference(input) {
|
|
79034
|
-
const absolutePath = isAbsolute7(input.path) ? input.path :
|
|
79264
|
+
const absolutePath = isAbsolute7(input.path) ? input.path : join36(input.projectRoot, input.path);
|
|
79035
79265
|
return {
|
|
79036
79266
|
format: "html",
|
|
79037
79267
|
path: input.path,
|
|
@@ -79377,9 +79607,9 @@ function buildStructureSummary(input) {
|
|
|
79377
79607
|
async function writeStructureSummaryReport(input) {
|
|
79378
79608
|
const summary = buildStructureSummary(input);
|
|
79379
79609
|
const shortDigest = summary.structure_digest.replace(/^sha256:/u, "").slice(0, 16);
|
|
79380
|
-
const reportPath =
|
|
79381
|
-
const absolutePath =
|
|
79382
|
-
await mkdir18(
|
|
79610
|
+
const reportPath = join37(".tmp", "context-runtime", "reports", `structure-summary-${shortDigest}.html`);
|
|
79611
|
+
const absolutePath = join37(input.projectRoot, reportPath);
|
|
79612
|
+
await mkdir18(dirname23(absolutePath), { recursive: true });
|
|
79383
79613
|
await writeFile14(absolutePath, renderStructureSummaryHtml({ summary, diagnostics: input.diagnostics }), "utf8");
|
|
79384
79614
|
return {
|
|
79385
79615
|
summary,
|
|
@@ -79554,9 +79784,9 @@ function withStructureReviewArtifacts(input) {
|
|
|
79554
79784
|
// src/project/proseCompileViews.ts
|
|
79555
79785
|
var import_yaml17 = __toESM(require_dist3(), 1);
|
|
79556
79786
|
import { createHash as createHash14 } from "node:crypto";
|
|
79557
|
-
import { existsSync as
|
|
79787
|
+
import { existsSync as existsSync24 } from "node:fs";
|
|
79558
79788
|
import { readFile as readFile30 } from "node:fs/promises";
|
|
79559
|
-
import { join as
|
|
79789
|
+
import { join as join38 } from "node:path";
|
|
79560
79790
|
|
|
79561
79791
|
// src/project/proseCompileSemanticRules.ts
|
|
79562
79792
|
function compileSemanticRules(input) {
|
|
@@ -79959,8 +80189,8 @@ function canonicalizeApprovedSourceRef2(ref2, sources) {
|
|
|
79959
80189
|
}
|
|
79960
80190
|
async function existingApprovedNodeSections(input) {
|
|
79961
80191
|
const relativePath = `knowledge/${input.node.path}`;
|
|
79962
|
-
const absolutePath =
|
|
79963
|
-
if (!
|
|
80192
|
+
const absolutePath = join38(input.projectRoot, relativePath);
|
|
80193
|
+
if (!existsSync24(absolutePath)) {
|
|
79964
80194
|
return {
|
|
79965
80195
|
path: relativePath,
|
|
79966
80196
|
present: false,
|
|
@@ -80342,7 +80572,7 @@ function parsePayloadText(raw) {
|
|
|
80342
80572
|
// src/project/proseAlignPayloadStage.ts
|
|
80343
80573
|
var import_yaml19 = __toESM(require_dist3(), 1);
|
|
80344
80574
|
import { mkdir as mkdir19, writeFile as writeFile15 } from "node:fs/promises";
|
|
80345
|
-
import { dirname as
|
|
80575
|
+
import { dirname as dirname24, join as join39 } from "node:path";
|
|
80346
80576
|
init_writeLock();
|
|
80347
80577
|
async function resolveStagedPayloadConfirmation(input) {
|
|
80348
80578
|
await archiveActiveStructure(input.projectRoot);
|
|
@@ -80413,7 +80643,7 @@ async function stageAlignPayload(input) {
|
|
|
80413
80643
|
next: readPlanCommand
|
|
80414
80644
|
});
|
|
80415
80645
|
}
|
|
80416
|
-
const structurePath =
|
|
80646
|
+
const structurePath = join39(input.projectRoot, LIFECYCLE_STRUCTURE_FILE);
|
|
80417
80647
|
const resolved = await resolveStagedPayloadConfirmation(input);
|
|
80418
80648
|
const effectivePayload = {
|
|
80419
80649
|
...resolved.payload,
|
|
@@ -80425,7 +80655,7 @@ async function stageAlignPayload(input) {
|
|
|
80425
80655
|
if (effectivePayload.lifecycle.state === "confirmed" || effectivePayload.lifecycle.state === "frozen") {
|
|
80426
80656
|
await writeStructureSnapshot(input.projectRoot, effectivePayload);
|
|
80427
80657
|
}
|
|
80428
|
-
await mkdir19(
|
|
80658
|
+
await mkdir19(dirname24(structurePath), { recursive: true });
|
|
80429
80659
|
await writeFile15(structurePath, import_yaml19.default.stringify(normalizeAlignPayloadForWrite(effectivePayload)), "utf8");
|
|
80430
80660
|
return {
|
|
80431
80661
|
structureFile: LIFECYCLE_STRUCTURE_FILE,
|
|
@@ -80941,7 +81171,7 @@ function canonicalJson2(value) {
|
|
|
80941
81171
|
function digest3(value) {
|
|
80942
81172
|
return `sha256:${createHash15("sha256").update(canonicalJson2(value)).digest("hex")}`;
|
|
80943
81173
|
}
|
|
80944
|
-
function
|
|
81174
|
+
function isRecord16(value) {
|
|
80945
81175
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
80946
81176
|
}
|
|
80947
81177
|
function stringField4(record, field) {
|
|
@@ -80952,8 +81182,8 @@ function stringArray2(value) {
|
|
|
80952
81182
|
return Array.isArray(value) ? value.filter((item) => typeof item === "string" && item.trim().length > 0) : [];
|
|
80953
81183
|
}
|
|
80954
81184
|
async function readStructureFile(projectRoot) {
|
|
80955
|
-
const structurePath =
|
|
80956
|
-
if (!
|
|
81185
|
+
const structurePath = join40(projectRoot, LIFECYCLE_STRUCTURE_FILE);
|
|
81186
|
+
if (!existsSync25(structurePath)) {
|
|
80957
81187
|
return null;
|
|
80958
81188
|
}
|
|
80959
81189
|
let raw;
|
|
@@ -80978,8 +81208,8 @@ async function readStructureFile(projectRoot) {
|
|
|
80978
81208
|
}
|
|
80979
81209
|
}
|
|
80980
81210
|
async function readApprovedStructureFile(projectRoot) {
|
|
80981
|
-
const structurePath =
|
|
80982
|
-
if (!
|
|
81211
|
+
const structurePath = join40(projectRoot, APPROVED_STRUCTURE_FILE2);
|
|
81212
|
+
if (!existsSync25(structurePath))
|
|
80983
81213
|
return null;
|
|
80984
81214
|
try {
|
|
80985
81215
|
return import_yaml20.default.parse(await readFile32(structurePath, "utf8"));
|
|
@@ -80994,13 +81224,13 @@ async function readApprovedStructureFile(projectRoot) {
|
|
|
80994
81224
|
async function compileStructureSlotDigest(input) {
|
|
80995
81225
|
const slotDigest = await currentStructureSlotDigest(input.projectRoot, input.sourceKey, input.collection);
|
|
80996
81226
|
const current2 = await readStructureFile(input.projectRoot);
|
|
80997
|
-
if (current2 === null || !
|
|
81227
|
+
if (current2 === null || !isRecord16(current2) || !Array.isArray(current2.sources) || !Array.isArray(current2.views)) {
|
|
80998
81228
|
return slotDigest;
|
|
80999
81229
|
}
|
|
81000
|
-
const currentOwnsTarget = current2.sources.includes(input.sourceKey) && current2.views.some((view) =>
|
|
81230
|
+
const currentOwnsTarget = current2.sources.includes(input.sourceKey) && current2.views.some((view) => isRecord16(view) && view.collection === input.collection);
|
|
81001
81231
|
if (!currentOwnsTarget)
|
|
81002
81232
|
return slotDigest;
|
|
81003
|
-
const lifecycle =
|
|
81233
|
+
const lifecycle = isRecord16(current2.lifecycle) ? current2.lifecycle : undefined;
|
|
81004
81234
|
const currentDigest = lifecycle === undefined ? undefined : stringField4(lifecycle, "structure_digest");
|
|
81005
81235
|
return slotDigest !== undefined && slotDigest !== currentDigest ? slotDigest : undefined;
|
|
81006
81236
|
}
|
|
@@ -81009,7 +81239,7 @@ function parseApprovedSections(value, viewRef) {
|
|
|
81009
81239
|
return [];
|
|
81010
81240
|
const sections = [];
|
|
81011
81241
|
for (const rawSection of value) {
|
|
81012
|
-
if (!
|
|
81242
|
+
if (!isRecord16(rawSection))
|
|
81013
81243
|
continue;
|
|
81014
81244
|
const id2 = stringField4(rawSection, "id");
|
|
81015
81245
|
const kind = stringField4(rawSection, "kind");
|
|
@@ -81032,7 +81262,7 @@ function parseApprovedNodes(value) {
|
|
|
81032
81262
|
return [];
|
|
81033
81263
|
const nodes = [];
|
|
81034
81264
|
for (const rawNode of value) {
|
|
81035
|
-
if (!
|
|
81265
|
+
if (!isRecord16(rawNode))
|
|
81036
81266
|
continue;
|
|
81037
81267
|
const nodeRef = stringField4(rawNode, "node_ref");
|
|
81038
81268
|
const title = stringField4(rawNode, "title");
|
|
@@ -81056,7 +81286,7 @@ function parseApprovedViews(value, nodes) {
|
|
|
81056
81286
|
const nodeByRef = new Map(nodes.map((node3) => [node3.node_ref, node3]));
|
|
81057
81287
|
const views = [];
|
|
81058
81288
|
for (const rawView of value) {
|
|
81059
|
-
if (!
|
|
81289
|
+
if (!isRecord16(rawView))
|
|
81060
81290
|
continue;
|
|
81061
81291
|
const viewRef = stringField4(rawView, "view_ref");
|
|
81062
81292
|
const nodeRef = stringField4(rawView, "node_ref");
|
|
@@ -81094,7 +81324,7 @@ function parseApprovedEdges2(value) {
|
|
|
81094
81324
|
return [];
|
|
81095
81325
|
const edges = [];
|
|
81096
81326
|
for (const rawEdge of value) {
|
|
81097
|
-
if (!
|
|
81327
|
+
if (!isRecord16(rawEdge))
|
|
81098
81328
|
continue;
|
|
81099
81329
|
const type = stringField4(rawEdge, "type");
|
|
81100
81330
|
const from = stringField4(rawEdge, "from");
|
|
@@ -81158,7 +81388,7 @@ function assertApprovedEdgeContract(value, endpointRefs) {
|
|
|
81158
81388
|
});
|
|
81159
81389
|
}
|
|
81160
81390
|
for (const [index2, rawEdge] of value.entries()) {
|
|
81161
|
-
if (!
|
|
81391
|
+
if (!isRecord16(rawEdge)) {
|
|
81162
81392
|
throw workspaceError("knowledge/structure.yaml edge must be an object", {
|
|
81163
81393
|
path: APPROVED_STRUCTURE_FILE2,
|
|
81164
81394
|
edge_index: index2,
|
|
@@ -81298,7 +81528,7 @@ async function loadConfirmedStructure(input) {
|
|
|
81298
81528
|
let rawStructure = input.structureDigest === undefined ? await readStructureFile(input.projectRoot) : await readStructureSnapshot(input.projectRoot, input.structureDigest);
|
|
81299
81529
|
if (rawStructure === null && input.structureDigest !== undefined) {
|
|
81300
81530
|
const active = await readStructureFile(input.projectRoot);
|
|
81301
|
-
const activeDigest =
|
|
81531
|
+
const activeDigest = isRecord16(active) && isRecord16(active.lifecycle) ? stringField4(active.lifecycle, "structure_digest") : undefined;
|
|
81302
81532
|
if (activeDigest === input.structureDigest) {
|
|
81303
81533
|
rawStructure = active;
|
|
81304
81534
|
} else if (input.readOnly !== true) {
|
|
@@ -81315,7 +81545,7 @@ async function loadConfirmedStructure(input) {
|
|
|
81315
81545
|
});
|
|
81316
81546
|
}
|
|
81317
81547
|
const approvedStructure = await readApprovedStructureFile(input.projectRoot);
|
|
81318
|
-
if (!
|
|
81548
|
+
if (!isRecord16(approvedStructure)) {
|
|
81319
81549
|
throw workspaceError("compileProse requires confirmed .tmp/context-runtime/lifecycle/structure.yaml or approved knowledge/structure.yaml", {
|
|
81320
81550
|
path: LIFECYCLE_STRUCTURE_FILE,
|
|
81321
81551
|
approved_structure: APPROVED_STRUCTURE_FILE2,
|
|
@@ -81411,8 +81641,8 @@ async function freezeStructureIfNeeded(input) {
|
|
|
81411
81641
|
};
|
|
81412
81642
|
await archiveActiveStructure(input.projectRoot);
|
|
81413
81643
|
await writeStructureSnapshot(input.projectRoot, nextStructure);
|
|
81414
|
-
const structurePath =
|
|
81415
|
-
await mkdir20(
|
|
81644
|
+
const structurePath = join40(input.projectRoot, LIFECYCLE_STRUCTURE_FILE);
|
|
81645
|
+
await mkdir20(dirname25(structurePath), { recursive: true });
|
|
81416
81646
|
await writeFile16(structurePath, import_yaml20.default.stringify({
|
|
81417
81647
|
schema_version: nextStructure.schema_version,
|
|
81418
81648
|
sources: nextStructure.sources,
|
|
@@ -81495,9 +81725,9 @@ var import_yaml22 = __toESM(require_dist3(), 1);
|
|
|
81495
81725
|
|
|
81496
81726
|
// src/project/reviewShared.ts
|
|
81497
81727
|
import { createHash as createHash16 } from "node:crypto";
|
|
81498
|
-
import { existsSync as
|
|
81728
|
+
import { existsSync as existsSync26, readdirSync as readdirSync2, readFileSync as readFileSync7 } from "node:fs";
|
|
81499
81729
|
import { mkdir as mkdir21, readFile as readFile33, rm as rm10, rmdir as rmdir2, writeFile as writeFile17 } from "node:fs/promises";
|
|
81500
|
-
import { dirname as
|
|
81730
|
+
import { dirname as dirname26, join as join41 } from "node:path";
|
|
81501
81731
|
init_cliFeedback();
|
|
81502
81732
|
init_errors();
|
|
81503
81733
|
init_exitCode();
|
|
@@ -81527,10 +81757,10 @@ function proseCandidateMarkdown(input) {
|
|
|
81527
81757
|
|
|
81528
81758
|
// src/project/reviewShared.ts
|
|
81529
81759
|
init_workspace();
|
|
81530
|
-
var SNAPSHOT_ROOT2 =
|
|
81531
|
-
var REVIEW_ACTION_ROOT2 =
|
|
81760
|
+
var SNAPSHOT_ROOT2 = join41(".tmp", "context-runtime", "extract", "candidates");
|
|
81761
|
+
var REVIEW_ACTION_ROOT2 = join41(".tmp", "context-runtime", "review-actions");
|
|
81532
81762
|
var REVIEW_PAYLOAD_SCHEMA = "context.review.decisions.v1";
|
|
81533
|
-
function
|
|
81763
|
+
function isRecord17(value) {
|
|
81534
81764
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
81535
81765
|
}
|
|
81536
81766
|
function assertCollection(value) {
|
|
@@ -81551,26 +81781,26 @@ function assertCollection(value) {
|
|
|
81551
81781
|
}
|
|
81552
81782
|
function snapshotPath2(projectRoot, candidateId) {
|
|
81553
81783
|
assertSafeEntityId(candidateId);
|
|
81554
|
-
return
|
|
81784
|
+
return join41(projectRoot, SNAPSHOT_ROOT2, `${candidateId}.json`);
|
|
81555
81785
|
}
|
|
81556
81786
|
async function readCandidateSnapshot(projectRoot, candidateId) {
|
|
81557
81787
|
const file = snapshotPath2(projectRoot, candidateId);
|
|
81558
|
-
if (!
|
|
81788
|
+
if (!existsSync26(file))
|
|
81559
81789
|
return;
|
|
81560
81790
|
let parsed;
|
|
81561
81791
|
try {
|
|
81562
81792
|
parsed = JSON.parse(await readFile33(file, "utf8"));
|
|
81563
81793
|
} catch (error) {
|
|
81564
81794
|
const message = error instanceof Error ? error.message : String(error);
|
|
81565
|
-
throw new ContextError(ExitCode.WorkspaceStateError, `candidate snapshot is invalid JSON: ${
|
|
81795
|
+
throw new ContextError(ExitCode.WorkspaceStateError, `candidate snapshot is invalid JSON: ${join41(SNAPSHOT_ROOT2, `${candidateId}.json`)}`, {
|
|
81566
81796
|
category: ErrorCategory.SchemaInvalid,
|
|
81567
81797
|
candidate_id: candidateId,
|
|
81568
81798
|
reason: message,
|
|
81569
81799
|
next: "Rerun the extract phase before reviewing this candidate."
|
|
81570
81800
|
});
|
|
81571
81801
|
}
|
|
81572
|
-
if (!
|
|
81573
|
-
throw new ContextError(ExitCode.WorkspaceStateError, `candidate snapshot is invalid: ${
|
|
81802
|
+
if (!isRecord17(parsed) || typeof parsed.candidate_id !== "string" || typeof parsed.markdown !== "string") {
|
|
81803
|
+
throw new ContextError(ExitCode.WorkspaceStateError, `candidate snapshot is invalid: ${join41(SNAPSHOT_ROOT2, `${candidateId}.json`)}`, {
|
|
81574
81804
|
category: ErrorCategory.SchemaInvalid,
|
|
81575
81805
|
candidate_id: candidateId,
|
|
81576
81806
|
next: "Rerun the extract phase before reviewing this candidate."
|
|
@@ -81601,15 +81831,15 @@ async function extractCandidateSnapshotIsCurrent(projectRoot, snapshot) {
|
|
|
81601
81831
|
async function removeCandidateSnapshot2(projectRoot, candidateId) {
|
|
81602
81832
|
const file = snapshotPath2(projectRoot, candidateId);
|
|
81603
81833
|
await rm10(file, { force: true });
|
|
81604
|
-
const snapshotRoot =
|
|
81605
|
-
let current2 =
|
|
81834
|
+
const snapshotRoot = join41(projectRoot, SNAPSHOT_ROOT2);
|
|
81835
|
+
let current2 = dirname26(file);
|
|
81606
81836
|
while (current2 !== snapshotRoot && current2.startsWith(snapshotRoot)) {
|
|
81607
81837
|
try {
|
|
81608
81838
|
await rmdir2(current2);
|
|
81609
81839
|
} catch {
|
|
81610
81840
|
break;
|
|
81611
81841
|
}
|
|
81612
|
-
current2 =
|
|
81842
|
+
current2 = dirname26(current2);
|
|
81613
81843
|
}
|
|
81614
81844
|
}
|
|
81615
81845
|
function parseCanonicalSourceRef(ref2) {
|
|
@@ -81730,11 +81960,11 @@ function findApprovedPageForViewRef(projectRoot, viewRef) {
|
|
|
81730
81960
|
}
|
|
81731
81961
|
const nodeRef = viewRef.slice(separator + 1);
|
|
81732
81962
|
assertSafeEntityId(nodeRef);
|
|
81733
|
-
const collectionRoot =
|
|
81734
|
-
if (
|
|
81963
|
+
const collectionRoot = join41(projectRoot, "knowledge", collection);
|
|
81964
|
+
if (existsSync26(collectionRoot)) {
|
|
81735
81965
|
const visit3 = (dir, relDir) => {
|
|
81736
81966
|
for (const entry of readdirSync2(dir, { withFileTypes: true })) {
|
|
81737
|
-
const absPath =
|
|
81967
|
+
const absPath = join41(dir, entry.name);
|
|
81738
81968
|
const rel = relDir.length === 0 ? entry.name : `${relDir}/${entry.name}`;
|
|
81739
81969
|
if (entry.isDirectory()) {
|
|
81740
81970
|
const found2 = visit3(absPath, rel);
|
|
@@ -81744,16 +81974,16 @@ function findApprovedPageForViewRef(projectRoot, viewRef) {
|
|
|
81744
81974
|
}
|
|
81745
81975
|
if (!entry.isFile() || !entry.name.endsWith(".md"))
|
|
81746
81976
|
continue;
|
|
81747
|
-
const block = frontmatterBlock(
|
|
81977
|
+
const block = frontmatterBlock(readFileSync7(absPath, "utf8"));
|
|
81748
81978
|
if (block === null)
|
|
81749
81979
|
continue;
|
|
81750
81980
|
const parsed = import_yaml21.default.parse(block.yaml);
|
|
81751
|
-
if (!
|
|
81981
|
+
if (!isRecord17(parsed) || parsed.view_ref !== viewRef)
|
|
81752
81982
|
continue;
|
|
81753
81983
|
const approvedNodeRef = typeof parsed.node_ref === "string" && parsed.node_ref.trim().length > 0 ? parsed.node_ref.trim() : nodeRef;
|
|
81754
81984
|
return {
|
|
81755
81985
|
path: absPath,
|
|
81756
|
-
relPath:
|
|
81986
|
+
relPath: join41("knowledge", collection, rel),
|
|
81757
81987
|
nodeRef: approvedNodeRef
|
|
81758
81988
|
};
|
|
81759
81989
|
}
|
|
@@ -81794,7 +82024,7 @@ function updateFrontmatter(content3, mutate) {
|
|
|
81794
82024
|
});
|
|
81795
82025
|
}
|
|
81796
82026
|
const parsed = import_yaml21.default.parse(block.yaml);
|
|
81797
|
-
if (!
|
|
82027
|
+
if (!isRecord17(parsed)) {
|
|
81798
82028
|
throw new ContextError(ExitCode.WorkspaceStateError, "approved page frontmatter must be a YAML object", {
|
|
81799
82029
|
category: ErrorCategory.SchemaInvalid
|
|
81800
82030
|
});
|
|
@@ -81809,16 +82039,16 @@ function parseApprovedSources(content3) {
|
|
|
81809
82039
|
if (block === null)
|
|
81810
82040
|
return [];
|
|
81811
82041
|
const parsed = import_yaml21.default.parse(block.yaml);
|
|
81812
|
-
if (!
|
|
82042
|
+
if (!isRecord17(parsed))
|
|
81813
82043
|
return [];
|
|
81814
82044
|
const sources = parsed.sources;
|
|
81815
82045
|
return Array.isArray(sources) ? sources.filter((source2) => typeof source2 === "string") : [];
|
|
81816
82046
|
}
|
|
81817
82047
|
async function writeReviewActionLog(input) {
|
|
81818
82048
|
const stamp = new Date().toISOString().replace(/[-:.TZ]/gu, "");
|
|
81819
|
-
const relPath =
|
|
81820
|
-
const path4 =
|
|
81821
|
-
await mkdir21(
|
|
82049
|
+
const relPath = join41(REVIEW_ACTION_ROOT2, `${stamp}-${input.action}-${input.id.replace(/[\\/]+/gu, "_")}.json`);
|
|
82050
|
+
const path4 = join41(input.projectRoot, relPath);
|
|
82051
|
+
await mkdir21(dirname26(path4), { recursive: true });
|
|
81822
82052
|
await writeFile17(path4, `${JSON.stringify({
|
|
81823
82053
|
action: input.action,
|
|
81824
82054
|
id: input.id,
|
|
@@ -82313,7 +82543,7 @@ async function prepareApprovedPage(input) {
|
|
|
82313
82543
|
if (input.record.candidate_type !== "prose-align") {
|
|
82314
82544
|
assertSafeEntityId(input.record.node_ref);
|
|
82315
82545
|
}
|
|
82316
|
-
relPath =
|
|
82546
|
+
relPath = join42("knowledge", input.record.path);
|
|
82317
82547
|
const existingView = findApprovedPageForViewRef(input.projectRoot, input.record.view_ref);
|
|
82318
82548
|
if (existingView !== undefined && existingView.relPath !== relPath) {
|
|
82319
82549
|
throw new ContextError(ExitCode.WorkspaceStateError, `approved page already exists for view_ref at a different path: ${input.record.view_ref}`, {
|
|
@@ -82325,8 +82555,8 @@ async function prepareApprovedPage(input) {
|
|
|
82325
82555
|
next: "Resolve the approved page path migration explicitly before approving this candidate."
|
|
82326
82556
|
});
|
|
82327
82557
|
}
|
|
82328
|
-
const absPath =
|
|
82329
|
-
const existing =
|
|
82558
|
+
const absPath = join42(input.projectRoot, relPath);
|
|
82559
|
+
const existing = existsSync27(absPath) ? await readFile34(absPath, "utf8") : undefined;
|
|
82330
82560
|
if (existing !== undefined) {
|
|
82331
82561
|
const frontmatter = parseFrontmatterLoose(existing);
|
|
82332
82562
|
const existingViewRef = typeof frontmatter.view_ref === "string" ? frontmatter.view_ref : undefined;
|
|
@@ -82398,11 +82628,11 @@ async function prepareApprovedPage(input) {
|
|
|
82398
82628
|
}
|
|
82399
82629
|
async function writePreparedApprovedPage(page) {
|
|
82400
82630
|
for (const asset of page.assets) {
|
|
82401
|
-
await mkdir22(
|
|
82631
|
+
await mkdir22(dirname27(asset.absPath), { recursive: true });
|
|
82402
82632
|
await writeFile18(asset.absPath, asset.bytes);
|
|
82403
82633
|
}
|
|
82404
82634
|
if (page.changed) {
|
|
82405
|
-
await mkdir22(
|
|
82635
|
+
await mkdir22(dirname27(page.absPath), { recursive: true });
|
|
82406
82636
|
await writeFile18(page.absPath, page.content, "utf8");
|
|
82407
82637
|
}
|
|
82408
82638
|
}
|
|
@@ -82633,18 +82863,18 @@ init_errors();
|
|
|
82633
82863
|
init_exitCode();
|
|
82634
82864
|
|
|
82635
82865
|
// src/project/repoSources.ts
|
|
82636
|
-
import { existsSync as
|
|
82866
|
+
import { existsSync as existsSync30 } from "node:fs";
|
|
82637
82867
|
import { lstat, mkdir as mkdir23, readFile as readFile35, readlink, realpath as realpath2, rm as rm12, symlink } from "node:fs/promises";
|
|
82638
82868
|
import { execFile as execFile4 } from "node:child_process";
|
|
82639
82869
|
import { promisify as promisify4 } from "node:util";
|
|
82640
|
-
import { dirname as
|
|
82870
|
+
import { dirname as dirname28, isAbsolute as isAbsolute8, join as join45, relative as relative15, resolve as resolve17 } from "node:path";
|
|
82641
82871
|
init_cliFeedback();
|
|
82642
82872
|
init_errors();
|
|
82643
82873
|
init_exitCode();
|
|
82644
82874
|
|
|
82645
82875
|
// src/project/repoSourceModules.ts
|
|
82646
|
-
import { existsSync as
|
|
82647
|
-
import { join as
|
|
82876
|
+
import { existsSync as existsSync28 } from "node:fs";
|
|
82877
|
+
import { join as join43, resolve as resolve16 } from "node:path";
|
|
82648
82878
|
function normalizeSubpath(value) {
|
|
82649
82879
|
if (value === undefined)
|
|
82650
82880
|
return;
|
|
@@ -82671,8 +82901,8 @@ function suggestedModuleName(module) {
|
|
|
82671
82901
|
return slug || "module";
|
|
82672
82902
|
}
|
|
82673
82903
|
async function inspectRepoSourceModules(input) {
|
|
82674
|
-
const inspectPath = input.scopedAbs !== null &&
|
|
82675
|
-
const modules =
|
|
82904
|
+
const inspectPath = input.scopedAbs !== null && existsSync28(input.scopedAbs) ? input.scopedAbs : join43(input.projectRoot, input.status.materializedAt);
|
|
82905
|
+
const modules = existsSync28(inspectPath) ? await detectModuleBoundaries(inspectPath, input.status.head ?? input.status.ref, DEFAULT_PATH_FILTER) : [];
|
|
82676
82906
|
const recommended_sources = modules.filter((module) => module.path !== "." || modules.length === 1).map((module) => {
|
|
82677
82907
|
const local = sourceModuleLocalForDisplay({ source: input.source, status: input.status, module });
|
|
82678
82908
|
return {
|
|
@@ -82703,8 +82933,8 @@ function resolveRepoSourceScopedPath(localAbs, subpath) {
|
|
|
82703
82933
|
|
|
82704
82934
|
// src/project/repoSourceRegistry.ts
|
|
82705
82935
|
var import_yaml24 = __toESM(require_dist3(), 1);
|
|
82706
|
-
import { existsSync as
|
|
82707
|
-
import { join as
|
|
82936
|
+
import { existsSync as existsSync29 } from "node:fs";
|
|
82937
|
+
import { join as join44 } from "node:path";
|
|
82708
82938
|
init_cliFeedback();
|
|
82709
82939
|
init_errors();
|
|
82710
82940
|
init_exitCode();
|
|
@@ -82761,14 +82991,14 @@ function registryEntryToRecord(entry) {
|
|
|
82761
82991
|
};
|
|
82762
82992
|
}
|
|
82763
82993
|
function registryPath(projectRoot) {
|
|
82764
|
-
return
|
|
82994
|
+
return join44(projectRoot, DEFAULT_REPO_SOURCES_REGISTRY_PATH);
|
|
82765
82995
|
}
|
|
82766
82996
|
function defaultRepoMaterializedAt(source2) {
|
|
82767
82997
|
return `sources/repo/${source2.namespace}/${source2.module}`;
|
|
82768
82998
|
}
|
|
82769
82999
|
async function readRepoRegistry(projectRoot) {
|
|
82770
83000
|
const path4 = registryPath(projectRoot);
|
|
82771
|
-
if (!
|
|
83001
|
+
if (!existsSync29(path4))
|
|
82772
83002
|
return { repos: [] };
|
|
82773
83003
|
const registry2 = await loadSourcesRegistry({ rootDir: projectRoot });
|
|
82774
83004
|
return {
|
|
@@ -82844,13 +83074,13 @@ async function gitOutput(cwd, args) {
|
|
|
82844
83074
|
}
|
|
82845
83075
|
}
|
|
82846
83076
|
async function readGitOriginRemote(cwd) {
|
|
82847
|
-
const directConfigPath =
|
|
83077
|
+
const directConfigPath = join45(cwd, ".git", "config");
|
|
82848
83078
|
let config = await readFile35(directConfigPath, "utf8").catch(() => "");
|
|
82849
83079
|
if (config.length === 0) {
|
|
82850
83080
|
const gitDir = await resolveGitDir(cwd);
|
|
82851
83081
|
if (gitDir === null)
|
|
82852
83082
|
return null;
|
|
82853
|
-
config = await readFile35(
|
|
83083
|
+
config = await readFile35(join45(gitDir, "config"), "utf8").catch(() => "");
|
|
82854
83084
|
}
|
|
82855
83085
|
let inOriginBlock = false;
|
|
82856
83086
|
for (const line of config.split(/\r?\n/u)) {
|
|
@@ -82870,17 +83100,17 @@ async function readGitOriginRemote(cwd) {
|
|
|
82870
83100
|
async function resolveGitRoot(cwd) {
|
|
82871
83101
|
let current2 = resolve17(cwd);
|
|
82872
83102
|
while (true) {
|
|
82873
|
-
if (
|
|
83103
|
+
if (existsSync30(join45(current2, ".git")))
|
|
82874
83104
|
return current2;
|
|
82875
|
-
const parent =
|
|
83105
|
+
const parent = dirname28(current2);
|
|
82876
83106
|
if (parent === current2)
|
|
82877
83107
|
return null;
|
|
82878
83108
|
current2 = parent;
|
|
82879
83109
|
}
|
|
82880
83110
|
}
|
|
82881
83111
|
async function resolveGitDir(cwd) {
|
|
82882
|
-
const dotGit =
|
|
82883
|
-
if (!
|
|
83112
|
+
const dotGit = join45(cwd, ".git");
|
|
83113
|
+
if (!existsSync30(dotGit))
|
|
82884
83114
|
return null;
|
|
82885
83115
|
const stats = await lstat(dotGit);
|
|
82886
83116
|
if (stats.isDirectory())
|
|
@@ -82897,17 +83127,17 @@ async function readGitHead(cwd) {
|
|
|
82897
83127
|
const gitDir = await resolveGitDir(cwd);
|
|
82898
83128
|
if (gitDir === null)
|
|
82899
83129
|
return null;
|
|
82900
|
-
const headRaw = (await readFile35(
|
|
83130
|
+
const headRaw = (await readFile35(join45(gitDir, "HEAD"), "utf8").catch(() => "")).trim();
|
|
82901
83131
|
if (/^[a-f0-9]{40}$/iu.test(headRaw))
|
|
82902
83132
|
return headRaw.toLowerCase();
|
|
82903
83133
|
const match = /^ref:\s*(.+)\s*$/iu.exec(headRaw);
|
|
82904
83134
|
const refPath = match?.[1];
|
|
82905
83135
|
if (refPath === undefined)
|
|
82906
83136
|
return null;
|
|
82907
|
-
const looseRef = (await readFile35(
|
|
83137
|
+
const looseRef = (await readFile35(join45(gitDir, refPath), "utf8").catch(() => "")).trim();
|
|
82908
83138
|
if (/^[a-f0-9]{40}$/iu.test(looseRef))
|
|
82909
83139
|
return looseRef.toLowerCase();
|
|
82910
|
-
const packedRefs = await readFile35(
|
|
83140
|
+
const packedRefs = await readFile35(join45(gitDir, "packed-refs"), "utf8").catch(() => "");
|
|
82911
83141
|
for (const line of packedRefs.split(/\r?\n/u)) {
|
|
82912
83142
|
if (line.startsWith("#") || line.startsWith("^"))
|
|
82913
83143
|
continue;
|
|
@@ -82918,27 +83148,27 @@ async function readGitHead(cwd) {
|
|
|
82918
83148
|
return null;
|
|
82919
83149
|
}
|
|
82920
83150
|
async function ensureMaterializedSymlink(input) {
|
|
82921
|
-
const linkPath =
|
|
82922
|
-
await mkdir23(
|
|
82923
|
-
if (
|
|
83151
|
+
const linkPath = join45(input.projectRoot, input.materializedAt);
|
|
83152
|
+
await mkdir23(dirname28(linkPath), { recursive: true });
|
|
83153
|
+
if (existsSync30(linkPath)) {
|
|
82924
83154
|
const stats = await lstat(linkPath);
|
|
82925
83155
|
if (!stats.isSymbolicLink()) {
|
|
82926
83156
|
input.diagnostics.push(`materialized path exists and is not a symlink: ${input.materializedAt}`);
|
|
82927
83157
|
return false;
|
|
82928
83158
|
}
|
|
82929
83159
|
const current2 = await readlink(linkPath);
|
|
82930
|
-
const currentAbs = resolve17(
|
|
83160
|
+
const currentAbs = resolve17(dirname28(linkPath), current2);
|
|
82931
83161
|
if (currentAbs === input.localAbs)
|
|
82932
83162
|
return true;
|
|
82933
83163
|
await rm12(linkPath);
|
|
82934
83164
|
}
|
|
82935
|
-
const relTarget = relative15(
|
|
83165
|
+
const relTarget = relative15(dirname28(linkPath), input.localAbs) || ".";
|
|
82936
83166
|
await symlink(relTarget, linkPath);
|
|
82937
83167
|
return true;
|
|
82938
83168
|
}
|
|
82939
83169
|
async function diagnoseMaterializedSymlink(input) {
|
|
82940
|
-
const linkPath =
|
|
82941
|
-
if (!
|
|
83170
|
+
const linkPath = join45(input.projectRoot, input.materializedAt);
|
|
83171
|
+
if (!existsSync30(linkPath)) {
|
|
82942
83172
|
input.diagnostics.push(`materialized path is missing: ${input.materializedAt}`);
|
|
82943
83173
|
input.agent_hints.push(`Run context source ensure ${input.sourceName} to materialize the local source link.`);
|
|
82944
83174
|
return false;
|
|
@@ -82949,9 +83179,9 @@ async function diagnoseMaterializedSymlink(input) {
|
|
|
82949
83179
|
return false;
|
|
82950
83180
|
}
|
|
82951
83181
|
const current2 = await readlink(linkPath);
|
|
82952
|
-
const currentAbs = resolve17(
|
|
83182
|
+
const currentAbs = resolve17(dirname28(linkPath), current2);
|
|
82953
83183
|
if (currentAbs !== input.localAbs) {
|
|
82954
|
-
input.diagnostics.push(`materialized path points to ${current2}, expected local checkout ${relative15(
|
|
83184
|
+
input.diagnostics.push(`materialized path points to ${current2}, expected local checkout ${relative15(dirname28(linkPath), input.localAbs) || "."}`);
|
|
82955
83185
|
input.agent_hints.push(`Run context source ensure ${input.sourceName} to refresh the local source link.`);
|
|
82956
83186
|
return false;
|
|
82957
83187
|
}
|
|
@@ -82983,7 +83213,7 @@ async function normalizeInputRef(input) {
|
|
|
82983
83213
|
next: "Pass --local <path> with a git checkout, or use a full 40-character commit sha."
|
|
82984
83214
|
});
|
|
82985
83215
|
}
|
|
82986
|
-
if (!
|
|
83216
|
+
if (!existsSync30(localAbs)) {
|
|
82987
83217
|
throw new ContextError(ExitCode.UserError, `short repo source ref cannot be resolved because local path is missing: ${input.local}`, {
|
|
82988
83218
|
category: ErrorCategory.UserInputInvalid,
|
|
82989
83219
|
sourceName: input.sourceName,
|
|
@@ -83035,7 +83265,7 @@ async function normalizeAddInput(input, existing) {
|
|
|
83035
83265
|
let gitRootAbs = null;
|
|
83036
83266
|
if (originalLocal !== undefined) {
|
|
83037
83267
|
const originalLocalAbs = resolveLocalPath(input.projectRoot, originalLocal);
|
|
83038
|
-
if (originalLocalAbs !== null &&
|
|
83268
|
+
if (originalLocalAbs !== null && existsSync30(originalLocalAbs)) {
|
|
83039
83269
|
gitRootAbs = await resolveGitRoot(originalLocalAbs);
|
|
83040
83270
|
if (gitRootAbs !== null && input.local !== undefined) {
|
|
83041
83271
|
const detectedSubpath = normalizeSubpath2(relative15(gitRootAbs, originalLocalAbs));
|
|
@@ -83131,11 +83361,11 @@ async function inspectRepoSource(input) {
|
|
|
83131
83361
|
const diagnostics = [];
|
|
83132
83362
|
const agent_hints = [];
|
|
83133
83363
|
const localAbs = resolveLocalPath(input.projectRoot, source2.local);
|
|
83134
|
-
const localExists = localAbs !== null &&
|
|
83364
|
+
const localExists = localAbs !== null && existsSync30(localAbs);
|
|
83135
83365
|
const subpath = normalizeSubpath2(source2.subpath);
|
|
83136
83366
|
const scopedAbs = localAbs === null ? null : scopedLocalPath(localAbs, subpath);
|
|
83137
|
-
const scopeExists = scopedAbs !== null &&
|
|
83138
|
-
let materialized =
|
|
83367
|
+
const scopeExists = scopedAbs !== null && existsSync30(scopedAbs);
|
|
83368
|
+
let materialized = existsSync30(join45(input.projectRoot, materializedAt));
|
|
83139
83369
|
const checkout = await inspectRepoCheckout({
|
|
83140
83370
|
source: source2,
|
|
83141
83371
|
localAbs,
|
|
@@ -83784,24 +84014,24 @@ The approved symbol is no longer present in the current code extraction.
|
|
|
83784
84014
|
// src/project/packageBuilder.ts
|
|
83785
84015
|
init_cliFeedback();
|
|
83786
84016
|
init_errors();
|
|
83787
|
-
init_exitCode();
|
|
83788
84017
|
var import_yaml28 = __toESM(require_dist3(), 1);
|
|
83789
84018
|
import { createHash as createHash20 } from "node:crypto";
|
|
83790
|
-
import { existsSync as
|
|
84019
|
+
import { existsSync as existsSync35 } from "node:fs";
|
|
83791
84020
|
import { mkdir as mkdir27, readdir as readdir15, readFile as readFile41, rm as rm13, writeFile as writeFile22 } from "node:fs/promises";
|
|
83792
|
-
import { dirname as
|
|
84021
|
+
import { dirname as dirname34, join as join52, resolve as resolve19 } from "node:path";
|
|
84022
|
+
init_exitCode();
|
|
83793
84023
|
|
|
83794
84024
|
// src/project/packageBuildInventory.ts
|
|
83795
84025
|
var import_yaml26 = __toESM(require_dist3(), 1);
|
|
83796
84026
|
import { createHash as createHash17 } from "node:crypto";
|
|
83797
|
-
import { existsSync as
|
|
84027
|
+
import { existsSync as existsSync32 } from "node:fs";
|
|
83798
84028
|
import { mkdir as mkdir25, readFile as readFile37, writeFile as writeFile20 } from "node:fs/promises";
|
|
83799
|
-
import { dirname as
|
|
84029
|
+
import { dirname as dirname30, join as join47 } from "node:path";
|
|
83800
84030
|
|
|
83801
84031
|
// src/project/packageIndexes.ts
|
|
83802
|
-
import { existsSync as
|
|
84032
|
+
import { existsSync as existsSync31, statSync } from "node:fs";
|
|
83803
84033
|
import { mkdir as mkdir24, readdir as readdir13, readFile as readFile36, writeFile as writeFile19 } from "node:fs/promises";
|
|
83804
|
-
import { dirname as
|
|
84034
|
+
import { dirname as dirname29, join as join46, posix as pathPosix, relative as relative16 } from "node:path";
|
|
83805
84035
|
init_cliFeedback();
|
|
83806
84036
|
init_errors();
|
|
83807
84037
|
init_exitCode();
|
|
@@ -83955,7 +84185,7 @@ var PACKAGE_INVENTORY_FIELDS = [
|
|
|
83955
84185
|
"candidate_fingerprint"
|
|
83956
84186
|
];
|
|
83957
84187
|
var COMPILER_ONLY_TAGS = new Set(["docs", "prose", "parent-index"]);
|
|
83958
|
-
function
|
|
84188
|
+
function isRecord18(value) {
|
|
83959
84189
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
83960
84190
|
}
|
|
83961
84191
|
function stringList2(value) {
|
|
@@ -83969,7 +84199,7 @@ function parseKnowledgeFrontmatter(content3) {
|
|
|
83969
84199
|
return {};
|
|
83970
84200
|
try {
|
|
83971
84201
|
const parsed = import_yaml25.parse(match[1]);
|
|
83972
|
-
return
|
|
84202
|
+
return isRecord18(parsed) ? parsed : {};
|
|
83973
84203
|
} catch {
|
|
83974
84204
|
return {};
|
|
83975
84205
|
}
|
|
@@ -84064,13 +84294,13 @@ function packageKind(pkg) {
|
|
|
84064
84294
|
return pkg.kind === "package.kb" ? "kb" : "llms";
|
|
84065
84295
|
}
|
|
84066
84296
|
async function walkFiles3(root2) {
|
|
84067
|
-
if (!
|
|
84297
|
+
if (!existsSync31(root2))
|
|
84068
84298
|
return [];
|
|
84069
84299
|
const files = [];
|
|
84070
84300
|
const visit3 = async (dir) => {
|
|
84071
84301
|
const entries = await readdir13(dir, { withFileTypes: true });
|
|
84072
84302
|
for (const entry of entries) {
|
|
84073
|
-
const absPath =
|
|
84303
|
+
const absPath = join46(dir, entry.name);
|
|
84074
84304
|
if (entry.isDirectory()) {
|
|
84075
84305
|
await visit3(absPath);
|
|
84076
84306
|
continue;
|
|
@@ -84362,10 +84592,10 @@ async function writeKnowledgeDirectoryIndexes(input) {
|
|
|
84362
84592
|
let written = 0;
|
|
84363
84593
|
for (const directory of collectKnowledgeDirectoryIndexes(input.pkg, input.selected)) {
|
|
84364
84594
|
assertSafeRenderedPath(directory.relPath, "knowledge directory index path");
|
|
84365
|
-
const outputPath =
|
|
84366
|
-
if (
|
|
84595
|
+
const outputPath = join46(input.projectRoot, input.pkg.outDir, directory.relPath);
|
|
84596
|
+
if (existsSync31(outputPath))
|
|
84367
84597
|
continue;
|
|
84368
|
-
await mkdir24(
|
|
84598
|
+
await mkdir24(dirname29(outputPath), { recursive: true });
|
|
84369
84599
|
await writeFile19(outputPath, renderKnowledgeDirectoryIndex({
|
|
84370
84600
|
pkg: input.pkg,
|
|
84371
84601
|
directory,
|
|
@@ -84411,23 +84641,23 @@ function packageLinkTargetExists(packageRoot, targetRelPath) {
|
|
|
84411
84641
|
return false;
|
|
84412
84642
|
}
|
|
84413
84643
|
const normalized = targetRelPath.endsWith("/") ? `${targetRelPath}index.md` : targetRelPath;
|
|
84414
|
-
const targetPath =
|
|
84415
|
-
if (
|
|
84644
|
+
const targetPath = join46(packageRoot, normalized);
|
|
84645
|
+
if (existsSync31(targetPath)) {
|
|
84416
84646
|
const stat6 = statSync(targetPath);
|
|
84417
84647
|
if (stat6.isFile())
|
|
84418
84648
|
return true;
|
|
84419
84649
|
if (stat6.isDirectory())
|
|
84420
|
-
return
|
|
84650
|
+
return existsSync31(join46(targetPath, "index.md"));
|
|
84421
84651
|
return false;
|
|
84422
84652
|
}
|
|
84423
|
-
if (!pathPosix.extname(normalized) &&
|
|
84653
|
+
if (!pathPosix.extname(normalized) && existsSync31(join46(packageRoot, normalized, "index.md")))
|
|
84424
84654
|
return true;
|
|
84425
84655
|
return false;
|
|
84426
84656
|
}
|
|
84427
84657
|
async function validatePackageIndexLinks(input) {
|
|
84428
84658
|
if (packageKind(input.pkg) !== "kb")
|
|
84429
84659
|
return;
|
|
84430
|
-
const packageRoot =
|
|
84660
|
+
const packageRoot = join46(input.projectRoot, input.pkg.outDir);
|
|
84431
84661
|
const files = await walkFiles3(packageRoot);
|
|
84432
84662
|
for (const file of files) {
|
|
84433
84663
|
if (file.relPath !== "index.md" && !file.relPath.endsWith("/index.md"))
|
|
@@ -84498,10 +84728,10 @@ function packageKind2(pkg) {
|
|
|
84498
84728
|
// src/project/packageBuildInventory.ts
|
|
84499
84729
|
var PACKAGE_BUILD_INVENTORY_PATH = "context-build-inventory.json";
|
|
84500
84730
|
function knowledgeStructurePath(projectRoot) {
|
|
84501
|
-
return
|
|
84731
|
+
return join47(projectRoot, "knowledge", "structure.yaml");
|
|
84502
84732
|
}
|
|
84503
84733
|
async function readOptionalText(path4) {
|
|
84504
|
-
if (!
|
|
84734
|
+
if (!existsSync32(path4))
|
|
84505
84735
|
return null;
|
|
84506
84736
|
return readFile37(path4, "utf8");
|
|
84507
84737
|
}
|
|
@@ -84880,8 +85110,8 @@ function packageBuildInventory(input) {
|
|
|
84880
85110
|
};
|
|
84881
85111
|
}
|
|
84882
85112
|
async function writePackageBuildInventory(input) {
|
|
84883
|
-
const outputPath =
|
|
84884
|
-
await mkdir25(
|
|
85113
|
+
const outputPath = join47(input.projectRoot, input.pkg.outDir, PACKAGE_BUILD_INVENTORY_PATH);
|
|
85114
|
+
await mkdir25(dirname30(outputPath), { recursive: true });
|
|
84885
85115
|
await writeFile20(outputPath, `${JSON.stringify(input.inventory, null, 2)}
|
|
84886
85116
|
`, "utf8");
|
|
84887
85117
|
return 1;
|
|
@@ -84889,12 +85119,12 @@ async function writePackageBuildInventory(input) {
|
|
|
84889
85119
|
|
|
84890
85120
|
// src/project/packageBuildReceipt.ts
|
|
84891
85121
|
import { createHash as createHash18 } from "node:crypto";
|
|
84892
|
-
import { existsSync as
|
|
85122
|
+
import { existsSync as existsSync33 } from "node:fs";
|
|
84893
85123
|
import { readdir as readdir14, readFile as readFile38 } from "node:fs/promises";
|
|
84894
|
-
import { join as
|
|
85124
|
+
import { join as join48, relative as relative17 } from "node:path";
|
|
84895
85125
|
var IGNORED_PACKAGE_FS_ENTRIES = new Set([".DS_Store"]);
|
|
84896
85126
|
async function walkPackageFiles(root2) {
|
|
84897
|
-
if (!
|
|
85127
|
+
if (!existsSync33(root2))
|
|
84898
85128
|
return [];
|
|
84899
85129
|
const files = [];
|
|
84900
85130
|
const visit3 = async (dir) => {
|
|
@@ -84902,7 +85132,7 @@ async function walkPackageFiles(root2) {
|
|
|
84902
85132
|
for (const entry of entries) {
|
|
84903
85133
|
if (IGNORED_PACKAGE_FS_ENTRIES.has(entry.name))
|
|
84904
85134
|
continue;
|
|
84905
|
-
const absPath =
|
|
85135
|
+
const absPath = join48(dir, entry.name);
|
|
84906
85136
|
if (entry.isDirectory()) {
|
|
84907
85137
|
await visit3(absPath);
|
|
84908
85138
|
continue;
|
|
@@ -84933,7 +85163,7 @@ function classifyOutputFile(path4, knowledgeGroups) {
|
|
|
84933
85163
|
}
|
|
84934
85164
|
async function packageOutputSnapshot(projectRoot, pkg, knowledgeGroups, previousOutputs = []) {
|
|
84935
85165
|
const previousByPath = new Map(previousOutputs.map((file) => [file.path, file]));
|
|
84936
|
-
return Promise.all((await walkPackageFiles(
|
|
85166
|
+
return Promise.all((await walkPackageFiles(join48(projectRoot, pkg.outDir))).map(async (file) => {
|
|
84937
85167
|
const current2 = classifyOutputFile(file.relPath, knowledgeGroups);
|
|
84938
85168
|
const previous3 = previousByPath.get(file.relPath);
|
|
84939
85169
|
const classification = current2.kind === "file" && previous3 !== undefined ? { path: file.relPath, kind: previous3.kind, ...previous3.group === undefined ? {} : { group: previous3.group } } : current2;
|
|
@@ -84947,7 +85177,7 @@ async function packageOutputFingerprint(projectRoot, pkg) {
|
|
|
84947
85177
|
const snapshot = await packageOutputSnapshot(projectRoot, pkg, new Map);
|
|
84948
85178
|
return {
|
|
84949
85179
|
fingerprint: createHash18("sha256").update(JSON.stringify({
|
|
84950
|
-
outDirExists:
|
|
85180
|
+
outDirExists: existsSync33(join48(projectRoot, pkg.outDir)),
|
|
84951
85181
|
files: snapshot.map(({ path: path4, sha256: sha2564 }) => ({ path: path4, sha256: sha2564 }))
|
|
84952
85182
|
})).digest("hex"),
|
|
84953
85183
|
files: snapshot.length
|
|
@@ -85021,16 +85251,16 @@ function formatPackageBuildSummary(pkg) {
|
|
|
85021
85251
|
}
|
|
85022
85252
|
|
|
85023
85253
|
// src/project/packageBuildContent.ts
|
|
85024
|
-
import { existsSync as
|
|
85254
|
+
import { existsSync as existsSync34 } from "node:fs";
|
|
85025
85255
|
import { mkdir as mkdir26, readFile as readFile40, writeFile as writeFile21 } from "node:fs/promises";
|
|
85026
|
-
import { dirname as
|
|
85256
|
+
import { dirname as dirname33, join as join51 } from "node:path";
|
|
85027
85257
|
|
|
85028
85258
|
// src/project/packageAssets.ts
|
|
85029
85259
|
init_errors();
|
|
85030
85260
|
init_cliFeedback();
|
|
85031
85261
|
init_exitCode();
|
|
85032
85262
|
import { readFile as readFile39 } from "node:fs/promises";
|
|
85033
|
-
import { dirname as
|
|
85263
|
+
import { dirname as dirname31, relative as relative18, sep as sep3 } from "node:path";
|
|
85034
85264
|
function posixPath2(value) {
|
|
85035
85265
|
return value.split(sep3).join("/");
|
|
85036
85266
|
}
|
|
@@ -85052,7 +85282,7 @@ function packageAssetPath(projectRoot, absolute) {
|
|
|
85052
85282
|
};
|
|
85053
85283
|
}
|
|
85054
85284
|
function packageMarkdownTarget(pageOutputPath, assetOutputPath) {
|
|
85055
|
-
const target = posixPath2(relative18(
|
|
85285
|
+
const target = posixPath2(relative18(dirname31(pageOutputPath), assetOutputPath));
|
|
85056
85286
|
return target.startsWith(".") ? target : `./${target}`;
|
|
85057
85287
|
}
|
|
85058
85288
|
async function projectPackageKnowledgeAssets(input) {
|
|
@@ -85092,7 +85322,7 @@ init_errors();
|
|
|
85092
85322
|
init_exitCode();
|
|
85093
85323
|
import { execFile as execFile5 } from "node:child_process";
|
|
85094
85324
|
import { realpath as realpath3 } from "node:fs/promises";
|
|
85095
|
-
import { join as
|
|
85325
|
+
import { join as join50, relative as relative19, sep as sep4 } from "node:path";
|
|
85096
85326
|
import { promisify as promisify5 } from "node:util";
|
|
85097
85327
|
|
|
85098
85328
|
// src/project/packageAssetOptimization.ts
|
|
@@ -85101,7 +85331,7 @@ init_errors();
|
|
|
85101
85331
|
init_exitCode();
|
|
85102
85332
|
import { createHash as createHash19 } from "node:crypto";
|
|
85103
85333
|
import { createRequire as createRequire4 } from "node:module";
|
|
85104
|
-
import { dirname as
|
|
85334
|
+
import { dirname as dirname32, extname as extname10, join as join49 } from "node:path";
|
|
85105
85335
|
import { pathToFileURL as pathToFileURL2 } from "node:url";
|
|
85106
85336
|
var PACKAGE_ASSET_OPTIMIZATION_THRESHOLD_BYTES = 20 * 1024 * 1024;
|
|
85107
85337
|
function isPng(bytes) {
|
|
@@ -85123,10 +85353,10 @@ function isWebp(bytes) {
|
|
|
85123
85353
|
}
|
|
85124
85354
|
function contentAddressedWebpPath(asset, bytes) {
|
|
85125
85355
|
const digest4 = createHash19("sha256").update(bytes).digest("hex");
|
|
85126
|
-
return `${
|
|
85356
|
+
return `${dirname32(asset.packageRelPath)}/${digest4}.webp`;
|
|
85127
85357
|
}
|
|
85128
85358
|
async function loadSharpProcessor(projectRoot) {
|
|
85129
|
-
const requireFromWorkspace = createRequire4(
|
|
85359
|
+
const requireFromWorkspace = createRequire4(join49(projectRoot, "package.json"));
|
|
85130
85360
|
let resolved;
|
|
85131
85361
|
try {
|
|
85132
85362
|
resolved = requireFromWorkspace.resolve("sharp");
|
|
@@ -85246,7 +85476,7 @@ async function git(projectRoot, args) {
|
|
|
85246
85476
|
}
|
|
85247
85477
|
}
|
|
85248
85478
|
function repositoryPath(repoRoot, projectRoot, asset) {
|
|
85249
|
-
const path4 = relative19(repoRoot,
|
|
85479
|
+
const path4 = relative19(repoRoot, join50(projectRoot, asset.knowledgeRelPath)).split(sep4).join("/");
|
|
85250
85480
|
if (path4 === ".." || path4.startsWith("../") || path4.startsWith("/")) {
|
|
85251
85481
|
throw new ContextError(ExitCode.WorkspaceStateError, "knowledge asset is outside the current Git repository", {
|
|
85252
85482
|
category: ErrorCategory.WorkspaceStateInvalid,
|
|
@@ -85553,8 +85783,8 @@ async function writeRenderedPackageTemplate(input) {
|
|
|
85553
85783
|
templateRelPath: renderedRelPath,
|
|
85554
85784
|
logicalTemplateRelPath: renderedLogicalRelPath
|
|
85555
85785
|
});
|
|
85556
|
-
const outputPath =
|
|
85557
|
-
await mkdir26(
|
|
85786
|
+
const outputPath = join51(input.projectRoot, input.pkg.outDir, renderedRelPath);
|
|
85787
|
+
await mkdir26(dirname33(outputPath), { recursive: true });
|
|
85558
85788
|
await writeFile21(outputPath, renderTemplateText(file.content, contentVars), "utf8");
|
|
85559
85789
|
written++;
|
|
85560
85790
|
}
|
|
@@ -85580,7 +85810,7 @@ async function writeSelectedPackageKnowledge(input) {
|
|
|
85580
85810
|
const { projectedPages, delivered } = input.prepared ?? await prepareSelectedPackageKnowledge(input);
|
|
85581
85811
|
for (const projected of projectedPages) {
|
|
85582
85812
|
assertSafeRenderedPath2(projected.pageOutputPath, "knowledge path");
|
|
85583
|
-
const outputPath =
|
|
85813
|
+
const outputPath = join51(input.projectRoot, input.pkg.outDir, projected.pageOutputPath);
|
|
85584
85814
|
const rewritten = replaceMarkdownInlineLinkTargets(projected.content, (link2) => {
|
|
85585
85815
|
for (const [inputPath, outputPath2] of delivered.targetByOriginal) {
|
|
85586
85816
|
if (link2.target === packageMarkdownTarget(projected.pageOutputPath, inputPath)) {
|
|
@@ -85589,14 +85819,14 @@ async function writeSelectedPackageKnowledge(input) {
|
|
|
85589
85819
|
}
|
|
85590
85820
|
return;
|
|
85591
85821
|
});
|
|
85592
|
-
await mkdir26(
|
|
85822
|
+
await mkdir26(dirname33(outputPath), { recursive: true });
|
|
85593
85823
|
await writeFile21(outputPath, projectPackageKnowledgeMarkdown(rewritten), "utf8");
|
|
85594
85824
|
}
|
|
85595
85825
|
const deliveredAssets = new Map(delivered.assets.map((asset) => [asset.packageRelPath, asset]));
|
|
85596
85826
|
for (const asset of deliveredAssets.values()) {
|
|
85597
85827
|
assertSafeRenderedPath2(asset.packageRelPath, "package resource path");
|
|
85598
|
-
const outputPath =
|
|
85599
|
-
await mkdir26(
|
|
85828
|
+
const outputPath = join51(input.projectRoot, input.pkg.outDir, asset.packageRelPath);
|
|
85829
|
+
await mkdir26(dirname33(outputPath), { recursive: true });
|
|
85600
85830
|
await writeFile21(outputPath, asset.bytes);
|
|
85601
85831
|
}
|
|
85602
85832
|
return {
|
|
@@ -85609,8 +85839,8 @@ async function writeSelectedPackageKnowledge(input) {
|
|
|
85609
85839
|
async function appendLlmsKnowledge(input) {
|
|
85610
85840
|
if (packageKind2(input.pkg) !== "llms" || input.templateConsumesKnowledge || input.knowledgeCount === 0)
|
|
85611
85841
|
return 0;
|
|
85612
|
-
const outputPath =
|
|
85613
|
-
const existed =
|
|
85842
|
+
const outputPath = join51(input.projectRoot, input.pkg.outDir, "llms.txt");
|
|
85843
|
+
const existed = existsSync34(outputPath);
|
|
85614
85844
|
const existing = existed ? await readFile40(outputPath, "utf8") : "";
|
|
85615
85845
|
const content3 = existing.trim().length > 0 ? `${existing.trimEnd()}
|
|
85616
85846
|
|
|
@@ -85619,7 +85849,7 @@ async function appendLlmsKnowledge(input) {
|
|
|
85619
85849
|
${input.bundle}
|
|
85620
85850
|
` : `${input.bundle}
|
|
85621
85851
|
`;
|
|
85622
|
-
await mkdir26(
|
|
85852
|
+
await mkdir26(dirname33(outputPath), { recursive: true });
|
|
85623
85853
|
await writeFile21(outputPath, content3, "utf8");
|
|
85624
85854
|
return existed ? 0 : 1;
|
|
85625
85855
|
}
|
|
@@ -85805,7 +86035,7 @@ function validateRenderedSkillDefinition(input) {
|
|
|
85805
86035
|
init_workspace();
|
|
85806
86036
|
init_packageTemplateReview();
|
|
85807
86037
|
var KNOWLEDGE_ROOT4 = "knowledge";
|
|
85808
|
-
var PACKAGE_FINGERPRINT_ROOT =
|
|
86038
|
+
var PACKAGE_FINGERPRINT_ROOT = join52(".tmp", "context-runtime", "packages");
|
|
85809
86039
|
var PACKAGE_BUILDER_PROTOCOL_VERSION = "v14-git-asset-identity";
|
|
85810
86040
|
function packageAssetDeliverySummary(value) {
|
|
85811
86041
|
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
@@ -85828,10 +86058,10 @@ function assertPackageOutputDir(pkg) {
|
|
|
85828
86058
|
}
|
|
85829
86059
|
function packageFingerprintPath(projectRoot, pkg) {
|
|
85830
86060
|
assertSafeRenderedPath2(`${pkg.name}.json`, "package fingerprint path");
|
|
85831
|
-
return
|
|
86061
|
+
return join52(projectRoot, PACKAGE_FINGERPRINT_ROOT, `${pkg.name}.json`);
|
|
85832
86062
|
}
|
|
85833
86063
|
async function listApprovedKnowledge(projectRoot) {
|
|
85834
|
-
const files = await walkPackageFiles(
|
|
86064
|
+
const files = await walkPackageFiles(join52(projectRoot, KNOWLEDGE_ROOT4));
|
|
85835
86065
|
const knowledge = await Promise.all(files.filter((file) => file.relPath.endsWith(".md") && !file.relPath.startsWith("assets/")).map(async (file) => ({
|
|
85836
86066
|
...file,
|
|
85837
86067
|
content: await readFile41(file.absPath, "utf8")
|
|
@@ -85852,7 +86082,7 @@ function isDeprecatedKnowledge(content3) {
|
|
|
85852
86082
|
async function listTemplateFiles(projectRoot, templatePath) {
|
|
85853
86083
|
assertSafeRenderedPath2(templatePath, "package template path");
|
|
85854
86084
|
const templateRoot = resolve19(projectRoot, templatePath);
|
|
85855
|
-
if (!
|
|
86085
|
+
if (!existsSync35(templateRoot)) {
|
|
85856
86086
|
throw new ContextError(ExitCode.WorkspaceStateError, `package template path is missing: ${templatePath}`, {
|
|
85857
86087
|
category: ErrorCategory.WorkspaceStateInvalid,
|
|
85858
86088
|
path: templatePath,
|
|
@@ -85914,7 +86144,7 @@ async function packageInputFingerprint(input) {
|
|
|
85914
86144
|
}
|
|
85915
86145
|
async function readPackageManifest(projectRoot, pkg) {
|
|
85916
86146
|
const filePath = packageFingerprintPath(projectRoot, pkg);
|
|
85917
|
-
if (!
|
|
86147
|
+
if (!existsSync35(filePath))
|
|
85918
86148
|
return null;
|
|
85919
86149
|
try {
|
|
85920
86150
|
const parsed = JSON.parse(await readFile41(filePath, "utf8"));
|
|
@@ -85947,7 +86177,7 @@ async function readPackageManifest(projectRoot, pkg) {
|
|
|
85947
86177
|
}
|
|
85948
86178
|
async function writePackageFingerprint(input) {
|
|
85949
86179
|
const filePath = packageFingerprintPath(input.projectRoot, input.pkg);
|
|
85950
|
-
await mkdir27(
|
|
86180
|
+
await mkdir27(dirname34(filePath), { recursive: true });
|
|
85951
86181
|
await writeFile22(filePath, `${JSON.stringify({
|
|
85952
86182
|
package: input.pkg.name,
|
|
85953
86183
|
kind: packageKind2(input.pkg),
|
|
@@ -85962,12 +86192,12 @@ async function writePackageFingerprint(input) {
|
|
|
85962
86192
|
`, "utf8");
|
|
85963
86193
|
}
|
|
85964
86194
|
async function removeOrphanPackageDirs(projectRoot, packages) {
|
|
85965
|
-
const distRoot =
|
|
85966
|
-
if (!
|
|
86195
|
+
const distRoot = join52(projectRoot, "dist");
|
|
86196
|
+
if (!existsSync35(distRoot))
|
|
85967
86197
|
return;
|
|
85968
86198
|
const declaredNames = new Set(packages.map((pkg) => pkg.name));
|
|
85969
86199
|
const entries = await readdir15(distRoot, { withFileTypes: true });
|
|
85970
|
-
await Promise.all(entries.filter((entry) => entry.isDirectory() && !declaredNames.has(entry.name)).map((entry) => rm13(
|
|
86200
|
+
await Promise.all(entries.filter((entry) => entry.isDirectory() && !declaredNames.has(entry.name)).map((entry) => rm13(join52(distRoot, entry.name), { recursive: true, force: true, maxRetries: 3, retryDelay: 100 })));
|
|
85971
86201
|
}
|
|
85972
86202
|
async function collectPackageFreshness(projectRoot, packages) {
|
|
85973
86203
|
const approved = await listApprovedKnowledge(projectRoot);
|
|
@@ -85975,8 +86205,8 @@ async function collectPackageFreshness(projectRoot, packages) {
|
|
|
85975
86205
|
assertPackageOutputDir(pkg);
|
|
85976
86206
|
const selected = selectPackageKnowledge(approved, pkg);
|
|
85977
86207
|
assertSafeRenderedPath2(pkg.template.path, "package template path");
|
|
85978
|
-
const templateRoot =
|
|
85979
|
-
const templateExists =
|
|
86208
|
+
const templateRoot = join52(projectRoot, pkg.template.path);
|
|
86209
|
+
const templateExists = existsSync35(templateRoot);
|
|
85980
86210
|
if (!templateExists) {
|
|
85981
86211
|
throw new ContextError(ExitCode.WorkspaceStateError, `package template path is missing: ${pkg.template.path}`, {
|
|
85982
86212
|
category: ErrorCategory.WorkspaceStateInvalid,
|
|
@@ -86110,8 +86340,8 @@ async function buildProjectPackages(projectRoot) {
|
|
|
86110
86340
|
files: selected,
|
|
86111
86341
|
...assetProcessor === undefined ? {} : { assetProcessor }
|
|
86112
86342
|
});
|
|
86113
|
-
await rm13(
|
|
86114
|
-
await mkdir27(
|
|
86343
|
+
await rm13(join52(projectRoot, pkg.outDir), { recursive: true, force: true, maxRetries: 3, retryDelay: 100 });
|
|
86344
|
+
await mkdir27(join52(projectRoot, pkg.outDir), { recursive: true });
|
|
86115
86345
|
const rendered = await writeRenderedPackageTemplate({
|
|
86116
86346
|
projectRoot,
|
|
86117
86347
|
pkg,
|
|
@@ -86249,20 +86479,32 @@ async function runProjectBuildCommand(input) {
|
|
|
86249
86479
|
return false;
|
|
86250
86480
|
const result = await buildProjectPackages(found.projectRoot);
|
|
86251
86481
|
process.stdout.write(formatProjectBuildResult(result, input.format ?? "text", input.verbose === true));
|
|
86482
|
+
queueContextRuntimeEvent({
|
|
86483
|
+
cwd: result.projectRoot,
|
|
86484
|
+
kind: "package.build.completed",
|
|
86485
|
+
properties: {
|
|
86486
|
+
package_count: result.packages.length,
|
|
86487
|
+
created_count: result.packages.filter((pkg) => pkg.state === "created").length,
|
|
86488
|
+
updated_count: result.packages.filter((pkg) => pkg.state === "updated").length,
|
|
86489
|
+
unchanged_count: result.packages.filter((pkg) => pkg.state === "unchanged").length,
|
|
86490
|
+
output_file_count: result.packages.reduce((total, pkg) => total + pkg.files, 0),
|
|
86491
|
+
resource_file_count: result.packages.reduce((total, pkg) => total + pkg.resources.files, 0)
|
|
86492
|
+
}
|
|
86493
|
+
});
|
|
86252
86494
|
return true;
|
|
86253
86495
|
}
|
|
86254
86496
|
|
|
86255
86497
|
// src/project/statusReaders.ts
|
|
86256
86498
|
init_workspace();
|
|
86257
86499
|
async function countFiles(root2, predicate) {
|
|
86258
|
-
if (!
|
|
86500
|
+
if (!existsSync36(root2))
|
|
86259
86501
|
return 0;
|
|
86260
86502
|
let count = 0;
|
|
86261
86503
|
const visit3 = async (dir, prefix = "") => {
|
|
86262
86504
|
const entries = await readdir16(dir, { withFileTypes: true });
|
|
86263
86505
|
for (const entry of entries) {
|
|
86264
86506
|
const rel = prefix.length === 0 ? entry.name : `${prefix}/${entry.name}`;
|
|
86265
|
-
const abs =
|
|
86507
|
+
const abs = join53(dir, entry.name);
|
|
86266
86508
|
if (entry.isDirectory())
|
|
86267
86509
|
await visit3(abs, rel);
|
|
86268
86510
|
else if (entry.isFile() && predicate(rel))
|
|
@@ -86304,14 +86546,14 @@ async function readDraftCandidateStatus(projectRoot) {
|
|
|
86304
86546
|
throw error;
|
|
86305
86547
|
}
|
|
86306
86548
|
}
|
|
86307
|
-
function
|
|
86549
|
+
function isRecord19(value) {
|
|
86308
86550
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
86309
86551
|
}
|
|
86310
86552
|
function stagedStructureCounts(parsed) {
|
|
86311
86553
|
const views = Array.isArray(parsed.views) ? parsed.views : [];
|
|
86312
|
-
const sections = views.flatMap((view) =>
|
|
86554
|
+
const sections = views.flatMap((view) => isRecord19(view) && Array.isArray(view.sections) ? view.sections : []);
|
|
86313
86555
|
const sourceRefs = new Set(sections.flatMap((section) => {
|
|
86314
|
-
if (!
|
|
86556
|
+
if (!isRecord19(section))
|
|
86315
86557
|
return [];
|
|
86316
86558
|
return [
|
|
86317
86559
|
...typeof section.source_ref === "string" ? [section.source_ref] : [],
|
|
@@ -86328,12 +86570,12 @@ function stagedStructureCounts(parsed) {
|
|
|
86328
86570
|
};
|
|
86329
86571
|
}
|
|
86330
86572
|
function readStructureDraftStatus(projectRoot) {
|
|
86331
|
-
const structurePath =
|
|
86332
|
-
if (!
|
|
86573
|
+
const structurePath = join53(projectRoot, LIFECYCLE_STRUCTURE_FILE);
|
|
86574
|
+
if (!existsSync36(structurePath))
|
|
86333
86575
|
return { state: "missing", sourceKeys: [], collections: [], diagnostics: [] };
|
|
86334
86576
|
try {
|
|
86335
|
-
const parsed = import_yaml29.default.parse(
|
|
86336
|
-
if (!
|
|
86577
|
+
const parsed = import_yaml29.default.parse(readFileSync8(structurePath, "utf8"));
|
|
86578
|
+
if (!isRecord19(parsed)) {
|
|
86337
86579
|
return {
|
|
86338
86580
|
state: "invalid",
|
|
86339
86581
|
sourceKeys: [],
|
|
@@ -86341,7 +86583,7 @@ function readStructureDraftStatus(projectRoot) {
|
|
|
86341
86583
|
diagnostics: [`${LIFECYCLE_STRUCTURE_FILE} must be a YAML object`]
|
|
86342
86584
|
};
|
|
86343
86585
|
}
|
|
86344
|
-
const lifecycle =
|
|
86586
|
+
const lifecycle = isRecord19(parsed.lifecycle) ? parsed.lifecycle : {};
|
|
86345
86587
|
const lifecycleState = lifecycle.state;
|
|
86346
86588
|
if (lifecycleState === "draft" || lifecycleState === "confirmed" || lifecycleState === "frozen") {
|
|
86347
86589
|
const structureDigest = typeof parsed.structure_digest === "string" ? parsed.structure_digest : typeof lifecycle.structure_digest === "string" ? lifecycle.structure_digest : undefined;
|
|
@@ -86351,7 +86593,7 @@ function readStructureDraftStatus(projectRoot) {
|
|
|
86351
86593
|
lifecycleState,
|
|
86352
86594
|
...typeof lifecycle.phase_collection === "string" ? { phaseCollection: lifecycle.phase_collection } : {},
|
|
86353
86595
|
sourceKeys: Array.isArray(parsed.sources) ? parsed.sources.filter((item) => typeof item === "string") : [],
|
|
86354
|
-
collections: Array.isArray(parsed.views) ? [...new Set(parsed.views.flatMap((view) =>
|
|
86596
|
+
collections: Array.isArray(parsed.views) ? [...new Set(parsed.views.flatMap((view) => isRecord19(view) && typeof view.collection === "string" ? [view.collection] : []))].sort() : [],
|
|
86355
86597
|
...structureDigest === undefined ? {} : { structureDigest },
|
|
86356
86598
|
...evidenceSnapshotHash === undefined ? {} : { evidenceSnapshotHash },
|
|
86357
86599
|
...stagedStructureCounts(parsed),
|
|
@@ -86528,8 +86770,8 @@ async function documentSourceSiteHint(input) {
|
|
|
86528
86770
|
});
|
|
86529
86771
|
}
|
|
86530
86772
|
function documentSnapshotReadiness(input) {
|
|
86531
|
-
const manifestPath =
|
|
86532
|
-
if (!
|
|
86773
|
+
const manifestPath = join53(input.projectRoot, input.manifest);
|
|
86774
|
+
if (!existsSync36(manifestPath)) {
|
|
86533
86775
|
return {
|
|
86534
86776
|
ready: false,
|
|
86535
86777
|
diagnostics: [`snapshot is missing: ${input.manifest}`],
|
|
@@ -86537,7 +86779,7 @@ function documentSnapshotReadiness(input) {
|
|
|
86537
86779
|
};
|
|
86538
86780
|
}
|
|
86539
86781
|
try {
|
|
86540
|
-
const manifest = findDocumentSnapshotForSource(JSON.parse(
|
|
86782
|
+
const manifest = findDocumentSnapshotForSource(JSON.parse(readFileSync8(manifestPath, "utf8")), input.sourceName);
|
|
86541
86783
|
if (manifest === null) {
|
|
86542
86784
|
return {
|
|
86543
86785
|
ready: false,
|
|
@@ -86598,7 +86840,7 @@ function documentSnapshotReadiness(input) {
|
|
|
86598
86840
|
const missingFiles = [
|
|
86599
86841
|
...manifest.files.map((file) => file.path),
|
|
86600
86842
|
...(manifest.assets ?? []).filter((asset) => asset.content_hash !== undefined).map((asset) => asset.path)
|
|
86601
|
-
].filter((path4) => !
|
|
86843
|
+
].filter((path4) => !existsSync36(join53(input.projectRoot, input.materializedAt, path4)));
|
|
86602
86844
|
if (missingFiles.length > 0) {
|
|
86603
86845
|
return {
|
|
86604
86846
|
ready: false,
|
|
@@ -86845,9 +87087,9 @@ async function readActiveStructuresStatus(projectRoot, currentSnapshotHashes) {
|
|
|
86845
87087
|
init_packageTemplateReview();
|
|
86846
87088
|
|
|
86847
87089
|
// src/project/workflow/workflowProvider.ts
|
|
86848
|
-
import { existsSync as
|
|
86849
|
-
import { dirname as
|
|
86850
|
-
import { fileURLToPath as
|
|
87090
|
+
import { existsSync as existsSync37 } from "node:fs";
|
|
87091
|
+
import { dirname as dirname35, resolve as resolve20 } from "node:path";
|
|
87092
|
+
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
86851
87093
|
|
|
86852
87094
|
// src/project/workflow/verifyFacts.ts
|
|
86853
87095
|
var CLOSE_REPAIRABLE_APPROVED_STRUCTURE_CODES = new Set([
|
|
@@ -87419,7 +87661,7 @@ function planForResolvedCommandPlan(commandPlan, observation) {
|
|
|
87419
87661
|
|
|
87420
87662
|
// src/project/workflow/workflowEvidenceResources.ts
|
|
87421
87663
|
import { createHash as createHash21 } from "node:crypto";
|
|
87422
|
-
import { join as
|
|
87664
|
+
import { join as join54 } from "node:path";
|
|
87423
87665
|
function sourceKeysForRoute(node3, observation) {
|
|
87424
87666
|
if (node3 === "classify-document") {
|
|
87425
87667
|
return observation.unclassifiedDocumentTargets.map((target) => target.sourceKey);
|
|
@@ -87471,7 +87713,7 @@ async function currentSourceBodyResources(input) {
|
|
|
87471
87713
|
kind: "context-view",
|
|
87472
87714
|
media_type: "text/markdown",
|
|
87473
87715
|
digest: document4.content_hash,
|
|
87474
|
-
path:
|
|
87716
|
+
path: join54(input.observation.projectRoot, source2.materializedAt, document4.path),
|
|
87475
87717
|
read_state: isCurrent(id2, document4.content_hash, input.receipts) ? "current" : "read-required"
|
|
87476
87718
|
});
|
|
87477
87719
|
}
|
|
@@ -87483,7 +87725,7 @@ async function currentSourceBodyResources(input) {
|
|
|
87483
87725
|
// src/project/workflow/workflowProvider.ts
|
|
87484
87726
|
var providerPromise;
|
|
87485
87727
|
function providerCandidates() {
|
|
87486
|
-
const moduleDir2 =
|
|
87728
|
+
const moduleDir2 = dirname35(fileURLToPath7(import.meta.url));
|
|
87487
87729
|
return [
|
|
87488
87730
|
...process.env.C4A_CONTEXT_WORKFLOW_PROVIDER ? [resolve20(process.env.C4A_CONTEXT_WORKFLOW_PROVIDER)] : [],
|
|
87489
87731
|
resolve20(moduleDir2, "providers", "context", "manifest.json"),
|
|
@@ -87491,7 +87733,7 @@ function providerCandidates() {
|
|
|
87491
87733
|
];
|
|
87492
87734
|
}
|
|
87493
87735
|
function contextWorkflowProviderPath() {
|
|
87494
|
-
const candidate = providerCandidates().find((path4) =>
|
|
87736
|
+
const candidate = providerCandidates().find((path4) => existsSync37(path4));
|
|
87495
87737
|
if (candidate === undefined) {
|
|
87496
87738
|
throw new Error("Context workflow Provider is missing. Rebuild @c4a/context-cli or reinstall the published package.");
|
|
87497
87739
|
}
|
|
@@ -88505,13 +88747,13 @@ async function collectProjectStatusSnapshot(projectRoot, options = {}) {
|
|
|
88505
88747
|
requestedCollections: [...new Set(alignTargets.map((target) => target.collection))],
|
|
88506
88748
|
requestedGroups: alignGroups
|
|
88507
88749
|
});
|
|
88508
|
-
const approvedPages = await countFiles(
|
|
88750
|
+
const approvedPages = await countFiles(join55(projectRoot, "knowledge"), (rel) => rel.endsWith(".md") && !rel.startsWith("assets/"));
|
|
88509
88751
|
const approvedCollections = (await Promise.all(KNOWLEDGE_COLLECTIONS.map(async (collection) => ({
|
|
88510
88752
|
collection,
|
|
88511
|
-
count: await countFiles(
|
|
88753
|
+
count: await countFiles(join55(projectRoot, "knowledge", collection), (rel) => rel.endsWith(".md"))
|
|
88512
88754
|
})))).filter((item) => item.count > 0).map((item) => item.collection);
|
|
88513
88755
|
const closeStatus = await readCloseStatus(projectRoot);
|
|
88514
|
-
const distFiles = await countFiles(
|
|
88756
|
+
const distFiles = await countFiles(join55(projectRoot, "dist"), () => true);
|
|
88515
88757
|
const sourceFreshness = phaseStatus.projectEntryValid ? await collectSourceFreshness({
|
|
88516
88758
|
projectRoot,
|
|
88517
88759
|
phases,
|
|
@@ -88875,6 +89117,7 @@ async function runProjectStatusCommand(input) {
|
|
|
88875
89117
|
} else {
|
|
88876
89118
|
process.stdout.write(formatProjectStatus(status));
|
|
88877
89119
|
}
|
|
89120
|
+
input.onSuccess?.(status);
|
|
88878
89121
|
return true;
|
|
88879
89122
|
}
|
|
88880
89123
|
async function assertProjectWorkflowRevision(input) {
|
|
@@ -88931,11 +89174,11 @@ function shellQuote6(value) {
|
|
|
88931
89174
|
}
|
|
88932
89175
|
function receiptSetPath(receipts) {
|
|
88933
89176
|
const token = digestText(JSON.stringify(receipts)).slice("sha256:".length);
|
|
88934
|
-
return
|
|
89177
|
+
return join56(".tmp", "context-runtime", "workflow", "read-receipts", `${token}.json`);
|
|
88935
89178
|
}
|
|
88936
89179
|
async function writeReceiptContinuation(input) {
|
|
88937
89180
|
const path4 = receiptSetPath(input.receipts);
|
|
88938
|
-
await writeJsonAtomic(
|
|
89181
|
+
await writeJsonAtomic(join56(input.projectRoot, path4), input.receipts);
|
|
88939
89182
|
const command2 = input.managed ? [
|
|
88940
89183
|
"context",
|
|
88941
89184
|
"--workflow-resource-receipts",
|
|
@@ -88996,7 +89239,7 @@ async function materializeContextWorkflowResource(input) {
|
|
|
88996
89239
|
}
|
|
88997
89240
|
const content3 = renderContextWorkflowResource(resourceId2, status);
|
|
88998
89241
|
const location = await materializeResource(await loadContextWorkflowProvider(), resourceId2, {
|
|
88999
|
-
cache:
|
|
89242
|
+
cache: join56(found.projectRoot, ".tmp", "context-runtime", "workflow", "resources"),
|
|
89000
89243
|
workspace: found.projectRoot,
|
|
89001
89244
|
revision: input.revision,
|
|
89002
89245
|
input: {
|
|
@@ -89222,7 +89465,7 @@ function registerContextWorkflowResourceCommands(program2) {
|
|
|
89222
89465
|
}
|
|
89223
89466
|
|
|
89224
89467
|
// src/commands/runProject.ts
|
|
89225
|
-
import { fileURLToPath as
|
|
89468
|
+
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
89226
89469
|
init_cliFeedback();
|
|
89227
89470
|
init_errors();
|
|
89228
89471
|
|
|
@@ -89233,11 +89476,11 @@ init_exitCode();
|
|
|
89233
89476
|
|
|
89234
89477
|
// src/project/documentCaptureLark.ts
|
|
89235
89478
|
import { readdir as readdir18, readFile as readFile44 } from "node:fs/promises";
|
|
89236
|
-
import { basename as basename8, extname as extname12, join as
|
|
89479
|
+
import { basename as basename8, extname as extname12, join as join59 } from "node:path";
|
|
89237
89480
|
|
|
89238
89481
|
// src/lib/atomicFileBatch.ts
|
|
89239
89482
|
import { lstat as lstat2, mkdir as mkdir28, mkdtemp, rename as rename4, rm as rm14, writeFile as writeFile23 } from "node:fs/promises";
|
|
89240
|
-
import { dirname as
|
|
89483
|
+
import { dirname as dirname36, join as join57, resolve as resolve22 } from "node:path";
|
|
89241
89484
|
async function existingFileKind(path4) {
|
|
89242
89485
|
try {
|
|
89243
89486
|
const stats = await lstat2(path4);
|
|
@@ -89267,9 +89510,9 @@ async function applyAtomicFileBatch(input) {
|
|
|
89267
89510
|
for (const path4 of writesByPath.keys())
|
|
89268
89511
|
removalPaths.delete(path4);
|
|
89269
89512
|
await mkdir28(input.transactionRoot, { recursive: true });
|
|
89270
|
-
const transactionDir = await mkdtemp(
|
|
89271
|
-
const stagedRoot =
|
|
89272
|
-
const backupRoot =
|
|
89513
|
+
const transactionDir = await mkdtemp(join57(input.transactionRoot, "batch-"));
|
|
89514
|
+
const stagedRoot = join57(transactionDir, "staged");
|
|
89515
|
+
const backupRoot = join57(transactionDir, "backup");
|
|
89273
89516
|
const writes = [...writesByPath.values()].sort((left, right) => left.path.localeCompare(right.path));
|
|
89274
89517
|
const affectedPaths = [...new Set([...writesByPath.keys(), ...removalPaths])].sort();
|
|
89275
89518
|
const staged = new Map;
|
|
@@ -89279,20 +89522,20 @@ async function applyAtomicFileBatch(input) {
|
|
|
89279
89522
|
try {
|
|
89280
89523
|
await mkdir28(stagedRoot, { recursive: true });
|
|
89281
89524
|
for (const [index2, write] of writes.entries()) {
|
|
89282
|
-
const path4 =
|
|
89525
|
+
const path4 = join57(stagedRoot, String(index2));
|
|
89283
89526
|
await writeFile23(path4, write.bytes);
|
|
89284
89527
|
staged.set(write.path, path4);
|
|
89285
89528
|
}
|
|
89286
89529
|
for (const [index2, path4] of affectedPaths.entries()) {
|
|
89287
89530
|
if (await existingFileKind(path4) === "missing")
|
|
89288
89531
|
continue;
|
|
89289
|
-
const backupPath =
|
|
89290
|
-
await mkdir28(
|
|
89532
|
+
const backupPath = join57(backupRoot, String(index2));
|
|
89533
|
+
await mkdir28(dirname36(backupPath), { recursive: true });
|
|
89291
89534
|
await rename4(path4, backupPath);
|
|
89292
89535
|
backups.set(path4, backupPath);
|
|
89293
89536
|
}
|
|
89294
89537
|
for (const write of writes) {
|
|
89295
|
-
await mkdir28(
|
|
89538
|
+
await mkdir28(dirname36(write.path), { recursive: true });
|
|
89296
89539
|
await rename4(staged.get(write.path), write.path);
|
|
89297
89540
|
installed.push(write.path);
|
|
89298
89541
|
}
|
|
@@ -89304,7 +89547,7 @@ async function applyAtomicFileBatch(input) {
|
|
|
89304
89547
|
});
|
|
89305
89548
|
}
|
|
89306
89549
|
for (const [path4, backupPath] of [...backups.entries()].reverse()) {
|
|
89307
|
-
await mkdir28(
|
|
89550
|
+
await mkdir28(dirname36(path4), { recursive: true });
|
|
89308
89551
|
await rename4(backupPath, path4).catch((rollbackError) => {
|
|
89309
89552
|
rollbackFailures.push(`restore ${path4}: ${String(rollbackError)}`);
|
|
89310
89553
|
});
|
|
@@ -89341,7 +89584,7 @@ function detectExternalEnvironmentIssue(value) {
|
|
|
89341
89584
|
}
|
|
89342
89585
|
|
|
89343
89586
|
// src/lib/feishu.ts
|
|
89344
|
-
import { spawn as
|
|
89587
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
89345
89588
|
|
|
89346
89589
|
// src/lib/larkDocxXml.ts
|
|
89347
89590
|
import { createHash as createHash23 } from "node:crypto";
|
|
@@ -93626,7 +93869,7 @@ function projectLarkDocxXmlBlock(input) {
|
|
|
93626
93869
|
// src/lib/larkResourceMaterialization.ts
|
|
93627
93870
|
import { createHash as createHash24 } from "node:crypto";
|
|
93628
93871
|
import { mkdtemp as mkdtemp2, readFile as readFile43, readdir as readdir17, rm as rm15 } from "node:fs/promises";
|
|
93629
|
-
import { extname as extname11, join as
|
|
93872
|
+
import { extname as extname11, join as join58 } from "node:path";
|
|
93630
93873
|
import { tmpdir } from "node:os";
|
|
93631
93874
|
|
|
93632
93875
|
// src/lib/larkResourceCommand.ts
|
|
@@ -93825,7 +94068,7 @@ function findBooleanField(value, name2) {
|
|
|
93825
94068
|
return;
|
|
93826
94069
|
}
|
|
93827
94070
|
async function downloadedFile(input) {
|
|
93828
|
-
const tempRoot = await mkdtemp2(
|
|
94071
|
+
const tempRoot = await mkdtemp2(join58(tmpdir(), "context-lark-resource-"));
|
|
93829
94072
|
try {
|
|
93830
94073
|
await runLarkResourceCommand(input.runner, [
|
|
93831
94074
|
"docs",
|
|
@@ -93846,7 +94089,7 @@ async function downloadedFile(input) {
|
|
|
93846
94089
|
if (entries.length !== 1)
|
|
93847
94090
|
throw new Error(`media download produced ${entries.length} files, expected exactly one`);
|
|
93848
94091
|
const path4 = entries[0]?.name ?? "resource.bin";
|
|
93849
|
-
const bytes = await readFile43(
|
|
94092
|
+
const bytes = await readFile43(join58(tempRoot, path4));
|
|
93850
94093
|
return { path: path4, bytes, mediaType: mediaTypeFor(path4, bytes) };
|
|
93851
94094
|
} finally {
|
|
93852
94095
|
await rm15(tempRoot, { recursive: true, force: true });
|
|
@@ -93937,9 +94180,9 @@ async function sheetMaterialization(resource, runner2) {
|
|
|
93937
94180
|
const sheetId = resource.attributes["sheet-id"];
|
|
93938
94181
|
if (token === undefined || sheetId === undefined)
|
|
93939
94182
|
throw new Error("embedded Sheet requires token and sheet-id");
|
|
93940
|
-
const tempRoot = await mkdtemp2(
|
|
94183
|
+
const tempRoot = await mkdtemp2(join58(tmpdir(), "context-lark-sheet-"));
|
|
93941
94184
|
try {
|
|
93942
|
-
const outputPath =
|
|
94185
|
+
const outputPath = join58(tempRoot, "sheet.json");
|
|
93943
94186
|
const stdout = await runLarkResourceCommand(runner2, [
|
|
93944
94187
|
"sheets",
|
|
93945
94188
|
"+csv-get",
|
|
@@ -94095,7 +94338,7 @@ async function whiteboardMaterialization(resource, runner2) {
|
|
|
94095
94338
|
if (token === undefined)
|
|
94096
94339
|
throw new Error(`${resource.kind} has no whiteboard token`);
|
|
94097
94340
|
const preview = await downloadedFile({ runner: runner2, token, type: "whiteboard" });
|
|
94098
|
-
const tempRoot = await mkdtemp2(
|
|
94341
|
+
const tempRoot = await mkdtemp2(join58(tmpdir(), "context-lark-whiteboard-"));
|
|
94099
94342
|
let rawPayload;
|
|
94100
94343
|
try {
|
|
94101
94344
|
await runLarkResourceCommand(runner2, [
|
|
@@ -94113,7 +94356,7 @@ async function whiteboardMaterialization(resource, runner2) {
|
|
|
94113
94356
|
"--format",
|
|
94114
94357
|
"json"
|
|
94115
94358
|
], { cwd: tempRoot });
|
|
94116
|
-
rawPayload = JSON.parse(await readFile43(
|
|
94359
|
+
rawPayload = JSON.parse(await readFile43(join58(tempRoot, "raw.json"), "utf8"));
|
|
94117
94360
|
} finally {
|
|
94118
94361
|
await rm15(tempRoot, { recursive: true, force: true });
|
|
94119
94362
|
}
|
|
@@ -94386,7 +94629,7 @@ class LarkCliError extends Error {
|
|
|
94386
94629
|
}
|
|
94387
94630
|
}
|
|
94388
94631
|
var defaultRunner = (args, options) => new Promise((resolve8, reject) => {
|
|
94389
|
-
const child =
|
|
94632
|
+
const child = spawn3(LARK_BIN, args, {
|
|
94390
94633
|
...options?.cwd === undefined ? {} : { cwd: options.cwd },
|
|
94391
94634
|
stdio: ["ignore", "pipe", "pipe"]
|
|
94392
94635
|
});
|
|
@@ -94793,7 +95036,7 @@ async function fileContentMatches(path4, content3) {
|
|
|
94793
95036
|
}
|
|
94794
95037
|
}
|
|
94795
95038
|
function sourceManifestPath2(entry) {
|
|
94796
|
-
return entry.snapshot?.manifest ??
|
|
95039
|
+
return entry.snapshot?.manifest ?? join59(entry.materializedAt, "manifest.json");
|
|
94797
95040
|
}
|
|
94798
95041
|
function larkRuntimeError(message, detail) {
|
|
94799
95042
|
return new ContextError(ExitCode.ExternalToolError, message, {
|
|
@@ -94919,7 +95162,7 @@ function assetManifestEntry(asset, assetRoot) {
|
|
|
94919
95162
|
};
|
|
94920
95163
|
}
|
|
94921
95164
|
async function listSnapshotAssetFiles(root2, assetRoot) {
|
|
94922
|
-
const assetsRoot =
|
|
95165
|
+
const assetsRoot = join59(root2, assetRoot);
|
|
94923
95166
|
const files = [];
|
|
94924
95167
|
const visit3 = async (dir, prefix = assetRoot) => {
|
|
94925
95168
|
let entries;
|
|
@@ -94932,7 +95175,7 @@ async function listSnapshotAssetFiles(root2, assetRoot) {
|
|
|
94932
95175
|
}
|
|
94933
95176
|
for (const entry of entries) {
|
|
94934
95177
|
const relPath = `${prefix}/${entry.name}`;
|
|
94935
|
-
const absolutePath =
|
|
95178
|
+
const absolutePath = join59(dir, entry.name);
|
|
94936
95179
|
if (entry.isDirectory()) {
|
|
94937
95180
|
await visit3(absolutePath, relPath);
|
|
94938
95181
|
continue;
|
|
@@ -94947,7 +95190,7 @@ async function listSnapshotAssetFiles(root2, assetRoot) {
|
|
|
94947
95190
|
}
|
|
94948
95191
|
async function staleSnapshotAssetPaths(input) {
|
|
94949
95192
|
const existingPaths = await listSnapshotAssetFiles(input.materializedAtAbsPath, input.assetRoot);
|
|
94950
|
-
return existingPaths.filter((path4) => !input.currentPaths.has(path4)).map((path4) =>
|
|
95193
|
+
return existingPaths.filter((path4) => !input.currentPaths.has(path4)).map((path4) => join59(input.materializedAtAbsPath, path4));
|
|
94951
95194
|
}
|
|
94952
95195
|
function normalizeLarkError(error, sourceName) {
|
|
94953
95196
|
if (error instanceof ContextError)
|
|
@@ -95021,9 +95264,9 @@ async function runCaptureLarkPhaseUnlocked(input) {
|
|
|
95021
95264
|
locator
|
|
95022
95265
|
}];
|
|
95023
95266
|
const manifestPath = sourceManifestPath2(entry);
|
|
95024
|
-
const manifestAbsPath =
|
|
95267
|
+
const manifestAbsPath = join59(input.projectRoot, manifestPath);
|
|
95025
95268
|
const materializedAt = entry.materializedAt;
|
|
95026
|
-
const materializedAtAbsPath =
|
|
95269
|
+
const materializedAtAbsPath = join59(input.projectRoot, materializedAt);
|
|
95027
95270
|
const manifest = createDocumentSnapshotManifest({
|
|
95028
95271
|
sourceType: "lark",
|
|
95029
95272
|
sourceName: resolved.sourceName,
|
|
@@ -95053,13 +95296,13 @@ async function runCaptureLarkPhaseUnlocked(input) {
|
|
|
95053
95296
|
}));
|
|
95054
95297
|
try {
|
|
95055
95298
|
const requestedWrites = [{
|
|
95056
|
-
path:
|
|
95299
|
+
path: join59(materializedAtAbsPath, documentPath),
|
|
95057
95300
|
bytes: normalized
|
|
95058
95301
|
}];
|
|
95059
95302
|
for (const asset of assets) {
|
|
95060
95303
|
if (asset.bytes !== undefined) {
|
|
95061
95304
|
requestedWrites.push({
|
|
95062
|
-
path:
|
|
95305
|
+
path: join59(materializedAtAbsPath, asset.entry.path),
|
|
95063
95306
|
bytes: asset.bytes
|
|
95064
95307
|
});
|
|
95065
95308
|
}
|
|
@@ -95076,7 +95319,7 @@ async function runCaptureLarkPhaseUnlocked(input) {
|
|
|
95076
95319
|
currentPaths: new Set(assets.filter((asset) => asset.bytes !== undefined).map((asset) => asset.entry.path))
|
|
95077
95320
|
});
|
|
95078
95321
|
await applyAtomicFileBatch({
|
|
95079
|
-
transactionRoot:
|
|
95322
|
+
transactionRoot: join59(input.projectRoot, ".tmp", "context-runtime", "capture-transactions"),
|
|
95080
95323
|
writes,
|
|
95081
95324
|
removals
|
|
95082
95325
|
});
|
|
@@ -97499,7 +97742,7 @@ function compileDiagnostic(severity, code3, family, message, field, extra = {})
|
|
|
97499
97742
|
...extra
|
|
97500
97743
|
};
|
|
97501
97744
|
}
|
|
97502
|
-
function
|
|
97745
|
+
function isRecord20(value) {
|
|
97503
97746
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
97504
97747
|
}
|
|
97505
97748
|
|
|
@@ -97894,7 +98137,7 @@ function compileActionFromFields(fields) {
|
|
|
97894
98137
|
return action;
|
|
97895
98138
|
}
|
|
97896
98139
|
function parseCompileAction(raw, index2, diagnostics) {
|
|
97897
|
-
if (!
|
|
98140
|
+
if (!isRecord20(raw)) {
|
|
97898
98141
|
diagnostics.push(compileDiagnostic("error", "schema.action_object", "schema", "Each action must be an object.", `actions[${index2}]`));
|
|
97899
98142
|
return;
|
|
97900
98143
|
}
|
|
@@ -97906,7 +98149,7 @@ function parseCompileAction(raw, index2, diagnostics) {
|
|
|
97906
98149
|
}
|
|
97907
98150
|
function parseCompilePayload(value) {
|
|
97908
98151
|
const diagnostics = [];
|
|
97909
|
-
if (!
|
|
98152
|
+
if (!isRecord20(value)) {
|
|
97910
98153
|
return {
|
|
97911
98154
|
diagnostics: [compileDiagnostic("error", "schema.payload_object", "schema", "Compile action payload must be an object.", "schema")]
|
|
97912
98155
|
};
|
|
@@ -98869,9 +99112,9 @@ init_atomicWrite();
|
|
|
98869
99112
|
init_cliFeedback();
|
|
98870
99113
|
init_errors();
|
|
98871
99114
|
init_exitCode();
|
|
98872
|
-
import { existsSync as
|
|
99115
|
+
import { existsSync as existsSync38 } from "node:fs";
|
|
98873
99116
|
import { readFile as readFile46 } from "node:fs/promises";
|
|
98874
|
-
import { join as
|
|
99117
|
+
import { join as join60 } from "node:path";
|
|
98875
99118
|
init_writeLock();
|
|
98876
99119
|
var CUSTOM_PHASE_MANIFEST = ".tmp/context-runtime/extract/custom-phase-candidates.json";
|
|
98877
99120
|
function customInputError(phaseId, message, detail = {}) {
|
|
@@ -99025,8 +99268,8 @@ function candidateFromCustom(input) {
|
|
|
99025
99268
|
};
|
|
99026
99269
|
}
|
|
99027
99270
|
async function readManifest(projectRoot) {
|
|
99028
|
-
const path4 =
|
|
99029
|
-
if (!
|
|
99271
|
+
const path4 = join60(projectRoot, CUSTOM_PHASE_MANIFEST);
|
|
99272
|
+
if (!existsSync38(path4))
|
|
99030
99273
|
return { version: 2, phases: {} };
|
|
99031
99274
|
try {
|
|
99032
99275
|
const parsed = JSON.parse(await readFile46(path4, "utf8"));
|
|
@@ -99126,7 +99369,7 @@ async function runExtractCustomPhase(input) {
|
|
|
99126
99369
|
symbols: built.flatMap((item) => item.symbols),
|
|
99127
99370
|
removeSymbols: previousOwned?.symbols ?? []
|
|
99128
99371
|
});
|
|
99129
|
-
await atomicWriteFile(
|
|
99372
|
+
await atomicWriteFile(join60(input.projectRoot, CUSTOM_PHASE_MANIFEST), `${JSON.stringify({
|
|
99130
99373
|
version: 2,
|
|
99131
99374
|
phases: {
|
|
99132
99375
|
...manifest.phases,
|
|
@@ -99186,7 +99429,7 @@ async function runExtractCustomPhase(input) {
|
|
|
99186
99429
|
|
|
99187
99430
|
// src/project/reviewHtml.ts
|
|
99188
99431
|
import { mkdir as mkdir29, writeFile as writeFile24 } from "node:fs/promises";
|
|
99189
|
-
import { dirname as
|
|
99432
|
+
import { dirname as dirname37, isAbsolute as isAbsolute9, join as join62, resolve as resolve23 } from "node:path";
|
|
99190
99433
|
import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
99191
99434
|
|
|
99192
99435
|
// src/project/reviewSourceExcerpts.ts
|
|
@@ -99296,9 +99539,9 @@ async function collectReviewSourceExcerpts(projectRoot, candidates) {
|
|
|
99296
99539
|
}
|
|
99297
99540
|
|
|
99298
99541
|
// src/project/reviewHtmlPresentation.ts
|
|
99299
|
-
import { existsSync as
|
|
99542
|
+
import { existsSync as existsSync39 } from "node:fs";
|
|
99300
99543
|
import { readFile as readFile47 } from "node:fs/promises";
|
|
99301
|
-
import { join as
|
|
99544
|
+
import { join as join61 } from "node:path";
|
|
99302
99545
|
var import_yaml31 = __toESM(require_dist3(), 1);
|
|
99303
99546
|
function escapeHtml3(value) {
|
|
99304
99547
|
return value.replace(/&/gu, "&").replace(/</gu, "<").replace(/>/gu, ">").replace(/"/gu, """);
|
|
@@ -99379,8 +99622,8 @@ function filterEdgePreviewForCandidate(record, edges) {
|
|
|
99379
99622
|
return edges.filter((edge2) => endpoints.has(edge2.from) || endpoints.has(edge2.to));
|
|
99380
99623
|
}
|
|
99381
99624
|
async function readEdgePreview(projectRoot) {
|
|
99382
|
-
const filePath =
|
|
99383
|
-
if (!
|
|
99625
|
+
const filePath = join61(projectRoot, LIFECYCLE_STRUCTURE_FILE);
|
|
99626
|
+
if (!existsSync39(filePath))
|
|
99384
99627
|
return [];
|
|
99385
99628
|
try {
|
|
99386
99629
|
const parsed = import_yaml31.default.parse(await readFile47(filePath, "utf8"));
|
|
@@ -99557,7 +99800,7 @@ var REVIEW_HTML_STYLES = `
|
|
|
99557
99800
|
`;
|
|
99558
99801
|
|
|
99559
99802
|
// src/project/reviewHtml.ts
|
|
99560
|
-
var REVIEW_HTML_ROOT =
|
|
99803
|
+
var REVIEW_HTML_ROOT = join62(".tmp", "context-runtime", "review");
|
|
99561
99804
|
function decodedLinkTarget(value) {
|
|
99562
99805
|
try {
|
|
99563
99806
|
return decodeURIComponent(value);
|
|
@@ -99571,7 +99814,7 @@ function linkedResourcePreviews(input) {
|
|
|
99571
99814
|
const target = link2.target;
|
|
99572
99815
|
if (/^[a-z][a-z0-9+.-]*:/iu.test(target) || target.startsWith("/"))
|
|
99573
99816
|
continue;
|
|
99574
|
-
const assetPath =
|
|
99817
|
+
const assetPath = join62(dirname37(input.documentPath), decodedLinkTarget(target)).split("\\").join("/");
|
|
99575
99818
|
const asset = input.assetsByPath.get(assetPath);
|
|
99576
99819
|
if (asset?.content_hash === undefined || asset.role === "audit")
|
|
99577
99820
|
continue;
|
|
@@ -99579,7 +99822,7 @@ function linkedResourcePreviews(input) {
|
|
|
99579
99822
|
label: link2.label || "Resource",
|
|
99580
99823
|
kind: asset.source?.kind ?? "resource",
|
|
99581
99824
|
status: "materialized",
|
|
99582
|
-
url: pathToFileURL3(
|
|
99825
|
+
url: pathToFileURL3(join62(input.projectRoot, input.materializedAt, asset.path)).href,
|
|
99583
99826
|
media_type: asset.media_type ?? "application/octet-stream",
|
|
99584
99827
|
image: asset.media_type?.startsWith("image/") === true
|
|
99585
99828
|
});
|
|
@@ -99588,7 +99831,7 @@ function linkedResourcePreviews(input) {
|
|
|
99588
99831
|
}
|
|
99589
99832
|
function materializationPreview(input) {
|
|
99590
99833
|
const linkedAsset = input.item.asset_paths.flatMap((path4) => [path4, path4.startsWith("assets/") ? path4 : `assets/${path4}`]).map((path4) => input.assetsByPath.get(path4)).find((asset) => asset !== undefined && asset.role !== "audit");
|
|
99591
|
-
const url = input.existing?.url ?? (linkedAsset?.content_hash === undefined ? undefined : pathToFileURL3(
|
|
99834
|
+
const url = input.existing?.url ?? (linkedAsset?.content_hash === undefined ? undefined : pathToFileURL3(join62(input.projectRoot, input.materializedAt, linkedAsset.path)).href);
|
|
99592
99835
|
return {
|
|
99593
99836
|
key: linkedAsset?.path ?? input.item.locator,
|
|
99594
99837
|
preview: {
|
|
@@ -100132,7 +100375,7 @@ function renderReviewHtml(candidates, reviewScope, edgePreview, sourceExcerpts,
|
|
|
100132
100375
|
}
|
|
100133
100376
|
function resolveOutputPath(projectRoot, outPath, reviewScope) {
|
|
100134
100377
|
if (outPath === undefined)
|
|
100135
|
-
return
|
|
100378
|
+
return join62(projectRoot, REVIEW_HTML_ROOT, `${reviewScope}.html`);
|
|
100136
100379
|
return isAbsolute9(outPath) ? outPath : resolve23(projectRoot, outPath);
|
|
100137
100380
|
}
|
|
100138
100381
|
async function writeReviewHtml(input) {
|
|
@@ -100145,7 +100388,7 @@ async function writeReviewHtml(input) {
|
|
|
100145
100388
|
const sourceExcerpts = await collectReviewSourceExcerpts(input.projectRoot, candidates);
|
|
100146
100389
|
const resourcePreviews = await collectReviewResourcePreviews(input.projectRoot, candidates);
|
|
100147
100390
|
const outPath = resolveOutputPath(input.projectRoot, input.out, reviewScope);
|
|
100148
|
-
await mkdir29(
|
|
100391
|
+
await mkdir29(dirname37(outPath), { recursive: true });
|
|
100149
100392
|
await writeFile24(outPath, renderReviewHtml(candidates, reviewScope, edgePreview, sourceExcerpts, resourcePreviews), "utf8");
|
|
100150
100393
|
return {
|
|
100151
100394
|
path: outPath,
|
|
@@ -100560,17 +100803,17 @@ function compactJsonResult(result, verbose) {
|
|
|
100560
100803
|
}
|
|
100561
100804
|
|
|
100562
100805
|
// src/project/runLog.ts
|
|
100563
|
-
import { randomUUID as
|
|
100806
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
100564
100807
|
import { mkdir as mkdir30, writeFile as writeFile25 } from "node:fs/promises";
|
|
100565
|
-
import { dirname as
|
|
100808
|
+
import { dirname as dirname38, join as join63 } from "node:path";
|
|
100566
100809
|
var createPhaseRunId = () => {
|
|
100567
100810
|
const timestamp = new Date().toISOString().replace(/[-:.TZ]/gu, "");
|
|
100568
|
-
return `run_${timestamp}_${
|
|
100811
|
+
return `run_${timestamp}_${randomUUID3().slice(0, 8)}`;
|
|
100569
100812
|
};
|
|
100570
100813
|
async function writePhaseRunLog(input) {
|
|
100571
|
-
const relPath =
|
|
100572
|
-
const absPath =
|
|
100573
|
-
await mkdir30(
|
|
100814
|
+
const relPath = join63(".tmp", "context-runtime", "runs", `${input.runId}.json`);
|
|
100815
|
+
const absPath = join63(input.projectRoot, relPath);
|
|
100816
|
+
await mkdir30(dirname38(absPath), { recursive: true });
|
|
100574
100817
|
await writeFile25(absPath, `${JSON.stringify({
|
|
100575
100818
|
run_id: input.runId,
|
|
100576
100819
|
phase_id: input.phase.id,
|
|
@@ -101271,14 +101514,14 @@ init_exitCode();
|
|
|
101271
101514
|
import { resolve as resolve24 } from "node:path";
|
|
101272
101515
|
init_workspace();
|
|
101273
101516
|
var PROSE_STRUCTURE_BATCH_SCHEMA = "context.prose.structure-batch.v1";
|
|
101274
|
-
function
|
|
101517
|
+
function isRecord21(value) {
|
|
101275
101518
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
101276
101519
|
}
|
|
101277
101520
|
function shellQuote8(value) {
|
|
101278
101521
|
return /^[A-Za-z0-9._/=-]+$/u.test(value) ? value : `'${value.replace(/'/gu, `'"'"'`)}'`;
|
|
101279
101522
|
}
|
|
101280
101523
|
function parseBatchPayload(value) {
|
|
101281
|
-
if (!
|
|
101524
|
+
if (!isRecord21(value) || value.schema !== PROSE_STRUCTURE_BATCH_SCHEMA || !Array.isArray(value.items)) {
|
|
101282
101525
|
throw new ContextError(ExitCode.UserError, `batch input must match ${PROSE_STRUCTURE_BATCH_SCHEMA}`, {
|
|
101283
101526
|
category: ErrorCategory.UserInputInvalid,
|
|
101284
101527
|
next: "Read the current Route action input_schema and provide one phase_id/input pair per pending structure slot."
|
|
@@ -101291,7 +101534,7 @@ function parseBatchPayload(value) {
|
|
|
101291
101534
|
}
|
|
101292
101535
|
const seen = new Set;
|
|
101293
101536
|
return value.items.map((item, index2) => {
|
|
101294
|
-
if (!
|
|
101537
|
+
if (!isRecord21(item) || typeof item.phase_id !== "string" || typeof item.input !== "string") {
|
|
101295
101538
|
throw new ContextError(ExitCode.UserError, `structure batch items[${index2}] requires phase_id and input`, {
|
|
101296
101539
|
category: ErrorCategory.UserInputInvalid
|
|
101297
101540
|
});
|
|
@@ -101323,7 +101566,7 @@ function alignPhase(phases, phaseId) {
|
|
|
101323
101566
|
return phase;
|
|
101324
101567
|
}
|
|
101325
101568
|
function validationSummary(phaseId, input, result) {
|
|
101326
|
-
const counts2 = result.structure_summary_compact !== undefined &&
|
|
101569
|
+
const counts2 = result.structure_summary_compact !== undefined && isRecord21(result.structure_summary_compact.counts) ? result.structure_summary_compact.counts : undefined;
|
|
101327
101570
|
return {
|
|
101328
101571
|
phase_id: phaseId,
|
|
101329
101572
|
input,
|
|
@@ -101817,7 +102060,7 @@ init_debugTrace();
|
|
|
101817
102060
|
// src/project/workflow/workflowExecutionRuntime.ts
|
|
101818
102061
|
init_debugTrace();
|
|
101819
102062
|
import { createHash as createHash26 } from "node:crypto";
|
|
101820
|
-
import { spawn as
|
|
102063
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
101821
102064
|
function digestText2(value, includeTail) {
|
|
101822
102065
|
const bytes = Buffer.byteLength(value);
|
|
101823
102066
|
return {
|
|
@@ -101967,7 +102210,7 @@ execution scope cleanup failed`, true)
|
|
|
101967
102210
|
try {
|
|
101968
102211
|
receipt = await new Promise((resolve8, reject) => {
|
|
101969
102212
|
let settled = false;
|
|
101970
|
-
const child =
|
|
102213
|
+
const child = spawn4(process.execPath, [this.cliEntryPath, ...args], {
|
|
101971
102214
|
cwd: input.cwd,
|
|
101972
102215
|
env: { ...process.env, ...debugChildEnvironment() },
|
|
101973
102216
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -102332,7 +102575,7 @@ function requirePayloadHeaderField(value, field) {
|
|
|
102332
102575
|
return value;
|
|
102333
102576
|
}
|
|
102334
102577
|
function parsePayloadLineDecision(value, index2) {
|
|
102335
|
-
if (!
|
|
102578
|
+
if (!isRecord17(value) || typeof value.candidate_id !== "string") {
|
|
102336
102579
|
throw new ContextError(ExitCode.UserError, `review payload line ${index2} must contain candidate_id and status`, {
|
|
102337
102580
|
category: ErrorCategory.UserInputInvalid
|
|
102338
102581
|
});
|
|
@@ -102345,7 +102588,7 @@ function parsePayloadLineDecision(value, index2) {
|
|
|
102345
102588
|
function parsePayloadScope(value) {
|
|
102346
102589
|
if (value === undefined)
|
|
102347
102590
|
return;
|
|
102348
|
-
if (!
|
|
102591
|
+
if (!isRecord17(value) || typeof value.count !== "number" || !Number.isInteger(value.count) || value.count < 0 || typeof value.ids_sha256 !== "string" || !/^[a-f0-9]{64}$/iu.test(value.ids_sha256)) {
|
|
102349
102592
|
throw new ContextError(ExitCode.UserError, "review payload scope must contain count and ids_sha256", {
|
|
102350
102593
|
category: ErrorCategory.UserInputInvalid
|
|
102351
102594
|
});
|
|
@@ -102384,7 +102627,7 @@ function parsePayloadScope(value) {
|
|
|
102384
102627
|
}
|
|
102385
102628
|
function parsePayloadValues(parsed) {
|
|
102386
102629
|
const first = parsed[0];
|
|
102387
|
-
if (!
|
|
102630
|
+
if (!isRecord17(first)) {
|
|
102388
102631
|
throw new ContextError(ExitCode.UserError, "review payload header must be a JSON object", {
|
|
102389
102632
|
category: ErrorCategory.UserInputInvalid
|
|
102390
102633
|
});
|
|
@@ -103296,7 +103539,7 @@ async function runManagedUntil(input) {
|
|
|
103296
103539
|
const resourceReceipts = input.resourceReceiptsReference === undefined ? undefined : await parseWorkflowResourceReceipts(input.resourceReceiptsReference, found.projectRoot);
|
|
103297
103540
|
const runtime = new WorkspaceExecutionRuntime({
|
|
103298
103541
|
projectRoot: found.projectRoot,
|
|
103299
|
-
cliEntryPath:
|
|
103542
|
+
cliEntryPath: fileURLToPath8(input.cliModuleUrl),
|
|
103300
103543
|
inProcess: createWorkflowInProcessExecutor()
|
|
103301
103544
|
});
|
|
103302
103545
|
let result;
|
|
@@ -103441,10 +103684,10 @@ function registerDebugCommands(program2) {
|
|
|
103441
103684
|
|
|
103442
103685
|
// src/commands/cleanClaudePluginCache.ts
|
|
103443
103686
|
init_cliFeedback();
|
|
103444
|
-
import { existsSync as
|
|
103687
|
+
import { existsSync as existsSync40 } from "node:fs";
|
|
103445
103688
|
import { readdir as readdir19, rm as rm16 } from "node:fs/promises";
|
|
103446
103689
|
import { homedir } from "node:os";
|
|
103447
|
-
import { join as
|
|
103690
|
+
import { join as join64 } from "node:path";
|
|
103448
103691
|
var ORPHAN_MARKER = ".orphaned_at";
|
|
103449
103692
|
var CLAUDE_PLUGIN_CACHE_ROOT_ENV = "C4A_CLAUDE_PLUGIN_CACHE_ROOT";
|
|
103450
103693
|
var CLAUDE_PLUGIN_CACHE_HOME_ENV = "C4A_CLAUDE_PLUGIN_CACHE_HOME";
|
|
@@ -103453,7 +103696,7 @@ async function cleanClaudePluginCache(opts = {}) {
|
|
|
103453
103696
|
const lines = [];
|
|
103454
103697
|
let removed = 0;
|
|
103455
103698
|
let scanned = 0;
|
|
103456
|
-
if (!
|
|
103699
|
+
if (!existsSync40(cacheRoot)) {
|
|
103457
103700
|
lines.push("· claude plugin cache: missing — nothing to clean");
|
|
103458
103701
|
return { lines, removed, scanned };
|
|
103459
103702
|
}
|
|
@@ -103461,20 +103704,20 @@ async function cleanClaudePluginCache(opts = {}) {
|
|
|
103461
103704
|
for (const mp of marketplaces) {
|
|
103462
103705
|
if (!mp.isDirectory())
|
|
103463
103706
|
continue;
|
|
103464
|
-
const mpDir =
|
|
103707
|
+
const mpDir = join64(cacheRoot, mp.name);
|
|
103465
103708
|
const plugins = await readdir19(mpDir, { withFileTypes: true });
|
|
103466
103709
|
for (const pl of plugins) {
|
|
103467
103710
|
if (!pl.isDirectory())
|
|
103468
103711
|
continue;
|
|
103469
|
-
const plDir =
|
|
103712
|
+
const plDir = join64(mpDir, pl.name);
|
|
103470
103713
|
const versions = await readdir19(plDir, { withFileTypes: true });
|
|
103471
103714
|
for (const ver of versions) {
|
|
103472
103715
|
if (!ver.isDirectory())
|
|
103473
103716
|
continue;
|
|
103474
103717
|
scanned += 1;
|
|
103475
|
-
const verDir =
|
|
103476
|
-
const markerPath =
|
|
103477
|
-
if (!
|
|
103718
|
+
const verDir = join64(plDir, ver.name);
|
|
103719
|
+
const markerPath = join64(verDir, ORPHAN_MARKER);
|
|
103720
|
+
if (!existsSync40(markerPath))
|
|
103478
103721
|
continue;
|
|
103479
103722
|
const label3 = `${mp.name}/${pl.name}/${ver.name}`;
|
|
103480
103723
|
if (opts.dryRun) {
|
|
@@ -103505,7 +103748,7 @@ function resolveClaudePluginCacheRoot(opts) {
|
|
|
103505
103748
|
if (explicitRoot)
|
|
103506
103749
|
return explicitRoot;
|
|
103507
103750
|
const home = opts.home ?? process.env[CLAUDE_PLUGIN_CACHE_HOME_ENV] ?? homedir();
|
|
103508
|
-
return
|
|
103751
|
+
return join64(home, ".claude", "plugins", "cache");
|
|
103509
103752
|
}
|
|
103510
103753
|
async function isEmptyDir(dir) {
|
|
103511
103754
|
try {
|
|
@@ -103531,17 +103774,17 @@ async function runDoctorCleanClaudePluginCache(opts = {}) {
|
|
|
103531
103774
|
}
|
|
103532
103775
|
|
|
103533
103776
|
// src/commands/cleanCache.ts
|
|
103534
|
-
import { existsSync as
|
|
103777
|
+
import { existsSync as existsSync42 } from "node:fs";
|
|
103535
103778
|
import { readdir as readdir20, rm as rm17 } from "node:fs/promises";
|
|
103536
|
-
import { join as
|
|
103779
|
+
import { join as join68 } from "node:path";
|
|
103537
103780
|
|
|
103538
103781
|
// src/incremental/cache.ts
|
|
103539
|
-
import { basename as basename10, dirname as
|
|
103782
|
+
import { basename as basename10, dirname as dirname40, isAbsolute as isAbsolute11, join as join67, resolve as resolve27 } from "node:path";
|
|
103540
103783
|
|
|
103541
103784
|
// src/lib/workspaceLayout.ts
|
|
103542
103785
|
var import_yaml32 = __toESM(require_dist3(), 1);
|
|
103543
|
-
import { existsSync as
|
|
103544
|
-
import { dirname as
|
|
103786
|
+
import { existsSync as existsSync41, readFileSync as readFileSync9, statSync as statSync2 } from "node:fs";
|
|
103787
|
+
import { dirname as dirname39, join as join65, parse as parse7, resolve as resolve26 } from "node:path";
|
|
103545
103788
|
function isDirectorySafe(path4) {
|
|
103546
103789
|
try {
|
|
103547
103790
|
return statSync2(path4).isDirectory();
|
|
@@ -103550,11 +103793,11 @@ function isDirectorySafe(path4) {
|
|
|
103550
103793
|
}
|
|
103551
103794
|
}
|
|
103552
103795
|
function hasRootLayoutMarker(dir) {
|
|
103553
|
-
const configPath =
|
|
103554
|
-
if (!
|
|
103796
|
+
const configPath = join65(dir, "config.yaml");
|
|
103797
|
+
if (!existsSync41(configPath))
|
|
103555
103798
|
return false;
|
|
103556
103799
|
try {
|
|
103557
|
-
const parsed = import_yaml32.default.parse(
|
|
103800
|
+
const parsed = import_yaml32.default.parse(readFileSync9(configPath, "utf8"));
|
|
103558
103801
|
if (!parsed || typeof parsed !== "object")
|
|
103559
103802
|
return false;
|
|
103560
103803
|
const workspace = parsed.workspace;
|
|
@@ -103567,8 +103810,8 @@ function hasRootLayoutMarker(dir) {
|
|
|
103567
103810
|
}
|
|
103568
103811
|
function findWorkspaceAt(dir) {
|
|
103569
103812
|
const root2 = resolve26(dir);
|
|
103570
|
-
const embedded =
|
|
103571
|
-
if (
|
|
103813
|
+
const embedded = join65(root2, ".context");
|
|
103814
|
+
if (existsSync41(join65(embedded, "config.yaml")) && isDirectorySafe(embedded)) {
|
|
103572
103815
|
return { ctxDir: embedded, workspaceRoot: root2, layout: "embedded" };
|
|
103573
103816
|
}
|
|
103574
103817
|
if (hasRootLayoutMarker(root2)) {
|
|
@@ -103585,7 +103828,7 @@ function findNearestWorkspace(startDir = process.cwd()) {
|
|
|
103585
103828
|
return found;
|
|
103586
103829
|
if (dir === root2)
|
|
103587
103830
|
return null;
|
|
103588
|
-
const parent =
|
|
103831
|
+
const parent = dirname39(dir);
|
|
103589
103832
|
if (parent === dir)
|
|
103590
103833
|
return null;
|
|
103591
103834
|
dir = parent;
|
|
@@ -103593,9 +103836,9 @@ function findNearestWorkspace(startDir = process.cwd()) {
|
|
|
103593
103836
|
}
|
|
103594
103837
|
|
|
103595
103838
|
// src/lib/userCache.ts
|
|
103596
|
-
import { basename as basename9, join as
|
|
103839
|
+
import { basename as basename9, join as join66 } from "node:path";
|
|
103597
103840
|
function workspaceLocalUserCacheRoot(ctxDir) {
|
|
103598
|
-
return
|
|
103841
|
+
return join66(ctxDir, ".tmp", "context-cli");
|
|
103599
103842
|
}
|
|
103600
103843
|
|
|
103601
103844
|
// src/incremental/cache.ts
|
|
@@ -103605,7 +103848,7 @@ function resolveCachePath(value) {
|
|
|
103605
103848
|
}
|
|
103606
103849
|
function workspaceCacheHome(workspaceRoot) {
|
|
103607
103850
|
const location = findWorkspaceAt(workspaceRoot);
|
|
103608
|
-
return workspaceLocalUserCacheRoot(location?.ctxDir ??
|
|
103851
|
+
return workspaceLocalUserCacheRoot(location?.ctxDir ?? join67(workspaceRoot, ".context"));
|
|
103609
103852
|
}
|
|
103610
103853
|
function resolveCacheHome(input = {}) {
|
|
103611
103854
|
const explicit = input.cacheHome ?? process.env.C4A_CONTEXT_CACHE_HOME;
|
|
@@ -103614,24 +103857,24 @@ function resolveCacheHome(input = {}) {
|
|
|
103614
103857
|
if (input.workspaceRoot !== undefined)
|
|
103615
103858
|
return workspaceCacheHome(resolveCachePath(input.workspaceRoot));
|
|
103616
103859
|
const nearest = findNearestWorkspace(process.cwd());
|
|
103617
|
-
return workspaceLocalUserCacheRoot(nearest?.ctxDir ??
|
|
103860
|
+
return workspaceLocalUserCacheRoot(nearest?.ctxDir ?? join67(process.cwd(), ".context"));
|
|
103618
103861
|
}
|
|
103619
103862
|
|
|
103620
103863
|
// src/commands/cleanCache.ts
|
|
103621
103864
|
async function countFiles2(dir) {
|
|
103622
|
-
if (!
|
|
103865
|
+
if (!existsSync42(dir))
|
|
103623
103866
|
return 0;
|
|
103624
103867
|
let count = 0;
|
|
103625
103868
|
for (const entry of await readdir20(dir, { withFileTypes: true })) {
|
|
103626
|
-
const full =
|
|
103869
|
+
const full = join68(dir, entry.name);
|
|
103627
103870
|
count += entry.isDirectory() ? await countFiles2(full) : 1;
|
|
103628
103871
|
}
|
|
103629
103872
|
return count;
|
|
103630
103873
|
}
|
|
103631
103874
|
async function inspectAllRetrievalCache() {
|
|
103632
103875
|
const cacheHome = resolveCacheHome();
|
|
103633
|
-
const cacheRoot =
|
|
103634
|
-
const projectIds =
|
|
103876
|
+
const cacheRoot = join68(cacheHome, "retrieval");
|
|
103877
|
+
const projectIds = existsSync42(cacheRoot) ? (await readdir20(cacheRoot, { withFileTypes: true })).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort() : [];
|
|
103635
103878
|
const files = await countFiles2(cacheRoot);
|
|
103636
103879
|
return { cacheRoot, projects: projectIds.length, files, projectIds };
|
|
103637
103880
|
}
|
|
@@ -103649,8 +103892,6 @@ async function cleanAllRetrievalCache() {
|
|
|
103649
103892
|
init_errors();
|
|
103650
103893
|
init_cliFeedback();
|
|
103651
103894
|
init_exitCode();
|
|
103652
|
-
init_workspace();
|
|
103653
|
-
init_packageTemplateReview();
|
|
103654
103895
|
|
|
103655
103896
|
// src/project/sourceCommands.ts
|
|
103656
103897
|
import { readFile as readFile54 } from "node:fs/promises";
|
|
@@ -103665,9 +103906,9 @@ init_cliFeedback();
|
|
|
103665
103906
|
init_errors();
|
|
103666
103907
|
init_exitCode();
|
|
103667
103908
|
import { execFile as execFile6 } from "node:child_process";
|
|
103668
|
-
import { existsSync as
|
|
103909
|
+
import { existsSync as existsSync43 } from "node:fs";
|
|
103669
103910
|
import { lstat as lstat3, mkdir as mkdir31, readlink as readlink2, realpath as realpath4, rm as rm18, symlink as symlink2 } from "node:fs/promises";
|
|
103670
|
-
import { basename as basename11, dirname as
|
|
103911
|
+
import { basename as basename11, dirname as dirname41, isAbsolute as isAbsolute12, relative as relative20, resolve as resolve28 } from "node:path";
|
|
103671
103912
|
import { promisify as promisify6 } from "node:util";
|
|
103672
103913
|
init_writeLock();
|
|
103673
103914
|
var execFileAsync6 = promisify6(execFile6);
|
|
@@ -103809,7 +104050,7 @@ async function git2(cwd, args) {
|
|
|
103809
104050
|
}
|
|
103810
104051
|
async function resolveGitRoot2(path4) {
|
|
103811
104052
|
const root2 = await git2(path4, ["rev-parse", "--show-toplevel"]);
|
|
103812
|
-
if (root2.length === 0 || !
|
|
104053
|
+
if (root2.length === 0 || !existsSync43(root2)) {
|
|
103813
104054
|
throw userInputError3(`local repository path is not a Git checkout: ${path4}`, { path: path4 });
|
|
103814
104055
|
}
|
|
103815
104056
|
return realpath4(root2);
|
|
@@ -103830,13 +104071,13 @@ async function verifyCheckout(input) {
|
|
|
103830
104071
|
}
|
|
103831
104072
|
async function cloneCheckout(input) {
|
|
103832
104073
|
const target = resolve28(input.projectRoot, input.target ?? `.tmp/repo/${repositorySlug(input.remote)}-${input.ref.slice(0, 12)}`);
|
|
103833
|
-
if (
|
|
104074
|
+
if (existsSync43(target)) {
|
|
103834
104075
|
throw userInputError3(`clone target already exists: ${target}`, {
|
|
103835
104076
|
target,
|
|
103836
104077
|
next: `Use local mode with path ${JSON.stringify(target)} after inspecting the existing checkout.`
|
|
103837
104078
|
});
|
|
103838
104079
|
}
|
|
103839
|
-
await mkdir31(
|
|
104080
|
+
await mkdir31(dirname41(target), { recursive: true });
|
|
103840
104081
|
const cloneArgs = ["clone", "--no-checkout", "--depth=1", "--filter=blob:none", input.remote, target];
|
|
103841
104082
|
try {
|
|
103842
104083
|
await execFileAsync6("git", cloneArgs, { encoding: "utf8", maxBuffer: 4 * 1024 * 1024 });
|
|
@@ -103885,7 +104126,7 @@ async function bindLocalAlias(input) {
|
|
|
103885
104126
|
const stats = await lstat3(alias).catch(() => null);
|
|
103886
104127
|
if (stats !== null) {
|
|
103887
104128
|
if (stats.isSymbolicLink()) {
|
|
103888
|
-
const actual = resolve28(
|
|
104129
|
+
const actual = resolve28(dirname41(alias), await readlink2(alias));
|
|
103889
104130
|
const actualReal = await realpath4(actual).catch(() => null);
|
|
103890
104131
|
if (actualReal !== null && actualReal === await realpath4(input.checkout))
|
|
103891
104132
|
return;
|
|
@@ -103901,8 +104142,8 @@ async function bindLocalAlias(input) {
|
|
|
103901
104142
|
});
|
|
103902
104143
|
}
|
|
103903
104144
|
}
|
|
103904
|
-
await mkdir31(
|
|
103905
|
-
await symlink2(relative20(
|
|
104145
|
+
await mkdir31(dirname41(alias), { recursive: true });
|
|
104146
|
+
await symlink2(relative20(dirname41(alias), input.checkout) || ".", alias);
|
|
103906
104147
|
}
|
|
103907
104148
|
function selectPhysicalGroup(sources, selector) {
|
|
103908
104149
|
const direct = selectRepoSources(sources, selector);
|
|
@@ -103989,13 +104230,13 @@ async function restoreRepositorySources(input) {
|
|
|
103989
104230
|
}
|
|
103990
104231
|
|
|
103991
104232
|
// src/project/sourceDocumentStatus.ts
|
|
103992
|
-
import { existsSync as
|
|
104233
|
+
import { existsSync as existsSync44 } from "node:fs";
|
|
103993
104234
|
import { readFile as readFile51 } from "node:fs/promises";
|
|
103994
|
-
import { join as
|
|
104235
|
+
import { join as join70 } from "node:path";
|
|
103995
104236
|
|
|
103996
104237
|
// src/project/sourceCommandViews.ts
|
|
103997
104238
|
import { readFile as readFile50 } from "node:fs/promises";
|
|
103998
|
-
import { join as
|
|
104239
|
+
import { join as join69 } from "node:path";
|
|
103999
104240
|
init_workspace();
|
|
104000
104241
|
function repoSourceAgentView(source2) {
|
|
104001
104242
|
return {
|
|
@@ -104057,7 +104298,7 @@ async function fileSourceAgentViewWithNextAction(input) {
|
|
|
104057
104298
|
};
|
|
104058
104299
|
}
|
|
104059
104300
|
function documentSourceManifestPath(source2) {
|
|
104060
|
-
return source2.snapshot?.manifest ??
|
|
104301
|
+
return source2.snapshot?.manifest ?? join69(source2.materializedAt, "manifest.json");
|
|
104061
104302
|
}
|
|
104062
104303
|
async function fileSourceDocumentSiteHint(input) {
|
|
104063
104304
|
const detection = await detectDocumentSiteFiles({
|
|
@@ -104067,7 +104308,7 @@ async function fileSourceDocumentSiteHint(input) {
|
|
|
104067
104308
|
let snapshotConfigured = false;
|
|
104068
104309
|
const manifest = documentSourceManifestPath(input.source);
|
|
104069
104310
|
try {
|
|
104070
|
-
const parsed = parseDocumentSnapshotForSource(JSON.parse(await readFile50(
|
|
104311
|
+
const parsed = parseDocumentSnapshotForSource(JSON.parse(await readFile50(join69(input.projectRoot, manifest), "utf8")), input.source.name);
|
|
104071
104312
|
snapshotConfigured = manifestUsesMdxJsonDocs(parsed);
|
|
104072
104313
|
} catch {
|
|
104073
104314
|
snapshotConfigured = false;
|
|
@@ -104098,12 +104339,12 @@ async function larkSourceAgentViewWithNextAction(input) {
|
|
|
104098
104339
|
|
|
104099
104340
|
// src/project/sourceDocumentStatus.ts
|
|
104100
104341
|
function documentSourceManifestPath2(source2) {
|
|
104101
|
-
return source2.snapshot?.manifest ??
|
|
104342
|
+
return source2.snapshot?.manifest ?? join70(source2.materializedAt, "manifest.json");
|
|
104102
104343
|
}
|
|
104103
104344
|
async function documentSnapshotState(input) {
|
|
104104
104345
|
const manifest = documentSourceManifestPath2(input.source);
|
|
104105
|
-
const manifestPath =
|
|
104106
|
-
if (!
|
|
104346
|
+
const manifestPath = join70(input.projectRoot, manifest);
|
|
104347
|
+
if (!existsSync44(manifestPath)) {
|
|
104107
104348
|
return {
|
|
104108
104349
|
snapshotReady: false,
|
|
104109
104350
|
state: "needs-capture",
|
|
@@ -104181,7 +104422,7 @@ async function documentSnapshotState(input) {
|
|
|
104181
104422
|
const missing = [
|
|
104182
104423
|
...parsed.files.map((file) => file.path),
|
|
104183
104424
|
...(parsed.assets ?? []).filter((asset) => asset.content_hash !== undefined).map((asset) => asset.path)
|
|
104184
|
-
].find((path4) => !
|
|
104425
|
+
].find((path4) => !existsSync44(join70(input.projectRoot, input.source.materializedAt, path4)));
|
|
104185
104426
|
if (missing !== undefined) {
|
|
104186
104427
|
return {
|
|
104187
104428
|
snapshotReady: false,
|
|
@@ -104253,7 +104494,7 @@ async function inspectDocumentSources(input) {
|
|
|
104253
104494
|
// src/project/documentSourceRegistration.ts
|
|
104254
104495
|
import { createHash as createHash27 } from "node:crypto";
|
|
104255
104496
|
import { readFile as readFile52, realpath as realpath5 } from "node:fs/promises";
|
|
104256
|
-
import { basename as basename12, extname as extname13, isAbsolute as isAbsolute13, join as
|
|
104497
|
+
import { basename as basename12, extname as extname13, isAbsolute as isAbsolute13, join as join71, relative as relative21, resolve as resolve29 } from "node:path";
|
|
104257
104498
|
init_atomicWrite();
|
|
104258
104499
|
init_cliFeedback();
|
|
104259
104500
|
init_errors();
|
|
@@ -104354,7 +104595,7 @@ function assertSafeFileInclude(value) {
|
|
|
104354
104595
|
}
|
|
104355
104596
|
async function readRegistryDocument(projectRoot, registryPath2) {
|
|
104356
104597
|
try {
|
|
104357
|
-
const content3 = await readFile52(
|
|
104598
|
+
const content3 = await readFile52(join71(projectRoot, registryPath2), "utf8");
|
|
104358
104599
|
return content3.trim().length === 0 ? { sources: [] } : import_yaml33.default.parse(content3);
|
|
104359
104600
|
} catch (error) {
|
|
104360
104601
|
if (error instanceof Error && "code" in error && error.code === "ENOENT")
|
|
@@ -104472,7 +104713,7 @@ async function addFileSourceUnlocked(input) {
|
|
|
104472
104713
|
const record2 = entry2;
|
|
104473
104714
|
return record2.name !== input.name && record2.id !== input.name;
|
|
104474
104715
|
}), nextEntry];
|
|
104475
|
-
await atomicWriteFile(
|
|
104716
|
+
await atomicWriteFile(join71(input.projectRoot, DEFAULT_FILE_SOURCES_REGISTRY_PATH), import_yaml33.default.stringify({ sources: nextSources }));
|
|
104476
104717
|
const updated = await loadSourcesRegistry({ rootDir: input.projectRoot });
|
|
104477
104718
|
const entry = updated.files.find((source2) => source2.name === input.name || source2.id === input.name);
|
|
104478
104719
|
if (entry === undefined) {
|
|
@@ -104528,7 +104769,7 @@ async function addLarkSourceUnlocked(input) {
|
|
|
104528
104769
|
const record2 = entry2;
|
|
104529
104770
|
return record2.name !== input.name && record2.id !== input.name;
|
|
104530
104771
|
}), nextEntry];
|
|
104531
|
-
await atomicWriteFile(
|
|
104772
|
+
await atomicWriteFile(join71(input.projectRoot, DEFAULT_LARK_SOURCES_REGISTRY_PATH), import_yaml33.default.stringify({ sources: nextSources }));
|
|
104532
104773
|
const updated = await loadSourcesRegistry({ rootDir: input.projectRoot });
|
|
104533
104774
|
const entry = updated.larks.find((source2) => source2.name === input.name || source2.id === input.name);
|
|
104534
104775
|
if (entry === undefined) {
|
|
@@ -104716,10 +104957,10 @@ async function registerSourceBatch(input) {
|
|
|
104716
104957
|
}
|
|
104717
104958
|
|
|
104718
104959
|
// src/project/sourceRemoval.ts
|
|
104719
|
-
import { existsSync as
|
|
104960
|
+
import { existsSync as existsSync45 } from "node:fs";
|
|
104720
104961
|
import { createHash as createHash28 } from "node:crypto";
|
|
104721
104962
|
import { readFile as readFile53, readdir as readdir21, rm as rm19 } from "node:fs/promises";
|
|
104722
|
-
import { isAbsolute as isAbsolute14, join as
|
|
104963
|
+
import { isAbsolute as isAbsolute14, join as join72, relative as relative22, resolve as resolve30, sep as sep6 } from "node:path";
|
|
104723
104964
|
var import_yaml34 = __toESM(require_dist3(), 1);
|
|
104724
104965
|
init_atomicWrite();
|
|
104725
104966
|
init_cliFeedback();
|
|
@@ -104758,8 +104999,8 @@ function collectStrings(value, output) {
|
|
|
104758
104999
|
}
|
|
104759
105000
|
}
|
|
104760
105001
|
async function yamlReferences(input) {
|
|
104761
|
-
const absolutePath =
|
|
104762
|
-
if (!
|
|
105002
|
+
const absolutePath = join72(input.projectRoot, input.path);
|
|
105003
|
+
if (!existsSync45(absolutePath))
|
|
104763
105004
|
return false;
|
|
104764
105005
|
const parsed = import_yaml34.default.parse(await readFile53(absolutePath, "utf8"));
|
|
104765
105006
|
const strings = [];
|
|
@@ -104866,8 +105107,8 @@ function removeDocumentEntry(document4, source2) {
|
|
|
104866
105107
|
}
|
|
104867
105108
|
async function registryRemovalWrite(projectRoot, source2) {
|
|
104868
105109
|
const path4 = registryPath2(source2.type);
|
|
104869
|
-
const absolutePath =
|
|
104870
|
-
const document4 =
|
|
105110
|
+
const absolutePath = join72(projectRoot, path4);
|
|
105111
|
+
const document4 = existsSync45(absolutePath) ? import_yaml34.default.parse(await readFile53(absolutePath, "utf8")) : { sources: [] };
|
|
104871
105112
|
return {
|
|
104872
105113
|
path: absolutePath,
|
|
104873
105114
|
bytes: import_yaml34.default.stringify(removeDocumentEntry(document4, source2))
|
|
@@ -104885,7 +105126,7 @@ function safeManagedMaterializedPath(projectRoot, source2) {
|
|
|
104885
105126
|
return absolute;
|
|
104886
105127
|
}
|
|
104887
105128
|
function safeManagedManifestPath(projectRoot, source2) {
|
|
104888
|
-
const manifest = source2.manifest ??
|
|
105129
|
+
const manifest = source2.manifest ?? join72(source2.materializedAt, "manifest.json");
|
|
104889
105130
|
if (isAbsolute14(manifest))
|
|
104890
105131
|
throw unsafeOwnership(source2, manifest);
|
|
104891
105132
|
const absolute = resolve30(projectRoot, manifest);
|
|
@@ -104991,7 +105232,7 @@ async function createRemovalPlan(projectRoot, selector) {
|
|
|
104991
105232
|
}
|
|
104992
105233
|
} else {
|
|
104993
105234
|
const materializedPath = safeManagedMaterializedPath(projectRoot, source2);
|
|
104994
|
-
if (materializedPath !== undefined && sharedMaterializedBy.length === 0 &&
|
|
105235
|
+
if (materializedPath !== undefined && sharedMaterializedBy.length === 0 && existsSync45(materializedPath)) {
|
|
104995
105236
|
absoluteRemovals.push(materializedPath);
|
|
104996
105237
|
cleanup = {
|
|
104997
105238
|
mode: "exclusive-materialization",
|
|
@@ -105037,9 +105278,9 @@ function publicRemovalResult(plan, action) {
|
|
|
105037
105278
|
};
|
|
105038
105279
|
}
|
|
105039
105280
|
async function pruneExtractRuntime(projectRoot, source2) {
|
|
105040
|
-
const fingerprintPath =
|
|
105281
|
+
const fingerprintPath = join72(projectRoot, ".tmp/context-runtime/extract/source-fingerprints.json");
|
|
105041
105282
|
const removedPhaseIds = new Set;
|
|
105042
|
-
if (
|
|
105283
|
+
if (existsSync45(fingerprintPath)) {
|
|
105043
105284
|
const parsed = JSON.parse(await readFile53(fingerprintPath, "utf8"));
|
|
105044
105285
|
const phases = parsed.phases ?? {};
|
|
105045
105286
|
const next = Object.fromEntries(Object.entries(phases).filter(([phaseId, raw]) => {
|
|
@@ -105054,20 +105295,20 @@ async function pruneExtractRuntime(projectRoot, source2) {
|
|
|
105054
105295
|
await atomicWriteFile(fingerprintPath, `${JSON.stringify({ ...parsed, phases: next }, null, 2)}
|
|
105055
105296
|
`);
|
|
105056
105297
|
}
|
|
105057
|
-
const symbolPath =
|
|
105058
|
-
if (
|
|
105298
|
+
const symbolPath = join72(projectRoot, ".tmp/context-runtime/extract/source-symbols.json");
|
|
105299
|
+
if (existsSync45(symbolPath)) {
|
|
105059
105300
|
const parsed = JSON.parse(await readFile53(symbolPath, "utf8"));
|
|
105060
105301
|
const symbols = Array.isArray(parsed.symbols) ? parsed.symbols.filter((entry) => entry === null || typeof entry !== "object" || Array.isArray(entry) || entry.source !== source2.name) : [];
|
|
105061
105302
|
const phaseFingerprints = Object.fromEntries(Object.entries(parsed.phaseFingerprints ?? {}).filter(([phaseId]) => !removedPhaseIds.has(phaseId)));
|
|
105062
105303
|
await atomicWriteFile(symbolPath, `${JSON.stringify({ ...parsed, phaseFingerprints, symbols }, null, 2)}
|
|
105063
105304
|
`);
|
|
105064
105305
|
}
|
|
105065
|
-
const snapshotRoot =
|
|
105306
|
+
const snapshotRoot = join72(projectRoot, ".tmp/context-runtime/extract/candidates");
|
|
105066
105307
|
const visit3 = async (directory) => {
|
|
105067
|
-
if (!
|
|
105308
|
+
if (!existsSync45(directory))
|
|
105068
105309
|
return;
|
|
105069
105310
|
for (const entry of await readdir21(directory, { withFileTypes: true })) {
|
|
105070
|
-
const path4 =
|
|
105311
|
+
const path4 = join72(directory, entry.name);
|
|
105071
105312
|
if (entry.isDirectory()) {
|
|
105072
105313
|
await visit3(path4);
|
|
105073
105314
|
continue;
|
|
@@ -105117,7 +105358,7 @@ async function removeProjectSource(input) {
|
|
|
105117
105358
|
});
|
|
105118
105359
|
}
|
|
105119
105360
|
await applyAtomicFileBatch({
|
|
105120
|
-
transactionRoot:
|
|
105361
|
+
transactionRoot: join72(input.projectRoot, ".tmp", "context-runtime", "source-remove-transactions"),
|
|
105121
105362
|
writes: [plan.registryWrite, ...plan.manifestWrite !== undefined ? [plan.manifestWrite] : []],
|
|
105122
105363
|
removals: plan.absoluteRemovals
|
|
105123
105364
|
});
|
|
@@ -105515,16 +105756,147 @@ the CLI derives a lowercase path-safe module and rejects duplicate batch identit
|
|
|
105515
105756
|
});
|
|
105516
105757
|
}
|
|
105517
105758
|
|
|
105759
|
+
// src/cli.ts
|
|
105760
|
+
init_debugTrace();
|
|
105761
|
+
|
|
105762
|
+
// src/registerProjectLifecycleCommands.ts
|
|
105763
|
+
init_cliFeedback();
|
|
105764
|
+
init_errors();
|
|
105765
|
+
init_workspace();
|
|
105766
|
+
init_exitCode();
|
|
105767
|
+
function registerProjectInitCommand(program2) {
|
|
105768
|
+
program2.command("init [project-dir]").description("Initialize a project-local context workspace").option("--name <name>", "display/package name override").option("--language <language>", "workspace and starter-template language: en | zh-CN").option("--dev", "initialize with the locally linked @c4a/context SDK").option("--debug", "enable workspace-local command and Agent Graph tracing").option("--allow-nonempty", "after explicit confirmation, preserve existing files and initialize inside a non-empty non-Context directory").action(async (projectDir, options) => {
|
|
105769
|
+
const targetRoot = resolveContextProjectInitTarget(process.cwd(), projectDir);
|
|
105770
|
+
const wasContextWorkspace = isContextProjectRoot(targetRoot);
|
|
105771
|
+
const result = await initContextProject({
|
|
105772
|
+
cwd: process.cwd(),
|
|
105773
|
+
...projectDir !== undefined ? { projectDir } : {},
|
|
105774
|
+
...typeof options.name === "string" ? { name: options.name } : {},
|
|
105775
|
+
...typeof options.language === "string" ? { language: projectLanguage(options.language) } : {},
|
|
105776
|
+
...options.dev === true ? { dev: true } : {},
|
|
105777
|
+
...options.debug === true ? { debug: true } : {},
|
|
105778
|
+
...options.allowNonempty === true ? { allowNonempty: true } : {}
|
|
105779
|
+
});
|
|
105780
|
+
process.stdout.write(formatProjectInitResult(result));
|
|
105781
|
+
if (!wasContextWorkspace) {
|
|
105782
|
+
queueContextRuntimeEvent({
|
|
105783
|
+
cwd: result.projectRoot,
|
|
105784
|
+
kind: "workspace.initialized",
|
|
105785
|
+
properties: {
|
|
105786
|
+
init_mode: result.kept.length > 0 ? "nonempty_existing" : "new",
|
|
105787
|
+
language: result.language,
|
|
105788
|
+
created_file_count: result.created.length
|
|
105789
|
+
}
|
|
105790
|
+
});
|
|
105791
|
+
}
|
|
105792
|
+
});
|
|
105793
|
+
}
|
|
105794
|
+
function registerProjectStatusCommand(program2) {
|
|
105795
|
+
program2.command("status").description("Print workspace overview and suggested next actions").option("--format <format>", "output format: table | json", "table").option("--view <view>", "with --format json, output view: summary | full", "summary").option("--managed", "use explicit current-conversation managed approval for this status loop").option("--resource-receipts <json-or-@file>", "current-conversation Agent Graph resource read receipts").addOption(new Option("--authority <authority>", "current-conversation scoped authority granted by the user; repeatable").argParser(collectWorkflowAuthorityOption).default([])).action(async (options) => {
|
|
105796
|
+
const rootOptions = program2.opts();
|
|
105797
|
+
const resourceReceiptsReference = typeof options.resourceReceipts === "string" ? options.resourceReceipts : typeof rootOptions.workflowResourceReceipts === "string" ? rootOptions.workflowResourceReceipts : undefined;
|
|
105798
|
+
const resourceReceipts = resourceReceiptsReference !== undefined ? await parseWorkflowResourceReceipts(resourceReceiptsReference, process.cwd()) : undefined;
|
|
105799
|
+
if (await runProjectStatusCommand({
|
|
105800
|
+
cwd: process.cwd(),
|
|
105801
|
+
format: options.format === "json" ? "json" : "table",
|
|
105802
|
+
view: options.view === "full" ? "full" : "summary",
|
|
105803
|
+
managed: options.managed === true,
|
|
105804
|
+
authorities: workflowAuthorities(options.authority),
|
|
105805
|
+
...resourceReceipts === undefined ? {} : { resourceReceipts },
|
|
105806
|
+
...resourceReceiptsReference === undefined ? {} : { resourceReceiptsReference },
|
|
105807
|
+
onSuccess: (status) => {
|
|
105808
|
+
queueContextRuntimeEvent({
|
|
105809
|
+
cwd: status.projectRoot,
|
|
105810
|
+
kind: "workspace.active",
|
|
105811
|
+
properties: { workflow_status: status.workflow.status }
|
|
105812
|
+
});
|
|
105813
|
+
}
|
|
105814
|
+
})) {
|
|
105815
|
+
return;
|
|
105816
|
+
}
|
|
105817
|
+
throw new ContextError(ExitCode.WorkspaceStateError, "status requires a context project workspace", {
|
|
105818
|
+
category: ErrorCategory.WorkspaceNotFound
|
|
105819
|
+
});
|
|
105820
|
+
});
|
|
105821
|
+
}
|
|
105822
|
+
function registerProjectCloseAndBuildCommands(program2) {
|
|
105823
|
+
program2.command("close").description("Close approved project knowledge by deriving structure and running final verification").option("--format <format>", "output format: text | json", "text").action(async (options) => {
|
|
105824
|
+
if (options.format !== "text" && options.format !== "json") {
|
|
105825
|
+
throw new ContextError(ExitCode.UserError, "--format must be text or json", {
|
|
105826
|
+
category: ErrorCategory.UserInputInvalid
|
|
105827
|
+
});
|
|
105828
|
+
}
|
|
105829
|
+
if (await runProjectCloseCommand({
|
|
105830
|
+
cwd: process.cwd(),
|
|
105831
|
+
format: options.format === "json" ? "json" : "text"
|
|
105832
|
+
})) {
|
|
105833
|
+
return;
|
|
105834
|
+
}
|
|
105835
|
+
throw new ContextError(ExitCode.WorkspaceStateError, "close requires a context project workspace", {
|
|
105836
|
+
category: ErrorCategory.WorkspaceNotFound
|
|
105837
|
+
});
|
|
105838
|
+
});
|
|
105839
|
+
program2.command("build").description("Build declared project packages").option("--format <format>", "output format: text | json", "text").option("--verbose", "include per-file build changes in JSON output").action(async (options) => {
|
|
105840
|
+
if (options.format !== "text" && options.format !== "json") {
|
|
105841
|
+
throw new ContextError(ExitCode.UserError, "--format must be text or json", {
|
|
105842
|
+
category: ErrorCategory.UserInputInvalid
|
|
105843
|
+
});
|
|
105844
|
+
}
|
|
105845
|
+
if (await runProjectBuildCommand({
|
|
105846
|
+
cwd: process.cwd(),
|
|
105847
|
+
format: options.format === "json" ? "json" : "text",
|
|
105848
|
+
verbose: options.verbose === true
|
|
105849
|
+
})) {
|
|
105850
|
+
return;
|
|
105851
|
+
}
|
|
105852
|
+
throw new ContextError(ExitCode.WorkspaceStateError, "build requires a context project workspace", {
|
|
105853
|
+
category: ErrorCategory.WorkspaceNotFound
|
|
105854
|
+
});
|
|
105855
|
+
});
|
|
105856
|
+
}
|
|
105857
|
+
function registerProjectVerifyCommand(program2) {
|
|
105858
|
+
program2.command("verify").description("Validate knowledge workspace").option("--format <format>", "output format: table | json", "table").option("--compact", "return grouped diagnostics without the complete issue list").option("--view <view>", "read a verification view: diagnostics").option("--page-size <n>", "with --view diagnostics, limit returned issues").option("--page-token <token>", "with --view diagnostics, continue pagination").action(async (options) => {
|
|
105859
|
+
if (options.format !== "table" && options.format !== "json") {
|
|
105860
|
+
throw new ContextError(ExitCode.UserError, "--format must be table or json", {
|
|
105861
|
+
category: ErrorCategory.UserInputInvalid
|
|
105862
|
+
});
|
|
105863
|
+
}
|
|
105864
|
+
if (options.view !== undefined && options.view !== "diagnostics") {
|
|
105865
|
+
throw new ContextError(ExitCode.UserError, "--view must be diagnostics", {
|
|
105866
|
+
category: ErrorCategory.UserInputInvalid
|
|
105867
|
+
});
|
|
105868
|
+
}
|
|
105869
|
+
if (options.view === "diagnostics" && options.format !== "json") {
|
|
105870
|
+
throw new ContextError(ExitCode.UserError, "--view diagnostics requires --format json", {
|
|
105871
|
+
category: ErrorCategory.UserInputInvalid
|
|
105872
|
+
});
|
|
105873
|
+
}
|
|
105874
|
+
if (await runProjectVerifyCommand({
|
|
105875
|
+
cwd: process.cwd(),
|
|
105876
|
+
format: options.format === "json" ? "json" : "table",
|
|
105877
|
+
...options.compact === true ? { compact: true } : {},
|
|
105878
|
+
...options.view === "diagnostics" ? { view: "diagnostics" } : {},
|
|
105879
|
+
...typeof options.pageSize === "string" ? { pageSize: options.pageSize } : {},
|
|
105880
|
+
...typeof options.pageToken === "string" ? { pageToken: options.pageToken } : {}
|
|
105881
|
+
})) {
|
|
105882
|
+
return;
|
|
105883
|
+
}
|
|
105884
|
+
throw new ContextError(ExitCode.WorkspaceStateError, "verify requires a context project workspace", {
|
|
105885
|
+
category: ErrorCategory.WorkspaceNotFound
|
|
105886
|
+
});
|
|
105887
|
+
});
|
|
105888
|
+
}
|
|
105889
|
+
|
|
105518
105890
|
// src/project/pluginInstall.ts
|
|
105519
105891
|
init_cliFeedback();
|
|
105520
105892
|
init_errors();
|
|
105521
105893
|
init_exitCode();
|
|
105522
|
-
import { existsSync as
|
|
105894
|
+
import { existsSync as existsSync46 } from "node:fs";
|
|
105523
105895
|
import { cp, mkdir as mkdir32, readdir as readdir22, readFile as readFile55, rename as rename5, rm as rm20, writeFile as writeFile27 } from "node:fs/promises";
|
|
105524
105896
|
import { execFile as execFile7 } from "node:child_process";
|
|
105525
105897
|
import { homedir as homedir2 } from "node:os";
|
|
105526
|
-
import { dirname as
|
|
105527
|
-
import { fileURLToPath as
|
|
105898
|
+
import { dirname as dirname42, join as join73, resolve as resolve32 } from "node:path";
|
|
105899
|
+
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
105528
105900
|
import { promisify as promisify7 } from "node:util";
|
|
105529
105901
|
var execFileAsync7 = promisify7(execFile7);
|
|
105530
105902
|
var MARKETPLACE_NAME = "c4a";
|
|
@@ -105563,10 +105935,10 @@ function pluginAgentOption(value) {
|
|
|
105563
105935
|
}
|
|
105564
105936
|
function packageCandidateDirs() {
|
|
105565
105937
|
const dirs = [];
|
|
105566
|
-
let dir =
|
|
105938
|
+
let dir = dirname42(fileURLToPath9(import.meta.url));
|
|
105567
105939
|
for (let index2 = 0;index2 < 8; index2++) {
|
|
105568
105940
|
dirs.push(dir);
|
|
105569
|
-
const parent =
|
|
105941
|
+
const parent = dirname42(dir);
|
|
105570
105942
|
if (parent === dir)
|
|
105571
105943
|
break;
|
|
105572
105944
|
dir = parent;
|
|
@@ -105579,13 +105951,13 @@ function pluginRootCandidates() {
|
|
|
105579
105951
|
return [resolve32(envRoot)];
|
|
105580
105952
|
const candidates = [];
|
|
105581
105953
|
for (const dir of packageCandidateDirs()) {
|
|
105582
|
-
candidates.push(
|
|
105583
|
-
candidates.push(
|
|
105954
|
+
candidates.push(join73(dir, "plugins"));
|
|
105955
|
+
candidates.push(join73(dir, "dist", "plugins"));
|
|
105584
105956
|
}
|
|
105585
105957
|
return [...new Set(candidates)];
|
|
105586
105958
|
}
|
|
105587
105959
|
function isInstallablePluginRoot(root2) {
|
|
105588
|
-
return
|
|
105960
|
+
return existsSync46(join73(root2, ".claude-plugin", "marketplace.json")) && existsSync46(join73(root2, ".agents", "plugins", "marketplace.json")) && existsSync46(join73(root2, "claude", ".claude-plugin", "plugin.json")) && existsSync46(join73(root2, "codex", ".codex-plugin", "plugin.json"));
|
|
105589
105961
|
}
|
|
105590
105962
|
function resolveBundledPluginsRoot() {
|
|
105591
105963
|
const candidates = pluginRootCandidates();
|
|
@@ -105650,14 +106022,14 @@ function failedAgentResult(agent, error) {
|
|
|
105650
106022
|
};
|
|
105651
106023
|
}
|
|
105652
106024
|
function codexHome() {
|
|
105653
|
-
return process.env.CODEX_HOME?.trim() ||
|
|
106025
|
+
return process.env.CODEX_HOME?.trim() || join73(homedir2(), ".codex");
|
|
105654
106026
|
}
|
|
105655
106027
|
function claudePluginCacheRoot() {
|
|
105656
106028
|
const explicitRoot = process.env[CLAUDE_PLUGIN_CACHE_ROOT_ENV2]?.trim();
|
|
105657
106029
|
if (explicitRoot)
|
|
105658
106030
|
return explicitRoot;
|
|
105659
106031
|
const home = process.env[CLAUDE_PLUGIN_CACHE_HOME_ENV2]?.trim() || homedir2();
|
|
105660
|
-
return
|
|
106032
|
+
return join73(home, ".claude", "plugins", "cache");
|
|
105661
106033
|
}
|
|
105662
106034
|
function blockHeader(line) {
|
|
105663
106035
|
const match = line.match(/^\s*\[([^\]]+)\]\s*$/u);
|
|
@@ -105708,7 +106080,7 @@ function pruneLegacyCodexConfigContent(content3) {
|
|
|
105708
106080
|
`), removed };
|
|
105709
106081
|
}
|
|
105710
106082
|
async function pruneLegacyCodexConfig(dryRun, steps) {
|
|
105711
|
-
const configPath =
|
|
106083
|
+
const configPath = join73(codexHome(), "config.toml");
|
|
105712
106084
|
const current2 = await readFile55(configPath, "utf8").catch(() => "");
|
|
105713
106085
|
if (!current2)
|
|
105714
106086
|
return;
|
|
@@ -105725,8 +106097,8 @@ async function pruneLegacyCodexConfig(dryRun, steps) {
|
|
|
105725
106097
|
}
|
|
105726
106098
|
}
|
|
105727
106099
|
async function pruneCodexPluginCacheForName(pluginName, keepVersion, dryRun, steps) {
|
|
105728
|
-
const cacheRoot =
|
|
105729
|
-
if (!
|
|
106100
|
+
const cacheRoot = join73(codexHome(), "plugins", "cache", MARKETPLACE_NAME, pluginName);
|
|
106101
|
+
if (!existsSync46(cacheRoot))
|
|
105730
106102
|
return;
|
|
105731
106103
|
const versions = (await readdir22(cacheRoot, { withFileTypes: true }).catch(() => [])).filter((entry) => entry.isDirectory() && entry.name !== keepVersion).map((entry) => entry.name).sort();
|
|
105732
106104
|
if (versions.length === 0)
|
|
@@ -105737,7 +106109,7 @@ async function pruneCodexPluginCacheForName(pluginName, keepVersion, dryRun, ste
|
|
|
105737
106109
|
status: dryRun ? "planned" : "ran"
|
|
105738
106110
|
});
|
|
105739
106111
|
if (!dryRun)
|
|
105740
|
-
await Promise.all(versions.map((version3) => rm20(
|
|
106112
|
+
await Promise.all(versions.map((version3) => rm20(join73(cacheRoot, version3), { recursive: true, force: true })));
|
|
105741
106113
|
}
|
|
105742
106114
|
async function pruneCodexPluginCache(currentVersion, dryRun, steps) {
|
|
105743
106115
|
await pruneCodexPluginCacheForName(PLUGIN_NAME, currentVersion, dryRun, steps);
|
|
@@ -105754,22 +106126,22 @@ async function isEmptyDir2(dir) {
|
|
|
105754
106126
|
}
|
|
105755
106127
|
async function pruneClaudeOrphanContextCache(dryRun, steps) {
|
|
105756
106128
|
const cacheRoot = claudePluginCacheRoot();
|
|
105757
|
-
if (!
|
|
106129
|
+
if (!existsSync46(cacheRoot))
|
|
105758
106130
|
return;
|
|
105759
106131
|
const removed = [];
|
|
105760
106132
|
const marketplaces = await readdir22(cacheRoot, { withFileTypes: true }).catch(() => []);
|
|
105761
106133
|
for (const marketplace of marketplaces) {
|
|
105762
106134
|
if (!marketplace.isDirectory())
|
|
105763
106135
|
continue;
|
|
105764
|
-
const pluginDir =
|
|
105765
|
-
if (!
|
|
106136
|
+
const pluginDir = join73(cacheRoot, marketplace.name, PLUGIN_NAME);
|
|
106137
|
+
if (!existsSync46(pluginDir))
|
|
105766
106138
|
continue;
|
|
105767
106139
|
const versions = await readdir22(pluginDir, { withFileTypes: true }).catch(() => []);
|
|
105768
106140
|
for (const version3 of versions) {
|
|
105769
106141
|
if (!version3.isDirectory())
|
|
105770
106142
|
continue;
|
|
105771
|
-
const versionDir =
|
|
105772
|
-
if (!
|
|
106143
|
+
const versionDir = join73(pluginDir, version3.name);
|
|
106144
|
+
if (!existsSync46(join73(versionDir, ORPHAN_MARKER2)))
|
|
105773
106145
|
continue;
|
|
105774
106146
|
removed.push(`${marketplace.name}/${PLUGIN_NAME}/${version3.name}`);
|
|
105775
106147
|
if (!dryRun) {
|
|
@@ -105779,7 +106151,7 @@ async function pruneClaudeOrphanContextCache(dryRun, steps) {
|
|
|
105779
106151
|
if (!dryRun && await isEmptyDir2(pluginDir)) {
|
|
105780
106152
|
await rm20(pluginDir, { recursive: true, force: true });
|
|
105781
106153
|
}
|
|
105782
|
-
const marketplaceDir =
|
|
106154
|
+
const marketplaceDir = join73(cacheRoot, marketplace.name);
|
|
105783
106155
|
if (!dryRun && await isEmptyDir2(marketplaceDir)) {
|
|
105784
106156
|
await rm20(marketplaceDir, { recursive: true, force: true });
|
|
105785
106157
|
}
|
|
@@ -105796,12 +106168,12 @@ async function pruneClaudeLegacyPluginCache(dryRun, steps) {
|
|
|
105796
106168
|
if (LEGACY_PLUGIN_NAMES.length === 0)
|
|
105797
106169
|
return;
|
|
105798
106170
|
const cacheRoot = claudePluginCacheRoot();
|
|
105799
|
-
if (!
|
|
106171
|
+
if (!existsSync46(cacheRoot))
|
|
105800
106172
|
return;
|
|
105801
106173
|
const removed = [];
|
|
105802
106174
|
for (const pluginName of LEGACY_PLUGIN_NAMES) {
|
|
105803
|
-
const pluginDir =
|
|
105804
|
-
if (!
|
|
106175
|
+
const pluginDir = join73(cacheRoot, MARKETPLACE_NAME, pluginName);
|
|
106176
|
+
if (!existsSync46(pluginDir))
|
|
105805
106177
|
continue;
|
|
105806
106178
|
removed.push(`${MARKETPLACE_NAME}/${pluginName}`);
|
|
105807
106179
|
if (!dryRun) {
|
|
@@ -105817,11 +106189,11 @@ async function pruneClaudeLegacyPluginCache(dryRun, steps) {
|
|
|
105817
106189
|
}
|
|
105818
106190
|
}
|
|
105819
106191
|
async function pruneClaudeSupersededContextCache(root2, dryRun, steps) {
|
|
105820
|
-
const manifest = await readFile55(
|
|
106192
|
+
const manifest = await readFile55(join73(root2, "claude", ".claude-plugin", "plugin.json"), "utf8").then((content3) => JSON.parse(content3)).catch(() => null);
|
|
105821
106193
|
const currentVersion = typeof manifest?.version === "string" ? manifest.version : null;
|
|
105822
106194
|
if (!currentVersion)
|
|
105823
106195
|
return;
|
|
105824
|
-
const pluginDir =
|
|
106196
|
+
const pluginDir = join73(claudePluginCacheRoot(), MARKETPLACE_NAME, PLUGIN_NAME);
|
|
105825
106197
|
const staleVersions = (await readdir22(pluginDir, { withFileTypes: true }).catch(() => [])).filter((entry) => entry.isDirectory() && entry.name !== currentVersion).map((entry) => entry.name);
|
|
105826
106198
|
if (staleVersions.length === 0)
|
|
105827
106199
|
return;
|
|
@@ -105831,7 +106203,7 @@ async function pruneClaudeSupersededContextCache(root2, dryRun, steps) {
|
|
|
105831
106203
|
status: dryRun ? "planned" : "ran"
|
|
105832
106204
|
});
|
|
105833
106205
|
if (!dryRun) {
|
|
105834
|
-
await Promise.all(staleVersions.map((version3) => rm20(
|
|
106206
|
+
await Promise.all(staleVersions.map((version3) => rm20(join73(pluginDir, version3), { recursive: true, force: true })));
|
|
105835
106207
|
}
|
|
105836
106208
|
}
|
|
105837
106209
|
function enableCodexPluginConfig(content3) {
|
|
@@ -105895,8 +106267,8 @@ source = ${JSON.stringify(root2)}
|
|
|
105895
106267
|
`;
|
|
105896
106268
|
}
|
|
105897
106269
|
async function ensureCodexPluginEnabled() {
|
|
105898
|
-
const configPath =
|
|
105899
|
-
await mkdir32(
|
|
106270
|
+
const configPath = join73(codexHome(), "config.toml");
|
|
106271
|
+
await mkdir32(dirname42(configPath), { recursive: true });
|
|
105900
106272
|
const current2 = await readFile55(configPath, "utf8").catch(() => "");
|
|
105901
106273
|
const next = enableCodexPluginConfig(current2);
|
|
105902
106274
|
if (next !== current2) {
|
|
@@ -105904,8 +106276,8 @@ async function ensureCodexPluginEnabled() {
|
|
|
105904
106276
|
}
|
|
105905
106277
|
}
|
|
105906
106278
|
async function ensureCodexLocalMarketplace(root2) {
|
|
105907
|
-
const configPath =
|
|
105908
|
-
await mkdir32(
|
|
106279
|
+
const configPath = join73(codexHome(), "config.toml");
|
|
106280
|
+
await mkdir32(dirname42(configPath), { recursive: true });
|
|
105909
106281
|
const current2 = await readFile55(configPath, "utf8").catch(() => "");
|
|
105910
106282
|
const next = upsertCodexLocalMarketplaceConfig(current2, root2);
|
|
105911
106283
|
if (next !== current2) {
|
|
@@ -105913,7 +106285,7 @@ async function ensureCodexLocalMarketplace(root2) {
|
|
|
105913
106285
|
}
|
|
105914
106286
|
}
|
|
105915
106287
|
async function codexPluginVersion(root2) {
|
|
105916
|
-
const manifestPath =
|
|
106288
|
+
const manifestPath = join73(root2, "codex", ".codex-plugin", "plugin.json");
|
|
105917
106289
|
const manifest = JSON.parse(await readFile55(manifestPath, "utf8"));
|
|
105918
106290
|
if (typeof manifest.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/u.test(manifest.version)) {
|
|
105919
106291
|
throw new Error(`Codex plugin manifest has an invalid version: ${manifestPath}`);
|
|
@@ -105921,10 +106293,10 @@ async function codexPluginVersion(root2) {
|
|
|
105921
106293
|
return manifest.version;
|
|
105922
106294
|
}
|
|
105923
106295
|
function codexPluginCacheDir(version3) {
|
|
105924
|
-
return
|
|
106296
|
+
return join73(codexHome(), "plugins", "cache", MARKETPLACE_NAME, PLUGIN_NAME, version3);
|
|
105925
106297
|
}
|
|
105926
106298
|
async function materializeCodexPluginCache(root2, version3, dryRun, steps) {
|
|
105927
|
-
const source2 =
|
|
106299
|
+
const source2 = join73(root2, "codex");
|
|
105928
106300
|
const target = codexPluginCacheDir(version3);
|
|
105929
106301
|
steps.push({
|
|
105930
106302
|
agent: "codex",
|
|
@@ -105933,12 +106305,12 @@ async function materializeCodexPluginCache(root2, version3, dryRun, steps) {
|
|
|
105933
106305
|
});
|
|
105934
106306
|
if (dryRun)
|
|
105935
106307
|
return;
|
|
105936
|
-
await mkdir32(
|
|
106308
|
+
await mkdir32(dirname42(target), { recursive: true });
|
|
105937
106309
|
const temporary = `${target}.tmp-${process.pid}-${Date.now()}`;
|
|
105938
106310
|
const previous3 = `${target}.previous-${process.pid}-${Date.now()}`;
|
|
105939
106311
|
await rm20(temporary, { recursive: true, force: true });
|
|
105940
106312
|
await cp(source2, temporary, { recursive: true, force: true });
|
|
105941
|
-
const hadPrevious =
|
|
106313
|
+
const hadPrevious = existsSync46(target);
|
|
105942
106314
|
try {
|
|
105943
106315
|
if (hadPrevious)
|
|
105944
106316
|
await rename5(target, previous3);
|
|
@@ -105947,7 +106319,7 @@ async function materializeCodexPluginCache(root2, version3, dryRun, steps) {
|
|
|
105947
106319
|
await rm20(previous3, { recursive: true, force: true });
|
|
105948
106320
|
} catch (error) {
|
|
105949
106321
|
await rm20(temporary, { recursive: true, force: true });
|
|
105950
|
-
if (hadPrevious && !
|
|
106322
|
+
if (hadPrevious && !existsSync46(target) && existsSync46(previous3))
|
|
105951
106323
|
await rename5(previous3, target);
|
|
105952
106324
|
throw error;
|
|
105953
106325
|
}
|
|
@@ -105982,12 +106354,12 @@ async function installCodex(root2, dryRun, steps) {
|
|
|
105982
106354
|
steps.push({ agent: "codex", command: commandLine("codex", addArgs), status: dryRun ? "planned" : "ran" });
|
|
105983
106355
|
steps.push({
|
|
105984
106356
|
agent: "codex",
|
|
105985
|
-
command: `ensure ${shellQuote9(
|
|
106357
|
+
command: `ensure ${shellQuote9(join73(codexHome(), "config.toml"))} registers local marketplace ${shellQuote9(MARKETPLACE_NAME)}`,
|
|
105986
106358
|
status: dryRun ? "planned" : "ran"
|
|
105987
106359
|
});
|
|
105988
106360
|
steps.push({
|
|
105989
106361
|
agent: "codex",
|
|
105990
|
-
command: `ensure ${shellQuote9(
|
|
106362
|
+
command: `ensure ${shellQuote9(join73(codexHome(), "config.toml"))} enables ${shellQuote9(PLUGIN_ID)}`,
|
|
105991
106363
|
status: dryRun ? "planned" : "ran"
|
|
105992
106364
|
});
|
|
105993
106365
|
if (dryRun) {
|
|
@@ -106098,8 +106470,75 @@ function formatPluginInstallResult(result) {
|
|
|
106098
106470
|
});
|
|
106099
106471
|
}
|
|
106100
106472
|
|
|
106473
|
+
// src/registerPluginCommands.ts
|
|
106474
|
+
function registerPluginCommands(program2) {
|
|
106475
|
+
const plugin = program2.command("plugin").description("Install or inspect global Context agent plugins");
|
|
106476
|
+
plugin.command("path").description("Print the bundled plugin marketplace root used by `context plugin install`").action(async () => {
|
|
106477
|
+
process.stdout.write(formatPluginPathResult(await runPluginPathCommand()));
|
|
106478
|
+
});
|
|
106479
|
+
plugin.command("status").description("Inspect the bundled plugin marketplace root and global agent availability").option("--agent <agent>", "agent target: claude | codex | all", "all").action(async (options) => {
|
|
106480
|
+
const agent = pluginAgentOption(options.agent);
|
|
106481
|
+
process.stdout.write(formatPluginStatusResult(await runPluginStatusCommand({ agent })));
|
|
106482
|
+
});
|
|
106483
|
+
plugin.command("install").description("Install the bundled Context plugin globally for Claude and/or Codex").option("--agent <agent>", "agent target: claude | codex | all", "all").option("--dry-run", "Print install commands without mutating global agent config").action(async (options) => {
|
|
106484
|
+
const agent = pluginAgentOption(options.agent);
|
|
106485
|
+
const result = await runPluginInstallCommand({
|
|
106486
|
+
agent,
|
|
106487
|
+
dryRun: options.dryRun === true
|
|
106488
|
+
});
|
|
106489
|
+
process.stdout.write(formatPluginInstallResult(result));
|
|
106490
|
+
});
|
|
106491
|
+
}
|
|
106492
|
+
|
|
106493
|
+
// src/registerPackageCommands.ts
|
|
106494
|
+
init_cliFeedback();
|
|
106495
|
+
init_errors();
|
|
106496
|
+
init_packageTemplateReview();
|
|
106497
|
+
init_workspace();
|
|
106498
|
+
init_exitCode();
|
|
106499
|
+
function registerPackageCommands(program2) {
|
|
106500
|
+
const packageCommand = program2.command("package").description("Inspect or resolve package output configuration");
|
|
106501
|
+
const packageTemplate = packageCommand.command("template").description("Manage package template review state");
|
|
106502
|
+
packageTemplate.command("accept [package-name]").description("Explicitly accept an unchanged generated starter template").option("--all", "accept all unchanged generated starter templates").option("--format <format>", "output format: text | json", "text").action(async (packageName, options) => {
|
|
106503
|
+
if (packageName === undefined === (options.all !== true)) {
|
|
106504
|
+
throw new ContextError(ExitCode.UserError, "provide one package name or --all", { category: ErrorCategory.UserInputInvalid });
|
|
106505
|
+
}
|
|
106506
|
+
if (options.format !== "text" && options.format !== "json") {
|
|
106507
|
+
throw new ContextError(ExitCode.UserError, "--format must be text or json", {
|
|
106508
|
+
category: ErrorCategory.UserInputInvalid
|
|
106509
|
+
});
|
|
106510
|
+
}
|
|
106511
|
+
const found = findContextProjectRoot(process.cwd());
|
|
106512
|
+
if (!found) {
|
|
106513
|
+
throw new ContextError(ExitCode.WorkspaceStateError, "package template acceptance requires a context project workspace", { category: ErrorCategory.WorkspaceNotFound });
|
|
106514
|
+
}
|
|
106515
|
+
const result = await acceptStarterPackageTemplates({
|
|
106516
|
+
projectRoot: found.projectRoot,
|
|
106517
|
+
...packageName === undefined ? {} : { packageNames: [packageName] }
|
|
106518
|
+
});
|
|
106519
|
+
if (options.format === "json") {
|
|
106520
|
+
process.stdout.write(`${JSON.stringify({
|
|
106521
|
+
action: "package-template-accepted",
|
|
106522
|
+
...result,
|
|
106523
|
+
next_action: {
|
|
106524
|
+
kind: "reevaluate-workspace",
|
|
106525
|
+
command: "context status --format json"
|
|
106526
|
+
}
|
|
106527
|
+
}, null, 2)}
|
|
106528
|
+
`);
|
|
106529
|
+
} else {
|
|
106530
|
+
process.stdout.write(formatFeedback({
|
|
106531
|
+
symbol: "✓",
|
|
106532
|
+
action: "accepted",
|
|
106533
|
+
subject: result.accepted.join(", ") || "package templates",
|
|
106534
|
+
headline: "starter package template",
|
|
106535
|
+
body: result.alreadyResolved.length === 0 ? [] : [`already resolved: ${result.alreadyResolved.join(", ")}`]
|
|
106536
|
+
}));
|
|
106537
|
+
}
|
|
106538
|
+
});
|
|
106539
|
+
}
|
|
106540
|
+
|
|
106101
106541
|
// src/cli.ts
|
|
106102
|
-
init_debugTrace();
|
|
106103
106542
|
var TOP_LEVEL_COMMANDS = new Set([
|
|
106104
106543
|
"init",
|
|
106105
106544
|
"plugin",
|
|
@@ -106135,14 +106574,14 @@ function inferErrorCategory(message) {
|
|
|
106135
106574
|
}
|
|
106136
106575
|
function readPackageVersion() {
|
|
106137
106576
|
try {
|
|
106138
|
-
let dir =
|
|
106577
|
+
let dir = dirname43(fileURLToPath10(import.meta.url));
|
|
106139
106578
|
for (let i2 = 0;i2 < 8; i2++) {
|
|
106140
|
-
const pkg =
|
|
106141
|
-
if (
|
|
106142
|
-
const parsed = JSON.parse(
|
|
106579
|
+
const pkg = join74(dir, "package.json");
|
|
106580
|
+
if (existsSync47(pkg)) {
|
|
106581
|
+
const parsed = JSON.parse(readFileSync10(pkg, "utf8"));
|
|
106143
106582
|
return parsed.version ?? "unknown";
|
|
106144
106583
|
}
|
|
106145
|
-
const parent =
|
|
106584
|
+
const parent = dirname43(dir);
|
|
106146
106585
|
if (parent === dir)
|
|
106147
106586
|
break;
|
|
106148
106587
|
dir = parent;
|
|
@@ -106152,21 +106591,21 @@ function readPackageVersion() {
|
|
|
106152
106591
|
}
|
|
106153
106592
|
function readQuickstartPath() {
|
|
106154
106593
|
try {
|
|
106155
|
-
let dir =
|
|
106594
|
+
let dir = dirname43(fileURLToPath10(import.meta.url));
|
|
106156
106595
|
for (let i2 = 0;i2 < 8; i2++) {
|
|
106157
|
-
const candidate =
|
|
106158
|
-
if (
|
|
106596
|
+
const candidate = join74(dir, "docs", "quickstart.md");
|
|
106597
|
+
if (existsSync47(candidate))
|
|
106159
106598
|
return candidate;
|
|
106160
|
-
const pkg =
|
|
106161
|
-
if (
|
|
106599
|
+
const pkg = join74(dir, "package.json");
|
|
106600
|
+
if (existsSync47(pkg))
|
|
106162
106601
|
return candidate;
|
|
106163
|
-
const parent =
|
|
106602
|
+
const parent = dirname43(dir);
|
|
106164
106603
|
if (parent === dir)
|
|
106165
106604
|
break;
|
|
106166
106605
|
dir = parent;
|
|
106167
106606
|
}
|
|
106168
106607
|
} catch {}
|
|
106169
|
-
return
|
|
106608
|
+
return join74(dirname43(fileURLToPath10(import.meta.url)), "docs", "quickstart.md");
|
|
106170
106609
|
}
|
|
106171
106610
|
var GREEN = "\x1B[32m";
|
|
106172
106611
|
var RESET = "\x1B[0m";
|
|
@@ -106251,94 +106690,12 @@ function createCliProgram() {
|
|
|
106251
106690
|
});
|
|
106252
106691
|
const baseHelpInformation = program2.helpInformation.bind(program2);
|
|
106253
106692
|
program2.helpInformation = () => `${headerHelpText()}${baseHelpInformation()}${quickstartHelpText()}`;
|
|
106254
|
-
program2
|
|
106255
|
-
|
|
106256
|
-
cwd: process.cwd(),
|
|
106257
|
-
...projectDir !== undefined ? { projectDir } : {},
|
|
106258
|
-
...typeof options.name === "string" ? { name: options.name } : {},
|
|
106259
|
-
...typeof options.language === "string" ? { language: projectLanguage(options.language) } : {},
|
|
106260
|
-
...options.dev === true ? { dev: true } : {},
|
|
106261
|
-
...options.debug === true ? { debug: true } : {},
|
|
106262
|
-
...options.allowNonempty === true ? { allowNonempty: true } : {}
|
|
106263
|
-
});
|
|
106264
|
-
process.stdout.write(formatProjectInitResult(result));
|
|
106265
|
-
});
|
|
106266
|
-
const plugin = program2.command("plugin").description("Install or inspect global Context agent plugins");
|
|
106693
|
+
registerProjectInitCommand(program2);
|
|
106694
|
+
registerPluginCommands(program2);
|
|
106267
106695
|
registerDebugCommands(program2);
|
|
106268
|
-
plugin.command("path").description("Print the bundled plugin marketplace root used by `context plugin install`").action(async () => {
|
|
106269
|
-
process.stdout.write(formatPluginPathResult(await runPluginPathCommand()));
|
|
106270
|
-
});
|
|
106271
|
-
plugin.command("status").description("Inspect the bundled plugin marketplace root and global agent availability").option("--agent <agent>", "agent target: claude | codex | all", "all").action(async (options) => {
|
|
106272
|
-
const agent = pluginAgentOption(options.agent);
|
|
106273
|
-
process.stdout.write(formatPluginStatusResult(await runPluginStatusCommand({ agent })));
|
|
106274
|
-
});
|
|
106275
|
-
plugin.command("install").description("Install the bundled Context plugin globally for Claude and/or Codex").option("--agent <agent>", "agent target: claude | codex | all", "all").option("--dry-run", "Print install commands without mutating global agent config").action(async (options) => {
|
|
106276
|
-
const agent = pluginAgentOption(options.agent);
|
|
106277
|
-
const result = await runPluginInstallCommand({
|
|
106278
|
-
agent,
|
|
106279
|
-
dryRun: options.dryRun === true
|
|
106280
|
-
});
|
|
106281
|
-
process.stdout.write(formatPluginInstallResult(result));
|
|
106282
|
-
});
|
|
106283
106696
|
registerContextWorkflowResourceCommands(program2);
|
|
106284
|
-
|
|
106285
|
-
|
|
106286
|
-
packageTemplate.command("accept [package-name]").description("Explicitly accept an unchanged generated starter template").option("--all", "accept all unchanged generated starter templates").option("--format <format>", "output format: text | json", "text").action(async (packageName, options) => {
|
|
106287
|
-
if (packageName === undefined === (options.all !== true)) {
|
|
106288
|
-
throw new ContextError(ExitCode.UserError, "provide one package name or --all", { category: ErrorCategory.UserInputInvalid });
|
|
106289
|
-
}
|
|
106290
|
-
if (options.format !== "text" && options.format !== "json") {
|
|
106291
|
-
throw new ContextError(ExitCode.UserError, "--format must be text or json", {
|
|
106292
|
-
category: ErrorCategory.UserInputInvalid
|
|
106293
|
-
});
|
|
106294
|
-
}
|
|
106295
|
-
const found = findContextProjectRoot(process.cwd());
|
|
106296
|
-
if (!found) {
|
|
106297
|
-
throw new ContextError(ExitCode.WorkspaceStateError, "package template acceptance requires a context project workspace", { category: ErrorCategory.WorkspaceNotFound });
|
|
106298
|
-
}
|
|
106299
|
-
const result = await acceptStarterPackageTemplates({
|
|
106300
|
-
projectRoot: found.projectRoot,
|
|
106301
|
-
...packageName === undefined ? {} : { packageNames: [packageName] }
|
|
106302
|
-
});
|
|
106303
|
-
if (options.format === "json") {
|
|
106304
|
-
process.stdout.write(`${JSON.stringify({
|
|
106305
|
-
action: "package-template-accepted",
|
|
106306
|
-
...result,
|
|
106307
|
-
next_action: {
|
|
106308
|
-
kind: "reevaluate-workspace",
|
|
106309
|
-
command: "context status --format json"
|
|
106310
|
-
}
|
|
106311
|
-
}, null, 2)}
|
|
106312
|
-
`);
|
|
106313
|
-
} else {
|
|
106314
|
-
process.stdout.write(formatFeedback({
|
|
106315
|
-
symbol: "✓",
|
|
106316
|
-
action: "accepted",
|
|
106317
|
-
subject: result.accepted.join(", ") || "package templates",
|
|
106318
|
-
headline: "starter package template",
|
|
106319
|
-
body: result.alreadyResolved.length === 0 ? [] : [`already resolved: ${result.alreadyResolved.join(", ")}`]
|
|
106320
|
-
}));
|
|
106321
|
-
}
|
|
106322
|
-
});
|
|
106323
|
-
program2.command("status").description("Print workspace overview and suggested next actions").option("--format <format>", "output format: table | json", "table").option("--view <view>", "with --format json, output view: summary | full", "summary").option("--managed", "use explicit current-conversation managed approval for this status loop").option("--resource-receipts <json-or-@file>", "current-conversation Agent Graph resource read receipts").addOption(new Option("--authority <authority>", "current-conversation scoped authority granted by the user; repeatable").argParser(collectWorkflowAuthorityOption).default([])).action(async (options) => {
|
|
106324
|
-
const rootOptions = program2.opts();
|
|
106325
|
-
const resourceReceiptsReference = typeof options.resourceReceipts === "string" ? options.resourceReceipts : typeof rootOptions.workflowResourceReceipts === "string" ? rootOptions.workflowResourceReceipts : undefined;
|
|
106326
|
-
const resourceReceipts = resourceReceiptsReference !== undefined ? await parseWorkflowResourceReceipts(resourceReceiptsReference, process.cwd()) : undefined;
|
|
106327
|
-
if (await runProjectStatusCommand({
|
|
106328
|
-
cwd: process.cwd(),
|
|
106329
|
-
format: options.format === "json" ? "json" : "table",
|
|
106330
|
-
view: options.view === "full" ? "full" : "summary",
|
|
106331
|
-
managed: options.managed === true,
|
|
106332
|
-
authorities: workflowAuthorities(options.authority),
|
|
106333
|
-
...resourceReceipts === undefined ? {} : { resourceReceipts },
|
|
106334
|
-
...resourceReceiptsReference === undefined ? {} : { resourceReceiptsReference }
|
|
106335
|
-
})) {
|
|
106336
|
-
return;
|
|
106337
|
-
}
|
|
106338
|
-
throw new ContextError(ExitCode.WorkspaceStateError, "status requires a context project workspace", {
|
|
106339
|
-
category: ErrorCategory.WorkspaceNotFound
|
|
106340
|
-
});
|
|
106341
|
-
});
|
|
106697
|
+
registerPackageCommands(program2);
|
|
106698
|
+
registerProjectStatusCommand(program2);
|
|
106342
106699
|
registerProjectRunCommand(program2, import.meta.url);
|
|
106343
106700
|
const review = program2.command("review").description("Review draft project candidates and apply approval decisions");
|
|
106344
106701
|
review.command("html [collection]").description("Render a self-contained local review HTML page").option("--all", "review all draft candidates across internal collections").option("--out <file>", "output HTML path, defaults to .tmp/context-runtime/review/<collection>.html").option("--open", "open the generated HTML with the system default browser").option("--format <format>", "output format: text | json", "text").action(async (collection, options) => {
|
|
@@ -106486,70 +106843,9 @@ function createCliProgram() {
|
|
|
106486
106843
|
format: options.format === "json" ? "json" : "text"
|
|
106487
106844
|
});
|
|
106488
106845
|
});
|
|
106489
|
-
program2
|
|
106490
|
-
if (options.format !== "text" && options.format !== "json") {
|
|
106491
|
-
throw new ContextError(ExitCode.UserError, "--format must be text or json", {
|
|
106492
|
-
category: ErrorCategory.UserInputInvalid
|
|
106493
|
-
});
|
|
106494
|
-
}
|
|
106495
|
-
if (await runProjectCloseCommand({
|
|
106496
|
-
cwd: process.cwd(),
|
|
106497
|
-
format: options.format === "json" ? "json" : "text"
|
|
106498
|
-
})) {
|
|
106499
|
-
return;
|
|
106500
|
-
}
|
|
106501
|
-
throw new ContextError(ExitCode.WorkspaceStateError, "close requires a context project workspace", {
|
|
106502
|
-
category: ErrorCategory.WorkspaceNotFound
|
|
106503
|
-
});
|
|
106504
|
-
});
|
|
106505
|
-
program2.command("build").description("Build declared project packages").option("--format <format>", "output format: text | json", "text").option("--verbose", "include per-file build changes in JSON output").action(async (options) => {
|
|
106506
|
-
if (options.format !== "text" && options.format !== "json") {
|
|
106507
|
-
throw new ContextError(ExitCode.UserError, "--format must be text or json", {
|
|
106508
|
-
category: ErrorCategory.UserInputInvalid
|
|
106509
|
-
});
|
|
106510
|
-
}
|
|
106511
|
-
if (await runProjectBuildCommand({
|
|
106512
|
-
cwd: process.cwd(),
|
|
106513
|
-
format: options.format === "json" ? "json" : "text",
|
|
106514
|
-
verbose: options.verbose === true
|
|
106515
|
-
})) {
|
|
106516
|
-
return;
|
|
106517
|
-
}
|
|
106518
|
-
throw new ContextError(ExitCode.WorkspaceStateError, "build requires a context project workspace", {
|
|
106519
|
-
category: ErrorCategory.WorkspaceNotFound
|
|
106520
|
-
});
|
|
106521
|
-
});
|
|
106846
|
+
registerProjectCloseAndBuildCommands(program2);
|
|
106522
106847
|
registerProjectSourceCommands(program2);
|
|
106523
|
-
program2
|
|
106524
|
-
if (options.format !== "table" && options.format !== "json") {
|
|
106525
|
-
throw new ContextError(ExitCode.UserError, "--format must be table or json", {
|
|
106526
|
-
category: ErrorCategory.UserInputInvalid
|
|
106527
|
-
});
|
|
106528
|
-
}
|
|
106529
|
-
if (options.view !== undefined && options.view !== "diagnostics") {
|
|
106530
|
-
throw new ContextError(ExitCode.UserError, "--view must be diagnostics", {
|
|
106531
|
-
category: ErrorCategory.UserInputInvalid
|
|
106532
|
-
});
|
|
106533
|
-
}
|
|
106534
|
-
if (options.view === "diagnostics" && options.format !== "json") {
|
|
106535
|
-
throw new ContextError(ExitCode.UserError, "--view diagnostics requires --format json", {
|
|
106536
|
-
category: ErrorCategory.UserInputInvalid
|
|
106537
|
-
});
|
|
106538
|
-
}
|
|
106539
|
-
if (await runProjectVerifyCommand({
|
|
106540
|
-
cwd: process.cwd(),
|
|
106541
|
-
format: options.format === "json" ? "json" : "table",
|
|
106542
|
-
...options.compact === true ? { compact: true } : {},
|
|
106543
|
-
...options.view === "diagnostics" ? { view: "diagnostics" } : {},
|
|
106544
|
-
...typeof options.pageSize === "string" ? { pageSize: options.pageSize } : {},
|
|
106545
|
-
...typeof options.pageToken === "string" ? { pageToken: options.pageToken } : {}
|
|
106546
|
-
})) {
|
|
106547
|
-
return;
|
|
106548
|
-
}
|
|
106549
|
-
throw new ContextError(ExitCode.WorkspaceStateError, "verify requires a context project workspace", {
|
|
106550
|
-
category: ErrorCategory.WorkspaceNotFound
|
|
106551
|
-
});
|
|
106552
|
-
});
|
|
106848
|
+
registerProjectVerifyCommand(program2);
|
|
106553
106849
|
const cleanCacheAction = async (options) => {
|
|
106554
106850
|
const dryRun = options.dryRun === true;
|
|
106555
106851
|
await runDoctorCleanClaudePluginCache({ dryRun });
|
|
@@ -106581,10 +106877,12 @@ function createCliProgram() {
|
|
|
106581
106877
|
return program2;
|
|
106582
106878
|
}
|
|
106583
106879
|
async function cli_main(argv = process.argv) {
|
|
106584
|
-
await
|
|
106585
|
-
|
|
106586
|
-
|
|
106587
|
-
|
|
106880
|
+
await withContextRuntimeEventDelivery(async () => {
|
|
106881
|
+
await withDebugCliInvocation(argv, async () => {
|
|
106882
|
+
assertKnownTopLevelCommand(argv);
|
|
106883
|
+
const program2 = createCliProgram();
|
|
106884
|
+
await program2.parseAsync(argv);
|
|
106885
|
+
});
|
|
106588
106886
|
});
|
|
106589
106887
|
}
|
|
106590
106888
|
function isDirectCliInvocation(metaUrl, argv1) {
|