@c4a/context-cli 0.6.4 → 0.6.6
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 +989 -733
- 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 +5 -5
- package/providers/context/provider.yaml +1 -1
- package/providers/context/resources/manuals/reference/package-templates.md +21 -10
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";
|
|
@@ -47498,12 +47502,22 @@ var loadSourceInfo = async (modulePath, fs) => {
|
|
|
47498
47502
|
content: { raw: await fs.readFile(GO_MOD) }
|
|
47499
47503
|
});
|
|
47500
47504
|
}
|
|
47505
|
+
const detectedLanguages = [
|
|
47506
|
+
...manifests.some((manifest) => manifest.type === GO_MOD) ? ["go"] : [],
|
|
47507
|
+
...manifests.some((manifest) => manifest.type === PACKAGE_JSON) ? ["typescript"] : []
|
|
47508
|
+
];
|
|
47501
47509
|
return {
|
|
47502
47510
|
path: normalizeRelativePath(modulePath),
|
|
47503
47511
|
manifests,
|
|
47504
|
-
...
|
|
47512
|
+
...detectedLanguages.length === 1 ? { language: detectedLanguages[0] } : {}
|
|
47505
47513
|
};
|
|
47506
47514
|
};
|
|
47515
|
+
function manifestForPlugin(source2, plugin) {
|
|
47516
|
+
if (plugin.manifestTypes !== undefined) {
|
|
47517
|
+
return source2.manifests.find((manifest) => plugin.manifestTypes?.includes(manifest.type));
|
|
47518
|
+
}
|
|
47519
|
+
return source2.manifests.length === 1 ? source2.manifests[0] : undefined;
|
|
47520
|
+
}
|
|
47507
47521
|
var prefixSymbolPaths = (symbol, modulePath) => ({
|
|
47508
47522
|
...symbol,
|
|
47509
47523
|
...symbol.file.trim() ? { file: resolveRepoRelativePath(modulePath, symbol.file) } : {},
|
|
@@ -47600,12 +47614,12 @@ var runRepositoryExtraction = async (input) => {
|
|
|
47600
47614
|
});
|
|
47601
47615
|
continue;
|
|
47602
47616
|
}
|
|
47603
|
-
const manifest = sourceInfo
|
|
47617
|
+
const manifest = manifestForPlugin(sourceInfo, plugin);
|
|
47604
47618
|
if (!manifest) {
|
|
47605
47619
|
moduleErrors.push({
|
|
47606
47620
|
module_name: module.name,
|
|
47607
47621
|
module_path: module.path,
|
|
47608
|
-
error: `Module "${module.name}" has no supported
|
|
47622
|
+
error: plugin.manifestTypes === undefined && sourceInfo.manifests.length > 1 ? `Extraction plugin "${plugin.id}" must declare manifestTypes for mixed-manifest module "${module.name}"` : `Module "${module.name}" has no manifest supported by extraction plugin "${plugin.id}"`
|
|
47609
47623
|
});
|
|
47610
47624
|
continue;
|
|
47611
47625
|
}
|
|
@@ -65763,6 +65777,7 @@ class TypeScriptPlugin {
|
|
|
65763
65777
|
id = "c4a-extract-ts";
|
|
65764
65778
|
languages = ["typescript", "tsx"];
|
|
65765
65779
|
packageManagers = ["npm"];
|
|
65780
|
+
manifestTypes = ["package.json"];
|
|
65766
65781
|
#lastDetection = null;
|
|
65767
65782
|
canHandle(source2) {
|
|
65768
65783
|
return source2.manifests.some((manifest) => manifest.type === "package.json");
|
|
@@ -68933,20 +68948,156 @@ async function readApprovedCodegraphPages(input) {
|
|
|
68933
68948
|
// src/project/close.ts
|
|
68934
68949
|
init_cliFeedback();
|
|
68935
68950
|
init_errors();
|
|
68936
|
-
init_exitCode();
|
|
68937
68951
|
var import_yaml14 = __toESM(require_dist3(), 1);
|
|
68938
|
-
import { existsSync as
|
|
68952
|
+
import { existsSync as existsSync22 } from "node:fs";
|
|
68939
68953
|
import { mkdir as mkdir17, readdir as readdir11, readFile as readFile27, writeFile as writeFile13 } from "node:fs/promises";
|
|
68940
|
-
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 { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
|
|
68959
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
68960
|
+
import { dirname as dirname15, join as join17 } from "node:path";
|
|
68961
|
+
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
68962
|
+
var CONTEXT_RUNTIME_EVENT_BATCH_SCHEMA = "context.runtime-event-batch.v1";
|
|
68963
|
+
var CONTEXT_RUNTIME_EVENT_SINK_SCHEMA = "context.runtime-event-sink.v1";
|
|
68964
|
+
var activeScope;
|
|
68965
|
+
function isRecord8(value) {
|
|
68966
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
68967
|
+
}
|
|
68968
|
+
function parseContextRuntimeEventSink(value) {
|
|
68969
|
+
if (!isRecord8(value))
|
|
68970
|
+
return null;
|
|
68971
|
+
if (value.schema !== CONTEXT_RUNTIME_EVENT_SINK_SCHEMA || value.transport !== "command")
|
|
68972
|
+
return null;
|
|
68973
|
+
if (typeof value.command !== "string" || value.command.trim().length === 0)
|
|
68974
|
+
return null;
|
|
68975
|
+
if (!Array.isArray(value.args) || !value.args.every((arg) => typeof arg === "string"))
|
|
68976
|
+
return null;
|
|
68977
|
+
return {
|
|
68978
|
+
schema: CONTEXT_RUNTIME_EVENT_SINK_SCHEMA,
|
|
68979
|
+
transport: "command",
|
|
68980
|
+
command: value.command,
|
|
68981
|
+
args: [...value.args]
|
|
68982
|
+
};
|
|
68983
|
+
}
|
|
68984
|
+
function readRuntimePackageMetadata() {
|
|
68985
|
+
try {
|
|
68986
|
+
let dir = dirname15(fileURLToPath4(import.meta.url));
|
|
68987
|
+
for (let index2 = 0;index2 < 8; index2++) {
|
|
68988
|
+
const packagePath = join17(dir, "package.json");
|
|
68989
|
+
if (existsSync8(packagePath)) {
|
|
68990
|
+
const parsed = JSON.parse(readFileSync4(packagePath, "utf8"));
|
|
68991
|
+
if (isRecord8(parsed)) {
|
|
68992
|
+
return {
|
|
68993
|
+
contextVersion: typeof parsed.version === "string" ? parsed.version : "unknown",
|
|
68994
|
+
sink: parseContextRuntimeEventSink(parsed.contextRuntimeEventSink)
|
|
68995
|
+
};
|
|
68996
|
+
}
|
|
68997
|
+
}
|
|
68998
|
+
const parent = dirname15(dir);
|
|
68999
|
+
if (parent === dir)
|
|
69000
|
+
break;
|
|
69001
|
+
dir = parent;
|
|
69002
|
+
}
|
|
69003
|
+
} catch {}
|
|
69004
|
+
return { contextVersion: "unknown", sink: null };
|
|
69005
|
+
}
|
|
69006
|
+
function dispatchCommand(sink, batch, cwd) {
|
|
69007
|
+
return new Promise((resolve8) => {
|
|
69008
|
+
let settled = false;
|
|
69009
|
+
let timer;
|
|
69010
|
+
const finish = () => {
|
|
69011
|
+
if (settled)
|
|
69012
|
+
return;
|
|
69013
|
+
settled = true;
|
|
69014
|
+
if (timer !== undefined)
|
|
69015
|
+
clearTimeout(timer);
|
|
69016
|
+
resolve8();
|
|
69017
|
+
};
|
|
69018
|
+
try {
|
|
69019
|
+
const child = spawn2(sink.command, sink.args, {
|
|
69020
|
+
cwd,
|
|
69021
|
+
detached: true,
|
|
69022
|
+
env: process.env,
|
|
69023
|
+
shell: false,
|
|
69024
|
+
stdio: ["pipe", "ignore", "ignore"]
|
|
69025
|
+
});
|
|
69026
|
+
child.once("error", finish);
|
|
69027
|
+
child.stdin.once("error", finish);
|
|
69028
|
+
child.stdin.end(JSON.stringify(batch), finish);
|
|
69029
|
+
child.unref();
|
|
69030
|
+
timer = setTimeout(finish, 250);
|
|
69031
|
+
timer.unref();
|
|
69032
|
+
} catch {
|
|
69033
|
+
finish();
|
|
69034
|
+
}
|
|
69035
|
+
});
|
|
69036
|
+
}
|
|
69037
|
+
async function flushRuntimeEvents(scope) {
|
|
69038
|
+
const grouped = new Map;
|
|
69039
|
+
for (const queued of scope.events) {
|
|
69040
|
+
const events = grouped.get(queued.cwd) ?? [];
|
|
69041
|
+
events.push(queued.event);
|
|
69042
|
+
grouped.set(queued.cwd, events);
|
|
69043
|
+
}
|
|
69044
|
+
await Promise.all([...grouped.entries()].map(async ([cwd, events]) => {
|
|
69045
|
+
try {
|
|
69046
|
+
await scope.dispatch(scope.sink, {
|
|
69047
|
+
schema: CONTEXT_RUNTIME_EVENT_BATCH_SCHEMA,
|
|
69048
|
+
context_version: scope.contextVersion,
|
|
69049
|
+
events
|
|
69050
|
+
}, cwd);
|
|
69051
|
+
} catch {}
|
|
69052
|
+
}));
|
|
69053
|
+
}
|
|
69054
|
+
function queueContextRuntimeEvent(input) {
|
|
69055
|
+
if (activeScope === undefined)
|
|
69056
|
+
return;
|
|
69057
|
+
activeScope.events.push({
|
|
69058
|
+
cwd: input.cwd,
|
|
69059
|
+
event: {
|
|
69060
|
+
event_id: randomUUID2(),
|
|
69061
|
+
event_time: Date.now(),
|
|
69062
|
+
kind: input.kind,
|
|
69063
|
+
properties: input.properties ?? {}
|
|
69064
|
+
}
|
|
69065
|
+
});
|
|
69066
|
+
}
|
|
69067
|
+
async function withContextRuntimeEventDelivery(work, options = {}) {
|
|
69068
|
+
if (activeScope !== undefined || process.env.CONTEXT_RUNTIME_EVENTS_DISABLED === "1") {
|
|
69069
|
+
return work();
|
|
69070
|
+
}
|
|
69071
|
+
const metadata = readRuntimePackageMetadata();
|
|
69072
|
+
const sink = options.sink === undefined ? metadata.sink : options.sink;
|
|
69073
|
+
if (sink === null)
|
|
69074
|
+
return work();
|
|
69075
|
+
const scope = {
|
|
69076
|
+
contextVersion: options.contextVersion ?? metadata.contextVersion,
|
|
69077
|
+
dispatch: options.dispatch ?? dispatchCommand,
|
|
69078
|
+
events: [],
|
|
69079
|
+
sink
|
|
69080
|
+
};
|
|
69081
|
+
activeScope = scope;
|
|
69082
|
+
try {
|
|
69083
|
+
return await work();
|
|
69084
|
+
} finally {
|
|
69085
|
+
activeScope = undefined;
|
|
69086
|
+
await flushRuntimeEvents(scope);
|
|
69087
|
+
}
|
|
69088
|
+
}
|
|
69089
|
+
|
|
69090
|
+
// src/project/close.ts
|
|
69091
|
+
init_exitCode();
|
|
68941
69092
|
|
|
68942
69093
|
// src/project/approvedStructureEdges.ts
|
|
68943
69094
|
init_cliFeedback();
|
|
68944
69095
|
init_errors();
|
|
68945
69096
|
init_exitCode();
|
|
68946
69097
|
var import_yaml10 = __toESM(require_dist3(), 1);
|
|
68947
|
-
import { existsSync as
|
|
69098
|
+
import { existsSync as existsSync11 } from "node:fs";
|
|
68948
69099
|
import { readFile as readFile17 } from "node:fs/promises";
|
|
68949
|
-
import { join as
|
|
69100
|
+
import { join as join20 } from "node:path";
|
|
68950
69101
|
|
|
68951
69102
|
// src/project/proseAlignTypes.ts
|
|
68952
69103
|
import { createHash as createHash9 } from "node:crypto";
|
|
@@ -69003,21 +69154,21 @@ function slugify2(input, maxLen = 60) {
|
|
|
69003
69154
|
// src/project/semanticRules.ts
|
|
69004
69155
|
var import_yaml8 = __toESM(require_dist3(), 1);
|
|
69005
69156
|
import { createHash as createHash8 } from "node:crypto";
|
|
69006
|
-
import { existsSync as
|
|
69007
|
-
import { basename as basename4, dirname as
|
|
69008
|
-
import { fileURLToPath as
|
|
69157
|
+
import { existsSync as existsSync9, readFileSync as readFileSync5, readdirSync } from "node:fs";
|
|
69158
|
+
import { basename as basename4, dirname as dirname16, join as join18 } from "node:path";
|
|
69159
|
+
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
69009
69160
|
function sha256(value) {
|
|
69010
69161
|
return `sha256:${createHash8("sha256").update(value).digest("hex")}`;
|
|
69011
69162
|
}
|
|
69012
69163
|
function workflowRootCandidates() {
|
|
69013
|
-
const runtimeDir =
|
|
69164
|
+
const runtimeDir = dirname16(fileURLToPath5(import.meta.url));
|
|
69014
69165
|
return [
|
|
69015
|
-
|
|
69016
|
-
|
|
69166
|
+
join18(runtimeDir, "providers", "context"),
|
|
69167
|
+
join18(runtimeDir, "..", "..", "context-workflow")
|
|
69017
69168
|
];
|
|
69018
69169
|
}
|
|
69019
69170
|
function semanticRuleMetadata(scope, filePath) {
|
|
69020
|
-
const content3 =
|
|
69171
|
+
const content3 = readFileSync5(filePath, "utf8").replaceAll(`\r
|
|
69021
69172
|
`, `
|
|
69022
69173
|
`);
|
|
69023
69174
|
const end = content3.indexOf(`
|
|
@@ -69048,19 +69199,19 @@ function semanticRuleMetadata(scope, filePath) {
|
|
|
69048
69199
|
}
|
|
69049
69200
|
function semanticRuleDescriptors(scope) {
|
|
69050
69201
|
for (const root of workflowRootCandidates()) {
|
|
69051
|
-
const directory =
|
|
69052
|
-
if (!
|
|
69202
|
+
const directory = join18(root, "resources", "semantic", scope);
|
|
69203
|
+
if (!existsSync9(directory))
|
|
69053
69204
|
continue;
|
|
69054
|
-
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,
|
|
69205
|
+
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)));
|
|
69055
69206
|
}
|
|
69056
69207
|
throw new Error(`Context ${scope} semantic workflow resources are missing. Rebuild or reinstall @c4a/context-cli.`);
|
|
69057
69208
|
}
|
|
69058
69209
|
function ruleContent(rulePath) {
|
|
69059
69210
|
for (const root of workflowRootCandidates()) {
|
|
69060
|
-
const absolute =
|
|
69061
|
-
if (
|
|
69211
|
+
const absolute = join18(root, rulePath);
|
|
69212
|
+
if (existsSync9(absolute)) {
|
|
69062
69213
|
return {
|
|
69063
|
-
content:
|
|
69214
|
+
content: readFileSync5(absolute, "utf8"),
|
|
69064
69215
|
available: true,
|
|
69065
69216
|
filePath: absolute
|
|
69066
69217
|
};
|
|
@@ -69473,15 +69624,15 @@ init_cliFeedback();
|
|
|
69473
69624
|
init_errors();
|
|
69474
69625
|
init_exitCode();
|
|
69475
69626
|
var import_yaml9 = __toESM(require_dist3(), 1);
|
|
69476
|
-
import { existsSync as
|
|
69627
|
+
import { existsSync as existsSync10 } from "node:fs";
|
|
69477
69628
|
import { mkdir as mkdir12, readFile as readFile16, writeFile as writeFile8 } from "node:fs/promises";
|
|
69478
|
-
import { dirname as
|
|
69629
|
+
import { dirname as dirname17, join as join19 } from "node:path";
|
|
69479
69630
|
|
|
69480
69631
|
// src/project/proseAlignPayloadParse.ts
|
|
69481
69632
|
import { createHash as createHash10 } from "node:crypto";
|
|
69482
69633
|
|
|
69483
69634
|
// src/project/proseAlignSchemaUtils.ts
|
|
69484
|
-
function
|
|
69635
|
+
function isRecord9(value) {
|
|
69485
69636
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
69486
69637
|
}
|
|
69487
69638
|
function stringValue2(record, field) {
|
|
@@ -69548,7 +69699,7 @@ function parsePreferredNodes(value, diagnostics) {
|
|
|
69548
69699
|
}
|
|
69549
69700
|
const nodes = [];
|
|
69550
69701
|
for (const [index2, rawNode] of value.entries()) {
|
|
69551
|
-
if (!
|
|
69702
|
+
if (!isRecord9(rawNode)) {
|
|
69552
69703
|
diagnostics.push(diagnostic("error", "schema.preferred_node_object", "schema", "preferred_nodes item must be an object.", `user_or_agent_hints.preferred_nodes[${index2}]`));
|
|
69553
69704
|
continue;
|
|
69554
69705
|
}
|
|
@@ -69573,7 +69724,7 @@ function parsePreferredNodes(value, diagnostics) {
|
|
|
69573
69724
|
function parseUserOrAgentHints(value, diagnostics) {
|
|
69574
69725
|
if (value === undefined)
|
|
69575
69726
|
return;
|
|
69576
|
-
if (!
|
|
69727
|
+
if (!isRecord9(value)) {
|
|
69577
69728
|
diagnostics.push(diagnostic("error", "schema.user_or_agent_hints_object", "schema", "user_or_agent_hints must be an object.", "user_or_agent_hints"));
|
|
69578
69729
|
return;
|
|
69579
69730
|
}
|
|
@@ -69776,7 +69927,7 @@ function parseNodes(value, diagnostics) {
|
|
|
69776
69927
|
diagnostics.push(diagnostic("error", "schema.nodes_missing", "schema", "Payload must include at least one node.", "nodes"));
|
|
69777
69928
|
const nodes = [];
|
|
69778
69929
|
for (const [index2, rawNode] of value.entries()) {
|
|
69779
|
-
if (!
|
|
69930
|
+
if (!isRecord9(rawNode)) {
|
|
69780
69931
|
diagnostics.push(diagnostic("error", "schema.node_object", "schema", `Node ${index2 + 1} must be an object.`, `nodes[${index2}]`));
|
|
69781
69932
|
continue;
|
|
69782
69933
|
}
|
|
@@ -69813,7 +69964,7 @@ function parseSections(input) {
|
|
|
69813
69964
|
const sectionIds = new Set;
|
|
69814
69965
|
for (const [sectionIndex, rawSection] of input.value.entries()) {
|
|
69815
69966
|
const field = `views[${input.viewIndex}].sections[${sectionIndex}]`;
|
|
69816
|
-
if (!
|
|
69967
|
+
if (!isRecord9(rawSection)) {
|
|
69817
69968
|
input.diagnostics.push(diagnostic("error", "schema.section_object", "schema", "Section must be an object.", field));
|
|
69818
69969
|
continue;
|
|
69819
69970
|
}
|
|
@@ -69915,7 +70066,7 @@ function parseViews(value, nodes, diagnostics) {
|
|
|
69915
70066
|
const nodeByRef = new Map(nodes.map((node3) => [node3.node_ref, node3]));
|
|
69916
70067
|
const views = [];
|
|
69917
70068
|
for (const [index2, rawView] of value.entries()) {
|
|
69918
|
-
if (!
|
|
70069
|
+
if (!isRecord9(rawView)) {
|
|
69919
70070
|
diagnostics.push(diagnostic("error", "schema.view_object", "schema", `View ${index2 + 1} must be an object.`, `views[${index2}]`));
|
|
69920
70071
|
continue;
|
|
69921
70072
|
}
|
|
@@ -69934,7 +70085,7 @@ function parseEdges(value, diagnostics) {
|
|
|
69934
70085
|
}
|
|
69935
70086
|
const edges = [];
|
|
69936
70087
|
for (const [index2, rawEdge] of value.entries()) {
|
|
69937
|
-
if (!
|
|
70088
|
+
if (!isRecord9(rawEdge)) {
|
|
69938
70089
|
diagnostics.push(diagnostic("error", "schema.edge_object", "schema", `Edge ${index2 + 1} must be an object.`, `edges[${index2}]`));
|
|
69939
70090
|
continue;
|
|
69940
70091
|
}
|
|
@@ -69981,7 +70132,7 @@ function parseUnresolved(value, diagnostics) {
|
|
|
69981
70132
|
}
|
|
69982
70133
|
const unresolved = [];
|
|
69983
70134
|
for (const [index2, rawIssue] of value.entries()) {
|
|
69984
|
-
if (!
|
|
70135
|
+
if (!isRecord9(rawIssue)) {
|
|
69985
70136
|
diagnostics.push(diagnostic("error", "schema.unresolved_object", "schema", `Unresolved issue ${index2 + 1} must be an object.`, `unresolved[${index2}]`));
|
|
69986
70137
|
continue;
|
|
69987
70138
|
}
|
|
@@ -70004,7 +70155,7 @@ function parseUnresolved(value, diagnostics) {
|
|
|
70004
70155
|
function parseLifecycle(value, diagnostics) {
|
|
70005
70156
|
if (value === undefined)
|
|
70006
70157
|
return { state: "draft" };
|
|
70007
|
-
if (!
|
|
70158
|
+
if (!isRecord9(value)) {
|
|
70008
70159
|
diagnostics.push(diagnostic("error", "schema.lifecycle_object", "schema", "Payload lifecycle must be an object.", "lifecycle"));
|
|
70009
70160
|
return { state: "draft" };
|
|
70010
70161
|
}
|
|
@@ -70062,7 +70213,7 @@ function structureBody(input) {
|
|
|
70062
70213
|
}
|
|
70063
70214
|
function parseAlignPayload(value) {
|
|
70064
70215
|
const diagnostics = [];
|
|
70065
|
-
if (!
|
|
70216
|
+
if (!isRecord9(value)) {
|
|
70066
70217
|
return {
|
|
70067
70218
|
diagnostics: [diagnostic("error", "schema.payload_object", "schema", "Payload must be a YAML/JSON object.", "schema")]
|
|
70068
70219
|
};
|
|
@@ -70147,7 +70298,7 @@ function snapshotPath(projectRoot, structureDigest) {
|
|
|
70147
70298
|
structure_digest: structureDigest
|
|
70148
70299
|
});
|
|
70149
70300
|
}
|
|
70150
|
-
return
|
|
70301
|
+
return join19(projectRoot, STRUCTURE_SNAPSHOT_ROOT, `${match[1]}.yaml`);
|
|
70151
70302
|
}
|
|
70152
70303
|
function normalizedSnapshot(payload) {
|
|
70153
70304
|
const { user_or_agent_hints: _hints, ...body } = payload;
|
|
@@ -70163,8 +70314,8 @@ function normalizedSnapshot(payload) {
|
|
|
70163
70314
|
});
|
|
70164
70315
|
}
|
|
70165
70316
|
async function readSlots(projectRoot) {
|
|
70166
|
-
const path3 =
|
|
70167
|
-
if (!
|
|
70317
|
+
const path3 = join19(projectRoot, STRUCTURE_SLOT_FILE);
|
|
70318
|
+
if (!existsSync10(path3))
|
|
70168
70319
|
return [];
|
|
70169
70320
|
const parsed = import_yaml9.default.parse(await readFile16(path3, "utf8"));
|
|
70170
70321
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
@@ -70212,8 +70363,8 @@ async function updateSlots(projectRoot, payload) {
|
|
|
70212
70363
|
...current2.filter((slot) => !replacements.has(`${slot.source}\x00${slot.collection}`)),
|
|
70213
70364
|
...replacements.values()
|
|
70214
70365
|
].sort((left, right) => left.source.localeCompare(right.source) || left.collection.localeCompare(right.collection));
|
|
70215
|
-
const path3 =
|
|
70216
|
-
await mkdir12(
|
|
70366
|
+
const path3 = join19(projectRoot, STRUCTURE_SLOT_FILE);
|
|
70367
|
+
await mkdir12(dirname17(path3), { recursive: true });
|
|
70217
70368
|
await writeFile8(path3, import_yaml9.default.stringify({ schema_version: STRUCTURE_SLOT_SCHEMA_VERSION, slots }), "utf8");
|
|
70218
70369
|
}
|
|
70219
70370
|
async function writeStructureSnapshot(projectRoot, payload) {
|
|
@@ -70228,7 +70379,7 @@ async function writeStructureSnapshot(projectRoot, payload) {
|
|
|
70228
70379
|
});
|
|
70229
70380
|
}
|
|
70230
70381
|
const content3 = import_yaml9.default.stringify(normalized);
|
|
70231
|
-
if (
|
|
70382
|
+
if (existsSync10(path3)) {
|
|
70232
70383
|
const current2 = await readFile16(path3, "utf8");
|
|
70233
70384
|
const existing = parseAlignPayload(import_yaml9.default.parse(current2)).payload;
|
|
70234
70385
|
if (existing?.structure_digest !== payload.structure_digest) {
|
|
@@ -70244,14 +70395,14 @@ async function writeStructureSnapshot(projectRoot, payload) {
|
|
|
70244
70395
|
await updateSlots(projectRoot, payload);
|
|
70245
70396
|
return path3;
|
|
70246
70397
|
}
|
|
70247
|
-
await mkdir12(
|
|
70398
|
+
await mkdir12(dirname17(path3), { recursive: true });
|
|
70248
70399
|
await writeFile8(path3, content3, "utf8");
|
|
70249
70400
|
await updateSlots(projectRoot, payload);
|
|
70250
70401
|
return path3;
|
|
70251
70402
|
}
|
|
70252
70403
|
async function readStructureSnapshot(projectRoot, structureDigest) {
|
|
70253
70404
|
const path3 = snapshotPath(projectRoot, structureDigest);
|
|
70254
|
-
if (!
|
|
70405
|
+
if (!existsSync10(path3))
|
|
70255
70406
|
return null;
|
|
70256
70407
|
try {
|
|
70257
70408
|
return import_yaml9.default.parse(await readFile16(path3, "utf8"));
|
|
@@ -70279,8 +70430,8 @@ async function readStructureSnapshotPayload(projectRoot, structureDigest) {
|
|
|
70279
70430
|
return { ...record, structure_digest: structureDigest };
|
|
70280
70431
|
}
|
|
70281
70432
|
async function archiveActiveStructure(projectRoot) {
|
|
70282
|
-
const path3 =
|
|
70283
|
-
if (!
|
|
70433
|
+
const path3 = join19(projectRoot, LIFECYCLE_STRUCTURE_FILE);
|
|
70434
|
+
if (!existsSync10(path3))
|
|
70284
70435
|
return null;
|
|
70285
70436
|
let parsed;
|
|
70286
70437
|
try {
|
|
@@ -70308,7 +70459,7 @@ function structureSnapshotRelativePath(structureDigest) {
|
|
|
70308
70459
|
const match = STRUCTURE_DIGEST_PATTERN.exec(structureDigest);
|
|
70309
70460
|
if (match?.[1] === undefined)
|
|
70310
70461
|
return STRUCTURE_SNAPSHOT_ROOT;
|
|
70311
|
-
return
|
|
70462
|
+
return join19(STRUCTURE_SNAPSHOT_ROOT, `${match[1]}.yaml`);
|
|
70312
70463
|
}
|
|
70313
70464
|
async function currentStructureSlotDigest(projectRoot, source2, collection) {
|
|
70314
70465
|
return (await readSlots(projectRoot)).find((slot) => slot.source === source2 && slot.collection === collection)?.structure_digest;
|
|
@@ -70323,9 +70474,9 @@ async function activeStructureSlots(projectRoot, collection) {
|
|
|
70323
70474
|
|
|
70324
70475
|
// src/project/approvedStructureEdges.ts
|
|
70325
70476
|
var KNOWLEDGE_ROOT = "knowledge";
|
|
70326
|
-
var APPROVED_STRUCTURE_PATH =
|
|
70477
|
+
var APPROVED_STRUCTURE_PATH = join20(KNOWLEDGE_ROOT, "structure.yaml");
|
|
70327
70478
|
var STRUCTURE_EDGE_CONFIDENCE_SET = new Set(STRUCTURE_EDGE_CONFIDENCES);
|
|
70328
|
-
function
|
|
70479
|
+
function isRecord10(value) {
|
|
70329
70480
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
70330
70481
|
}
|
|
70331
70482
|
function readEdgeArray(structure) {
|
|
@@ -70335,7 +70486,7 @@ function normalizeApprovedEdges(input) {
|
|
|
70335
70486
|
const allowed = new Set(STRUCTURE_EDGE_TYPES);
|
|
70336
70487
|
const edges = [];
|
|
70337
70488
|
for (const [index2, rawEdge] of input.rawEdges.entries()) {
|
|
70338
|
-
if (!
|
|
70489
|
+
if (!isRecord10(rawEdge)) {
|
|
70339
70490
|
throw new ContextError(ExitCode.WorkspaceStateError, "structure edge must be an object", {
|
|
70340
70491
|
category: ErrorCategory.WorkspaceStateInvalid,
|
|
70341
70492
|
path: input.path,
|
|
@@ -70426,20 +70577,20 @@ function structureEndpointRefs(structure) {
|
|
|
70426
70577
|
const refs = [];
|
|
70427
70578
|
if (Array.isArray(structure.nodes)) {
|
|
70428
70579
|
for (const node3 of structure.nodes) {
|
|
70429
|
-
if (
|
|
70580
|
+
if (isRecord10(node3) && typeof node3.node_ref === "string")
|
|
70430
70581
|
refs.push(node3.node_ref);
|
|
70431
70582
|
}
|
|
70432
70583
|
}
|
|
70433
70584
|
if (Array.isArray(structure.views)) {
|
|
70434
70585
|
for (const view of structure.views) {
|
|
70435
|
-
if (!
|
|
70586
|
+
if (!isRecord10(view))
|
|
70436
70587
|
continue;
|
|
70437
70588
|
if (typeof view.view_ref === "string")
|
|
70438
70589
|
refs.push(view.view_ref);
|
|
70439
70590
|
if (!Array.isArray(view.sections))
|
|
70440
70591
|
continue;
|
|
70441
70592
|
for (const section of view.sections) {
|
|
70442
|
-
if (
|
|
70593
|
+
if (isRecord10(section) && typeof section.section_ref === "string")
|
|
70443
70594
|
refs.push(section.section_ref);
|
|
70444
70595
|
}
|
|
70445
70596
|
}
|
|
@@ -70447,12 +70598,12 @@ function structureEndpointRefs(structure) {
|
|
|
70447
70598
|
return refs;
|
|
70448
70599
|
}
|
|
70449
70600
|
async function readYamlRecord(projectRoot, relPath) {
|
|
70450
|
-
const absPath =
|
|
70451
|
-
if (!
|
|
70601
|
+
const absPath = join20(projectRoot, relPath);
|
|
70602
|
+
if (!existsSync11(absPath))
|
|
70452
70603
|
return null;
|
|
70453
70604
|
try {
|
|
70454
70605
|
const parsed = import_yaml10.default.parse(await readFile17(absPath, "utf8"));
|
|
70455
|
-
return
|
|
70606
|
+
return isRecord10(parsed) ? parsed : null;
|
|
70456
70607
|
} catch (error) {
|
|
70457
70608
|
throw new ContextError(ExitCode.WorkspaceStateError, `${relPath} is invalid YAML`, {
|
|
70458
70609
|
category: ErrorCategory.WorkspaceStateInvalid,
|
|
@@ -70491,7 +70642,7 @@ async function readConfirmedStructureEdgeProjection(projectRoot, approvedEndpoin
|
|
|
70491
70642
|
const snapshotEdges = [];
|
|
70492
70643
|
for (const structureDigest of [...new Set(slots.map((slot) => slot.structureDigest))].sort()) {
|
|
70493
70644
|
const structure2 = await readStructureSnapshot(projectRoot, structureDigest);
|
|
70494
|
-
if (!
|
|
70645
|
+
if (!isRecord10(structure2)) {
|
|
70495
70646
|
throw new ContextError(ExitCode.WorkspaceStateError, "active structure snapshot is missing", {
|
|
70496
70647
|
category: ErrorCategory.WorkspaceStateInvalid,
|
|
70497
70648
|
structure_digest: structureDigest,
|
|
@@ -70532,7 +70683,7 @@ async function readConfirmedStructureEdgeProjection(projectRoot, approvedEndpoin
|
|
|
70532
70683
|
}
|
|
70533
70684
|
if (structure === null)
|
|
70534
70685
|
return null;
|
|
70535
|
-
const lifecycle =
|
|
70686
|
+
const lifecycle = isRecord10(structure.lifecycle) ? structure.lifecycle : {};
|
|
70536
70687
|
if (lifecycle.state !== "confirmed" && lifecycle.state !== "frozen")
|
|
70537
70688
|
return null;
|
|
70538
70689
|
return normalizeApprovedEdges({
|
|
@@ -70548,15 +70699,15 @@ async function readConfirmedStructureEdgeProjection(projectRoot, approvedEndpoin
|
|
|
70548
70699
|
init_cliFeedback();
|
|
70549
70700
|
init_errors();
|
|
70550
70701
|
init_exitCode();
|
|
70551
|
-
import { existsSync as
|
|
70702
|
+
import { existsSync as existsSync18 } from "node:fs";
|
|
70552
70703
|
import { readFile as readFile23 } from "node:fs/promises";
|
|
70553
|
-
import { join as
|
|
70704
|
+
import { join as join28 } from "node:path";
|
|
70554
70705
|
|
|
70555
70706
|
// src/project/verifyApprovedStructure.ts
|
|
70556
70707
|
var import_yaml12 = __toESM(require_dist3(), 1);
|
|
70557
|
-
import { existsSync as
|
|
70708
|
+
import { existsSync as existsSync14 } from "node:fs";
|
|
70558
70709
|
import { readFile as readFile19 } from "node:fs/promises";
|
|
70559
|
-
import { join as
|
|
70710
|
+
import { join as join24 } from "node:path";
|
|
70560
70711
|
|
|
70561
70712
|
// src/project/approvedStructureInputHash.ts
|
|
70562
70713
|
import { createHash as createHash11 } from "node:crypto";
|
|
@@ -70597,11 +70748,11 @@ function approvedStructureInputHash(input) {
|
|
|
70597
70748
|
}
|
|
70598
70749
|
|
|
70599
70750
|
// src/project/verifyApprovedStructureEdges.ts
|
|
70600
|
-
import { join as
|
|
70751
|
+
import { join as join22 } from "node:path";
|
|
70601
70752
|
|
|
70602
70753
|
// src/project/verifyCanonicalSourceRefs.ts
|
|
70603
|
-
import { existsSync as
|
|
70604
|
-
import { join as
|
|
70754
|
+
import { existsSync as existsSync12 } from "node:fs";
|
|
70755
|
+
import { join as join21 } from "node:path";
|
|
70605
70756
|
var CANONICAL_SOURCE_REF = /^repo:([^#]+)#symbol:(.+):([^:@]+):([^:@]+)@([a-f0-9]+)$/iu;
|
|
70606
70757
|
function validateCanonicalSourceRef(input) {
|
|
70607
70758
|
const path3 = input.path ?? ".tmp/context-runtime/lifecycle/candidates.jsonl";
|
|
@@ -70657,7 +70808,7 @@ async function validateCanonicalEvidenceSourceRef(input) {
|
|
|
70657
70808
|
const registryEntry = input.sourceRegistry.loaded ? registeredDocumentSource(input.sourceRegistry, locator.sourceType, locator.sourceName) : undefined;
|
|
70658
70809
|
const materializedAt = registryEntry?.materializedAt ?? defaultDocumentMaterializedAt(locator.sourceType, locator.sourceName);
|
|
70659
70810
|
const manifestPath = registryEntry?.snapshot?.manifest ?? defaultDocumentManifest(materializedAt);
|
|
70660
|
-
if (!
|
|
70811
|
+
if (!existsSync12(join21(input.projectRoot, manifestPath)) && !snapshotRootExists(input.projectRoot, materializedAt)) {
|
|
70661
70812
|
input.issues.push({
|
|
70662
70813
|
severity: unresolvedSeverity,
|
|
70663
70814
|
code: "approved-evidence-unavailable",
|
|
@@ -70730,7 +70881,7 @@ async function validateCanonicalEvidenceSourceRef(input) {
|
|
|
70730
70881
|
}
|
|
70731
70882
|
|
|
70732
70883
|
// src/project/verifyApprovedStructureEdges.ts
|
|
70733
|
-
var APPROVED_STRUCTURE_PATH2 =
|
|
70884
|
+
var APPROVED_STRUCTURE_PATH2 = join22("knowledge", "structure.yaml");
|
|
70734
70885
|
function approvedStructureEdgeRecords(parsed, issues) {
|
|
70735
70886
|
if (parsed.edges === undefined)
|
|
70736
70887
|
return [];
|
|
@@ -70863,7 +71014,7 @@ async function validateApprovedStructureEdgeRecords(input) {
|
|
|
70863
71014
|
init_cliFeedback();
|
|
70864
71015
|
init_errors();
|
|
70865
71016
|
init_exitCode();
|
|
70866
|
-
function
|
|
71017
|
+
function isRecord11(value) {
|
|
70867
71018
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
70868
71019
|
}
|
|
70869
71020
|
function codegraphEdgesFromFrontmatter(frontmatter, path3) {
|
|
@@ -70876,7 +71027,7 @@ function codegraphEdgesFromFrontmatter(frontmatter, path3) {
|
|
|
70876
71027
|
});
|
|
70877
71028
|
}
|
|
70878
71029
|
return frontmatter.code_edges.map((rawEdge, index2) => {
|
|
70879
|
-
if (!
|
|
71030
|
+
if (!isRecord11(rawEdge)) {
|
|
70880
71031
|
throw new ContextError(ExitCode.WorkspaceStateError, "approved code edge must be an object", {
|
|
70881
71032
|
category: ErrorCategory.WorkspaceStateInvalid,
|
|
70882
71033
|
path: path3,
|
|
@@ -70936,17 +71087,17 @@ function codegraphRelationshipCoverage(input) {
|
|
|
70936
71087
|
}
|
|
70937
71088
|
|
|
70938
71089
|
// src/project/approvedStructureInputs.ts
|
|
70939
|
-
import { existsSync as
|
|
71090
|
+
import { existsSync as existsSync13 } from "node:fs";
|
|
70940
71091
|
import { readFile as readFile18 } from "node:fs/promises";
|
|
70941
|
-
import { join as
|
|
71092
|
+
import { join as join23 } from "node:path";
|
|
70942
71093
|
init_cliFeedback();
|
|
70943
71094
|
init_errors();
|
|
70944
71095
|
init_exitCode();
|
|
70945
71096
|
var import_yaml11 = __toESM(require_dist3(), 1);
|
|
70946
|
-
var APPROVED_STRUCTURE_FILE =
|
|
71097
|
+
var APPROVED_STRUCTURE_FILE = join23("knowledge", "structure.yaml");
|
|
70947
71098
|
var COLLECTIONS = new Set(KNOWLEDGE_COLLECTIONS);
|
|
70948
71099
|
var SNAPSHOT_HASH_PATTERN = /^sha256:[a-f0-9]{64}$/u;
|
|
70949
|
-
function
|
|
71100
|
+
function isRecord12(value) {
|
|
70950
71101
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
70951
71102
|
}
|
|
70952
71103
|
function invalidSourceInputs(reason) {
|
|
@@ -70965,14 +71116,14 @@ function sortedSourceInputs(values2) {
|
|
|
70965
71116
|
function parseApprovedStructureSourceInputs(structure) {
|
|
70966
71117
|
if (structure.source_inputs === undefined)
|
|
70967
71118
|
return [];
|
|
70968
|
-
if (!
|
|
71119
|
+
if (!isRecord12(structure.source_inputs)) {
|
|
70969
71120
|
throw invalidSourceInputs("source_inputs must be an object when present");
|
|
70970
71121
|
}
|
|
70971
71122
|
const inputs = new Map;
|
|
70972
71123
|
for (const [source2, collections] of Object.entries(structure.source_inputs)) {
|
|
70973
71124
|
if (source2.trim().length === 0)
|
|
70974
71125
|
throw invalidSourceInputs("source_inputs source key must not be empty");
|
|
70975
|
-
if (!
|
|
71126
|
+
if (!isRecord12(collections)) {
|
|
70976
71127
|
throw invalidSourceInputs(`source_inputs.${source2} must be an object`);
|
|
70977
71128
|
}
|
|
70978
71129
|
for (const [collection, snapshotHash] of Object.entries(collections)) {
|
|
@@ -70997,8 +71148,8 @@ function approvedStructureSourceInputsRecord(inputs) {
|
|
|
70997
71148
|
return result;
|
|
70998
71149
|
}
|
|
70999
71150
|
async function readApprovedStructureSourceInputs(projectRoot) {
|
|
71000
|
-
const path3 =
|
|
71001
|
-
if (!
|
|
71151
|
+
const path3 = join23(projectRoot, APPROVED_STRUCTURE_FILE);
|
|
71152
|
+
if (!existsSync13(path3))
|
|
71002
71153
|
return [];
|
|
71003
71154
|
let parsed;
|
|
71004
71155
|
try {
|
|
@@ -71006,7 +71157,7 @@ async function readApprovedStructureSourceInputs(projectRoot) {
|
|
|
71006
71157
|
} catch {
|
|
71007
71158
|
return [];
|
|
71008
71159
|
}
|
|
71009
|
-
if (!
|
|
71160
|
+
if (!isRecord12(parsed))
|
|
71010
71161
|
return [];
|
|
71011
71162
|
return parseApprovedStructureSourceInputs(parsed);
|
|
71012
71163
|
}
|
|
@@ -71035,14 +71186,14 @@ function approvedStructureSourceInputKey(input) {
|
|
|
71035
71186
|
}
|
|
71036
71187
|
|
|
71037
71188
|
// src/project/verifyApprovedStructure.ts
|
|
71038
|
-
var APPROVED_STRUCTURE_PATH3 =
|
|
71189
|
+
var APPROVED_STRUCTURE_PATH3 = join24("knowledge", "structure.yaml");
|
|
71039
71190
|
var APPROVED_STRUCTURE_SCHEMA_VERSION = "context.approved-structure.v1";
|
|
71040
71191
|
var LOCAL_REF = /^src-(\d+)(#(?:span|symbol):.+)$/u;
|
|
71041
71192
|
async function readApprovedStructureForVerify(input) {
|
|
71042
71193
|
if (input.structureOverride !== undefined)
|
|
71043
71194
|
return input.structureOverride;
|
|
71044
|
-
const structurePath =
|
|
71045
|
-
if (!
|
|
71195
|
+
const structurePath = join24(input.projectRoot, APPROVED_STRUCTURE_PATH3);
|
|
71196
|
+
if (!existsSync14(structurePath))
|
|
71046
71197
|
return;
|
|
71047
71198
|
let rawParsed;
|
|
71048
71199
|
try {
|
|
@@ -71267,7 +71418,7 @@ async function approvedStructureProjection(projectRoot) {
|
|
|
71267
71418
|
const views = [];
|
|
71268
71419
|
const parentIndexes = [];
|
|
71269
71420
|
const codeEdges = [];
|
|
71270
|
-
for (const file of await walkMarkdown(
|
|
71421
|
+
for (const file of await walkMarkdown(join24(projectRoot, "knowledge"))) {
|
|
71271
71422
|
if (isKnowledgeAssetPath(file.relPath))
|
|
71272
71423
|
continue;
|
|
71273
71424
|
const content3 = await readFile19(file.absPath, "utf8");
|
|
@@ -71681,13 +71832,13 @@ async function validateApprovedStructureEdges(input) {
|
|
|
71681
71832
|
init_workspace();
|
|
71682
71833
|
|
|
71683
71834
|
// src/project/reviewDecisions.ts
|
|
71684
|
-
import { existsSync as
|
|
71835
|
+
import { existsSync as existsSync17 } from "node:fs";
|
|
71685
71836
|
import { mkdir as mkdir15, readFile as readFile22, rename as rename3, rm as rm8, writeFile as writeFile11 } from "node:fs/promises";
|
|
71686
|
-
import { dirname as
|
|
71837
|
+
import { dirname as dirname20, join as join27 } from "node:path";
|
|
71687
71838
|
init_cliFeedback();
|
|
71688
71839
|
init_errors();
|
|
71689
71840
|
init_exitCode();
|
|
71690
|
-
var REVIEW_DECISIONS_FILE =
|
|
71841
|
+
var REVIEW_DECISIONS_FILE = join27("knowledge", "decisions.json");
|
|
71691
71842
|
var FINGERPRINT_PATTERN = /^sha256:[a-f0-9]{64}$/u;
|
|
71692
71843
|
var COLLECTIONS2 = new Set(KNOWLEDGE_COLLECTIONS);
|
|
71693
71844
|
function isCandidateId(value) {
|
|
@@ -71702,8 +71853,8 @@ function invalidDecisions(reason) {
|
|
|
71702
71853
|
});
|
|
71703
71854
|
}
|
|
71704
71855
|
async function readRejectedDecisions(projectRoot) {
|
|
71705
|
-
const path3 =
|
|
71706
|
-
if (!
|
|
71856
|
+
const path3 = join27(projectRoot, REVIEW_DECISIONS_FILE);
|
|
71857
|
+
if (!existsSync17(path3))
|
|
71707
71858
|
return new Map;
|
|
71708
71859
|
let parsed;
|
|
71709
71860
|
try {
|
|
@@ -71727,14 +71878,14 @@ async function readRejectedDecisions(projectRoot) {
|
|
|
71727
71878
|
return decisions;
|
|
71728
71879
|
}
|
|
71729
71880
|
async function writeRejectedDecisions(projectRoot, decisions) {
|
|
71730
|
-
const path3 =
|
|
71881
|
+
const path3 = join27(projectRoot, REVIEW_DECISIONS_FILE);
|
|
71731
71882
|
if (decisions.size === 0) {
|
|
71732
71883
|
await rm8(path3, { force: true });
|
|
71733
71884
|
return;
|
|
71734
71885
|
}
|
|
71735
71886
|
const rejected = Object.fromEntries([...decisions.entries()].sort(([left], [right]) => left.localeCompare(right)));
|
|
71736
71887
|
const tempPath = `${path3}.${process.pid}.tmp`;
|
|
71737
|
-
await mkdir15(
|
|
71888
|
+
await mkdir15(dirname20(path3), { recursive: true });
|
|
71738
71889
|
await writeFile11(tempPath, `${JSON.stringify(rejected, null, 2)}
|
|
71739
71890
|
`, "utf8");
|
|
71740
71891
|
await rename3(tempPath, path3);
|
|
@@ -71911,7 +72062,7 @@ async function verifyProjectWorkspace(projectRoot, options = {}) {
|
|
|
71911
72062
|
issues
|
|
71912
72063
|
});
|
|
71913
72064
|
const seenViewRefs = new Set;
|
|
71914
|
-
for (const file of await walkMarkdown(
|
|
72065
|
+
for (const file of await walkMarkdown(join28(projectRoot, "knowledge"))) {
|
|
71915
72066
|
if (isKnowledgeAssetPath(file.relPath))
|
|
71916
72067
|
continue;
|
|
71917
72068
|
const content3 = await readFile23(file.absPath, "utf8");
|
|
@@ -71934,7 +72085,7 @@ async function verifyProjectWorkspace(projectRoot, options = {}) {
|
|
|
71934
72085
|
pageRelPath: `knowledge/${file.relPath}`,
|
|
71935
72086
|
content: content3
|
|
71936
72087
|
})) {
|
|
71937
|
-
if (!
|
|
72088
|
+
if (!existsSync18(join28(projectRoot, assetPath))) {
|
|
71938
72089
|
issues.push({
|
|
71939
72090
|
severity: "error",
|
|
71940
72091
|
code: "approved-resource-missing",
|
|
@@ -72120,9 +72271,9 @@ init_writeLock();
|
|
|
72120
72271
|
|
|
72121
72272
|
// src/project/proseCompileBatch.ts
|
|
72122
72273
|
var import_yaml13 = __toESM(require_dist3(), 1);
|
|
72123
|
-
import { existsSync as
|
|
72274
|
+
import { existsSync as existsSync20 } from "node:fs";
|
|
72124
72275
|
import { readFile as readFile25 } from "node:fs/promises";
|
|
72125
|
-
import { join as
|
|
72276
|
+
import { join as join30 } from "node:path";
|
|
72126
72277
|
init_cliFeedback();
|
|
72127
72278
|
init_errors();
|
|
72128
72279
|
init_exitCode();
|
|
@@ -72131,9 +72282,9 @@ init_exitCode();
|
|
|
72131
72282
|
init_cliFeedback();
|
|
72132
72283
|
init_errors();
|
|
72133
72284
|
init_exitCode();
|
|
72134
|
-
import { existsSync as
|
|
72285
|
+
import { existsSync as existsSync19 } from "node:fs";
|
|
72135
72286
|
import { readFile as readFile24, readdir as readdir10 } from "node:fs/promises";
|
|
72136
|
-
import { basename as basename6, join as
|
|
72287
|
+
import { basename as basename6, join as join29, relative as relative12 } from "node:path";
|
|
72137
72288
|
init_writeLock();
|
|
72138
72289
|
function candidateSourceKey(record) {
|
|
72139
72290
|
return record.source === undefined ? undefined : `${record.source.type}:${record.source.name}`;
|
|
@@ -72145,11 +72296,11 @@ function toPosixPath8(value) {
|
|
|
72145
72296
|
return value.split(/[\\/]+/u).join("/");
|
|
72146
72297
|
}
|
|
72147
72298
|
async function approvedPageIdentities(projectRoot) {
|
|
72148
|
-
const root =
|
|
72299
|
+
const root = join29(projectRoot, "knowledge");
|
|
72149
72300
|
const identities = [];
|
|
72150
72301
|
const visit2 = async (directory) => {
|
|
72151
72302
|
for (const entry of await readdir10(directory, { withFileTypes: true })) {
|
|
72152
|
-
const absolutePath =
|
|
72303
|
+
const absolutePath = join29(directory, entry.name);
|
|
72153
72304
|
if (entry.isDirectory()) {
|
|
72154
72305
|
await visit2(absolutePath);
|
|
72155
72306
|
continue;
|
|
@@ -72167,7 +72318,7 @@ async function approvedPageIdentities(projectRoot) {
|
|
|
72167
72318
|
});
|
|
72168
72319
|
}
|
|
72169
72320
|
};
|
|
72170
|
-
if (
|
|
72321
|
+
if (existsSync19(root))
|
|
72171
72322
|
await visit2(root);
|
|
72172
72323
|
return {
|
|
72173
72324
|
byPath: new Map(identities.map((identity) => [identity.path, identity])),
|
|
@@ -72396,7 +72547,7 @@ async function preserveApprovedPathIdentities(input) {
|
|
|
72396
72547
|
}
|
|
72397
72548
|
|
|
72398
72549
|
// src/project/proseCompileBatch.ts
|
|
72399
|
-
function
|
|
72550
|
+
function isRecord14(value) {
|
|
72400
72551
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
72401
72552
|
}
|
|
72402
72553
|
function stringField2(value, field) {
|
|
@@ -72404,11 +72555,11 @@ function stringField2(value, field) {
|
|
|
72404
72555
|
return typeof candidate === "string" && candidate.trim().length > 0 ? candidate.trim() : undefined;
|
|
72405
72556
|
}
|
|
72406
72557
|
async function readConfirmedStructure(projectRoot) {
|
|
72407
|
-
const path3 =
|
|
72408
|
-
if (!
|
|
72558
|
+
const path3 = join30(projectRoot, LIFECYCLE_STRUCTURE_FILE);
|
|
72559
|
+
if (!existsSync20(path3))
|
|
72409
72560
|
return;
|
|
72410
72561
|
const parsed = import_yaml13.default.parse(await readFile25(path3, "utf8"));
|
|
72411
|
-
if (!
|
|
72562
|
+
if (!isRecord14(parsed) || !isRecord14(parsed.lifecycle))
|
|
72412
72563
|
return;
|
|
72413
72564
|
if (parsed.lifecycle.state !== "confirmed" && parsed.lifecycle.state !== "frozen")
|
|
72414
72565
|
return;
|
|
@@ -72423,7 +72574,7 @@ async function readCurrentSnapshotHashes(projectRoot) {
|
|
|
72423
72574
|
}
|
|
72424
72575
|
async function approvedViewRefs(projectRoot, planned) {
|
|
72425
72576
|
const approved = [];
|
|
72426
|
-
for (const file of await walkMarkdown(
|
|
72577
|
+
for (const file of await walkMarkdown(join30(projectRoot, "knowledge"))) {
|
|
72427
72578
|
if (isKnowledgeAssetPath(file.relPath))
|
|
72428
72579
|
continue;
|
|
72429
72580
|
const content3 = await readFile25(file.absPath, "utf8");
|
|
@@ -72691,7 +72842,7 @@ function proseCompileBatchNextAction(input) {
|
|
|
72691
72842
|
|
|
72692
72843
|
// src/project/lifecycleCleanup.ts
|
|
72693
72844
|
import { rm as rm9 } from "node:fs/promises";
|
|
72694
|
-
import { join as
|
|
72845
|
+
import { join as join31 } from "node:path";
|
|
72695
72846
|
var COMPLETED_RUNTIME_PATHS = [
|
|
72696
72847
|
LIFECYCLE_ROOT,
|
|
72697
72848
|
REVIEW_RUNTIME_ROOT,
|
|
@@ -72700,13 +72851,13 @@ var COMPLETED_RUNTIME_PATHS = [
|
|
|
72700
72851
|
CANDIDATE_SNAPSHOT_ROOT
|
|
72701
72852
|
];
|
|
72702
72853
|
async function clearCompletedLifecycle(projectRoot) {
|
|
72703
|
-
await Promise.all(COMPLETED_RUNTIME_PATHS.map((path3) => rm9(
|
|
72854
|
+
await Promise.all(COMPLETED_RUNTIME_PATHS.map((path3) => rm9(join31(projectRoot, path3), { recursive: true, force: true })));
|
|
72704
72855
|
}
|
|
72705
72856
|
|
|
72706
72857
|
// src/project/knowledgeAssetRepair.ts
|
|
72707
|
-
import { existsSync as
|
|
72858
|
+
import { existsSync as existsSync21 } from "node:fs";
|
|
72708
72859
|
import { mkdir as mkdir16, readFile as readFile26, writeFile as writeFile12 } from "node:fs/promises";
|
|
72709
|
-
import { dirname as
|
|
72860
|
+
import { dirname as dirname21, join as join32 } from "node:path";
|
|
72710
72861
|
init_cliFeedback();
|
|
72711
72862
|
init_errors();
|
|
72712
72863
|
init_exitCode();
|
|
@@ -72717,14 +72868,14 @@ function sourceLocators(frontmatter) {
|
|
|
72717
72868
|
])];
|
|
72718
72869
|
}
|
|
72719
72870
|
async function bytesEqual(path3, expected) {
|
|
72720
|
-
if (!
|
|
72871
|
+
if (!existsSync21(path3))
|
|
72721
72872
|
return false;
|
|
72722
72873
|
const actual = await readFile26(path3);
|
|
72723
72874
|
return actual.length === expected.length && actual.equals(Buffer.from(expected));
|
|
72724
72875
|
}
|
|
72725
72876
|
async function repairApprovedKnowledgeAssetProjections(projectRoot) {
|
|
72726
72877
|
const affected = [];
|
|
72727
|
-
for (const file of await walkMarkdown(
|
|
72878
|
+
for (const file of await walkMarkdown(join32(projectRoot, "knowledge"))) {
|
|
72728
72879
|
if (isKnowledgeAssetPath(file.relPath))
|
|
72729
72880
|
continue;
|
|
72730
72881
|
const content3 = await readFile26(file.absPath, "utf8");
|
|
@@ -72798,7 +72949,7 @@ async function repairApprovedKnowledgeAssetProjections(projectRoot) {
|
|
|
72798
72949
|
for (const asset of assets.values()) {
|
|
72799
72950
|
if (await bytesEqual(asset.absPath, asset.bytes))
|
|
72800
72951
|
continue;
|
|
72801
|
-
await mkdir16(
|
|
72952
|
+
await mkdir16(dirname21(asset.absPath), { recursive: true });
|
|
72802
72953
|
await writeFile12(asset.absPath, asset.bytes);
|
|
72803
72954
|
writtenAssets.push(asset.relPath);
|
|
72804
72955
|
}
|
|
@@ -72814,7 +72965,7 @@ async function repairApprovedKnowledgeAssetProjections(projectRoot) {
|
|
|
72814
72965
|
|
|
72815
72966
|
// src/project/close.ts
|
|
72816
72967
|
var KNOWLEDGE_ROOT2 = "knowledge";
|
|
72817
|
-
var STRUCTURE_PATH =
|
|
72968
|
+
var STRUCTURE_PATH = join33(KNOWLEDGE_ROOT2, "structure.yaml");
|
|
72818
72969
|
var STRUCTURE_SCHEMA_VERSION2 = "context.approved-structure.v1";
|
|
72819
72970
|
var LOCAL_REF2 = /^src-(\d+)(#(?:span|symbol):.+)$/u;
|
|
72820
72971
|
var APPROVED_NODE_TYPES2 = new Set(["entity", "domain", "action"]);
|
|
@@ -72844,13 +72995,13 @@ function requiredFrontmatterString(frontmatter, field, relPath) {
|
|
|
72844
72995
|
});
|
|
72845
72996
|
}
|
|
72846
72997
|
async function walkFiles2(root) {
|
|
72847
|
-
if (!
|
|
72998
|
+
if (!existsSync22(root))
|
|
72848
72999
|
return [];
|
|
72849
73000
|
const files = [];
|
|
72850
73001
|
const visit2 = async (dir) => {
|
|
72851
73002
|
const entries = await readdir11(dir, { withFileTypes: true });
|
|
72852
73003
|
for (const entry of entries) {
|
|
72853
|
-
const absPath =
|
|
73004
|
+
const absPath = join33(dir, entry.name);
|
|
72854
73005
|
if (entry.isDirectory()) {
|
|
72855
73006
|
await visit2(absPath);
|
|
72856
73007
|
continue;
|
|
@@ -72875,7 +73026,7 @@ function isDeprecated(content3) {
|
|
|
72875
73026
|
return parseFrontmatter3(content3).deprecated === true;
|
|
72876
73027
|
}
|
|
72877
73028
|
async function approvedKnowledgeFiles(projectRoot) {
|
|
72878
|
-
const files = await walkFiles2(
|
|
73029
|
+
const files = await walkFiles2(join33(projectRoot, KNOWLEDGE_ROOT2));
|
|
72879
73030
|
const markdown = await Promise.all(files.filter((file) => file.relPath.endsWith(".md") && !isKnowledgeAssetPath(file.relPath)).map(async (file) => ({
|
|
72880
73031
|
...file,
|
|
72881
73032
|
content: await readFile27(file.absPath, "utf8")
|
|
@@ -73145,11 +73296,11 @@ function referencesReceipt() {
|
|
|
73145
73296
|
}
|
|
73146
73297
|
async function readProjectCloseStatus(projectRoot) {
|
|
73147
73298
|
const approved = await approvedKnowledgeFiles(projectRoot);
|
|
73148
|
-
const structurePath =
|
|
73149
|
-
if (approved.length === 0 && !
|
|
73299
|
+
const structurePath = join33(projectRoot, STRUCTURE_PATH);
|
|
73300
|
+
if (approved.length === 0 && !existsSync22(structurePath))
|
|
73150
73301
|
return { state: "missing", diagnostics: [] };
|
|
73151
73302
|
const inputHash = await approvedKnowledgeInputHash(projectRoot);
|
|
73152
|
-
if (!
|
|
73303
|
+
if (!existsSync22(structurePath))
|
|
73153
73304
|
return { state: "missing", inputHash, diagnostics: [`close structure is missing: ${STRUCTURE_PATH}`] };
|
|
73154
73305
|
try {
|
|
73155
73306
|
const parsed = import_yaml14.default.parse(await readFile27(structurePath, "utf8"));
|
|
@@ -73218,8 +73369,8 @@ async function closeProjectWorkspace(projectRoot) {
|
|
|
73218
73369
|
next: "Fix context verify errors, then rerun context close --format json."
|
|
73219
73370
|
});
|
|
73220
73371
|
}
|
|
73221
|
-
const outputPath =
|
|
73222
|
-
await mkdir17(
|
|
73372
|
+
const outputPath = join33(projectRoot, STRUCTURE_PATH);
|
|
73373
|
+
await mkdir17(dirname22(outputPath), { recursive: true });
|
|
73223
73374
|
await writeFile13(outputPath, `${import_yaml14.default.stringify(structure)}`, "utf8");
|
|
73224
73375
|
await clearCompletedLifecycle(projectRoot);
|
|
73225
73376
|
return {
|
|
@@ -73268,22 +73419,33 @@ async function runProjectCloseCommand(input) {
|
|
|
73268
73419
|
].join(`
|
|
73269
73420
|
`));
|
|
73270
73421
|
}
|
|
73422
|
+
queueContextRuntimeEvent({
|
|
73423
|
+
cwd: result.projectRoot,
|
|
73424
|
+
kind: "knowledge.closed",
|
|
73425
|
+
properties: {
|
|
73426
|
+
node_count: result.nodes,
|
|
73427
|
+
view_count: result.views,
|
|
73428
|
+
edge_count: result.edges,
|
|
73429
|
+
verify_warning_count: result.verifyWarnings,
|
|
73430
|
+
relationship_coverage: result.relationshipCoverage.state
|
|
73431
|
+
}
|
|
73432
|
+
});
|
|
73271
73433
|
return true;
|
|
73272
73434
|
}
|
|
73273
73435
|
|
|
73274
73436
|
// src/project/reviewApply.ts
|
|
73275
|
-
import { existsSync as
|
|
73437
|
+
import { existsSync as existsSync27 } from "node:fs";
|
|
73276
73438
|
import { mkdir as mkdir22, readFile as readFile34, rm as rm11, writeFile as writeFile18 } from "node:fs/promises";
|
|
73277
|
-
import { dirname as
|
|
73439
|
+
import { dirname as dirname27, join as join42 } from "node:path";
|
|
73278
73440
|
init_cliFeedback();
|
|
73279
73441
|
init_errors();
|
|
73280
73442
|
init_exitCode();
|
|
73281
73443
|
|
|
73282
73444
|
// src/project/proseCompileStructure.ts
|
|
73283
73445
|
import { createHash as createHash15 } from "node:crypto";
|
|
73284
|
-
import { existsSync as
|
|
73446
|
+
import { existsSync as existsSync25 } from "node:fs";
|
|
73285
73447
|
import { mkdir as mkdir20, readFile as readFile32, writeFile as writeFile16 } from "node:fs/promises";
|
|
73286
|
-
import { dirname as
|
|
73448
|
+
import { dirname as dirname25, join as join40 } from "node:path";
|
|
73287
73449
|
init_cliFeedback();
|
|
73288
73450
|
init_errors();
|
|
73289
73451
|
init_exitCode();
|
|
@@ -73292,7 +73454,7 @@ var import_yaml20 = __toESM(require_dist3(), 1);
|
|
|
73292
73454
|
// src/project/proseAlignEvidence.ts
|
|
73293
73455
|
import { createHash as createHash13 } from "node:crypto";
|
|
73294
73456
|
import { readFile as readFile28 } from "node:fs/promises";
|
|
73295
|
-
import { join as
|
|
73457
|
+
import { join as join34 } from "node:path";
|
|
73296
73458
|
|
|
73297
73459
|
// src/incremental/rawBlocks.ts
|
|
73298
73460
|
var import_yaml15 = __toESM(require_dist3(), 1);
|
|
@@ -77187,7 +77349,7 @@ async function loadProseEvidence(input) {
|
|
|
77187
77349
|
const documents = [];
|
|
77188
77350
|
const chunks = [];
|
|
77189
77351
|
for (const [documentIndex, document4] of indexResult.index.documents.entries()) {
|
|
77190
|
-
const markdown = await readFile28(
|
|
77352
|
+
const markdown = await readFile28(join34(input.projectRoot, indexResult.index.materialized_at, document4.path), "utf8");
|
|
77191
77353
|
const locator = locatorFor({
|
|
77192
77354
|
sourceType: resolved.sourceType,
|
|
77193
77355
|
sourceName: resolved.sourceName,
|
|
@@ -77662,19 +77824,19 @@ function repairHints(diagnostics, phaseId) {
|
|
|
77662
77824
|
|
|
77663
77825
|
// src/project/proseAlignStructureSummary.ts
|
|
77664
77826
|
import { mkdir as mkdir18, writeFile as writeFile14 } from "node:fs/promises";
|
|
77665
|
-
import { dirname as
|
|
77827
|
+
import { dirname as dirname23, join as join37 } from "node:path";
|
|
77666
77828
|
|
|
77667
77829
|
// src/project/proseAlignExistingApprovedStructure.ts
|
|
77668
77830
|
var import_yaml16 = __toESM(require_dist3(), 1);
|
|
77669
|
-
import { existsSync as
|
|
77831
|
+
import { existsSync as existsSync23 } from "node:fs";
|
|
77670
77832
|
import { readFile as readFile29, readdir as readdir12 } from "node:fs/promises";
|
|
77671
|
-
import { basename as basename7, join as
|
|
77672
|
-
var APPROVED_STRUCTURE_PATH4 =
|
|
77833
|
+
import { basename as basename7, join as join35, relative as relative14 } from "node:path";
|
|
77834
|
+
var APPROVED_STRUCTURE_PATH4 = join35("knowledge", "structure.yaml");
|
|
77673
77835
|
var KNOWLEDGE_ROOT3 = "knowledge";
|
|
77674
77836
|
function uniqueRefs(refs) {
|
|
77675
77837
|
return [...new Set(refs)].sort();
|
|
77676
77838
|
}
|
|
77677
|
-
function
|
|
77839
|
+
function isRecord15(value) {
|
|
77678
77840
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
77679
77841
|
}
|
|
77680
77842
|
function stringField3(record, key) {
|
|
@@ -77691,14 +77853,14 @@ function toPosixPath10(path4) {
|
|
|
77691
77853
|
return path4.split(/[\\/]+/u).join("/");
|
|
77692
77854
|
}
|
|
77693
77855
|
async function approvedMarkdownFiles(projectRoot) {
|
|
77694
|
-
const root2 =
|
|
77695
|
-
if (!
|
|
77856
|
+
const root2 = join35(projectRoot, KNOWLEDGE_ROOT3);
|
|
77857
|
+
if (!existsSync23(root2))
|
|
77696
77858
|
return [];
|
|
77697
77859
|
const files = [];
|
|
77698
77860
|
const visit3 = async (directory) => {
|
|
77699
77861
|
const entries = await readdir12(directory, { withFileTypes: true });
|
|
77700
77862
|
for (const entry of entries) {
|
|
77701
|
-
const absolutePath =
|
|
77863
|
+
const absolutePath = join35(directory, entry.name);
|
|
77702
77864
|
if (entry.isDirectory()) {
|
|
77703
77865
|
await visit3(absolutePath);
|
|
77704
77866
|
continue;
|
|
@@ -77715,7 +77877,7 @@ function frontmatterRecord(markdown) {
|
|
|
77715
77877
|
if (match === null)
|
|
77716
77878
|
return;
|
|
77717
77879
|
const parsed = import_yaml16.default.parse(match[1] ?? "");
|
|
77718
|
-
return
|
|
77880
|
+
return isRecord15(parsed) ? parsed : undefined;
|
|
77719
77881
|
}
|
|
77720
77882
|
function isDeprecatedApprovedPage(markdown) {
|
|
77721
77883
|
return /^deprecated:\s*true\s*$/mu.test(markdown);
|
|
@@ -77764,7 +77926,7 @@ async function parseExistingApprovedMarkdown(projectRoot) {
|
|
|
77764
77926
|
node_type: existingNode?.node_type ?? nodeType,
|
|
77765
77927
|
tags: uniqueRefs([...existingNode?.tags ?? [], ...nodeTags])
|
|
77766
77928
|
});
|
|
77767
|
-
const relPath = toPosixPath10(relative14(
|
|
77929
|
+
const relPath = toPosixPath10(relative14(join35(projectRoot, KNOWLEDGE_ROOT3), filePath));
|
|
77768
77930
|
const location = pathLocation(relPath);
|
|
77769
77931
|
const collection = viewRef.split(":", 1)[0] ?? location.collection;
|
|
77770
77932
|
views.set(viewRef, {
|
|
@@ -77793,8 +77955,8 @@ async function parseExistingApprovedMarkdown(projectRoot) {
|
|
|
77793
77955
|
return { nodes, views, sections, edges: [], diagnostics: [] };
|
|
77794
77956
|
}
|
|
77795
77957
|
async function readFreshApprovedStructureEdges(projectRoot) {
|
|
77796
|
-
const absolutePath =
|
|
77797
|
-
if (!
|
|
77958
|
+
const absolutePath = join35(projectRoot, APPROVED_STRUCTURE_PATH4);
|
|
77959
|
+
if (!existsSync23(absolutePath))
|
|
77798
77960
|
return { edges: [], diagnostics: [] };
|
|
77799
77961
|
let raw;
|
|
77800
77962
|
try {
|
|
@@ -77803,7 +77965,7 @@ async function readFreshApprovedStructureEdges(projectRoot) {
|
|
|
77803
77965
|
const message = error instanceof Error ? error.message : String(error);
|
|
77804
77966
|
return { edges: [], diagnostics: [`knowledge/structure.yaml could not be parsed: ${message}`] };
|
|
77805
77967
|
}
|
|
77806
|
-
if (!
|
|
77968
|
+
if (!isRecord15(raw) || raw.schema_version !== "context.approved-structure.v1") {
|
|
77807
77969
|
return { edges: [], diagnostics: ["knowledge/structure.yaml schema is not current; approved summary uses Markdown projection only."] };
|
|
77808
77970
|
}
|
|
77809
77971
|
const expectedInputHash = await approvedKnowledgeInputHash(projectRoot).catch(() => {
|
|
@@ -77837,7 +77999,7 @@ function emptyExistingApprovedStructureSummary(diagnostics = []) {
|
|
|
77837
77999
|
function parseApprovedEdges(raw) {
|
|
77838
78000
|
const edges = [];
|
|
77839
78001
|
for (const rawEdge of Array.isArray(raw.edges) ? raw.edges : []) {
|
|
77840
|
-
if (!
|
|
78002
|
+
if (!isRecord15(rawEdge))
|
|
77841
78003
|
continue;
|
|
77842
78004
|
const type = stringField3(rawEdge, "type");
|
|
77843
78005
|
const from = stringField3(rawEdge, "from");
|
|
@@ -77907,7 +78069,7 @@ async function readExistingApprovedStructureSummary(input) {
|
|
|
77907
78069
|
const freshStructure = await readFreshApprovedStructureEdges(input.projectRoot);
|
|
77908
78070
|
approved.edges = freshStructure.edges;
|
|
77909
78071
|
approved.diagnostics.push(...freshStructure.diagnostics);
|
|
77910
|
-
if (approved.nodes.size === 0 && approved.views.size === 0 && approved.sections.size === 0 && !
|
|
78072
|
+
if (approved.nodes.size === 0 && approved.views.size === 0 && approved.sections.size === 0 && !existsSync23(join35(input.projectRoot, APPROVED_STRUCTURE_PATH4))) {
|
|
77911
78073
|
return emptyExistingApprovedStructureSummary();
|
|
77912
78074
|
}
|
|
77913
78075
|
const endpointRefs = new Set([
|
|
@@ -79015,12 +79177,12 @@ function renderStructureSummaryHtml(input) {
|
|
|
79015
79177
|
|
|
79016
79178
|
// src/project/localHtmlReport.ts
|
|
79017
79179
|
import { execFile as execFile3 } from "node:child_process";
|
|
79018
|
-
import { isAbsolute as isAbsolute7, join as
|
|
79180
|
+
import { isAbsolute as isAbsolute7, join as join36 } from "node:path";
|
|
79019
79181
|
import { pathToFileURL } from "node:url";
|
|
79020
79182
|
import { promisify as promisify3 } from "node:util";
|
|
79021
79183
|
var execFileAsync3 = promisify3(execFile3);
|
|
79022
79184
|
function htmlReportReference(input) {
|
|
79023
|
-
const absolutePath = isAbsolute7(input.path) ? input.path :
|
|
79185
|
+
const absolutePath = isAbsolute7(input.path) ? input.path : join36(input.projectRoot, input.path);
|
|
79024
79186
|
return {
|
|
79025
79187
|
format: "html",
|
|
79026
79188
|
path: input.path,
|
|
@@ -79366,9 +79528,9 @@ function buildStructureSummary(input) {
|
|
|
79366
79528
|
async function writeStructureSummaryReport(input) {
|
|
79367
79529
|
const summary = buildStructureSummary(input);
|
|
79368
79530
|
const shortDigest = summary.structure_digest.replace(/^sha256:/u, "").slice(0, 16);
|
|
79369
|
-
const reportPath =
|
|
79370
|
-
const absolutePath =
|
|
79371
|
-
await mkdir18(
|
|
79531
|
+
const reportPath = join37(".tmp", "context-runtime", "reports", `structure-summary-${shortDigest}.html`);
|
|
79532
|
+
const absolutePath = join37(input.projectRoot, reportPath);
|
|
79533
|
+
await mkdir18(dirname23(absolutePath), { recursive: true });
|
|
79372
79534
|
await writeFile14(absolutePath, renderStructureSummaryHtml({ summary, diagnostics: input.diagnostics }), "utf8");
|
|
79373
79535
|
return {
|
|
79374
79536
|
summary,
|
|
@@ -79543,9 +79705,9 @@ function withStructureReviewArtifacts(input) {
|
|
|
79543
79705
|
// src/project/proseCompileViews.ts
|
|
79544
79706
|
var import_yaml17 = __toESM(require_dist3(), 1);
|
|
79545
79707
|
import { createHash as createHash14 } from "node:crypto";
|
|
79546
|
-
import { existsSync as
|
|
79708
|
+
import { existsSync as existsSync24 } from "node:fs";
|
|
79547
79709
|
import { readFile as readFile30 } from "node:fs/promises";
|
|
79548
|
-
import { join as
|
|
79710
|
+
import { join as join38 } from "node:path";
|
|
79549
79711
|
|
|
79550
79712
|
// src/project/proseCompileSemanticRules.ts
|
|
79551
79713
|
function compileSemanticRules(input) {
|
|
@@ -79948,8 +80110,8 @@ function canonicalizeApprovedSourceRef2(ref2, sources) {
|
|
|
79948
80110
|
}
|
|
79949
80111
|
async function existingApprovedNodeSections(input) {
|
|
79950
80112
|
const relativePath = `knowledge/${input.node.path}`;
|
|
79951
|
-
const absolutePath =
|
|
79952
|
-
if (!
|
|
80113
|
+
const absolutePath = join38(input.projectRoot, relativePath);
|
|
80114
|
+
if (!existsSync24(absolutePath)) {
|
|
79953
80115
|
return {
|
|
79954
80116
|
path: relativePath,
|
|
79955
80117
|
present: false,
|
|
@@ -80331,7 +80493,7 @@ function parsePayloadText(raw) {
|
|
|
80331
80493
|
// src/project/proseAlignPayloadStage.ts
|
|
80332
80494
|
var import_yaml19 = __toESM(require_dist3(), 1);
|
|
80333
80495
|
import { mkdir as mkdir19, writeFile as writeFile15 } from "node:fs/promises";
|
|
80334
|
-
import { dirname as
|
|
80496
|
+
import { dirname as dirname24, join as join39 } from "node:path";
|
|
80335
80497
|
init_writeLock();
|
|
80336
80498
|
async function resolveStagedPayloadConfirmation(input) {
|
|
80337
80499
|
await archiveActiveStructure(input.projectRoot);
|
|
@@ -80402,7 +80564,7 @@ async function stageAlignPayload(input) {
|
|
|
80402
80564
|
next: readPlanCommand
|
|
80403
80565
|
});
|
|
80404
80566
|
}
|
|
80405
|
-
const structurePath =
|
|
80567
|
+
const structurePath = join39(input.projectRoot, LIFECYCLE_STRUCTURE_FILE);
|
|
80406
80568
|
const resolved = await resolveStagedPayloadConfirmation(input);
|
|
80407
80569
|
const effectivePayload = {
|
|
80408
80570
|
...resolved.payload,
|
|
@@ -80414,7 +80576,7 @@ async function stageAlignPayload(input) {
|
|
|
80414
80576
|
if (effectivePayload.lifecycle.state === "confirmed" || effectivePayload.lifecycle.state === "frozen") {
|
|
80415
80577
|
await writeStructureSnapshot(input.projectRoot, effectivePayload);
|
|
80416
80578
|
}
|
|
80417
|
-
await mkdir19(
|
|
80579
|
+
await mkdir19(dirname24(structurePath), { recursive: true });
|
|
80418
80580
|
await writeFile15(structurePath, import_yaml19.default.stringify(normalizeAlignPayloadForWrite(effectivePayload)), "utf8");
|
|
80419
80581
|
return {
|
|
80420
80582
|
structureFile: LIFECYCLE_STRUCTURE_FILE,
|
|
@@ -80930,7 +81092,7 @@ function canonicalJson2(value) {
|
|
|
80930
81092
|
function digest3(value) {
|
|
80931
81093
|
return `sha256:${createHash15("sha256").update(canonicalJson2(value)).digest("hex")}`;
|
|
80932
81094
|
}
|
|
80933
|
-
function
|
|
81095
|
+
function isRecord16(value) {
|
|
80934
81096
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
80935
81097
|
}
|
|
80936
81098
|
function stringField4(record, field) {
|
|
@@ -80941,8 +81103,8 @@ function stringArray2(value) {
|
|
|
80941
81103
|
return Array.isArray(value) ? value.filter((item) => typeof item === "string" && item.trim().length > 0) : [];
|
|
80942
81104
|
}
|
|
80943
81105
|
async function readStructureFile(projectRoot) {
|
|
80944
|
-
const structurePath =
|
|
80945
|
-
if (!
|
|
81106
|
+
const structurePath = join40(projectRoot, LIFECYCLE_STRUCTURE_FILE);
|
|
81107
|
+
if (!existsSync25(structurePath)) {
|
|
80946
81108
|
return null;
|
|
80947
81109
|
}
|
|
80948
81110
|
let raw;
|
|
@@ -80967,8 +81129,8 @@ async function readStructureFile(projectRoot) {
|
|
|
80967
81129
|
}
|
|
80968
81130
|
}
|
|
80969
81131
|
async function readApprovedStructureFile(projectRoot) {
|
|
80970
|
-
const structurePath =
|
|
80971
|
-
if (!
|
|
81132
|
+
const structurePath = join40(projectRoot, APPROVED_STRUCTURE_FILE2);
|
|
81133
|
+
if (!existsSync25(structurePath))
|
|
80972
81134
|
return null;
|
|
80973
81135
|
try {
|
|
80974
81136
|
return import_yaml20.default.parse(await readFile32(structurePath, "utf8"));
|
|
@@ -80983,13 +81145,13 @@ async function readApprovedStructureFile(projectRoot) {
|
|
|
80983
81145
|
async function compileStructureSlotDigest(input) {
|
|
80984
81146
|
const slotDigest = await currentStructureSlotDigest(input.projectRoot, input.sourceKey, input.collection);
|
|
80985
81147
|
const current2 = await readStructureFile(input.projectRoot);
|
|
80986
|
-
if (current2 === null || !
|
|
81148
|
+
if (current2 === null || !isRecord16(current2) || !Array.isArray(current2.sources) || !Array.isArray(current2.views)) {
|
|
80987
81149
|
return slotDigest;
|
|
80988
81150
|
}
|
|
80989
|
-
const currentOwnsTarget = current2.sources.includes(input.sourceKey) && current2.views.some((view) =>
|
|
81151
|
+
const currentOwnsTarget = current2.sources.includes(input.sourceKey) && current2.views.some((view) => isRecord16(view) && view.collection === input.collection);
|
|
80990
81152
|
if (!currentOwnsTarget)
|
|
80991
81153
|
return slotDigest;
|
|
80992
|
-
const lifecycle =
|
|
81154
|
+
const lifecycle = isRecord16(current2.lifecycle) ? current2.lifecycle : undefined;
|
|
80993
81155
|
const currentDigest = lifecycle === undefined ? undefined : stringField4(lifecycle, "structure_digest");
|
|
80994
81156
|
return slotDigest !== undefined && slotDigest !== currentDigest ? slotDigest : undefined;
|
|
80995
81157
|
}
|
|
@@ -80998,7 +81160,7 @@ function parseApprovedSections(value, viewRef) {
|
|
|
80998
81160
|
return [];
|
|
80999
81161
|
const sections = [];
|
|
81000
81162
|
for (const rawSection of value) {
|
|
81001
|
-
if (!
|
|
81163
|
+
if (!isRecord16(rawSection))
|
|
81002
81164
|
continue;
|
|
81003
81165
|
const id2 = stringField4(rawSection, "id");
|
|
81004
81166
|
const kind = stringField4(rawSection, "kind");
|
|
@@ -81021,7 +81183,7 @@ function parseApprovedNodes(value) {
|
|
|
81021
81183
|
return [];
|
|
81022
81184
|
const nodes = [];
|
|
81023
81185
|
for (const rawNode of value) {
|
|
81024
|
-
if (!
|
|
81186
|
+
if (!isRecord16(rawNode))
|
|
81025
81187
|
continue;
|
|
81026
81188
|
const nodeRef = stringField4(rawNode, "node_ref");
|
|
81027
81189
|
const title = stringField4(rawNode, "title");
|
|
@@ -81045,7 +81207,7 @@ function parseApprovedViews(value, nodes) {
|
|
|
81045
81207
|
const nodeByRef = new Map(nodes.map((node3) => [node3.node_ref, node3]));
|
|
81046
81208
|
const views = [];
|
|
81047
81209
|
for (const rawView of value) {
|
|
81048
|
-
if (!
|
|
81210
|
+
if (!isRecord16(rawView))
|
|
81049
81211
|
continue;
|
|
81050
81212
|
const viewRef = stringField4(rawView, "view_ref");
|
|
81051
81213
|
const nodeRef = stringField4(rawView, "node_ref");
|
|
@@ -81083,7 +81245,7 @@ function parseApprovedEdges2(value) {
|
|
|
81083
81245
|
return [];
|
|
81084
81246
|
const edges = [];
|
|
81085
81247
|
for (const rawEdge of value) {
|
|
81086
|
-
if (!
|
|
81248
|
+
if (!isRecord16(rawEdge))
|
|
81087
81249
|
continue;
|
|
81088
81250
|
const type = stringField4(rawEdge, "type");
|
|
81089
81251
|
const from = stringField4(rawEdge, "from");
|
|
@@ -81147,7 +81309,7 @@ function assertApprovedEdgeContract(value, endpointRefs) {
|
|
|
81147
81309
|
});
|
|
81148
81310
|
}
|
|
81149
81311
|
for (const [index2, rawEdge] of value.entries()) {
|
|
81150
|
-
if (!
|
|
81312
|
+
if (!isRecord16(rawEdge)) {
|
|
81151
81313
|
throw workspaceError("knowledge/structure.yaml edge must be an object", {
|
|
81152
81314
|
path: APPROVED_STRUCTURE_FILE2,
|
|
81153
81315
|
edge_index: index2,
|
|
@@ -81287,7 +81449,7 @@ async function loadConfirmedStructure(input) {
|
|
|
81287
81449
|
let rawStructure = input.structureDigest === undefined ? await readStructureFile(input.projectRoot) : await readStructureSnapshot(input.projectRoot, input.structureDigest);
|
|
81288
81450
|
if (rawStructure === null && input.structureDigest !== undefined) {
|
|
81289
81451
|
const active = await readStructureFile(input.projectRoot);
|
|
81290
|
-
const activeDigest =
|
|
81452
|
+
const activeDigest = isRecord16(active) && isRecord16(active.lifecycle) ? stringField4(active.lifecycle, "structure_digest") : undefined;
|
|
81291
81453
|
if (activeDigest === input.structureDigest) {
|
|
81292
81454
|
rawStructure = active;
|
|
81293
81455
|
} else if (input.readOnly !== true) {
|
|
@@ -81304,7 +81466,7 @@ async function loadConfirmedStructure(input) {
|
|
|
81304
81466
|
});
|
|
81305
81467
|
}
|
|
81306
81468
|
const approvedStructure = await readApprovedStructureFile(input.projectRoot);
|
|
81307
|
-
if (!
|
|
81469
|
+
if (!isRecord16(approvedStructure)) {
|
|
81308
81470
|
throw workspaceError("compileProse requires confirmed .tmp/context-runtime/lifecycle/structure.yaml or approved knowledge/structure.yaml", {
|
|
81309
81471
|
path: LIFECYCLE_STRUCTURE_FILE,
|
|
81310
81472
|
approved_structure: APPROVED_STRUCTURE_FILE2,
|
|
@@ -81400,8 +81562,8 @@ async function freezeStructureIfNeeded(input) {
|
|
|
81400
81562
|
};
|
|
81401
81563
|
await archiveActiveStructure(input.projectRoot);
|
|
81402
81564
|
await writeStructureSnapshot(input.projectRoot, nextStructure);
|
|
81403
|
-
const structurePath =
|
|
81404
|
-
await mkdir20(
|
|
81565
|
+
const structurePath = join40(input.projectRoot, LIFECYCLE_STRUCTURE_FILE);
|
|
81566
|
+
await mkdir20(dirname25(structurePath), { recursive: true });
|
|
81405
81567
|
await writeFile16(structurePath, import_yaml20.default.stringify({
|
|
81406
81568
|
schema_version: nextStructure.schema_version,
|
|
81407
81569
|
sources: nextStructure.sources,
|
|
@@ -81484,9 +81646,9 @@ var import_yaml22 = __toESM(require_dist3(), 1);
|
|
|
81484
81646
|
|
|
81485
81647
|
// src/project/reviewShared.ts
|
|
81486
81648
|
import { createHash as createHash16 } from "node:crypto";
|
|
81487
|
-
import { existsSync as
|
|
81649
|
+
import { existsSync as existsSync26, readdirSync as readdirSync2, readFileSync as readFileSync7 } from "node:fs";
|
|
81488
81650
|
import { mkdir as mkdir21, readFile as readFile33, rm as rm10, rmdir as rmdir2, writeFile as writeFile17 } from "node:fs/promises";
|
|
81489
|
-
import { dirname as
|
|
81651
|
+
import { dirname as dirname26, join as join41 } from "node:path";
|
|
81490
81652
|
init_cliFeedback();
|
|
81491
81653
|
init_errors();
|
|
81492
81654
|
init_exitCode();
|
|
@@ -81516,10 +81678,10 @@ function proseCandidateMarkdown(input) {
|
|
|
81516
81678
|
|
|
81517
81679
|
// src/project/reviewShared.ts
|
|
81518
81680
|
init_workspace();
|
|
81519
|
-
var SNAPSHOT_ROOT2 =
|
|
81520
|
-
var REVIEW_ACTION_ROOT2 =
|
|
81681
|
+
var SNAPSHOT_ROOT2 = join41(".tmp", "context-runtime", "extract", "candidates");
|
|
81682
|
+
var REVIEW_ACTION_ROOT2 = join41(".tmp", "context-runtime", "review-actions");
|
|
81521
81683
|
var REVIEW_PAYLOAD_SCHEMA = "context.review.decisions.v1";
|
|
81522
|
-
function
|
|
81684
|
+
function isRecord17(value) {
|
|
81523
81685
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
81524
81686
|
}
|
|
81525
81687
|
function assertCollection(value) {
|
|
@@ -81540,26 +81702,26 @@ function assertCollection(value) {
|
|
|
81540
81702
|
}
|
|
81541
81703
|
function snapshotPath2(projectRoot, candidateId) {
|
|
81542
81704
|
assertSafeEntityId(candidateId);
|
|
81543
|
-
return
|
|
81705
|
+
return join41(projectRoot, SNAPSHOT_ROOT2, `${candidateId}.json`);
|
|
81544
81706
|
}
|
|
81545
81707
|
async function readCandidateSnapshot(projectRoot, candidateId) {
|
|
81546
81708
|
const file = snapshotPath2(projectRoot, candidateId);
|
|
81547
|
-
if (!
|
|
81709
|
+
if (!existsSync26(file))
|
|
81548
81710
|
return;
|
|
81549
81711
|
let parsed;
|
|
81550
81712
|
try {
|
|
81551
81713
|
parsed = JSON.parse(await readFile33(file, "utf8"));
|
|
81552
81714
|
} catch (error) {
|
|
81553
81715
|
const message = error instanceof Error ? error.message : String(error);
|
|
81554
|
-
throw new ContextError(ExitCode.WorkspaceStateError, `candidate snapshot is invalid JSON: ${
|
|
81716
|
+
throw new ContextError(ExitCode.WorkspaceStateError, `candidate snapshot is invalid JSON: ${join41(SNAPSHOT_ROOT2, `${candidateId}.json`)}`, {
|
|
81555
81717
|
category: ErrorCategory.SchemaInvalid,
|
|
81556
81718
|
candidate_id: candidateId,
|
|
81557
81719
|
reason: message,
|
|
81558
81720
|
next: "Rerun the extract phase before reviewing this candidate."
|
|
81559
81721
|
});
|
|
81560
81722
|
}
|
|
81561
|
-
if (!
|
|
81562
|
-
throw new ContextError(ExitCode.WorkspaceStateError, `candidate snapshot is invalid: ${
|
|
81723
|
+
if (!isRecord17(parsed) || typeof parsed.candidate_id !== "string" || typeof parsed.markdown !== "string") {
|
|
81724
|
+
throw new ContextError(ExitCode.WorkspaceStateError, `candidate snapshot is invalid: ${join41(SNAPSHOT_ROOT2, `${candidateId}.json`)}`, {
|
|
81563
81725
|
category: ErrorCategory.SchemaInvalid,
|
|
81564
81726
|
candidate_id: candidateId,
|
|
81565
81727
|
next: "Rerun the extract phase before reviewing this candidate."
|
|
@@ -81590,15 +81752,15 @@ async function extractCandidateSnapshotIsCurrent(projectRoot, snapshot) {
|
|
|
81590
81752
|
async function removeCandidateSnapshot2(projectRoot, candidateId) {
|
|
81591
81753
|
const file = snapshotPath2(projectRoot, candidateId);
|
|
81592
81754
|
await rm10(file, { force: true });
|
|
81593
|
-
const snapshotRoot =
|
|
81594
|
-
let current2 =
|
|
81755
|
+
const snapshotRoot = join41(projectRoot, SNAPSHOT_ROOT2);
|
|
81756
|
+
let current2 = dirname26(file);
|
|
81595
81757
|
while (current2 !== snapshotRoot && current2.startsWith(snapshotRoot)) {
|
|
81596
81758
|
try {
|
|
81597
81759
|
await rmdir2(current2);
|
|
81598
81760
|
} catch {
|
|
81599
81761
|
break;
|
|
81600
81762
|
}
|
|
81601
|
-
current2 =
|
|
81763
|
+
current2 = dirname26(current2);
|
|
81602
81764
|
}
|
|
81603
81765
|
}
|
|
81604
81766
|
function parseCanonicalSourceRef(ref2) {
|
|
@@ -81719,11 +81881,11 @@ function findApprovedPageForViewRef(projectRoot, viewRef) {
|
|
|
81719
81881
|
}
|
|
81720
81882
|
const nodeRef = viewRef.slice(separator + 1);
|
|
81721
81883
|
assertSafeEntityId(nodeRef);
|
|
81722
|
-
const collectionRoot =
|
|
81723
|
-
if (
|
|
81884
|
+
const collectionRoot = join41(projectRoot, "knowledge", collection);
|
|
81885
|
+
if (existsSync26(collectionRoot)) {
|
|
81724
81886
|
const visit3 = (dir, relDir) => {
|
|
81725
81887
|
for (const entry of readdirSync2(dir, { withFileTypes: true })) {
|
|
81726
|
-
const absPath =
|
|
81888
|
+
const absPath = join41(dir, entry.name);
|
|
81727
81889
|
const rel = relDir.length === 0 ? entry.name : `${relDir}/${entry.name}`;
|
|
81728
81890
|
if (entry.isDirectory()) {
|
|
81729
81891
|
const found2 = visit3(absPath, rel);
|
|
@@ -81733,16 +81895,16 @@ function findApprovedPageForViewRef(projectRoot, viewRef) {
|
|
|
81733
81895
|
}
|
|
81734
81896
|
if (!entry.isFile() || !entry.name.endsWith(".md"))
|
|
81735
81897
|
continue;
|
|
81736
|
-
const block = frontmatterBlock(
|
|
81898
|
+
const block = frontmatterBlock(readFileSync7(absPath, "utf8"));
|
|
81737
81899
|
if (block === null)
|
|
81738
81900
|
continue;
|
|
81739
81901
|
const parsed = import_yaml21.default.parse(block.yaml);
|
|
81740
|
-
if (!
|
|
81902
|
+
if (!isRecord17(parsed) || parsed.view_ref !== viewRef)
|
|
81741
81903
|
continue;
|
|
81742
81904
|
const approvedNodeRef = typeof parsed.node_ref === "string" && parsed.node_ref.trim().length > 0 ? parsed.node_ref.trim() : nodeRef;
|
|
81743
81905
|
return {
|
|
81744
81906
|
path: absPath,
|
|
81745
|
-
relPath:
|
|
81907
|
+
relPath: join41("knowledge", collection, rel),
|
|
81746
81908
|
nodeRef: approvedNodeRef
|
|
81747
81909
|
};
|
|
81748
81910
|
}
|
|
@@ -81783,7 +81945,7 @@ function updateFrontmatter(content3, mutate) {
|
|
|
81783
81945
|
});
|
|
81784
81946
|
}
|
|
81785
81947
|
const parsed = import_yaml21.default.parse(block.yaml);
|
|
81786
|
-
if (!
|
|
81948
|
+
if (!isRecord17(parsed)) {
|
|
81787
81949
|
throw new ContextError(ExitCode.WorkspaceStateError, "approved page frontmatter must be a YAML object", {
|
|
81788
81950
|
category: ErrorCategory.SchemaInvalid
|
|
81789
81951
|
});
|
|
@@ -81798,16 +81960,16 @@ function parseApprovedSources(content3) {
|
|
|
81798
81960
|
if (block === null)
|
|
81799
81961
|
return [];
|
|
81800
81962
|
const parsed = import_yaml21.default.parse(block.yaml);
|
|
81801
|
-
if (!
|
|
81963
|
+
if (!isRecord17(parsed))
|
|
81802
81964
|
return [];
|
|
81803
81965
|
const sources = parsed.sources;
|
|
81804
81966
|
return Array.isArray(sources) ? sources.filter((source2) => typeof source2 === "string") : [];
|
|
81805
81967
|
}
|
|
81806
81968
|
async function writeReviewActionLog(input) {
|
|
81807
81969
|
const stamp = new Date().toISOString().replace(/[-:.TZ]/gu, "");
|
|
81808
|
-
const relPath =
|
|
81809
|
-
const path4 =
|
|
81810
|
-
await mkdir21(
|
|
81970
|
+
const relPath = join41(REVIEW_ACTION_ROOT2, `${stamp}-${input.action}-${input.id.replace(/[\\/]+/gu, "_")}.json`);
|
|
81971
|
+
const path4 = join41(input.projectRoot, relPath);
|
|
81972
|
+
await mkdir21(dirname26(path4), { recursive: true });
|
|
81811
81973
|
await writeFile17(path4, `${JSON.stringify({
|
|
81812
81974
|
action: input.action,
|
|
81813
81975
|
id: input.id,
|
|
@@ -82302,7 +82464,7 @@ async function prepareApprovedPage(input) {
|
|
|
82302
82464
|
if (input.record.candidate_type !== "prose-align") {
|
|
82303
82465
|
assertSafeEntityId(input.record.node_ref);
|
|
82304
82466
|
}
|
|
82305
|
-
relPath =
|
|
82467
|
+
relPath = join42("knowledge", input.record.path);
|
|
82306
82468
|
const existingView = findApprovedPageForViewRef(input.projectRoot, input.record.view_ref);
|
|
82307
82469
|
if (existingView !== undefined && existingView.relPath !== relPath) {
|
|
82308
82470
|
throw new ContextError(ExitCode.WorkspaceStateError, `approved page already exists for view_ref at a different path: ${input.record.view_ref}`, {
|
|
@@ -82314,8 +82476,8 @@ async function prepareApprovedPage(input) {
|
|
|
82314
82476
|
next: "Resolve the approved page path migration explicitly before approving this candidate."
|
|
82315
82477
|
});
|
|
82316
82478
|
}
|
|
82317
|
-
const absPath =
|
|
82318
|
-
const existing =
|
|
82479
|
+
const absPath = join42(input.projectRoot, relPath);
|
|
82480
|
+
const existing = existsSync27(absPath) ? await readFile34(absPath, "utf8") : undefined;
|
|
82319
82481
|
if (existing !== undefined) {
|
|
82320
82482
|
const frontmatter = parseFrontmatterLoose(existing);
|
|
82321
82483
|
const existingViewRef = typeof frontmatter.view_ref === "string" ? frontmatter.view_ref : undefined;
|
|
@@ -82387,11 +82549,11 @@ async function prepareApprovedPage(input) {
|
|
|
82387
82549
|
}
|
|
82388
82550
|
async function writePreparedApprovedPage(page) {
|
|
82389
82551
|
for (const asset of page.assets) {
|
|
82390
|
-
await mkdir22(
|
|
82552
|
+
await mkdir22(dirname27(asset.absPath), { recursive: true });
|
|
82391
82553
|
await writeFile18(asset.absPath, asset.bytes);
|
|
82392
82554
|
}
|
|
82393
82555
|
if (page.changed) {
|
|
82394
|
-
await mkdir22(
|
|
82556
|
+
await mkdir22(dirname27(page.absPath), { recursive: true });
|
|
82395
82557
|
await writeFile18(page.absPath, page.content, "utf8");
|
|
82396
82558
|
}
|
|
82397
82559
|
}
|
|
@@ -82622,18 +82784,18 @@ init_errors();
|
|
|
82622
82784
|
init_exitCode();
|
|
82623
82785
|
|
|
82624
82786
|
// src/project/repoSources.ts
|
|
82625
|
-
import { existsSync as
|
|
82787
|
+
import { existsSync as existsSync30 } from "node:fs";
|
|
82626
82788
|
import { lstat, mkdir as mkdir23, readFile as readFile35, readlink, realpath as realpath2, rm as rm12, symlink } from "node:fs/promises";
|
|
82627
82789
|
import { execFile as execFile4 } from "node:child_process";
|
|
82628
82790
|
import { promisify as promisify4 } from "node:util";
|
|
82629
|
-
import { dirname as
|
|
82791
|
+
import { dirname as dirname28, isAbsolute as isAbsolute8, join as join45, relative as relative15, resolve as resolve17 } from "node:path";
|
|
82630
82792
|
init_cliFeedback();
|
|
82631
82793
|
init_errors();
|
|
82632
82794
|
init_exitCode();
|
|
82633
82795
|
|
|
82634
82796
|
// src/project/repoSourceModules.ts
|
|
82635
|
-
import { existsSync as
|
|
82636
|
-
import { join as
|
|
82797
|
+
import { existsSync as existsSync28 } from "node:fs";
|
|
82798
|
+
import { join as join43, resolve as resolve16 } from "node:path";
|
|
82637
82799
|
function normalizeSubpath(value) {
|
|
82638
82800
|
if (value === undefined)
|
|
82639
82801
|
return;
|
|
@@ -82660,8 +82822,8 @@ function suggestedModuleName(module) {
|
|
|
82660
82822
|
return slug || "module";
|
|
82661
82823
|
}
|
|
82662
82824
|
async function inspectRepoSourceModules(input) {
|
|
82663
|
-
const inspectPath = input.scopedAbs !== null &&
|
|
82664
|
-
const modules =
|
|
82825
|
+
const inspectPath = input.scopedAbs !== null && existsSync28(input.scopedAbs) ? input.scopedAbs : join43(input.projectRoot, input.status.materializedAt);
|
|
82826
|
+
const modules = existsSync28(inspectPath) ? await detectModuleBoundaries(inspectPath, input.status.head ?? input.status.ref, DEFAULT_PATH_FILTER) : [];
|
|
82665
82827
|
const recommended_sources = modules.filter((module) => module.path !== "." || modules.length === 1).map((module) => {
|
|
82666
82828
|
const local = sourceModuleLocalForDisplay({ source: input.source, status: input.status, module });
|
|
82667
82829
|
return {
|
|
@@ -82692,8 +82854,8 @@ function resolveRepoSourceScopedPath(localAbs, subpath) {
|
|
|
82692
82854
|
|
|
82693
82855
|
// src/project/repoSourceRegistry.ts
|
|
82694
82856
|
var import_yaml24 = __toESM(require_dist3(), 1);
|
|
82695
|
-
import { existsSync as
|
|
82696
|
-
import { join as
|
|
82857
|
+
import { existsSync as existsSync29 } from "node:fs";
|
|
82858
|
+
import { join as join44 } from "node:path";
|
|
82697
82859
|
init_cliFeedback();
|
|
82698
82860
|
init_errors();
|
|
82699
82861
|
init_exitCode();
|
|
@@ -82750,14 +82912,14 @@ function registryEntryToRecord(entry) {
|
|
|
82750
82912
|
};
|
|
82751
82913
|
}
|
|
82752
82914
|
function registryPath(projectRoot) {
|
|
82753
|
-
return
|
|
82915
|
+
return join44(projectRoot, DEFAULT_REPO_SOURCES_REGISTRY_PATH);
|
|
82754
82916
|
}
|
|
82755
82917
|
function defaultRepoMaterializedAt(source2) {
|
|
82756
82918
|
return `sources/repo/${source2.namespace}/${source2.module}`;
|
|
82757
82919
|
}
|
|
82758
82920
|
async function readRepoRegistry(projectRoot) {
|
|
82759
82921
|
const path4 = registryPath(projectRoot);
|
|
82760
|
-
if (!
|
|
82922
|
+
if (!existsSync29(path4))
|
|
82761
82923
|
return { repos: [] };
|
|
82762
82924
|
const registry2 = await loadSourcesRegistry({ rootDir: projectRoot });
|
|
82763
82925
|
return {
|
|
@@ -82833,13 +82995,13 @@ async function gitOutput(cwd, args) {
|
|
|
82833
82995
|
}
|
|
82834
82996
|
}
|
|
82835
82997
|
async function readGitOriginRemote(cwd) {
|
|
82836
|
-
const directConfigPath =
|
|
82998
|
+
const directConfigPath = join45(cwd, ".git", "config");
|
|
82837
82999
|
let config = await readFile35(directConfigPath, "utf8").catch(() => "");
|
|
82838
83000
|
if (config.length === 0) {
|
|
82839
83001
|
const gitDir = await resolveGitDir(cwd);
|
|
82840
83002
|
if (gitDir === null)
|
|
82841
83003
|
return null;
|
|
82842
|
-
config = await readFile35(
|
|
83004
|
+
config = await readFile35(join45(gitDir, "config"), "utf8").catch(() => "");
|
|
82843
83005
|
}
|
|
82844
83006
|
let inOriginBlock = false;
|
|
82845
83007
|
for (const line of config.split(/\r?\n/u)) {
|
|
@@ -82859,17 +83021,17 @@ async function readGitOriginRemote(cwd) {
|
|
|
82859
83021
|
async function resolveGitRoot(cwd) {
|
|
82860
83022
|
let current2 = resolve17(cwd);
|
|
82861
83023
|
while (true) {
|
|
82862
|
-
if (
|
|
83024
|
+
if (existsSync30(join45(current2, ".git")))
|
|
82863
83025
|
return current2;
|
|
82864
|
-
const parent =
|
|
83026
|
+
const parent = dirname28(current2);
|
|
82865
83027
|
if (parent === current2)
|
|
82866
83028
|
return null;
|
|
82867
83029
|
current2 = parent;
|
|
82868
83030
|
}
|
|
82869
83031
|
}
|
|
82870
83032
|
async function resolveGitDir(cwd) {
|
|
82871
|
-
const dotGit =
|
|
82872
|
-
if (!
|
|
83033
|
+
const dotGit = join45(cwd, ".git");
|
|
83034
|
+
if (!existsSync30(dotGit))
|
|
82873
83035
|
return null;
|
|
82874
83036
|
const stats = await lstat(dotGit);
|
|
82875
83037
|
if (stats.isDirectory())
|
|
@@ -82886,17 +83048,17 @@ async function readGitHead(cwd) {
|
|
|
82886
83048
|
const gitDir = await resolveGitDir(cwd);
|
|
82887
83049
|
if (gitDir === null)
|
|
82888
83050
|
return null;
|
|
82889
|
-
const headRaw = (await readFile35(
|
|
83051
|
+
const headRaw = (await readFile35(join45(gitDir, "HEAD"), "utf8").catch(() => "")).trim();
|
|
82890
83052
|
if (/^[a-f0-9]{40}$/iu.test(headRaw))
|
|
82891
83053
|
return headRaw.toLowerCase();
|
|
82892
83054
|
const match = /^ref:\s*(.+)\s*$/iu.exec(headRaw);
|
|
82893
83055
|
const refPath = match?.[1];
|
|
82894
83056
|
if (refPath === undefined)
|
|
82895
83057
|
return null;
|
|
82896
|
-
const looseRef = (await readFile35(
|
|
83058
|
+
const looseRef = (await readFile35(join45(gitDir, refPath), "utf8").catch(() => "")).trim();
|
|
82897
83059
|
if (/^[a-f0-9]{40}$/iu.test(looseRef))
|
|
82898
83060
|
return looseRef.toLowerCase();
|
|
82899
|
-
const packedRefs = await readFile35(
|
|
83061
|
+
const packedRefs = await readFile35(join45(gitDir, "packed-refs"), "utf8").catch(() => "");
|
|
82900
83062
|
for (const line of packedRefs.split(/\r?\n/u)) {
|
|
82901
83063
|
if (line.startsWith("#") || line.startsWith("^"))
|
|
82902
83064
|
continue;
|
|
@@ -82907,27 +83069,27 @@ async function readGitHead(cwd) {
|
|
|
82907
83069
|
return null;
|
|
82908
83070
|
}
|
|
82909
83071
|
async function ensureMaterializedSymlink(input) {
|
|
82910
|
-
const linkPath =
|
|
82911
|
-
await mkdir23(
|
|
82912
|
-
if (
|
|
83072
|
+
const linkPath = join45(input.projectRoot, input.materializedAt);
|
|
83073
|
+
await mkdir23(dirname28(linkPath), { recursive: true });
|
|
83074
|
+
if (existsSync30(linkPath)) {
|
|
82913
83075
|
const stats = await lstat(linkPath);
|
|
82914
83076
|
if (!stats.isSymbolicLink()) {
|
|
82915
83077
|
input.diagnostics.push(`materialized path exists and is not a symlink: ${input.materializedAt}`);
|
|
82916
83078
|
return false;
|
|
82917
83079
|
}
|
|
82918
83080
|
const current2 = await readlink(linkPath);
|
|
82919
|
-
const currentAbs = resolve17(
|
|
83081
|
+
const currentAbs = resolve17(dirname28(linkPath), current2);
|
|
82920
83082
|
if (currentAbs === input.localAbs)
|
|
82921
83083
|
return true;
|
|
82922
83084
|
await rm12(linkPath);
|
|
82923
83085
|
}
|
|
82924
|
-
const relTarget = relative15(
|
|
83086
|
+
const relTarget = relative15(dirname28(linkPath), input.localAbs) || ".";
|
|
82925
83087
|
await symlink(relTarget, linkPath);
|
|
82926
83088
|
return true;
|
|
82927
83089
|
}
|
|
82928
83090
|
async function diagnoseMaterializedSymlink(input) {
|
|
82929
|
-
const linkPath =
|
|
82930
|
-
if (!
|
|
83091
|
+
const linkPath = join45(input.projectRoot, input.materializedAt);
|
|
83092
|
+
if (!existsSync30(linkPath)) {
|
|
82931
83093
|
input.diagnostics.push(`materialized path is missing: ${input.materializedAt}`);
|
|
82932
83094
|
input.agent_hints.push(`Run context source ensure ${input.sourceName} to materialize the local source link.`);
|
|
82933
83095
|
return false;
|
|
@@ -82938,9 +83100,9 @@ async function diagnoseMaterializedSymlink(input) {
|
|
|
82938
83100
|
return false;
|
|
82939
83101
|
}
|
|
82940
83102
|
const current2 = await readlink(linkPath);
|
|
82941
|
-
const currentAbs = resolve17(
|
|
83103
|
+
const currentAbs = resolve17(dirname28(linkPath), current2);
|
|
82942
83104
|
if (currentAbs !== input.localAbs) {
|
|
82943
|
-
input.diagnostics.push(`materialized path points to ${current2}, expected local checkout ${relative15(
|
|
83105
|
+
input.diagnostics.push(`materialized path points to ${current2}, expected local checkout ${relative15(dirname28(linkPath), input.localAbs) || "."}`);
|
|
82944
83106
|
input.agent_hints.push(`Run context source ensure ${input.sourceName} to refresh the local source link.`);
|
|
82945
83107
|
return false;
|
|
82946
83108
|
}
|
|
@@ -82972,7 +83134,7 @@ async function normalizeInputRef(input) {
|
|
|
82972
83134
|
next: "Pass --local <path> with a git checkout, or use a full 40-character commit sha."
|
|
82973
83135
|
});
|
|
82974
83136
|
}
|
|
82975
|
-
if (!
|
|
83137
|
+
if (!existsSync30(localAbs)) {
|
|
82976
83138
|
throw new ContextError(ExitCode.UserError, `short repo source ref cannot be resolved because local path is missing: ${input.local}`, {
|
|
82977
83139
|
category: ErrorCategory.UserInputInvalid,
|
|
82978
83140
|
sourceName: input.sourceName,
|
|
@@ -83024,7 +83186,7 @@ async function normalizeAddInput(input, existing) {
|
|
|
83024
83186
|
let gitRootAbs = null;
|
|
83025
83187
|
if (originalLocal !== undefined) {
|
|
83026
83188
|
const originalLocalAbs = resolveLocalPath(input.projectRoot, originalLocal);
|
|
83027
|
-
if (originalLocalAbs !== null &&
|
|
83189
|
+
if (originalLocalAbs !== null && existsSync30(originalLocalAbs)) {
|
|
83028
83190
|
gitRootAbs = await resolveGitRoot(originalLocalAbs);
|
|
83029
83191
|
if (gitRootAbs !== null && input.local !== undefined) {
|
|
83030
83192
|
const detectedSubpath = normalizeSubpath2(relative15(gitRootAbs, originalLocalAbs));
|
|
@@ -83120,11 +83282,11 @@ async function inspectRepoSource(input) {
|
|
|
83120
83282
|
const diagnostics = [];
|
|
83121
83283
|
const agent_hints = [];
|
|
83122
83284
|
const localAbs = resolveLocalPath(input.projectRoot, source2.local);
|
|
83123
|
-
const localExists = localAbs !== null &&
|
|
83285
|
+
const localExists = localAbs !== null && existsSync30(localAbs);
|
|
83124
83286
|
const subpath = normalizeSubpath2(source2.subpath);
|
|
83125
83287
|
const scopedAbs = localAbs === null ? null : scopedLocalPath(localAbs, subpath);
|
|
83126
|
-
const scopeExists = scopedAbs !== null &&
|
|
83127
|
-
let materialized =
|
|
83288
|
+
const scopeExists = scopedAbs !== null && existsSync30(scopedAbs);
|
|
83289
|
+
let materialized = existsSync30(join45(input.projectRoot, materializedAt));
|
|
83128
83290
|
const checkout = await inspectRepoCheckout({
|
|
83129
83291
|
source: source2,
|
|
83130
83292
|
localAbs,
|
|
@@ -83773,24 +83935,24 @@ The approved symbol is no longer present in the current code extraction.
|
|
|
83773
83935
|
// src/project/packageBuilder.ts
|
|
83774
83936
|
init_cliFeedback();
|
|
83775
83937
|
init_errors();
|
|
83776
|
-
init_exitCode();
|
|
83777
83938
|
var import_yaml28 = __toESM(require_dist3(), 1);
|
|
83778
83939
|
import { createHash as createHash20 } from "node:crypto";
|
|
83779
|
-
import { existsSync as
|
|
83940
|
+
import { existsSync as existsSync35 } from "node:fs";
|
|
83780
83941
|
import { mkdir as mkdir27, readdir as readdir15, readFile as readFile41, rm as rm13, writeFile as writeFile22 } from "node:fs/promises";
|
|
83781
|
-
import { dirname as
|
|
83942
|
+
import { dirname as dirname34, join as join52, resolve as resolve19 } from "node:path";
|
|
83943
|
+
init_exitCode();
|
|
83782
83944
|
|
|
83783
83945
|
// src/project/packageBuildInventory.ts
|
|
83784
83946
|
var import_yaml26 = __toESM(require_dist3(), 1);
|
|
83785
83947
|
import { createHash as createHash17 } from "node:crypto";
|
|
83786
|
-
import { existsSync as
|
|
83948
|
+
import { existsSync as existsSync32 } from "node:fs";
|
|
83787
83949
|
import { mkdir as mkdir25, readFile as readFile37, writeFile as writeFile20 } from "node:fs/promises";
|
|
83788
|
-
import { dirname as
|
|
83950
|
+
import { dirname as dirname30, join as join47 } from "node:path";
|
|
83789
83951
|
|
|
83790
83952
|
// src/project/packageIndexes.ts
|
|
83791
|
-
import { existsSync as
|
|
83953
|
+
import { existsSync as existsSync31, statSync } from "node:fs";
|
|
83792
83954
|
import { mkdir as mkdir24, readdir as readdir13, readFile as readFile36, writeFile as writeFile19 } from "node:fs/promises";
|
|
83793
|
-
import { dirname as
|
|
83955
|
+
import { dirname as dirname29, join as join46, posix as pathPosix, relative as relative16 } from "node:path";
|
|
83794
83956
|
init_cliFeedback();
|
|
83795
83957
|
init_errors();
|
|
83796
83958
|
init_exitCode();
|
|
@@ -83944,7 +84106,7 @@ var PACKAGE_INVENTORY_FIELDS = [
|
|
|
83944
84106
|
"candidate_fingerprint"
|
|
83945
84107
|
];
|
|
83946
84108
|
var COMPILER_ONLY_TAGS = new Set(["docs", "prose", "parent-index"]);
|
|
83947
|
-
function
|
|
84109
|
+
function isRecord18(value) {
|
|
83948
84110
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
83949
84111
|
}
|
|
83950
84112
|
function stringList2(value) {
|
|
@@ -83958,7 +84120,7 @@ function parseKnowledgeFrontmatter(content3) {
|
|
|
83958
84120
|
return {};
|
|
83959
84121
|
try {
|
|
83960
84122
|
const parsed = import_yaml25.parse(match[1]);
|
|
83961
|
-
return
|
|
84123
|
+
return isRecord18(parsed) ? parsed : {};
|
|
83962
84124
|
} catch {
|
|
83963
84125
|
return {};
|
|
83964
84126
|
}
|
|
@@ -84053,13 +84215,13 @@ function packageKind(pkg) {
|
|
|
84053
84215
|
return pkg.kind === "package.kb" ? "kb" : "llms";
|
|
84054
84216
|
}
|
|
84055
84217
|
async function walkFiles3(root2) {
|
|
84056
|
-
if (!
|
|
84218
|
+
if (!existsSync31(root2))
|
|
84057
84219
|
return [];
|
|
84058
84220
|
const files = [];
|
|
84059
84221
|
const visit3 = async (dir) => {
|
|
84060
84222
|
const entries = await readdir13(dir, { withFileTypes: true });
|
|
84061
84223
|
for (const entry of entries) {
|
|
84062
|
-
const absPath =
|
|
84224
|
+
const absPath = join46(dir, entry.name);
|
|
84063
84225
|
if (entry.isDirectory()) {
|
|
84064
84226
|
await visit3(absPath);
|
|
84065
84227
|
continue;
|
|
@@ -84351,10 +84513,10 @@ async function writeKnowledgeDirectoryIndexes(input) {
|
|
|
84351
84513
|
let written = 0;
|
|
84352
84514
|
for (const directory of collectKnowledgeDirectoryIndexes(input.pkg, input.selected)) {
|
|
84353
84515
|
assertSafeRenderedPath(directory.relPath, "knowledge directory index path");
|
|
84354
|
-
const outputPath =
|
|
84355
|
-
if (
|
|
84516
|
+
const outputPath = join46(input.projectRoot, input.pkg.outDir, directory.relPath);
|
|
84517
|
+
if (existsSync31(outputPath))
|
|
84356
84518
|
continue;
|
|
84357
|
-
await mkdir24(
|
|
84519
|
+
await mkdir24(dirname29(outputPath), { recursive: true });
|
|
84358
84520
|
await writeFile19(outputPath, renderKnowledgeDirectoryIndex({
|
|
84359
84521
|
pkg: input.pkg,
|
|
84360
84522
|
directory,
|
|
@@ -84400,23 +84562,23 @@ function packageLinkTargetExists(packageRoot, targetRelPath) {
|
|
|
84400
84562
|
return false;
|
|
84401
84563
|
}
|
|
84402
84564
|
const normalized = targetRelPath.endsWith("/") ? `${targetRelPath}index.md` : targetRelPath;
|
|
84403
|
-
const targetPath =
|
|
84404
|
-
if (
|
|
84565
|
+
const targetPath = join46(packageRoot, normalized);
|
|
84566
|
+
if (existsSync31(targetPath)) {
|
|
84405
84567
|
const stat6 = statSync(targetPath);
|
|
84406
84568
|
if (stat6.isFile())
|
|
84407
84569
|
return true;
|
|
84408
84570
|
if (stat6.isDirectory())
|
|
84409
|
-
return
|
|
84571
|
+
return existsSync31(join46(targetPath, "index.md"));
|
|
84410
84572
|
return false;
|
|
84411
84573
|
}
|
|
84412
|
-
if (!pathPosix.extname(normalized) &&
|
|
84574
|
+
if (!pathPosix.extname(normalized) && existsSync31(join46(packageRoot, normalized, "index.md")))
|
|
84413
84575
|
return true;
|
|
84414
84576
|
return false;
|
|
84415
84577
|
}
|
|
84416
84578
|
async function validatePackageIndexLinks(input) {
|
|
84417
84579
|
if (packageKind(input.pkg) !== "kb")
|
|
84418
84580
|
return;
|
|
84419
|
-
const packageRoot =
|
|
84581
|
+
const packageRoot = join46(input.projectRoot, input.pkg.outDir);
|
|
84420
84582
|
const files = await walkFiles3(packageRoot);
|
|
84421
84583
|
for (const file of files) {
|
|
84422
84584
|
if (file.relPath !== "index.md" && !file.relPath.endsWith("/index.md"))
|
|
@@ -84487,10 +84649,10 @@ function packageKind2(pkg) {
|
|
|
84487
84649
|
// src/project/packageBuildInventory.ts
|
|
84488
84650
|
var PACKAGE_BUILD_INVENTORY_PATH = "context-build-inventory.json";
|
|
84489
84651
|
function knowledgeStructurePath(projectRoot) {
|
|
84490
|
-
return
|
|
84652
|
+
return join47(projectRoot, "knowledge", "structure.yaml");
|
|
84491
84653
|
}
|
|
84492
84654
|
async function readOptionalText(path4) {
|
|
84493
|
-
if (!
|
|
84655
|
+
if (!existsSync32(path4))
|
|
84494
84656
|
return null;
|
|
84495
84657
|
return readFile37(path4, "utf8");
|
|
84496
84658
|
}
|
|
@@ -84869,8 +85031,8 @@ function packageBuildInventory(input) {
|
|
|
84869
85031
|
};
|
|
84870
85032
|
}
|
|
84871
85033
|
async function writePackageBuildInventory(input) {
|
|
84872
|
-
const outputPath =
|
|
84873
|
-
await mkdir25(
|
|
85034
|
+
const outputPath = join47(input.projectRoot, input.pkg.outDir, PACKAGE_BUILD_INVENTORY_PATH);
|
|
85035
|
+
await mkdir25(dirname30(outputPath), { recursive: true });
|
|
84874
85036
|
await writeFile20(outputPath, `${JSON.stringify(input.inventory, null, 2)}
|
|
84875
85037
|
`, "utf8");
|
|
84876
85038
|
return 1;
|
|
@@ -84878,12 +85040,12 @@ async function writePackageBuildInventory(input) {
|
|
|
84878
85040
|
|
|
84879
85041
|
// src/project/packageBuildReceipt.ts
|
|
84880
85042
|
import { createHash as createHash18 } from "node:crypto";
|
|
84881
|
-
import { existsSync as
|
|
85043
|
+
import { existsSync as existsSync33 } from "node:fs";
|
|
84882
85044
|
import { readdir as readdir14, readFile as readFile38 } from "node:fs/promises";
|
|
84883
|
-
import { join as
|
|
85045
|
+
import { join as join48, relative as relative17 } from "node:path";
|
|
84884
85046
|
var IGNORED_PACKAGE_FS_ENTRIES = new Set([".DS_Store"]);
|
|
84885
85047
|
async function walkPackageFiles(root2) {
|
|
84886
|
-
if (!
|
|
85048
|
+
if (!existsSync33(root2))
|
|
84887
85049
|
return [];
|
|
84888
85050
|
const files = [];
|
|
84889
85051
|
const visit3 = async (dir) => {
|
|
@@ -84891,7 +85053,7 @@ async function walkPackageFiles(root2) {
|
|
|
84891
85053
|
for (const entry of entries) {
|
|
84892
85054
|
if (IGNORED_PACKAGE_FS_ENTRIES.has(entry.name))
|
|
84893
85055
|
continue;
|
|
84894
|
-
const absPath =
|
|
85056
|
+
const absPath = join48(dir, entry.name);
|
|
84895
85057
|
if (entry.isDirectory()) {
|
|
84896
85058
|
await visit3(absPath);
|
|
84897
85059
|
continue;
|
|
@@ -84922,7 +85084,7 @@ function classifyOutputFile(path4, knowledgeGroups) {
|
|
|
84922
85084
|
}
|
|
84923
85085
|
async function packageOutputSnapshot(projectRoot, pkg, knowledgeGroups, previousOutputs = []) {
|
|
84924
85086
|
const previousByPath = new Map(previousOutputs.map((file) => [file.path, file]));
|
|
84925
|
-
return Promise.all((await walkPackageFiles(
|
|
85087
|
+
return Promise.all((await walkPackageFiles(join48(projectRoot, pkg.outDir))).map(async (file) => {
|
|
84926
85088
|
const current2 = classifyOutputFile(file.relPath, knowledgeGroups);
|
|
84927
85089
|
const previous3 = previousByPath.get(file.relPath);
|
|
84928
85090
|
const classification = current2.kind === "file" && previous3 !== undefined ? { path: file.relPath, kind: previous3.kind, ...previous3.group === undefined ? {} : { group: previous3.group } } : current2;
|
|
@@ -84936,7 +85098,7 @@ async function packageOutputFingerprint(projectRoot, pkg) {
|
|
|
84936
85098
|
const snapshot = await packageOutputSnapshot(projectRoot, pkg, new Map);
|
|
84937
85099
|
return {
|
|
84938
85100
|
fingerprint: createHash18("sha256").update(JSON.stringify({
|
|
84939
|
-
outDirExists:
|
|
85101
|
+
outDirExists: existsSync33(join48(projectRoot, pkg.outDir)),
|
|
84940
85102
|
files: snapshot.map(({ path: path4, sha256: sha2564 }) => ({ path: path4, sha256: sha2564 }))
|
|
84941
85103
|
})).digest("hex"),
|
|
84942
85104
|
files: snapshot.length
|
|
@@ -85010,16 +85172,16 @@ function formatPackageBuildSummary(pkg) {
|
|
|
85010
85172
|
}
|
|
85011
85173
|
|
|
85012
85174
|
// src/project/packageBuildContent.ts
|
|
85013
|
-
import { existsSync as
|
|
85175
|
+
import { existsSync as existsSync34 } from "node:fs";
|
|
85014
85176
|
import { mkdir as mkdir26, readFile as readFile40, writeFile as writeFile21 } from "node:fs/promises";
|
|
85015
|
-
import { dirname as
|
|
85177
|
+
import { dirname as dirname33, join as join51 } from "node:path";
|
|
85016
85178
|
|
|
85017
85179
|
// src/project/packageAssets.ts
|
|
85018
85180
|
init_errors();
|
|
85019
85181
|
init_cliFeedback();
|
|
85020
85182
|
init_exitCode();
|
|
85021
85183
|
import { readFile as readFile39 } from "node:fs/promises";
|
|
85022
|
-
import { dirname as
|
|
85184
|
+
import { dirname as dirname31, relative as relative18, sep as sep3 } from "node:path";
|
|
85023
85185
|
function posixPath2(value) {
|
|
85024
85186
|
return value.split(sep3).join("/");
|
|
85025
85187
|
}
|
|
@@ -85041,7 +85203,7 @@ function packageAssetPath(projectRoot, absolute) {
|
|
|
85041
85203
|
};
|
|
85042
85204
|
}
|
|
85043
85205
|
function packageMarkdownTarget(pageOutputPath, assetOutputPath) {
|
|
85044
|
-
const target = posixPath2(relative18(
|
|
85206
|
+
const target = posixPath2(relative18(dirname31(pageOutputPath), assetOutputPath));
|
|
85045
85207
|
return target.startsWith(".") ? target : `./${target}`;
|
|
85046
85208
|
}
|
|
85047
85209
|
async function projectPackageKnowledgeAssets(input) {
|
|
@@ -85081,7 +85243,7 @@ init_errors();
|
|
|
85081
85243
|
init_exitCode();
|
|
85082
85244
|
import { execFile as execFile5 } from "node:child_process";
|
|
85083
85245
|
import { realpath as realpath3 } from "node:fs/promises";
|
|
85084
|
-
import { join as
|
|
85246
|
+
import { join as join50, relative as relative19, sep as sep4 } from "node:path";
|
|
85085
85247
|
import { promisify as promisify5 } from "node:util";
|
|
85086
85248
|
|
|
85087
85249
|
// src/project/packageAssetOptimization.ts
|
|
@@ -85090,7 +85252,7 @@ init_errors();
|
|
|
85090
85252
|
init_exitCode();
|
|
85091
85253
|
import { createHash as createHash19 } from "node:crypto";
|
|
85092
85254
|
import { createRequire as createRequire4 } from "node:module";
|
|
85093
|
-
import { dirname as
|
|
85255
|
+
import { dirname as dirname32, extname as extname10, join as join49 } from "node:path";
|
|
85094
85256
|
import { pathToFileURL as pathToFileURL2 } from "node:url";
|
|
85095
85257
|
var PACKAGE_ASSET_OPTIMIZATION_THRESHOLD_BYTES = 20 * 1024 * 1024;
|
|
85096
85258
|
function isPng(bytes) {
|
|
@@ -85112,10 +85274,10 @@ function isWebp(bytes) {
|
|
|
85112
85274
|
}
|
|
85113
85275
|
function contentAddressedWebpPath(asset, bytes) {
|
|
85114
85276
|
const digest4 = createHash19("sha256").update(bytes).digest("hex");
|
|
85115
|
-
return `${
|
|
85277
|
+
return `${dirname32(asset.packageRelPath)}/${digest4}.webp`;
|
|
85116
85278
|
}
|
|
85117
85279
|
async function loadSharpProcessor(projectRoot) {
|
|
85118
|
-
const requireFromWorkspace = createRequire4(
|
|
85280
|
+
const requireFromWorkspace = createRequire4(join49(projectRoot, "package.json"));
|
|
85119
85281
|
let resolved;
|
|
85120
85282
|
try {
|
|
85121
85283
|
resolved = requireFromWorkspace.resolve("sharp");
|
|
@@ -85235,7 +85397,7 @@ async function git(projectRoot, args) {
|
|
|
85235
85397
|
}
|
|
85236
85398
|
}
|
|
85237
85399
|
function repositoryPath(repoRoot, projectRoot, asset) {
|
|
85238
|
-
const path4 = relative19(repoRoot,
|
|
85400
|
+
const path4 = relative19(repoRoot, join50(projectRoot, asset.knowledgeRelPath)).split(sep4).join("/");
|
|
85239
85401
|
if (path4 === ".." || path4.startsWith("../") || path4.startsWith("/")) {
|
|
85240
85402
|
throw new ContextError(ExitCode.WorkspaceStateError, "knowledge asset is outside the current Git repository", {
|
|
85241
85403
|
category: ErrorCategory.WorkspaceStateInvalid,
|
|
@@ -85350,6 +85512,20 @@ async function deliverFromGit(input) {
|
|
|
85350
85512
|
}
|
|
85351
85513
|
};
|
|
85352
85514
|
}
|
|
85515
|
+
async function packageAssetDeliveryFingerprintInput(input) {
|
|
85516
|
+
if (input.definition?.delivery !== "git-raw" || input.assets.length === 0)
|
|
85517
|
+
return null;
|
|
85518
|
+
const delivery = await deliverFromGit({
|
|
85519
|
+
projectRoot: input.projectRoot,
|
|
85520
|
+
assets: input.assets,
|
|
85521
|
+
definition: input.definition
|
|
85522
|
+
});
|
|
85523
|
+
return {
|
|
85524
|
+
state: "git-raw",
|
|
85525
|
+
...delivery.summary.git === undefined ? {} : { git: delivery.summary.git },
|
|
85526
|
+
targets: [...delivery.targetByOriginal.entries()].sort(([left], [right]) => left.localeCompare(right))
|
|
85527
|
+
};
|
|
85528
|
+
}
|
|
85353
85529
|
async function deliverPackageAssetFiles(input) {
|
|
85354
85530
|
if (input.definition?.delivery === "git-raw") {
|
|
85355
85531
|
return deliverFromGit({ projectRoot: input.projectRoot, assets: input.assets, definition: input.definition });
|
|
@@ -85528,8 +85704,8 @@ async function writeRenderedPackageTemplate(input) {
|
|
|
85528
85704
|
templateRelPath: renderedRelPath,
|
|
85529
85705
|
logicalTemplateRelPath: renderedLogicalRelPath
|
|
85530
85706
|
});
|
|
85531
|
-
const outputPath =
|
|
85532
|
-
await mkdir26(
|
|
85707
|
+
const outputPath = join51(input.projectRoot, input.pkg.outDir, renderedRelPath);
|
|
85708
|
+
await mkdir26(dirname33(outputPath), { recursive: true });
|
|
85533
85709
|
await writeFile21(outputPath, renderTemplateText(file.content, contentVars), "utf8");
|
|
85534
85710
|
written++;
|
|
85535
85711
|
}
|
|
@@ -85555,7 +85731,7 @@ async function writeSelectedPackageKnowledge(input) {
|
|
|
85555
85731
|
const { projectedPages, delivered } = input.prepared ?? await prepareSelectedPackageKnowledge(input);
|
|
85556
85732
|
for (const projected of projectedPages) {
|
|
85557
85733
|
assertSafeRenderedPath2(projected.pageOutputPath, "knowledge path");
|
|
85558
|
-
const outputPath =
|
|
85734
|
+
const outputPath = join51(input.projectRoot, input.pkg.outDir, projected.pageOutputPath);
|
|
85559
85735
|
const rewritten = replaceMarkdownInlineLinkTargets(projected.content, (link2) => {
|
|
85560
85736
|
for (const [inputPath, outputPath2] of delivered.targetByOriginal) {
|
|
85561
85737
|
if (link2.target === packageMarkdownTarget(projected.pageOutputPath, inputPath)) {
|
|
@@ -85564,14 +85740,14 @@ async function writeSelectedPackageKnowledge(input) {
|
|
|
85564
85740
|
}
|
|
85565
85741
|
return;
|
|
85566
85742
|
});
|
|
85567
|
-
await mkdir26(
|
|
85743
|
+
await mkdir26(dirname33(outputPath), { recursive: true });
|
|
85568
85744
|
await writeFile21(outputPath, projectPackageKnowledgeMarkdown(rewritten), "utf8");
|
|
85569
85745
|
}
|
|
85570
85746
|
const deliveredAssets = new Map(delivered.assets.map((asset) => [asset.packageRelPath, asset]));
|
|
85571
85747
|
for (const asset of deliveredAssets.values()) {
|
|
85572
85748
|
assertSafeRenderedPath2(asset.packageRelPath, "package resource path");
|
|
85573
|
-
const outputPath =
|
|
85574
|
-
await mkdir26(
|
|
85749
|
+
const outputPath = join51(input.projectRoot, input.pkg.outDir, asset.packageRelPath);
|
|
85750
|
+
await mkdir26(dirname33(outputPath), { recursive: true });
|
|
85575
85751
|
await writeFile21(outputPath, asset.bytes);
|
|
85576
85752
|
}
|
|
85577
85753
|
return {
|
|
@@ -85584,8 +85760,8 @@ async function writeSelectedPackageKnowledge(input) {
|
|
|
85584
85760
|
async function appendLlmsKnowledge(input) {
|
|
85585
85761
|
if (packageKind2(input.pkg) !== "llms" || input.templateConsumesKnowledge || input.knowledgeCount === 0)
|
|
85586
85762
|
return 0;
|
|
85587
|
-
const outputPath =
|
|
85588
|
-
const existed =
|
|
85763
|
+
const outputPath = join51(input.projectRoot, input.pkg.outDir, "llms.txt");
|
|
85764
|
+
const existed = existsSync34(outputPath);
|
|
85589
85765
|
const existing = existed ? await readFile40(outputPath, "utf8") : "";
|
|
85590
85766
|
const content3 = existing.trim().length > 0 ? `${existing.trimEnd()}
|
|
85591
85767
|
|
|
@@ -85594,7 +85770,7 @@ async function appendLlmsKnowledge(input) {
|
|
|
85594
85770
|
${input.bundle}
|
|
85595
85771
|
` : `${input.bundle}
|
|
85596
85772
|
`;
|
|
85597
|
-
await mkdir26(
|
|
85773
|
+
await mkdir26(dirname33(outputPath), { recursive: true });
|
|
85598
85774
|
await writeFile21(outputPath, content3, "utf8");
|
|
85599
85775
|
return existed ? 0 : 1;
|
|
85600
85776
|
}
|
|
@@ -85780,8 +85956,8 @@ function validateRenderedSkillDefinition(input) {
|
|
|
85780
85956
|
init_workspace();
|
|
85781
85957
|
init_packageTemplateReview();
|
|
85782
85958
|
var KNOWLEDGE_ROOT4 = "knowledge";
|
|
85783
|
-
var PACKAGE_FINGERPRINT_ROOT =
|
|
85784
|
-
var PACKAGE_BUILDER_PROTOCOL_VERSION = "
|
|
85959
|
+
var PACKAGE_FINGERPRINT_ROOT = join52(".tmp", "context-runtime", "packages");
|
|
85960
|
+
var PACKAGE_BUILDER_PROTOCOL_VERSION = "v14-git-asset-identity";
|
|
85785
85961
|
function packageAssetDeliverySummary(value) {
|
|
85786
85962
|
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
85787
85963
|
return;
|
|
@@ -85803,10 +85979,10 @@ function assertPackageOutputDir(pkg) {
|
|
|
85803
85979
|
}
|
|
85804
85980
|
function packageFingerprintPath(projectRoot, pkg) {
|
|
85805
85981
|
assertSafeRenderedPath2(`${pkg.name}.json`, "package fingerprint path");
|
|
85806
|
-
return
|
|
85982
|
+
return join52(projectRoot, PACKAGE_FINGERPRINT_ROOT, `${pkg.name}.json`);
|
|
85807
85983
|
}
|
|
85808
85984
|
async function listApprovedKnowledge(projectRoot) {
|
|
85809
|
-
const files = await walkPackageFiles(
|
|
85985
|
+
const files = await walkPackageFiles(join52(projectRoot, KNOWLEDGE_ROOT4));
|
|
85810
85986
|
const knowledge = await Promise.all(files.filter((file) => file.relPath.endsWith(".md") && !file.relPath.startsWith("assets/")).map(async (file) => ({
|
|
85811
85987
|
...file,
|
|
85812
85988
|
content: await readFile41(file.absPath, "utf8")
|
|
@@ -85827,7 +86003,7 @@ function isDeprecatedKnowledge(content3) {
|
|
|
85827
86003
|
async function listTemplateFiles(projectRoot, templatePath) {
|
|
85828
86004
|
assertSafeRenderedPath2(templatePath, "package template path");
|
|
85829
86005
|
const templateRoot = resolve19(projectRoot, templatePath);
|
|
85830
|
-
if (!
|
|
86006
|
+
if (!existsSync35(templateRoot)) {
|
|
85831
86007
|
throw new ContextError(ExitCode.WorkspaceStateError, `package template path is missing: ${templatePath}`, {
|
|
85832
86008
|
category: ErrorCategory.WorkspaceStateInvalid,
|
|
85833
86009
|
path: templatePath,
|
|
@@ -85851,11 +86027,18 @@ async function packageInputFingerprint(input) {
|
|
|
85851
86027
|
content: file.content
|
|
85852
86028
|
})));
|
|
85853
86029
|
const assets = new Map;
|
|
86030
|
+
const assetFiles = new Map;
|
|
85854
86031
|
for (const projection of projectedAssets) {
|
|
85855
86032
|
for (const asset of projection.assets) {
|
|
85856
86033
|
assets.set(asset.packageRelPath, createHash20("sha256").update(asset.bytes).digest("hex"));
|
|
86034
|
+
assetFiles.set(asset.packageRelPath, asset);
|
|
85857
86035
|
}
|
|
85858
86036
|
}
|
|
86037
|
+
const assetDelivery = input.pkg.kind === "package.kb" ? await packageAssetDeliveryFingerprintInput({
|
|
86038
|
+
projectRoot: input.projectRoot,
|
|
86039
|
+
assets: [...assetFiles.values()],
|
|
86040
|
+
...input.pkg.assets === undefined ? {} : { definition: input.pkg.assets }
|
|
86041
|
+
}) : null;
|
|
85859
86042
|
return stableHash3({
|
|
85860
86043
|
builder: PACKAGE_BUILDER_PROTOCOL_VERSION,
|
|
85861
86044
|
package: {
|
|
@@ -85873,6 +86056,7 @@ async function packageInputFingerprint(input) {
|
|
|
85873
86056
|
content: file.content
|
|
85874
86057
|
})),
|
|
85875
86058
|
assets: [...assets].sort(([left], [right]) => left.localeCompare(right)),
|
|
86059
|
+
assetDelivery,
|
|
85876
86060
|
template: input.templateFiles.map((file) => ({
|
|
85877
86061
|
path: file.relPath,
|
|
85878
86062
|
content: file.content
|
|
@@ -85881,7 +86065,7 @@ async function packageInputFingerprint(input) {
|
|
|
85881
86065
|
}
|
|
85882
86066
|
async function readPackageManifest(projectRoot, pkg) {
|
|
85883
86067
|
const filePath = packageFingerprintPath(projectRoot, pkg);
|
|
85884
|
-
if (!
|
|
86068
|
+
if (!existsSync35(filePath))
|
|
85885
86069
|
return null;
|
|
85886
86070
|
try {
|
|
85887
86071
|
const parsed = JSON.parse(await readFile41(filePath, "utf8"));
|
|
@@ -85914,7 +86098,7 @@ async function readPackageManifest(projectRoot, pkg) {
|
|
|
85914
86098
|
}
|
|
85915
86099
|
async function writePackageFingerprint(input) {
|
|
85916
86100
|
const filePath = packageFingerprintPath(input.projectRoot, input.pkg);
|
|
85917
|
-
await mkdir27(
|
|
86101
|
+
await mkdir27(dirname34(filePath), { recursive: true });
|
|
85918
86102
|
await writeFile22(filePath, `${JSON.stringify({
|
|
85919
86103
|
package: input.pkg.name,
|
|
85920
86104
|
kind: packageKind2(input.pkg),
|
|
@@ -85929,12 +86113,12 @@ async function writePackageFingerprint(input) {
|
|
|
85929
86113
|
`, "utf8");
|
|
85930
86114
|
}
|
|
85931
86115
|
async function removeOrphanPackageDirs(projectRoot, packages) {
|
|
85932
|
-
const distRoot =
|
|
85933
|
-
if (!
|
|
86116
|
+
const distRoot = join52(projectRoot, "dist");
|
|
86117
|
+
if (!existsSync35(distRoot))
|
|
85934
86118
|
return;
|
|
85935
86119
|
const declaredNames = new Set(packages.map((pkg) => pkg.name));
|
|
85936
86120
|
const entries = await readdir15(distRoot, { withFileTypes: true });
|
|
85937
|
-
await Promise.all(entries.filter((entry) => entry.isDirectory() && !declaredNames.has(entry.name)).map((entry) => rm13(
|
|
86121
|
+
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 })));
|
|
85938
86122
|
}
|
|
85939
86123
|
async function collectPackageFreshness(projectRoot, packages) {
|
|
85940
86124
|
const approved = await listApprovedKnowledge(projectRoot);
|
|
@@ -85942,8 +86126,8 @@ async function collectPackageFreshness(projectRoot, packages) {
|
|
|
85942
86126
|
assertPackageOutputDir(pkg);
|
|
85943
86127
|
const selected = selectPackageKnowledge(approved, pkg);
|
|
85944
86128
|
assertSafeRenderedPath2(pkg.template.path, "package template path");
|
|
85945
|
-
const templateRoot =
|
|
85946
|
-
const templateExists =
|
|
86129
|
+
const templateRoot = join52(projectRoot, pkg.template.path);
|
|
86130
|
+
const templateExists = existsSync35(templateRoot);
|
|
85947
86131
|
if (!templateExists) {
|
|
85948
86132
|
throw new ContextError(ExitCode.WorkspaceStateError, `package template path is missing: ${pkg.template.path}`, {
|
|
85949
86133
|
category: ErrorCategory.WorkspaceStateInvalid,
|
|
@@ -86077,8 +86261,8 @@ async function buildProjectPackages(projectRoot) {
|
|
|
86077
86261
|
files: selected,
|
|
86078
86262
|
...assetProcessor === undefined ? {} : { assetProcessor }
|
|
86079
86263
|
});
|
|
86080
|
-
await rm13(
|
|
86081
|
-
await mkdir27(
|
|
86264
|
+
await rm13(join52(projectRoot, pkg.outDir), { recursive: true, force: true, maxRetries: 3, retryDelay: 100 });
|
|
86265
|
+
await mkdir27(join52(projectRoot, pkg.outDir), { recursive: true });
|
|
86082
86266
|
const rendered = await writeRenderedPackageTemplate({
|
|
86083
86267
|
projectRoot,
|
|
86084
86268
|
pkg,
|
|
@@ -86216,20 +86400,32 @@ async function runProjectBuildCommand(input) {
|
|
|
86216
86400
|
return false;
|
|
86217
86401
|
const result = await buildProjectPackages(found.projectRoot);
|
|
86218
86402
|
process.stdout.write(formatProjectBuildResult(result, input.format ?? "text", input.verbose === true));
|
|
86403
|
+
queueContextRuntimeEvent({
|
|
86404
|
+
cwd: result.projectRoot,
|
|
86405
|
+
kind: "package.build.completed",
|
|
86406
|
+
properties: {
|
|
86407
|
+
package_count: result.packages.length,
|
|
86408
|
+
created_count: result.packages.filter((pkg) => pkg.state === "created").length,
|
|
86409
|
+
updated_count: result.packages.filter((pkg) => pkg.state === "updated").length,
|
|
86410
|
+
unchanged_count: result.packages.filter((pkg) => pkg.state === "unchanged").length,
|
|
86411
|
+
output_file_count: result.packages.reduce((total, pkg) => total + pkg.files, 0),
|
|
86412
|
+
resource_file_count: result.packages.reduce((total, pkg) => total + pkg.resources.files, 0)
|
|
86413
|
+
}
|
|
86414
|
+
});
|
|
86219
86415
|
return true;
|
|
86220
86416
|
}
|
|
86221
86417
|
|
|
86222
86418
|
// src/project/statusReaders.ts
|
|
86223
86419
|
init_workspace();
|
|
86224
86420
|
async function countFiles(root2, predicate) {
|
|
86225
|
-
if (!
|
|
86421
|
+
if (!existsSync36(root2))
|
|
86226
86422
|
return 0;
|
|
86227
86423
|
let count = 0;
|
|
86228
86424
|
const visit3 = async (dir, prefix = "") => {
|
|
86229
86425
|
const entries = await readdir16(dir, { withFileTypes: true });
|
|
86230
86426
|
for (const entry of entries) {
|
|
86231
86427
|
const rel = prefix.length === 0 ? entry.name : `${prefix}/${entry.name}`;
|
|
86232
|
-
const abs =
|
|
86428
|
+
const abs = join53(dir, entry.name);
|
|
86233
86429
|
if (entry.isDirectory())
|
|
86234
86430
|
await visit3(abs, rel);
|
|
86235
86431
|
else if (entry.isFile() && predicate(rel))
|
|
@@ -86271,14 +86467,14 @@ async function readDraftCandidateStatus(projectRoot) {
|
|
|
86271
86467
|
throw error;
|
|
86272
86468
|
}
|
|
86273
86469
|
}
|
|
86274
|
-
function
|
|
86470
|
+
function isRecord19(value) {
|
|
86275
86471
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
86276
86472
|
}
|
|
86277
86473
|
function stagedStructureCounts(parsed) {
|
|
86278
86474
|
const views = Array.isArray(parsed.views) ? parsed.views : [];
|
|
86279
|
-
const sections = views.flatMap((view) =>
|
|
86475
|
+
const sections = views.flatMap((view) => isRecord19(view) && Array.isArray(view.sections) ? view.sections : []);
|
|
86280
86476
|
const sourceRefs = new Set(sections.flatMap((section) => {
|
|
86281
|
-
if (!
|
|
86477
|
+
if (!isRecord19(section))
|
|
86282
86478
|
return [];
|
|
86283
86479
|
return [
|
|
86284
86480
|
...typeof section.source_ref === "string" ? [section.source_ref] : [],
|
|
@@ -86295,12 +86491,12 @@ function stagedStructureCounts(parsed) {
|
|
|
86295
86491
|
};
|
|
86296
86492
|
}
|
|
86297
86493
|
function readStructureDraftStatus(projectRoot) {
|
|
86298
|
-
const structurePath =
|
|
86299
|
-
if (!
|
|
86494
|
+
const structurePath = join53(projectRoot, LIFECYCLE_STRUCTURE_FILE);
|
|
86495
|
+
if (!existsSync36(structurePath))
|
|
86300
86496
|
return { state: "missing", sourceKeys: [], collections: [], diagnostics: [] };
|
|
86301
86497
|
try {
|
|
86302
|
-
const parsed = import_yaml29.default.parse(
|
|
86303
|
-
if (!
|
|
86498
|
+
const parsed = import_yaml29.default.parse(readFileSync8(structurePath, "utf8"));
|
|
86499
|
+
if (!isRecord19(parsed)) {
|
|
86304
86500
|
return {
|
|
86305
86501
|
state: "invalid",
|
|
86306
86502
|
sourceKeys: [],
|
|
@@ -86308,7 +86504,7 @@ function readStructureDraftStatus(projectRoot) {
|
|
|
86308
86504
|
diagnostics: [`${LIFECYCLE_STRUCTURE_FILE} must be a YAML object`]
|
|
86309
86505
|
};
|
|
86310
86506
|
}
|
|
86311
|
-
const lifecycle =
|
|
86507
|
+
const lifecycle = isRecord19(parsed.lifecycle) ? parsed.lifecycle : {};
|
|
86312
86508
|
const lifecycleState = lifecycle.state;
|
|
86313
86509
|
if (lifecycleState === "draft" || lifecycleState === "confirmed" || lifecycleState === "frozen") {
|
|
86314
86510
|
const structureDigest = typeof parsed.structure_digest === "string" ? parsed.structure_digest : typeof lifecycle.structure_digest === "string" ? lifecycle.structure_digest : undefined;
|
|
@@ -86318,7 +86514,7 @@ function readStructureDraftStatus(projectRoot) {
|
|
|
86318
86514
|
lifecycleState,
|
|
86319
86515
|
...typeof lifecycle.phase_collection === "string" ? { phaseCollection: lifecycle.phase_collection } : {},
|
|
86320
86516
|
sourceKeys: Array.isArray(parsed.sources) ? parsed.sources.filter((item) => typeof item === "string") : [],
|
|
86321
|
-
collections: Array.isArray(parsed.views) ? [...new Set(parsed.views.flatMap((view) =>
|
|
86517
|
+
collections: Array.isArray(parsed.views) ? [...new Set(parsed.views.flatMap((view) => isRecord19(view) && typeof view.collection === "string" ? [view.collection] : []))].sort() : [],
|
|
86322
86518
|
...structureDigest === undefined ? {} : { structureDigest },
|
|
86323
86519
|
...evidenceSnapshotHash === undefined ? {} : { evidenceSnapshotHash },
|
|
86324
86520
|
...stagedStructureCounts(parsed),
|
|
@@ -86495,8 +86691,8 @@ async function documentSourceSiteHint(input) {
|
|
|
86495
86691
|
});
|
|
86496
86692
|
}
|
|
86497
86693
|
function documentSnapshotReadiness(input) {
|
|
86498
|
-
const manifestPath =
|
|
86499
|
-
if (!
|
|
86694
|
+
const manifestPath = join53(input.projectRoot, input.manifest);
|
|
86695
|
+
if (!existsSync36(manifestPath)) {
|
|
86500
86696
|
return {
|
|
86501
86697
|
ready: false,
|
|
86502
86698
|
diagnostics: [`snapshot is missing: ${input.manifest}`],
|
|
@@ -86504,7 +86700,7 @@ function documentSnapshotReadiness(input) {
|
|
|
86504
86700
|
};
|
|
86505
86701
|
}
|
|
86506
86702
|
try {
|
|
86507
|
-
const manifest = findDocumentSnapshotForSource(JSON.parse(
|
|
86703
|
+
const manifest = findDocumentSnapshotForSource(JSON.parse(readFileSync8(manifestPath, "utf8")), input.sourceName);
|
|
86508
86704
|
if (manifest === null) {
|
|
86509
86705
|
return {
|
|
86510
86706
|
ready: false,
|
|
@@ -86565,7 +86761,7 @@ function documentSnapshotReadiness(input) {
|
|
|
86565
86761
|
const missingFiles = [
|
|
86566
86762
|
...manifest.files.map((file) => file.path),
|
|
86567
86763
|
...(manifest.assets ?? []).filter((asset) => asset.content_hash !== undefined).map((asset) => asset.path)
|
|
86568
|
-
].filter((path4) => !
|
|
86764
|
+
].filter((path4) => !existsSync36(join53(input.projectRoot, input.materializedAt, path4)));
|
|
86569
86765
|
if (missingFiles.length > 0) {
|
|
86570
86766
|
return {
|
|
86571
86767
|
ready: false,
|
|
@@ -86812,9 +87008,9 @@ async function readActiveStructuresStatus(projectRoot, currentSnapshotHashes) {
|
|
|
86812
87008
|
init_packageTemplateReview();
|
|
86813
87009
|
|
|
86814
87010
|
// src/project/workflow/workflowProvider.ts
|
|
86815
|
-
import { existsSync as
|
|
86816
|
-
import { dirname as
|
|
86817
|
-
import { fileURLToPath as
|
|
87011
|
+
import { existsSync as existsSync37 } from "node:fs";
|
|
87012
|
+
import { dirname as dirname35, resolve as resolve20 } from "node:path";
|
|
87013
|
+
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
86818
87014
|
|
|
86819
87015
|
// src/project/workflow/verifyFacts.ts
|
|
86820
87016
|
var CLOSE_REPAIRABLE_APPROVED_STRUCTURE_CODES = new Set([
|
|
@@ -87164,12 +87360,13 @@ function createContextWorkflowFacts(observation, authorities) {
|
|
|
87164
87360
|
}
|
|
87165
87361
|
|
|
87166
87362
|
// src/project/workflow/workflowHostPlans.ts
|
|
87167
|
-
function command(value, effect, managedExecution = effect === "write" ? "automatic" : "agent-required") {
|
|
87363
|
+
function command(value, effect, managedExecution = effect === "write" ? "automatic" : "agent-required", execution) {
|
|
87168
87364
|
return {
|
|
87169
87365
|
command: value,
|
|
87170
87366
|
effect,
|
|
87171
87367
|
availability: "immediate",
|
|
87172
|
-
managed_execution: managedExecution
|
|
87368
|
+
managed_execution: managedExecution,
|
|
87369
|
+
...execution === undefined ? {} : { execution }
|
|
87173
87370
|
};
|
|
87174
87371
|
}
|
|
87175
87372
|
function withJsonFormat(value) {
|
|
@@ -87257,8 +87454,10 @@ var HOST_PLAN_RESOLVERS = {
|
|
|
87257
87454
|
}),
|
|
87258
87455
|
"context.extract.next": (observation) => {
|
|
87259
87456
|
const phase = observation.staleSourcePhases[0] ?? observation.pendingExtractPhases[0];
|
|
87457
|
+
const definition3 = observation.phases.find((candidate) => candidate.id === phase);
|
|
87458
|
+
const projectCode = definition3?.kind === "phase.extract.custom" || definition3?.kind === "phase.custom";
|
|
87260
87459
|
return {
|
|
87261
|
-
commands: phase === undefined ? [] : [command(`context run ${phase} --format json`, "write")]
|
|
87460
|
+
commands: phase === undefined ? [] : [command(`context run ${phase} --format json`, "write", "automatic", projectCode ? { target: "subprocess" } : undefined)]
|
|
87262
87461
|
};
|
|
87263
87462
|
},
|
|
87264
87463
|
"context.document.inspect-classification": (observation) => ({
|
|
@@ -87383,7 +87582,7 @@ function planForResolvedCommandPlan(commandPlan, observation) {
|
|
|
87383
87582
|
|
|
87384
87583
|
// src/project/workflow/workflowEvidenceResources.ts
|
|
87385
87584
|
import { createHash as createHash21 } from "node:crypto";
|
|
87386
|
-
import { join as
|
|
87585
|
+
import { join as join54 } from "node:path";
|
|
87387
87586
|
function sourceKeysForRoute(node3, observation) {
|
|
87388
87587
|
if (node3 === "classify-document") {
|
|
87389
87588
|
return observation.unclassifiedDocumentTargets.map((target) => target.sourceKey);
|
|
@@ -87435,7 +87634,7 @@ async function currentSourceBodyResources(input) {
|
|
|
87435
87634
|
kind: "context-view",
|
|
87436
87635
|
media_type: "text/markdown",
|
|
87437
87636
|
digest: document4.content_hash,
|
|
87438
|
-
path:
|
|
87637
|
+
path: join54(input.observation.projectRoot, source2.materializedAt, document4.path),
|
|
87439
87638
|
read_state: isCurrent(id2, document4.content_hash, input.receipts) ? "current" : "read-required"
|
|
87440
87639
|
});
|
|
87441
87640
|
}
|
|
@@ -87447,7 +87646,7 @@ async function currentSourceBodyResources(input) {
|
|
|
87447
87646
|
// src/project/workflow/workflowProvider.ts
|
|
87448
87647
|
var providerPromise;
|
|
87449
87648
|
function providerCandidates() {
|
|
87450
|
-
const moduleDir2 =
|
|
87649
|
+
const moduleDir2 = dirname35(fileURLToPath7(import.meta.url));
|
|
87451
87650
|
return [
|
|
87452
87651
|
...process.env.C4A_CONTEXT_WORKFLOW_PROVIDER ? [resolve20(process.env.C4A_CONTEXT_WORKFLOW_PROVIDER)] : [],
|
|
87453
87652
|
resolve20(moduleDir2, "providers", "context", "manifest.json"),
|
|
@@ -87455,7 +87654,7 @@ function providerCandidates() {
|
|
|
87455
87654
|
];
|
|
87456
87655
|
}
|
|
87457
87656
|
function contextWorkflowProviderPath() {
|
|
87458
|
-
const candidate = providerCandidates().find((path4) =>
|
|
87657
|
+
const candidate = providerCandidates().find((path4) => existsSync37(path4));
|
|
87459
87658
|
if (candidate === undefined) {
|
|
87460
87659
|
throw new Error("Context workflow Provider is missing. Rebuild @c4a/context-cli or reinstall the published package.");
|
|
87461
87660
|
}
|
|
@@ -88469,13 +88668,13 @@ async function collectProjectStatusSnapshot(projectRoot, options = {}) {
|
|
|
88469
88668
|
requestedCollections: [...new Set(alignTargets.map((target) => target.collection))],
|
|
88470
88669
|
requestedGroups: alignGroups
|
|
88471
88670
|
});
|
|
88472
|
-
const approvedPages = await countFiles(
|
|
88671
|
+
const approvedPages = await countFiles(join55(projectRoot, "knowledge"), (rel) => rel.endsWith(".md") && !rel.startsWith("assets/"));
|
|
88473
88672
|
const approvedCollections = (await Promise.all(KNOWLEDGE_COLLECTIONS.map(async (collection) => ({
|
|
88474
88673
|
collection,
|
|
88475
|
-
count: await countFiles(
|
|
88674
|
+
count: await countFiles(join55(projectRoot, "knowledge", collection), (rel) => rel.endsWith(".md"))
|
|
88476
88675
|
})))).filter((item) => item.count > 0).map((item) => item.collection);
|
|
88477
88676
|
const closeStatus = await readCloseStatus(projectRoot);
|
|
88478
|
-
const distFiles = await countFiles(
|
|
88677
|
+
const distFiles = await countFiles(join55(projectRoot, "dist"), () => true);
|
|
88479
88678
|
const sourceFreshness = phaseStatus.projectEntryValid ? await collectSourceFreshness({
|
|
88480
88679
|
projectRoot,
|
|
88481
88680
|
phases,
|
|
@@ -88839,6 +89038,7 @@ async function runProjectStatusCommand(input) {
|
|
|
88839
89038
|
} else {
|
|
88840
89039
|
process.stdout.write(formatProjectStatus(status));
|
|
88841
89040
|
}
|
|
89041
|
+
input.onSuccess?.(status);
|
|
88842
89042
|
return true;
|
|
88843
89043
|
}
|
|
88844
89044
|
async function assertProjectWorkflowRevision(input) {
|
|
@@ -88895,11 +89095,11 @@ function shellQuote6(value) {
|
|
|
88895
89095
|
}
|
|
88896
89096
|
function receiptSetPath(receipts) {
|
|
88897
89097
|
const token = digestText(JSON.stringify(receipts)).slice("sha256:".length);
|
|
88898
|
-
return
|
|
89098
|
+
return join56(".tmp", "context-runtime", "workflow", "read-receipts", `${token}.json`);
|
|
88899
89099
|
}
|
|
88900
89100
|
async function writeReceiptContinuation(input) {
|
|
88901
89101
|
const path4 = receiptSetPath(input.receipts);
|
|
88902
|
-
await writeJsonAtomic(
|
|
89102
|
+
await writeJsonAtomic(join56(input.projectRoot, path4), input.receipts);
|
|
88903
89103
|
const command2 = input.managed ? [
|
|
88904
89104
|
"context",
|
|
88905
89105
|
"--workflow-resource-receipts",
|
|
@@ -88960,7 +89160,7 @@ async function materializeContextWorkflowResource(input) {
|
|
|
88960
89160
|
}
|
|
88961
89161
|
const content3 = renderContextWorkflowResource(resourceId2, status);
|
|
88962
89162
|
const location = await materializeResource(await loadContextWorkflowProvider(), resourceId2, {
|
|
88963
|
-
cache:
|
|
89163
|
+
cache: join56(found.projectRoot, ".tmp", "context-runtime", "workflow", "resources"),
|
|
88964
89164
|
workspace: found.projectRoot,
|
|
88965
89165
|
revision: input.revision,
|
|
88966
89166
|
input: {
|
|
@@ -89186,7 +89386,7 @@ function registerContextWorkflowResourceCommands(program2) {
|
|
|
89186
89386
|
}
|
|
89187
89387
|
|
|
89188
89388
|
// src/commands/runProject.ts
|
|
89189
|
-
import { fileURLToPath as
|
|
89389
|
+
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
89190
89390
|
init_cliFeedback();
|
|
89191
89391
|
init_errors();
|
|
89192
89392
|
|
|
@@ -89197,11 +89397,11 @@ init_exitCode();
|
|
|
89197
89397
|
|
|
89198
89398
|
// src/project/documentCaptureLark.ts
|
|
89199
89399
|
import { readdir as readdir18, readFile as readFile44 } from "node:fs/promises";
|
|
89200
|
-
import { basename as basename8, extname as extname12, join as
|
|
89400
|
+
import { basename as basename8, extname as extname12, join as join59 } from "node:path";
|
|
89201
89401
|
|
|
89202
89402
|
// src/lib/atomicFileBatch.ts
|
|
89203
89403
|
import { lstat as lstat2, mkdir as mkdir28, mkdtemp, rename as rename4, rm as rm14, writeFile as writeFile23 } from "node:fs/promises";
|
|
89204
|
-
import { dirname as
|
|
89404
|
+
import { dirname as dirname36, join as join57, resolve as resolve22 } from "node:path";
|
|
89205
89405
|
async function existingFileKind(path4) {
|
|
89206
89406
|
try {
|
|
89207
89407
|
const stats = await lstat2(path4);
|
|
@@ -89231,9 +89431,9 @@ async function applyAtomicFileBatch(input) {
|
|
|
89231
89431
|
for (const path4 of writesByPath.keys())
|
|
89232
89432
|
removalPaths.delete(path4);
|
|
89233
89433
|
await mkdir28(input.transactionRoot, { recursive: true });
|
|
89234
|
-
const transactionDir = await mkdtemp(
|
|
89235
|
-
const stagedRoot =
|
|
89236
|
-
const backupRoot =
|
|
89434
|
+
const transactionDir = await mkdtemp(join57(input.transactionRoot, "batch-"));
|
|
89435
|
+
const stagedRoot = join57(transactionDir, "staged");
|
|
89436
|
+
const backupRoot = join57(transactionDir, "backup");
|
|
89237
89437
|
const writes = [...writesByPath.values()].sort((left, right) => left.path.localeCompare(right.path));
|
|
89238
89438
|
const affectedPaths = [...new Set([...writesByPath.keys(), ...removalPaths])].sort();
|
|
89239
89439
|
const staged = new Map;
|
|
@@ -89243,20 +89443,20 @@ async function applyAtomicFileBatch(input) {
|
|
|
89243
89443
|
try {
|
|
89244
89444
|
await mkdir28(stagedRoot, { recursive: true });
|
|
89245
89445
|
for (const [index2, write] of writes.entries()) {
|
|
89246
|
-
const path4 =
|
|
89446
|
+
const path4 = join57(stagedRoot, String(index2));
|
|
89247
89447
|
await writeFile23(path4, write.bytes);
|
|
89248
89448
|
staged.set(write.path, path4);
|
|
89249
89449
|
}
|
|
89250
89450
|
for (const [index2, path4] of affectedPaths.entries()) {
|
|
89251
89451
|
if (await existingFileKind(path4) === "missing")
|
|
89252
89452
|
continue;
|
|
89253
|
-
const backupPath =
|
|
89254
|
-
await mkdir28(
|
|
89453
|
+
const backupPath = join57(backupRoot, String(index2));
|
|
89454
|
+
await mkdir28(dirname36(backupPath), { recursive: true });
|
|
89255
89455
|
await rename4(path4, backupPath);
|
|
89256
89456
|
backups.set(path4, backupPath);
|
|
89257
89457
|
}
|
|
89258
89458
|
for (const write of writes) {
|
|
89259
|
-
await mkdir28(
|
|
89459
|
+
await mkdir28(dirname36(write.path), { recursive: true });
|
|
89260
89460
|
await rename4(staged.get(write.path), write.path);
|
|
89261
89461
|
installed.push(write.path);
|
|
89262
89462
|
}
|
|
@@ -89268,7 +89468,7 @@ async function applyAtomicFileBatch(input) {
|
|
|
89268
89468
|
});
|
|
89269
89469
|
}
|
|
89270
89470
|
for (const [path4, backupPath] of [...backups.entries()].reverse()) {
|
|
89271
|
-
await mkdir28(
|
|
89471
|
+
await mkdir28(dirname36(path4), { recursive: true });
|
|
89272
89472
|
await rename4(backupPath, path4).catch((rollbackError) => {
|
|
89273
89473
|
rollbackFailures.push(`restore ${path4}: ${String(rollbackError)}`);
|
|
89274
89474
|
});
|
|
@@ -89305,7 +89505,7 @@ function detectExternalEnvironmentIssue(value) {
|
|
|
89305
89505
|
}
|
|
89306
89506
|
|
|
89307
89507
|
// src/lib/feishu.ts
|
|
89308
|
-
import { spawn as
|
|
89508
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
89309
89509
|
|
|
89310
89510
|
// src/lib/larkDocxXml.ts
|
|
89311
89511
|
import { createHash as createHash23 } from "node:crypto";
|
|
@@ -93590,7 +93790,7 @@ function projectLarkDocxXmlBlock(input) {
|
|
|
93590
93790
|
// src/lib/larkResourceMaterialization.ts
|
|
93591
93791
|
import { createHash as createHash24 } from "node:crypto";
|
|
93592
93792
|
import { mkdtemp as mkdtemp2, readFile as readFile43, readdir as readdir17, rm as rm15 } from "node:fs/promises";
|
|
93593
|
-
import { extname as extname11, join as
|
|
93793
|
+
import { extname as extname11, join as join58 } from "node:path";
|
|
93594
93794
|
import { tmpdir } from "node:os";
|
|
93595
93795
|
|
|
93596
93796
|
// src/lib/larkResourceCommand.ts
|
|
@@ -93789,7 +93989,7 @@ function findBooleanField(value, name2) {
|
|
|
93789
93989
|
return;
|
|
93790
93990
|
}
|
|
93791
93991
|
async function downloadedFile(input) {
|
|
93792
|
-
const tempRoot = await mkdtemp2(
|
|
93992
|
+
const tempRoot = await mkdtemp2(join58(tmpdir(), "context-lark-resource-"));
|
|
93793
93993
|
try {
|
|
93794
93994
|
await runLarkResourceCommand(input.runner, [
|
|
93795
93995
|
"docs",
|
|
@@ -93810,7 +94010,7 @@ async function downloadedFile(input) {
|
|
|
93810
94010
|
if (entries.length !== 1)
|
|
93811
94011
|
throw new Error(`media download produced ${entries.length} files, expected exactly one`);
|
|
93812
94012
|
const path4 = entries[0]?.name ?? "resource.bin";
|
|
93813
|
-
const bytes = await readFile43(
|
|
94013
|
+
const bytes = await readFile43(join58(tempRoot, path4));
|
|
93814
94014
|
return { path: path4, bytes, mediaType: mediaTypeFor(path4, bytes) };
|
|
93815
94015
|
} finally {
|
|
93816
94016
|
await rm15(tempRoot, { recursive: true, force: true });
|
|
@@ -93901,9 +94101,9 @@ async function sheetMaterialization(resource, runner2) {
|
|
|
93901
94101
|
const sheetId = resource.attributes["sheet-id"];
|
|
93902
94102
|
if (token === undefined || sheetId === undefined)
|
|
93903
94103
|
throw new Error("embedded Sheet requires token and sheet-id");
|
|
93904
|
-
const tempRoot = await mkdtemp2(
|
|
94104
|
+
const tempRoot = await mkdtemp2(join58(tmpdir(), "context-lark-sheet-"));
|
|
93905
94105
|
try {
|
|
93906
|
-
const outputPath =
|
|
94106
|
+
const outputPath = join58(tempRoot, "sheet.json");
|
|
93907
94107
|
const stdout = await runLarkResourceCommand(runner2, [
|
|
93908
94108
|
"sheets",
|
|
93909
94109
|
"+csv-get",
|
|
@@ -94059,7 +94259,7 @@ async function whiteboardMaterialization(resource, runner2) {
|
|
|
94059
94259
|
if (token === undefined)
|
|
94060
94260
|
throw new Error(`${resource.kind} has no whiteboard token`);
|
|
94061
94261
|
const preview = await downloadedFile({ runner: runner2, token, type: "whiteboard" });
|
|
94062
|
-
const tempRoot = await mkdtemp2(
|
|
94262
|
+
const tempRoot = await mkdtemp2(join58(tmpdir(), "context-lark-whiteboard-"));
|
|
94063
94263
|
let rawPayload;
|
|
94064
94264
|
try {
|
|
94065
94265
|
await runLarkResourceCommand(runner2, [
|
|
@@ -94077,7 +94277,7 @@ async function whiteboardMaterialization(resource, runner2) {
|
|
|
94077
94277
|
"--format",
|
|
94078
94278
|
"json"
|
|
94079
94279
|
], { cwd: tempRoot });
|
|
94080
|
-
rawPayload = JSON.parse(await readFile43(
|
|
94280
|
+
rawPayload = JSON.parse(await readFile43(join58(tempRoot, "raw.json"), "utf8"));
|
|
94081
94281
|
} finally {
|
|
94082
94282
|
await rm15(tempRoot, { recursive: true, force: true });
|
|
94083
94283
|
}
|
|
@@ -94350,7 +94550,7 @@ class LarkCliError extends Error {
|
|
|
94350
94550
|
}
|
|
94351
94551
|
}
|
|
94352
94552
|
var defaultRunner = (args, options) => new Promise((resolve8, reject) => {
|
|
94353
|
-
const child =
|
|
94553
|
+
const child = spawn3(LARK_BIN, args, {
|
|
94354
94554
|
...options?.cwd === undefined ? {} : { cwd: options.cwd },
|
|
94355
94555
|
stdio: ["ignore", "pipe", "pipe"]
|
|
94356
94556
|
});
|
|
@@ -94757,7 +94957,7 @@ async function fileContentMatches(path4, content3) {
|
|
|
94757
94957
|
}
|
|
94758
94958
|
}
|
|
94759
94959
|
function sourceManifestPath2(entry) {
|
|
94760
|
-
return entry.snapshot?.manifest ??
|
|
94960
|
+
return entry.snapshot?.manifest ?? join59(entry.materializedAt, "manifest.json");
|
|
94761
94961
|
}
|
|
94762
94962
|
function larkRuntimeError(message, detail) {
|
|
94763
94963
|
return new ContextError(ExitCode.ExternalToolError, message, {
|
|
@@ -94883,7 +95083,7 @@ function assetManifestEntry(asset, assetRoot) {
|
|
|
94883
95083
|
};
|
|
94884
95084
|
}
|
|
94885
95085
|
async function listSnapshotAssetFiles(root2, assetRoot) {
|
|
94886
|
-
const assetsRoot =
|
|
95086
|
+
const assetsRoot = join59(root2, assetRoot);
|
|
94887
95087
|
const files = [];
|
|
94888
95088
|
const visit3 = async (dir, prefix = assetRoot) => {
|
|
94889
95089
|
let entries;
|
|
@@ -94896,7 +95096,7 @@ async function listSnapshotAssetFiles(root2, assetRoot) {
|
|
|
94896
95096
|
}
|
|
94897
95097
|
for (const entry of entries) {
|
|
94898
95098
|
const relPath = `${prefix}/${entry.name}`;
|
|
94899
|
-
const absolutePath =
|
|
95099
|
+
const absolutePath = join59(dir, entry.name);
|
|
94900
95100
|
if (entry.isDirectory()) {
|
|
94901
95101
|
await visit3(absolutePath, relPath);
|
|
94902
95102
|
continue;
|
|
@@ -94911,7 +95111,7 @@ async function listSnapshotAssetFiles(root2, assetRoot) {
|
|
|
94911
95111
|
}
|
|
94912
95112
|
async function staleSnapshotAssetPaths(input) {
|
|
94913
95113
|
const existingPaths = await listSnapshotAssetFiles(input.materializedAtAbsPath, input.assetRoot);
|
|
94914
|
-
return existingPaths.filter((path4) => !input.currentPaths.has(path4)).map((path4) =>
|
|
95114
|
+
return existingPaths.filter((path4) => !input.currentPaths.has(path4)).map((path4) => join59(input.materializedAtAbsPath, path4));
|
|
94915
95115
|
}
|
|
94916
95116
|
function normalizeLarkError(error, sourceName) {
|
|
94917
95117
|
if (error instanceof ContextError)
|
|
@@ -94985,9 +95185,9 @@ async function runCaptureLarkPhaseUnlocked(input) {
|
|
|
94985
95185
|
locator
|
|
94986
95186
|
}];
|
|
94987
95187
|
const manifestPath = sourceManifestPath2(entry);
|
|
94988
|
-
const manifestAbsPath =
|
|
95188
|
+
const manifestAbsPath = join59(input.projectRoot, manifestPath);
|
|
94989
95189
|
const materializedAt = entry.materializedAt;
|
|
94990
|
-
const materializedAtAbsPath =
|
|
95190
|
+
const materializedAtAbsPath = join59(input.projectRoot, materializedAt);
|
|
94991
95191
|
const manifest = createDocumentSnapshotManifest({
|
|
94992
95192
|
sourceType: "lark",
|
|
94993
95193
|
sourceName: resolved.sourceName,
|
|
@@ -95017,13 +95217,13 @@ async function runCaptureLarkPhaseUnlocked(input) {
|
|
|
95017
95217
|
}));
|
|
95018
95218
|
try {
|
|
95019
95219
|
const requestedWrites = [{
|
|
95020
|
-
path:
|
|
95220
|
+
path: join59(materializedAtAbsPath, documentPath),
|
|
95021
95221
|
bytes: normalized
|
|
95022
95222
|
}];
|
|
95023
95223
|
for (const asset of assets) {
|
|
95024
95224
|
if (asset.bytes !== undefined) {
|
|
95025
95225
|
requestedWrites.push({
|
|
95026
|
-
path:
|
|
95226
|
+
path: join59(materializedAtAbsPath, asset.entry.path),
|
|
95027
95227
|
bytes: asset.bytes
|
|
95028
95228
|
});
|
|
95029
95229
|
}
|
|
@@ -95040,7 +95240,7 @@ async function runCaptureLarkPhaseUnlocked(input) {
|
|
|
95040
95240
|
currentPaths: new Set(assets.filter((asset) => asset.bytes !== undefined).map((asset) => asset.entry.path))
|
|
95041
95241
|
});
|
|
95042
95242
|
await applyAtomicFileBatch({
|
|
95043
|
-
transactionRoot:
|
|
95243
|
+
transactionRoot: join59(input.projectRoot, ".tmp", "context-runtime", "capture-transactions"),
|
|
95044
95244
|
writes,
|
|
95045
95245
|
removals
|
|
95046
95246
|
});
|
|
@@ -97463,7 +97663,7 @@ function compileDiagnostic(severity, code3, family, message, field, extra = {})
|
|
|
97463
97663
|
...extra
|
|
97464
97664
|
};
|
|
97465
97665
|
}
|
|
97466
|
-
function
|
|
97666
|
+
function isRecord20(value) {
|
|
97467
97667
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
97468
97668
|
}
|
|
97469
97669
|
|
|
@@ -97858,7 +98058,7 @@ function compileActionFromFields(fields) {
|
|
|
97858
98058
|
return action;
|
|
97859
98059
|
}
|
|
97860
98060
|
function parseCompileAction(raw, index2, diagnostics) {
|
|
97861
|
-
if (!
|
|
98061
|
+
if (!isRecord20(raw)) {
|
|
97862
98062
|
diagnostics.push(compileDiagnostic("error", "schema.action_object", "schema", "Each action must be an object.", `actions[${index2}]`));
|
|
97863
98063
|
return;
|
|
97864
98064
|
}
|
|
@@ -97870,7 +98070,7 @@ function parseCompileAction(raw, index2, diagnostics) {
|
|
|
97870
98070
|
}
|
|
97871
98071
|
function parseCompilePayload(value) {
|
|
97872
98072
|
const diagnostics = [];
|
|
97873
|
-
if (!
|
|
98073
|
+
if (!isRecord20(value)) {
|
|
97874
98074
|
return {
|
|
97875
98075
|
diagnostics: [compileDiagnostic("error", "schema.payload_object", "schema", "Compile action payload must be an object.", "schema")]
|
|
97876
98076
|
};
|
|
@@ -98833,9 +99033,9 @@ init_atomicWrite();
|
|
|
98833
99033
|
init_cliFeedback();
|
|
98834
99034
|
init_errors();
|
|
98835
99035
|
init_exitCode();
|
|
98836
|
-
import { existsSync as
|
|
99036
|
+
import { existsSync as existsSync38 } from "node:fs";
|
|
98837
99037
|
import { readFile as readFile46 } from "node:fs/promises";
|
|
98838
|
-
import { join as
|
|
99038
|
+
import { join as join60 } from "node:path";
|
|
98839
99039
|
init_writeLock();
|
|
98840
99040
|
var CUSTOM_PHASE_MANIFEST = ".tmp/context-runtime/extract/custom-phase-candidates.json";
|
|
98841
99041
|
function customInputError(phaseId, message, detail = {}) {
|
|
@@ -98989,8 +99189,8 @@ function candidateFromCustom(input) {
|
|
|
98989
99189
|
};
|
|
98990
99190
|
}
|
|
98991
99191
|
async function readManifest(projectRoot) {
|
|
98992
|
-
const path4 =
|
|
98993
|
-
if (!
|
|
99192
|
+
const path4 = join60(projectRoot, CUSTOM_PHASE_MANIFEST);
|
|
99193
|
+
if (!existsSync38(path4))
|
|
98994
99194
|
return { version: 2, phases: {} };
|
|
98995
99195
|
try {
|
|
98996
99196
|
const parsed = JSON.parse(await readFile46(path4, "utf8"));
|
|
@@ -99090,7 +99290,7 @@ async function runExtractCustomPhase(input) {
|
|
|
99090
99290
|
symbols: built.flatMap((item) => item.symbols),
|
|
99091
99291
|
removeSymbols: previousOwned?.symbols ?? []
|
|
99092
99292
|
});
|
|
99093
|
-
await atomicWriteFile(
|
|
99293
|
+
await atomicWriteFile(join60(input.projectRoot, CUSTOM_PHASE_MANIFEST), `${JSON.stringify({
|
|
99094
99294
|
version: 2,
|
|
99095
99295
|
phases: {
|
|
99096
99296
|
...manifest.phases,
|
|
@@ -99150,7 +99350,7 @@ async function runExtractCustomPhase(input) {
|
|
|
99150
99350
|
|
|
99151
99351
|
// src/project/reviewHtml.ts
|
|
99152
99352
|
import { mkdir as mkdir29, writeFile as writeFile24 } from "node:fs/promises";
|
|
99153
|
-
import { dirname as
|
|
99353
|
+
import { dirname as dirname37, isAbsolute as isAbsolute9, join as join62, resolve as resolve23 } from "node:path";
|
|
99154
99354
|
import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
99155
99355
|
|
|
99156
99356
|
// src/project/reviewSourceExcerpts.ts
|
|
@@ -99260,9 +99460,9 @@ async function collectReviewSourceExcerpts(projectRoot, candidates) {
|
|
|
99260
99460
|
}
|
|
99261
99461
|
|
|
99262
99462
|
// src/project/reviewHtmlPresentation.ts
|
|
99263
|
-
import { existsSync as
|
|
99463
|
+
import { existsSync as existsSync39 } from "node:fs";
|
|
99264
99464
|
import { readFile as readFile47 } from "node:fs/promises";
|
|
99265
|
-
import { join as
|
|
99465
|
+
import { join as join61 } from "node:path";
|
|
99266
99466
|
var import_yaml31 = __toESM(require_dist3(), 1);
|
|
99267
99467
|
function escapeHtml3(value) {
|
|
99268
99468
|
return value.replace(/&/gu, "&").replace(/</gu, "<").replace(/>/gu, ">").replace(/"/gu, """);
|
|
@@ -99343,8 +99543,8 @@ function filterEdgePreviewForCandidate(record, edges) {
|
|
|
99343
99543
|
return edges.filter((edge2) => endpoints.has(edge2.from) || endpoints.has(edge2.to));
|
|
99344
99544
|
}
|
|
99345
99545
|
async function readEdgePreview(projectRoot) {
|
|
99346
|
-
const filePath =
|
|
99347
|
-
if (!
|
|
99546
|
+
const filePath = join61(projectRoot, LIFECYCLE_STRUCTURE_FILE);
|
|
99547
|
+
if (!existsSync39(filePath))
|
|
99348
99548
|
return [];
|
|
99349
99549
|
try {
|
|
99350
99550
|
const parsed = import_yaml31.default.parse(await readFile47(filePath, "utf8"));
|
|
@@ -99521,7 +99721,7 @@ var REVIEW_HTML_STYLES = `
|
|
|
99521
99721
|
`;
|
|
99522
99722
|
|
|
99523
99723
|
// src/project/reviewHtml.ts
|
|
99524
|
-
var REVIEW_HTML_ROOT =
|
|
99724
|
+
var REVIEW_HTML_ROOT = join62(".tmp", "context-runtime", "review");
|
|
99525
99725
|
function decodedLinkTarget(value) {
|
|
99526
99726
|
try {
|
|
99527
99727
|
return decodeURIComponent(value);
|
|
@@ -99535,7 +99735,7 @@ function linkedResourcePreviews(input) {
|
|
|
99535
99735
|
const target = link2.target;
|
|
99536
99736
|
if (/^[a-z][a-z0-9+.-]*:/iu.test(target) || target.startsWith("/"))
|
|
99537
99737
|
continue;
|
|
99538
|
-
const assetPath =
|
|
99738
|
+
const assetPath = join62(dirname37(input.documentPath), decodedLinkTarget(target)).split("\\").join("/");
|
|
99539
99739
|
const asset = input.assetsByPath.get(assetPath);
|
|
99540
99740
|
if (asset?.content_hash === undefined || asset.role === "audit")
|
|
99541
99741
|
continue;
|
|
@@ -99543,7 +99743,7 @@ function linkedResourcePreviews(input) {
|
|
|
99543
99743
|
label: link2.label || "Resource",
|
|
99544
99744
|
kind: asset.source?.kind ?? "resource",
|
|
99545
99745
|
status: "materialized",
|
|
99546
|
-
url: pathToFileURL3(
|
|
99746
|
+
url: pathToFileURL3(join62(input.projectRoot, input.materializedAt, asset.path)).href,
|
|
99547
99747
|
media_type: asset.media_type ?? "application/octet-stream",
|
|
99548
99748
|
image: asset.media_type?.startsWith("image/") === true
|
|
99549
99749
|
});
|
|
@@ -99552,7 +99752,7 @@ function linkedResourcePreviews(input) {
|
|
|
99552
99752
|
}
|
|
99553
99753
|
function materializationPreview(input) {
|
|
99554
99754
|
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");
|
|
99555
|
-
const url = input.existing?.url ?? (linkedAsset?.content_hash === undefined ? undefined : pathToFileURL3(
|
|
99755
|
+
const url = input.existing?.url ?? (linkedAsset?.content_hash === undefined ? undefined : pathToFileURL3(join62(input.projectRoot, input.materializedAt, linkedAsset.path)).href);
|
|
99556
99756
|
return {
|
|
99557
99757
|
key: linkedAsset?.path ?? input.item.locator,
|
|
99558
99758
|
preview: {
|
|
@@ -100096,7 +100296,7 @@ function renderReviewHtml(candidates, reviewScope, edgePreview, sourceExcerpts,
|
|
|
100096
100296
|
}
|
|
100097
100297
|
function resolveOutputPath(projectRoot, outPath, reviewScope) {
|
|
100098
100298
|
if (outPath === undefined)
|
|
100099
|
-
return
|
|
100299
|
+
return join62(projectRoot, REVIEW_HTML_ROOT, `${reviewScope}.html`);
|
|
100100
100300
|
return isAbsolute9(outPath) ? outPath : resolve23(projectRoot, outPath);
|
|
100101
100301
|
}
|
|
100102
100302
|
async function writeReviewHtml(input) {
|
|
@@ -100109,7 +100309,7 @@ async function writeReviewHtml(input) {
|
|
|
100109
100309
|
const sourceExcerpts = await collectReviewSourceExcerpts(input.projectRoot, candidates);
|
|
100110
100310
|
const resourcePreviews = await collectReviewResourcePreviews(input.projectRoot, candidates);
|
|
100111
100311
|
const outPath = resolveOutputPath(input.projectRoot, input.out, reviewScope);
|
|
100112
|
-
await mkdir29(
|
|
100312
|
+
await mkdir29(dirname37(outPath), { recursive: true });
|
|
100113
100313
|
await writeFile24(outPath, renderReviewHtml(candidates, reviewScope, edgePreview, sourceExcerpts, resourcePreviews), "utf8");
|
|
100114
100314
|
return {
|
|
100115
100315
|
path: outPath,
|
|
@@ -100524,17 +100724,17 @@ function compactJsonResult(result, verbose) {
|
|
|
100524
100724
|
}
|
|
100525
100725
|
|
|
100526
100726
|
// src/project/runLog.ts
|
|
100527
|
-
import { randomUUID as
|
|
100727
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
100528
100728
|
import { mkdir as mkdir30, writeFile as writeFile25 } from "node:fs/promises";
|
|
100529
|
-
import { dirname as
|
|
100729
|
+
import { dirname as dirname38, join as join63 } from "node:path";
|
|
100530
100730
|
var createPhaseRunId = () => {
|
|
100531
100731
|
const timestamp = new Date().toISOString().replace(/[-:.TZ]/gu, "");
|
|
100532
|
-
return `run_${timestamp}_${
|
|
100732
|
+
return `run_${timestamp}_${randomUUID3().slice(0, 8)}`;
|
|
100533
100733
|
};
|
|
100534
100734
|
async function writePhaseRunLog(input) {
|
|
100535
|
-
const relPath =
|
|
100536
|
-
const absPath =
|
|
100537
|
-
await mkdir30(
|
|
100735
|
+
const relPath = join63(".tmp", "context-runtime", "runs", `${input.runId}.json`);
|
|
100736
|
+
const absPath = join63(input.projectRoot, relPath);
|
|
100737
|
+
await mkdir30(dirname38(absPath), { recursive: true });
|
|
100538
100738
|
await writeFile25(absPath, `${JSON.stringify({
|
|
100539
100739
|
run_id: input.runId,
|
|
100540
100740
|
phase_id: input.phase.id,
|
|
@@ -101235,14 +101435,14 @@ init_exitCode();
|
|
|
101235
101435
|
import { resolve as resolve24 } from "node:path";
|
|
101236
101436
|
init_workspace();
|
|
101237
101437
|
var PROSE_STRUCTURE_BATCH_SCHEMA = "context.prose.structure-batch.v1";
|
|
101238
|
-
function
|
|
101438
|
+
function isRecord21(value) {
|
|
101239
101439
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
101240
101440
|
}
|
|
101241
101441
|
function shellQuote8(value) {
|
|
101242
101442
|
return /^[A-Za-z0-9._/=-]+$/u.test(value) ? value : `'${value.replace(/'/gu, `'"'"'`)}'`;
|
|
101243
101443
|
}
|
|
101244
101444
|
function parseBatchPayload(value) {
|
|
101245
|
-
if (!
|
|
101445
|
+
if (!isRecord21(value) || value.schema !== PROSE_STRUCTURE_BATCH_SCHEMA || !Array.isArray(value.items)) {
|
|
101246
101446
|
throw new ContextError(ExitCode.UserError, `batch input must match ${PROSE_STRUCTURE_BATCH_SCHEMA}`, {
|
|
101247
101447
|
category: ErrorCategory.UserInputInvalid,
|
|
101248
101448
|
next: "Read the current Route action input_schema and provide one phase_id/input pair per pending structure slot."
|
|
@@ -101255,7 +101455,7 @@ function parseBatchPayload(value) {
|
|
|
101255
101455
|
}
|
|
101256
101456
|
const seen = new Set;
|
|
101257
101457
|
return value.items.map((item, index2) => {
|
|
101258
|
-
if (!
|
|
101458
|
+
if (!isRecord21(item) || typeof item.phase_id !== "string" || typeof item.input !== "string") {
|
|
101259
101459
|
throw new ContextError(ExitCode.UserError, `structure batch items[${index2}] requires phase_id and input`, {
|
|
101260
101460
|
category: ErrorCategory.UserInputInvalid
|
|
101261
101461
|
});
|
|
@@ -101287,7 +101487,7 @@ function alignPhase(phases, phaseId) {
|
|
|
101287
101487
|
return phase;
|
|
101288
101488
|
}
|
|
101289
101489
|
function validationSummary(phaseId, input, result) {
|
|
101290
|
-
const counts2 = result.structure_summary_compact !== undefined &&
|
|
101490
|
+
const counts2 = result.structure_summary_compact !== undefined && isRecord21(result.structure_summary_compact.counts) ? result.structure_summary_compact.counts : undefined;
|
|
101291
101491
|
return {
|
|
101292
101492
|
phase_id: phaseId,
|
|
101293
101493
|
input,
|
|
@@ -101629,7 +101829,8 @@ async function runWorkflowUntilBlockedOrComplete(input) {
|
|
|
101629
101829
|
receipt = await input.execute({
|
|
101630
101830
|
cwd: status.projectRoot,
|
|
101631
101831
|
command: selected.command.command,
|
|
101632
|
-
effect: selected.command.effect
|
|
101832
|
+
effect: selected.command.effect,
|
|
101833
|
+
...selected.command.execution === undefined ? {} : { execution: selected.command.execution }
|
|
101633
101834
|
});
|
|
101634
101835
|
} catch (error) {
|
|
101635
101836
|
steps.push(step);
|
|
@@ -101780,7 +101981,7 @@ init_debugTrace();
|
|
|
101780
101981
|
// src/project/workflow/workflowExecutionRuntime.ts
|
|
101781
101982
|
init_debugTrace();
|
|
101782
101983
|
import { createHash as createHash26 } from "node:crypto";
|
|
101783
|
-
import { spawn as
|
|
101984
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
101784
101985
|
function digestText2(value, includeTail) {
|
|
101785
101986
|
const bytes = Buffer.byteLength(value);
|
|
101786
101987
|
return {
|
|
@@ -101874,7 +102075,7 @@ class WorkspaceExecutionRuntime {
|
|
|
101874
102075
|
throw new Error(`workspace execution runtime cannot cross roots: ${input.cwd}`);
|
|
101875
102076
|
}
|
|
101876
102077
|
const args = parseContextCommand(input.command);
|
|
101877
|
-
if (input.effect !== "external" && this.inProcess.supports({ ...input, args })) {
|
|
102078
|
+
if (input.execution?.target !== "subprocess" && input.effect !== "external" && this.inProcess.supports({ ...input, args })) {
|
|
101878
102079
|
return this.executeInProcess({ ...input, args });
|
|
101879
102080
|
}
|
|
101880
102081
|
return this.executeSubprocess(input);
|
|
@@ -101930,7 +102131,7 @@ execution scope cleanup failed`, true)
|
|
|
101930
102131
|
try {
|
|
101931
102132
|
receipt = await new Promise((resolve8, reject) => {
|
|
101932
102133
|
let settled = false;
|
|
101933
|
-
const child =
|
|
102134
|
+
const child = spawn4(process.execPath, [this.cliEntryPath, ...args], {
|
|
101934
102135
|
cwd: input.cwd,
|
|
101935
102136
|
env: { ...process.env, ...debugChildEnvironment() },
|
|
101936
102137
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -102295,7 +102496,7 @@ function requirePayloadHeaderField(value, field) {
|
|
|
102295
102496
|
return value;
|
|
102296
102497
|
}
|
|
102297
102498
|
function parsePayloadLineDecision(value, index2) {
|
|
102298
|
-
if (!
|
|
102499
|
+
if (!isRecord17(value) || typeof value.candidate_id !== "string") {
|
|
102299
102500
|
throw new ContextError(ExitCode.UserError, `review payload line ${index2} must contain candidate_id and status`, {
|
|
102300
102501
|
category: ErrorCategory.UserInputInvalid
|
|
102301
102502
|
});
|
|
@@ -102308,7 +102509,7 @@ function parsePayloadLineDecision(value, index2) {
|
|
|
102308
102509
|
function parsePayloadScope(value) {
|
|
102309
102510
|
if (value === undefined)
|
|
102310
102511
|
return;
|
|
102311
|
-
if (!
|
|
102512
|
+
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)) {
|
|
102312
102513
|
throw new ContextError(ExitCode.UserError, "review payload scope must contain count and ids_sha256", {
|
|
102313
102514
|
category: ErrorCategory.UserInputInvalid
|
|
102314
102515
|
});
|
|
@@ -102347,7 +102548,7 @@ function parsePayloadScope(value) {
|
|
|
102347
102548
|
}
|
|
102348
102549
|
function parsePayloadValues(parsed) {
|
|
102349
102550
|
const first = parsed[0];
|
|
102350
|
-
if (!
|
|
102551
|
+
if (!isRecord17(first)) {
|
|
102351
102552
|
throw new ContextError(ExitCode.UserError, "review payload header must be a JSON object", {
|
|
102352
102553
|
category: ErrorCategory.UserInputInvalid
|
|
102353
102554
|
});
|
|
@@ -103259,7 +103460,7 @@ async function runManagedUntil(input) {
|
|
|
103259
103460
|
const resourceReceipts = input.resourceReceiptsReference === undefined ? undefined : await parseWorkflowResourceReceipts(input.resourceReceiptsReference, found.projectRoot);
|
|
103260
103461
|
const runtime = new WorkspaceExecutionRuntime({
|
|
103261
103462
|
projectRoot: found.projectRoot,
|
|
103262
|
-
cliEntryPath:
|
|
103463
|
+
cliEntryPath: fileURLToPath8(input.cliModuleUrl),
|
|
103263
103464
|
inProcess: createWorkflowInProcessExecutor()
|
|
103264
103465
|
});
|
|
103265
103466
|
let result;
|
|
@@ -103404,10 +103605,10 @@ function registerDebugCommands(program2) {
|
|
|
103404
103605
|
|
|
103405
103606
|
// src/commands/cleanClaudePluginCache.ts
|
|
103406
103607
|
init_cliFeedback();
|
|
103407
|
-
import { existsSync as
|
|
103608
|
+
import { existsSync as existsSync40 } from "node:fs";
|
|
103408
103609
|
import { readdir as readdir19, rm as rm16 } from "node:fs/promises";
|
|
103409
103610
|
import { homedir } from "node:os";
|
|
103410
|
-
import { join as
|
|
103611
|
+
import { join as join64 } from "node:path";
|
|
103411
103612
|
var ORPHAN_MARKER = ".orphaned_at";
|
|
103412
103613
|
var CLAUDE_PLUGIN_CACHE_ROOT_ENV = "C4A_CLAUDE_PLUGIN_CACHE_ROOT";
|
|
103413
103614
|
var CLAUDE_PLUGIN_CACHE_HOME_ENV = "C4A_CLAUDE_PLUGIN_CACHE_HOME";
|
|
@@ -103416,7 +103617,7 @@ async function cleanClaudePluginCache(opts = {}) {
|
|
|
103416
103617
|
const lines = [];
|
|
103417
103618
|
let removed = 0;
|
|
103418
103619
|
let scanned = 0;
|
|
103419
|
-
if (!
|
|
103620
|
+
if (!existsSync40(cacheRoot)) {
|
|
103420
103621
|
lines.push("· claude plugin cache: missing — nothing to clean");
|
|
103421
103622
|
return { lines, removed, scanned };
|
|
103422
103623
|
}
|
|
@@ -103424,20 +103625,20 @@ async function cleanClaudePluginCache(opts = {}) {
|
|
|
103424
103625
|
for (const mp of marketplaces) {
|
|
103425
103626
|
if (!mp.isDirectory())
|
|
103426
103627
|
continue;
|
|
103427
|
-
const mpDir =
|
|
103628
|
+
const mpDir = join64(cacheRoot, mp.name);
|
|
103428
103629
|
const plugins = await readdir19(mpDir, { withFileTypes: true });
|
|
103429
103630
|
for (const pl of plugins) {
|
|
103430
103631
|
if (!pl.isDirectory())
|
|
103431
103632
|
continue;
|
|
103432
|
-
const plDir =
|
|
103633
|
+
const plDir = join64(mpDir, pl.name);
|
|
103433
103634
|
const versions = await readdir19(plDir, { withFileTypes: true });
|
|
103434
103635
|
for (const ver of versions) {
|
|
103435
103636
|
if (!ver.isDirectory())
|
|
103436
103637
|
continue;
|
|
103437
103638
|
scanned += 1;
|
|
103438
|
-
const verDir =
|
|
103439
|
-
const markerPath =
|
|
103440
|
-
if (!
|
|
103639
|
+
const verDir = join64(plDir, ver.name);
|
|
103640
|
+
const markerPath = join64(verDir, ORPHAN_MARKER);
|
|
103641
|
+
if (!existsSync40(markerPath))
|
|
103441
103642
|
continue;
|
|
103442
103643
|
const label3 = `${mp.name}/${pl.name}/${ver.name}`;
|
|
103443
103644
|
if (opts.dryRun) {
|
|
@@ -103468,7 +103669,7 @@ function resolveClaudePluginCacheRoot(opts) {
|
|
|
103468
103669
|
if (explicitRoot)
|
|
103469
103670
|
return explicitRoot;
|
|
103470
103671
|
const home = opts.home ?? process.env[CLAUDE_PLUGIN_CACHE_HOME_ENV] ?? homedir();
|
|
103471
|
-
return
|
|
103672
|
+
return join64(home, ".claude", "plugins", "cache");
|
|
103472
103673
|
}
|
|
103473
103674
|
async function isEmptyDir(dir) {
|
|
103474
103675
|
try {
|
|
@@ -103494,17 +103695,17 @@ async function runDoctorCleanClaudePluginCache(opts = {}) {
|
|
|
103494
103695
|
}
|
|
103495
103696
|
|
|
103496
103697
|
// src/commands/cleanCache.ts
|
|
103497
|
-
import { existsSync as
|
|
103698
|
+
import { existsSync as existsSync42 } from "node:fs";
|
|
103498
103699
|
import { readdir as readdir20, rm as rm17 } from "node:fs/promises";
|
|
103499
|
-
import { join as
|
|
103700
|
+
import { join as join68 } from "node:path";
|
|
103500
103701
|
|
|
103501
103702
|
// src/incremental/cache.ts
|
|
103502
|
-
import { basename as basename10, dirname as
|
|
103703
|
+
import { basename as basename10, dirname as dirname40, isAbsolute as isAbsolute11, join as join67, resolve as resolve27 } from "node:path";
|
|
103503
103704
|
|
|
103504
103705
|
// src/lib/workspaceLayout.ts
|
|
103505
103706
|
var import_yaml32 = __toESM(require_dist3(), 1);
|
|
103506
|
-
import { existsSync as
|
|
103507
|
-
import { dirname as
|
|
103707
|
+
import { existsSync as existsSync41, readFileSync as readFileSync9, statSync as statSync2 } from "node:fs";
|
|
103708
|
+
import { dirname as dirname39, join as join65, parse as parse7, resolve as resolve26 } from "node:path";
|
|
103508
103709
|
function isDirectorySafe(path4) {
|
|
103509
103710
|
try {
|
|
103510
103711
|
return statSync2(path4).isDirectory();
|
|
@@ -103513,11 +103714,11 @@ function isDirectorySafe(path4) {
|
|
|
103513
103714
|
}
|
|
103514
103715
|
}
|
|
103515
103716
|
function hasRootLayoutMarker(dir) {
|
|
103516
|
-
const configPath =
|
|
103517
|
-
if (!
|
|
103717
|
+
const configPath = join65(dir, "config.yaml");
|
|
103718
|
+
if (!existsSync41(configPath))
|
|
103518
103719
|
return false;
|
|
103519
103720
|
try {
|
|
103520
|
-
const parsed = import_yaml32.default.parse(
|
|
103721
|
+
const parsed = import_yaml32.default.parse(readFileSync9(configPath, "utf8"));
|
|
103521
103722
|
if (!parsed || typeof parsed !== "object")
|
|
103522
103723
|
return false;
|
|
103523
103724
|
const workspace = parsed.workspace;
|
|
@@ -103530,8 +103731,8 @@ function hasRootLayoutMarker(dir) {
|
|
|
103530
103731
|
}
|
|
103531
103732
|
function findWorkspaceAt(dir) {
|
|
103532
103733
|
const root2 = resolve26(dir);
|
|
103533
|
-
const embedded =
|
|
103534
|
-
if (
|
|
103734
|
+
const embedded = join65(root2, ".context");
|
|
103735
|
+
if (existsSync41(join65(embedded, "config.yaml")) && isDirectorySafe(embedded)) {
|
|
103535
103736
|
return { ctxDir: embedded, workspaceRoot: root2, layout: "embedded" };
|
|
103536
103737
|
}
|
|
103537
103738
|
if (hasRootLayoutMarker(root2)) {
|
|
@@ -103548,7 +103749,7 @@ function findNearestWorkspace(startDir = process.cwd()) {
|
|
|
103548
103749
|
return found;
|
|
103549
103750
|
if (dir === root2)
|
|
103550
103751
|
return null;
|
|
103551
|
-
const parent =
|
|
103752
|
+
const parent = dirname39(dir);
|
|
103552
103753
|
if (parent === dir)
|
|
103553
103754
|
return null;
|
|
103554
103755
|
dir = parent;
|
|
@@ -103556,9 +103757,9 @@ function findNearestWorkspace(startDir = process.cwd()) {
|
|
|
103556
103757
|
}
|
|
103557
103758
|
|
|
103558
103759
|
// src/lib/userCache.ts
|
|
103559
|
-
import { basename as basename9, join as
|
|
103760
|
+
import { basename as basename9, join as join66 } from "node:path";
|
|
103560
103761
|
function workspaceLocalUserCacheRoot(ctxDir) {
|
|
103561
|
-
return
|
|
103762
|
+
return join66(ctxDir, ".tmp", "context-cli");
|
|
103562
103763
|
}
|
|
103563
103764
|
|
|
103564
103765
|
// src/incremental/cache.ts
|
|
@@ -103568,7 +103769,7 @@ function resolveCachePath(value) {
|
|
|
103568
103769
|
}
|
|
103569
103770
|
function workspaceCacheHome(workspaceRoot) {
|
|
103570
103771
|
const location = findWorkspaceAt(workspaceRoot);
|
|
103571
|
-
return workspaceLocalUserCacheRoot(location?.ctxDir ??
|
|
103772
|
+
return workspaceLocalUserCacheRoot(location?.ctxDir ?? join67(workspaceRoot, ".context"));
|
|
103572
103773
|
}
|
|
103573
103774
|
function resolveCacheHome(input = {}) {
|
|
103574
103775
|
const explicit = input.cacheHome ?? process.env.C4A_CONTEXT_CACHE_HOME;
|
|
@@ -103577,24 +103778,24 @@ function resolveCacheHome(input = {}) {
|
|
|
103577
103778
|
if (input.workspaceRoot !== undefined)
|
|
103578
103779
|
return workspaceCacheHome(resolveCachePath(input.workspaceRoot));
|
|
103579
103780
|
const nearest = findNearestWorkspace(process.cwd());
|
|
103580
|
-
return workspaceLocalUserCacheRoot(nearest?.ctxDir ??
|
|
103781
|
+
return workspaceLocalUserCacheRoot(nearest?.ctxDir ?? join67(process.cwd(), ".context"));
|
|
103581
103782
|
}
|
|
103582
103783
|
|
|
103583
103784
|
// src/commands/cleanCache.ts
|
|
103584
103785
|
async function countFiles2(dir) {
|
|
103585
|
-
if (!
|
|
103786
|
+
if (!existsSync42(dir))
|
|
103586
103787
|
return 0;
|
|
103587
103788
|
let count = 0;
|
|
103588
103789
|
for (const entry of await readdir20(dir, { withFileTypes: true })) {
|
|
103589
|
-
const full =
|
|
103790
|
+
const full = join68(dir, entry.name);
|
|
103590
103791
|
count += entry.isDirectory() ? await countFiles2(full) : 1;
|
|
103591
103792
|
}
|
|
103592
103793
|
return count;
|
|
103593
103794
|
}
|
|
103594
103795
|
async function inspectAllRetrievalCache() {
|
|
103595
103796
|
const cacheHome = resolveCacheHome();
|
|
103596
|
-
const cacheRoot =
|
|
103597
|
-
const projectIds =
|
|
103797
|
+
const cacheRoot = join68(cacheHome, "retrieval");
|
|
103798
|
+
const projectIds = existsSync42(cacheRoot) ? (await readdir20(cacheRoot, { withFileTypes: true })).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort() : [];
|
|
103598
103799
|
const files = await countFiles2(cacheRoot);
|
|
103599
103800
|
return { cacheRoot, projects: projectIds.length, files, projectIds };
|
|
103600
103801
|
}
|
|
@@ -103612,8 +103813,6 @@ async function cleanAllRetrievalCache() {
|
|
|
103612
103813
|
init_errors();
|
|
103613
103814
|
init_cliFeedback();
|
|
103614
103815
|
init_exitCode();
|
|
103615
|
-
init_workspace();
|
|
103616
|
-
init_packageTemplateReview();
|
|
103617
103816
|
|
|
103618
103817
|
// src/project/sourceCommands.ts
|
|
103619
103818
|
import { readFile as readFile54 } from "node:fs/promises";
|
|
@@ -103628,9 +103827,9 @@ init_cliFeedback();
|
|
|
103628
103827
|
init_errors();
|
|
103629
103828
|
init_exitCode();
|
|
103630
103829
|
import { execFile as execFile6 } from "node:child_process";
|
|
103631
|
-
import { existsSync as
|
|
103830
|
+
import { existsSync as existsSync43 } from "node:fs";
|
|
103632
103831
|
import { lstat as lstat3, mkdir as mkdir31, readlink as readlink2, realpath as realpath4, rm as rm18, symlink as symlink2 } from "node:fs/promises";
|
|
103633
|
-
import { basename as basename11, dirname as
|
|
103832
|
+
import { basename as basename11, dirname as dirname41, isAbsolute as isAbsolute12, relative as relative20, resolve as resolve28 } from "node:path";
|
|
103634
103833
|
import { promisify as promisify6 } from "node:util";
|
|
103635
103834
|
init_writeLock();
|
|
103636
103835
|
var execFileAsync6 = promisify6(execFile6);
|
|
@@ -103772,7 +103971,7 @@ async function git2(cwd, args) {
|
|
|
103772
103971
|
}
|
|
103773
103972
|
async function resolveGitRoot2(path4) {
|
|
103774
103973
|
const root2 = await git2(path4, ["rev-parse", "--show-toplevel"]);
|
|
103775
|
-
if (root2.length === 0 || !
|
|
103974
|
+
if (root2.length === 0 || !existsSync43(root2)) {
|
|
103776
103975
|
throw userInputError3(`local repository path is not a Git checkout: ${path4}`, { path: path4 });
|
|
103777
103976
|
}
|
|
103778
103977
|
return realpath4(root2);
|
|
@@ -103793,13 +103992,13 @@ async function verifyCheckout(input) {
|
|
|
103793
103992
|
}
|
|
103794
103993
|
async function cloneCheckout(input) {
|
|
103795
103994
|
const target = resolve28(input.projectRoot, input.target ?? `.tmp/repo/${repositorySlug(input.remote)}-${input.ref.slice(0, 12)}`);
|
|
103796
|
-
if (
|
|
103995
|
+
if (existsSync43(target)) {
|
|
103797
103996
|
throw userInputError3(`clone target already exists: ${target}`, {
|
|
103798
103997
|
target,
|
|
103799
103998
|
next: `Use local mode with path ${JSON.stringify(target)} after inspecting the existing checkout.`
|
|
103800
103999
|
});
|
|
103801
104000
|
}
|
|
103802
|
-
await mkdir31(
|
|
104001
|
+
await mkdir31(dirname41(target), { recursive: true });
|
|
103803
104002
|
const cloneArgs = ["clone", "--no-checkout", "--depth=1", "--filter=blob:none", input.remote, target];
|
|
103804
104003
|
try {
|
|
103805
104004
|
await execFileAsync6("git", cloneArgs, { encoding: "utf8", maxBuffer: 4 * 1024 * 1024 });
|
|
@@ -103848,7 +104047,7 @@ async function bindLocalAlias(input) {
|
|
|
103848
104047
|
const stats = await lstat3(alias).catch(() => null);
|
|
103849
104048
|
if (stats !== null) {
|
|
103850
104049
|
if (stats.isSymbolicLink()) {
|
|
103851
|
-
const actual = resolve28(
|
|
104050
|
+
const actual = resolve28(dirname41(alias), await readlink2(alias));
|
|
103852
104051
|
const actualReal = await realpath4(actual).catch(() => null);
|
|
103853
104052
|
if (actualReal !== null && actualReal === await realpath4(input.checkout))
|
|
103854
104053
|
return;
|
|
@@ -103864,8 +104063,8 @@ async function bindLocalAlias(input) {
|
|
|
103864
104063
|
});
|
|
103865
104064
|
}
|
|
103866
104065
|
}
|
|
103867
|
-
await mkdir31(
|
|
103868
|
-
await symlink2(relative20(
|
|
104066
|
+
await mkdir31(dirname41(alias), { recursive: true });
|
|
104067
|
+
await symlink2(relative20(dirname41(alias), input.checkout) || ".", alias);
|
|
103869
104068
|
}
|
|
103870
104069
|
function selectPhysicalGroup(sources, selector) {
|
|
103871
104070
|
const direct = selectRepoSources(sources, selector);
|
|
@@ -103952,13 +104151,13 @@ async function restoreRepositorySources(input) {
|
|
|
103952
104151
|
}
|
|
103953
104152
|
|
|
103954
104153
|
// src/project/sourceDocumentStatus.ts
|
|
103955
|
-
import { existsSync as
|
|
104154
|
+
import { existsSync as existsSync44 } from "node:fs";
|
|
103956
104155
|
import { readFile as readFile51 } from "node:fs/promises";
|
|
103957
|
-
import { join as
|
|
104156
|
+
import { join as join70 } from "node:path";
|
|
103958
104157
|
|
|
103959
104158
|
// src/project/sourceCommandViews.ts
|
|
103960
104159
|
import { readFile as readFile50 } from "node:fs/promises";
|
|
103961
|
-
import { join as
|
|
104160
|
+
import { join as join69 } from "node:path";
|
|
103962
104161
|
init_workspace();
|
|
103963
104162
|
function repoSourceAgentView(source2) {
|
|
103964
104163
|
return {
|
|
@@ -104020,7 +104219,7 @@ async function fileSourceAgentViewWithNextAction(input) {
|
|
|
104020
104219
|
};
|
|
104021
104220
|
}
|
|
104022
104221
|
function documentSourceManifestPath(source2) {
|
|
104023
|
-
return source2.snapshot?.manifest ??
|
|
104222
|
+
return source2.snapshot?.manifest ?? join69(source2.materializedAt, "manifest.json");
|
|
104024
104223
|
}
|
|
104025
104224
|
async function fileSourceDocumentSiteHint(input) {
|
|
104026
104225
|
const detection = await detectDocumentSiteFiles({
|
|
@@ -104030,7 +104229,7 @@ async function fileSourceDocumentSiteHint(input) {
|
|
|
104030
104229
|
let snapshotConfigured = false;
|
|
104031
104230
|
const manifest = documentSourceManifestPath(input.source);
|
|
104032
104231
|
try {
|
|
104033
|
-
const parsed = parseDocumentSnapshotForSource(JSON.parse(await readFile50(
|
|
104232
|
+
const parsed = parseDocumentSnapshotForSource(JSON.parse(await readFile50(join69(input.projectRoot, manifest), "utf8")), input.source.name);
|
|
104034
104233
|
snapshotConfigured = manifestUsesMdxJsonDocs(parsed);
|
|
104035
104234
|
} catch {
|
|
104036
104235
|
snapshotConfigured = false;
|
|
@@ -104061,12 +104260,12 @@ async function larkSourceAgentViewWithNextAction(input) {
|
|
|
104061
104260
|
|
|
104062
104261
|
// src/project/sourceDocumentStatus.ts
|
|
104063
104262
|
function documentSourceManifestPath2(source2) {
|
|
104064
|
-
return source2.snapshot?.manifest ??
|
|
104263
|
+
return source2.snapshot?.manifest ?? join70(source2.materializedAt, "manifest.json");
|
|
104065
104264
|
}
|
|
104066
104265
|
async function documentSnapshotState(input) {
|
|
104067
104266
|
const manifest = documentSourceManifestPath2(input.source);
|
|
104068
|
-
const manifestPath =
|
|
104069
|
-
if (!
|
|
104267
|
+
const manifestPath = join70(input.projectRoot, manifest);
|
|
104268
|
+
if (!existsSync44(manifestPath)) {
|
|
104070
104269
|
return {
|
|
104071
104270
|
snapshotReady: false,
|
|
104072
104271
|
state: "needs-capture",
|
|
@@ -104144,7 +104343,7 @@ async function documentSnapshotState(input) {
|
|
|
104144
104343
|
const missing = [
|
|
104145
104344
|
...parsed.files.map((file) => file.path),
|
|
104146
104345
|
...(parsed.assets ?? []).filter((asset) => asset.content_hash !== undefined).map((asset) => asset.path)
|
|
104147
|
-
].find((path4) => !
|
|
104346
|
+
].find((path4) => !existsSync44(join70(input.projectRoot, input.source.materializedAt, path4)));
|
|
104148
104347
|
if (missing !== undefined) {
|
|
104149
104348
|
return {
|
|
104150
104349
|
snapshotReady: false,
|
|
@@ -104216,7 +104415,7 @@ async function inspectDocumentSources(input) {
|
|
|
104216
104415
|
// src/project/documentSourceRegistration.ts
|
|
104217
104416
|
import { createHash as createHash27 } from "node:crypto";
|
|
104218
104417
|
import { readFile as readFile52, realpath as realpath5 } from "node:fs/promises";
|
|
104219
|
-
import { basename as basename12, extname as extname13, isAbsolute as isAbsolute13, join as
|
|
104418
|
+
import { basename as basename12, extname as extname13, isAbsolute as isAbsolute13, join as join71, relative as relative21, resolve as resolve29 } from "node:path";
|
|
104220
104419
|
init_atomicWrite();
|
|
104221
104420
|
init_cliFeedback();
|
|
104222
104421
|
init_errors();
|
|
@@ -104317,7 +104516,7 @@ function assertSafeFileInclude(value) {
|
|
|
104317
104516
|
}
|
|
104318
104517
|
async function readRegistryDocument(projectRoot, registryPath2) {
|
|
104319
104518
|
try {
|
|
104320
|
-
const content3 = await readFile52(
|
|
104519
|
+
const content3 = await readFile52(join71(projectRoot, registryPath2), "utf8");
|
|
104321
104520
|
return content3.trim().length === 0 ? { sources: [] } : import_yaml33.default.parse(content3);
|
|
104322
104521
|
} catch (error) {
|
|
104323
104522
|
if (error instanceof Error && "code" in error && error.code === "ENOENT")
|
|
@@ -104435,7 +104634,7 @@ async function addFileSourceUnlocked(input) {
|
|
|
104435
104634
|
const record2 = entry2;
|
|
104436
104635
|
return record2.name !== input.name && record2.id !== input.name;
|
|
104437
104636
|
}), nextEntry];
|
|
104438
|
-
await atomicWriteFile(
|
|
104637
|
+
await atomicWriteFile(join71(input.projectRoot, DEFAULT_FILE_SOURCES_REGISTRY_PATH), import_yaml33.default.stringify({ sources: nextSources }));
|
|
104439
104638
|
const updated = await loadSourcesRegistry({ rootDir: input.projectRoot });
|
|
104440
104639
|
const entry = updated.files.find((source2) => source2.name === input.name || source2.id === input.name);
|
|
104441
104640
|
if (entry === undefined) {
|
|
@@ -104491,7 +104690,7 @@ async function addLarkSourceUnlocked(input) {
|
|
|
104491
104690
|
const record2 = entry2;
|
|
104492
104691
|
return record2.name !== input.name && record2.id !== input.name;
|
|
104493
104692
|
}), nextEntry];
|
|
104494
|
-
await atomicWriteFile(
|
|
104693
|
+
await atomicWriteFile(join71(input.projectRoot, DEFAULT_LARK_SOURCES_REGISTRY_PATH), import_yaml33.default.stringify({ sources: nextSources }));
|
|
104495
104694
|
const updated = await loadSourcesRegistry({ rootDir: input.projectRoot });
|
|
104496
104695
|
const entry = updated.larks.find((source2) => source2.name === input.name || source2.id === input.name);
|
|
104497
104696
|
if (entry === undefined) {
|
|
@@ -104679,10 +104878,10 @@ async function registerSourceBatch(input) {
|
|
|
104679
104878
|
}
|
|
104680
104879
|
|
|
104681
104880
|
// src/project/sourceRemoval.ts
|
|
104682
|
-
import { existsSync as
|
|
104881
|
+
import { existsSync as existsSync45 } from "node:fs";
|
|
104683
104882
|
import { createHash as createHash28 } from "node:crypto";
|
|
104684
104883
|
import { readFile as readFile53, readdir as readdir21, rm as rm19 } from "node:fs/promises";
|
|
104685
|
-
import { isAbsolute as isAbsolute14, join as
|
|
104884
|
+
import { isAbsolute as isAbsolute14, join as join72, relative as relative22, resolve as resolve30, sep as sep6 } from "node:path";
|
|
104686
104885
|
var import_yaml34 = __toESM(require_dist3(), 1);
|
|
104687
104886
|
init_atomicWrite();
|
|
104688
104887
|
init_cliFeedback();
|
|
@@ -104721,8 +104920,8 @@ function collectStrings(value, output) {
|
|
|
104721
104920
|
}
|
|
104722
104921
|
}
|
|
104723
104922
|
async function yamlReferences(input) {
|
|
104724
|
-
const absolutePath =
|
|
104725
|
-
if (!
|
|
104923
|
+
const absolutePath = join72(input.projectRoot, input.path);
|
|
104924
|
+
if (!existsSync45(absolutePath))
|
|
104726
104925
|
return false;
|
|
104727
104926
|
const parsed = import_yaml34.default.parse(await readFile53(absolutePath, "utf8"));
|
|
104728
104927
|
const strings = [];
|
|
@@ -104829,8 +105028,8 @@ function removeDocumentEntry(document4, source2) {
|
|
|
104829
105028
|
}
|
|
104830
105029
|
async function registryRemovalWrite(projectRoot, source2) {
|
|
104831
105030
|
const path4 = registryPath2(source2.type);
|
|
104832
|
-
const absolutePath =
|
|
104833
|
-
const document4 =
|
|
105031
|
+
const absolutePath = join72(projectRoot, path4);
|
|
105032
|
+
const document4 = existsSync45(absolutePath) ? import_yaml34.default.parse(await readFile53(absolutePath, "utf8")) : { sources: [] };
|
|
104834
105033
|
return {
|
|
104835
105034
|
path: absolutePath,
|
|
104836
105035
|
bytes: import_yaml34.default.stringify(removeDocumentEntry(document4, source2))
|
|
@@ -104848,7 +105047,7 @@ function safeManagedMaterializedPath(projectRoot, source2) {
|
|
|
104848
105047
|
return absolute;
|
|
104849
105048
|
}
|
|
104850
105049
|
function safeManagedManifestPath(projectRoot, source2) {
|
|
104851
|
-
const manifest = source2.manifest ??
|
|
105050
|
+
const manifest = source2.manifest ?? join72(source2.materializedAt, "manifest.json");
|
|
104852
105051
|
if (isAbsolute14(manifest))
|
|
104853
105052
|
throw unsafeOwnership(source2, manifest);
|
|
104854
105053
|
const absolute = resolve30(projectRoot, manifest);
|
|
@@ -104954,7 +105153,7 @@ async function createRemovalPlan(projectRoot, selector) {
|
|
|
104954
105153
|
}
|
|
104955
105154
|
} else {
|
|
104956
105155
|
const materializedPath = safeManagedMaterializedPath(projectRoot, source2);
|
|
104957
|
-
if (materializedPath !== undefined && sharedMaterializedBy.length === 0 &&
|
|
105156
|
+
if (materializedPath !== undefined && sharedMaterializedBy.length === 0 && existsSync45(materializedPath)) {
|
|
104958
105157
|
absoluteRemovals.push(materializedPath);
|
|
104959
105158
|
cleanup = {
|
|
104960
105159
|
mode: "exclusive-materialization",
|
|
@@ -105000,9 +105199,9 @@ function publicRemovalResult(plan, action) {
|
|
|
105000
105199
|
};
|
|
105001
105200
|
}
|
|
105002
105201
|
async function pruneExtractRuntime(projectRoot, source2) {
|
|
105003
|
-
const fingerprintPath =
|
|
105202
|
+
const fingerprintPath = join72(projectRoot, ".tmp/context-runtime/extract/source-fingerprints.json");
|
|
105004
105203
|
const removedPhaseIds = new Set;
|
|
105005
|
-
if (
|
|
105204
|
+
if (existsSync45(fingerprintPath)) {
|
|
105006
105205
|
const parsed = JSON.parse(await readFile53(fingerprintPath, "utf8"));
|
|
105007
105206
|
const phases = parsed.phases ?? {};
|
|
105008
105207
|
const next = Object.fromEntries(Object.entries(phases).filter(([phaseId, raw]) => {
|
|
@@ -105017,20 +105216,20 @@ async function pruneExtractRuntime(projectRoot, source2) {
|
|
|
105017
105216
|
await atomicWriteFile(fingerprintPath, `${JSON.stringify({ ...parsed, phases: next }, null, 2)}
|
|
105018
105217
|
`);
|
|
105019
105218
|
}
|
|
105020
|
-
const symbolPath =
|
|
105021
|
-
if (
|
|
105219
|
+
const symbolPath = join72(projectRoot, ".tmp/context-runtime/extract/source-symbols.json");
|
|
105220
|
+
if (existsSync45(symbolPath)) {
|
|
105022
105221
|
const parsed = JSON.parse(await readFile53(symbolPath, "utf8"));
|
|
105023
105222
|
const symbols = Array.isArray(parsed.symbols) ? parsed.symbols.filter((entry) => entry === null || typeof entry !== "object" || Array.isArray(entry) || entry.source !== source2.name) : [];
|
|
105024
105223
|
const phaseFingerprints = Object.fromEntries(Object.entries(parsed.phaseFingerprints ?? {}).filter(([phaseId]) => !removedPhaseIds.has(phaseId)));
|
|
105025
105224
|
await atomicWriteFile(symbolPath, `${JSON.stringify({ ...parsed, phaseFingerprints, symbols }, null, 2)}
|
|
105026
105225
|
`);
|
|
105027
105226
|
}
|
|
105028
|
-
const snapshotRoot =
|
|
105227
|
+
const snapshotRoot = join72(projectRoot, ".tmp/context-runtime/extract/candidates");
|
|
105029
105228
|
const visit3 = async (directory) => {
|
|
105030
|
-
if (!
|
|
105229
|
+
if (!existsSync45(directory))
|
|
105031
105230
|
return;
|
|
105032
105231
|
for (const entry of await readdir21(directory, { withFileTypes: true })) {
|
|
105033
|
-
const path4 =
|
|
105232
|
+
const path4 = join72(directory, entry.name);
|
|
105034
105233
|
if (entry.isDirectory()) {
|
|
105035
105234
|
await visit3(path4);
|
|
105036
105235
|
continue;
|
|
@@ -105080,7 +105279,7 @@ async function removeProjectSource(input) {
|
|
|
105080
105279
|
});
|
|
105081
105280
|
}
|
|
105082
105281
|
await applyAtomicFileBatch({
|
|
105083
|
-
transactionRoot:
|
|
105282
|
+
transactionRoot: join72(input.projectRoot, ".tmp", "context-runtime", "source-remove-transactions"),
|
|
105084
105283
|
writes: [plan.registryWrite, ...plan.manifestWrite !== undefined ? [plan.manifestWrite] : []],
|
|
105085
105284
|
removals: plan.absoluteRemovals
|
|
105086
105285
|
});
|
|
@@ -105478,16 +105677,147 @@ the CLI derives a lowercase path-safe module and rejects duplicate batch identit
|
|
|
105478
105677
|
});
|
|
105479
105678
|
}
|
|
105480
105679
|
|
|
105680
|
+
// src/cli.ts
|
|
105681
|
+
init_debugTrace();
|
|
105682
|
+
|
|
105683
|
+
// src/registerProjectLifecycleCommands.ts
|
|
105684
|
+
init_cliFeedback();
|
|
105685
|
+
init_errors();
|
|
105686
|
+
init_workspace();
|
|
105687
|
+
init_exitCode();
|
|
105688
|
+
function registerProjectInitCommand(program2) {
|
|
105689
|
+
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) => {
|
|
105690
|
+
const targetRoot = resolveContextProjectInitTarget(process.cwd(), projectDir);
|
|
105691
|
+
const wasContextWorkspace = isContextProjectRoot(targetRoot);
|
|
105692
|
+
const result = await initContextProject({
|
|
105693
|
+
cwd: process.cwd(),
|
|
105694
|
+
...projectDir !== undefined ? { projectDir } : {},
|
|
105695
|
+
...typeof options.name === "string" ? { name: options.name } : {},
|
|
105696
|
+
...typeof options.language === "string" ? { language: projectLanguage(options.language) } : {},
|
|
105697
|
+
...options.dev === true ? { dev: true } : {},
|
|
105698
|
+
...options.debug === true ? { debug: true } : {},
|
|
105699
|
+
...options.allowNonempty === true ? { allowNonempty: true } : {}
|
|
105700
|
+
});
|
|
105701
|
+
process.stdout.write(formatProjectInitResult(result));
|
|
105702
|
+
if (!wasContextWorkspace) {
|
|
105703
|
+
queueContextRuntimeEvent({
|
|
105704
|
+
cwd: result.projectRoot,
|
|
105705
|
+
kind: "workspace.initialized",
|
|
105706
|
+
properties: {
|
|
105707
|
+
init_mode: result.kept.length > 0 ? "nonempty_existing" : "new",
|
|
105708
|
+
language: result.language,
|
|
105709
|
+
created_file_count: result.created.length
|
|
105710
|
+
}
|
|
105711
|
+
});
|
|
105712
|
+
}
|
|
105713
|
+
});
|
|
105714
|
+
}
|
|
105715
|
+
function registerProjectStatusCommand(program2) {
|
|
105716
|
+
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) => {
|
|
105717
|
+
const rootOptions = program2.opts();
|
|
105718
|
+
const resourceReceiptsReference = typeof options.resourceReceipts === "string" ? options.resourceReceipts : typeof rootOptions.workflowResourceReceipts === "string" ? rootOptions.workflowResourceReceipts : undefined;
|
|
105719
|
+
const resourceReceipts = resourceReceiptsReference !== undefined ? await parseWorkflowResourceReceipts(resourceReceiptsReference, process.cwd()) : undefined;
|
|
105720
|
+
if (await runProjectStatusCommand({
|
|
105721
|
+
cwd: process.cwd(),
|
|
105722
|
+
format: options.format === "json" ? "json" : "table",
|
|
105723
|
+
view: options.view === "full" ? "full" : "summary",
|
|
105724
|
+
managed: options.managed === true,
|
|
105725
|
+
authorities: workflowAuthorities(options.authority),
|
|
105726
|
+
...resourceReceipts === undefined ? {} : { resourceReceipts },
|
|
105727
|
+
...resourceReceiptsReference === undefined ? {} : { resourceReceiptsReference },
|
|
105728
|
+
onSuccess: (status) => {
|
|
105729
|
+
queueContextRuntimeEvent({
|
|
105730
|
+
cwd: status.projectRoot,
|
|
105731
|
+
kind: "workspace.active",
|
|
105732
|
+
properties: { workflow_status: status.workflow.status }
|
|
105733
|
+
});
|
|
105734
|
+
}
|
|
105735
|
+
})) {
|
|
105736
|
+
return;
|
|
105737
|
+
}
|
|
105738
|
+
throw new ContextError(ExitCode.WorkspaceStateError, "status requires a context project workspace", {
|
|
105739
|
+
category: ErrorCategory.WorkspaceNotFound
|
|
105740
|
+
});
|
|
105741
|
+
});
|
|
105742
|
+
}
|
|
105743
|
+
function registerProjectCloseAndBuildCommands(program2) {
|
|
105744
|
+
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) => {
|
|
105745
|
+
if (options.format !== "text" && options.format !== "json") {
|
|
105746
|
+
throw new ContextError(ExitCode.UserError, "--format must be text or json", {
|
|
105747
|
+
category: ErrorCategory.UserInputInvalid
|
|
105748
|
+
});
|
|
105749
|
+
}
|
|
105750
|
+
if (await runProjectCloseCommand({
|
|
105751
|
+
cwd: process.cwd(),
|
|
105752
|
+
format: options.format === "json" ? "json" : "text"
|
|
105753
|
+
})) {
|
|
105754
|
+
return;
|
|
105755
|
+
}
|
|
105756
|
+
throw new ContextError(ExitCode.WorkspaceStateError, "close requires a context project workspace", {
|
|
105757
|
+
category: ErrorCategory.WorkspaceNotFound
|
|
105758
|
+
});
|
|
105759
|
+
});
|
|
105760
|
+
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) => {
|
|
105761
|
+
if (options.format !== "text" && options.format !== "json") {
|
|
105762
|
+
throw new ContextError(ExitCode.UserError, "--format must be text or json", {
|
|
105763
|
+
category: ErrorCategory.UserInputInvalid
|
|
105764
|
+
});
|
|
105765
|
+
}
|
|
105766
|
+
if (await runProjectBuildCommand({
|
|
105767
|
+
cwd: process.cwd(),
|
|
105768
|
+
format: options.format === "json" ? "json" : "text",
|
|
105769
|
+
verbose: options.verbose === true
|
|
105770
|
+
})) {
|
|
105771
|
+
return;
|
|
105772
|
+
}
|
|
105773
|
+
throw new ContextError(ExitCode.WorkspaceStateError, "build requires a context project workspace", {
|
|
105774
|
+
category: ErrorCategory.WorkspaceNotFound
|
|
105775
|
+
});
|
|
105776
|
+
});
|
|
105777
|
+
}
|
|
105778
|
+
function registerProjectVerifyCommand(program2) {
|
|
105779
|
+
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) => {
|
|
105780
|
+
if (options.format !== "table" && options.format !== "json") {
|
|
105781
|
+
throw new ContextError(ExitCode.UserError, "--format must be table or json", {
|
|
105782
|
+
category: ErrorCategory.UserInputInvalid
|
|
105783
|
+
});
|
|
105784
|
+
}
|
|
105785
|
+
if (options.view !== undefined && options.view !== "diagnostics") {
|
|
105786
|
+
throw new ContextError(ExitCode.UserError, "--view must be diagnostics", {
|
|
105787
|
+
category: ErrorCategory.UserInputInvalid
|
|
105788
|
+
});
|
|
105789
|
+
}
|
|
105790
|
+
if (options.view === "diagnostics" && options.format !== "json") {
|
|
105791
|
+
throw new ContextError(ExitCode.UserError, "--view diagnostics requires --format json", {
|
|
105792
|
+
category: ErrorCategory.UserInputInvalid
|
|
105793
|
+
});
|
|
105794
|
+
}
|
|
105795
|
+
if (await runProjectVerifyCommand({
|
|
105796
|
+
cwd: process.cwd(),
|
|
105797
|
+
format: options.format === "json" ? "json" : "table",
|
|
105798
|
+
...options.compact === true ? { compact: true } : {},
|
|
105799
|
+
...options.view === "diagnostics" ? { view: "diagnostics" } : {},
|
|
105800
|
+
...typeof options.pageSize === "string" ? { pageSize: options.pageSize } : {},
|
|
105801
|
+
...typeof options.pageToken === "string" ? { pageToken: options.pageToken } : {}
|
|
105802
|
+
})) {
|
|
105803
|
+
return;
|
|
105804
|
+
}
|
|
105805
|
+
throw new ContextError(ExitCode.WorkspaceStateError, "verify requires a context project workspace", {
|
|
105806
|
+
category: ErrorCategory.WorkspaceNotFound
|
|
105807
|
+
});
|
|
105808
|
+
});
|
|
105809
|
+
}
|
|
105810
|
+
|
|
105481
105811
|
// src/project/pluginInstall.ts
|
|
105482
105812
|
init_cliFeedback();
|
|
105483
105813
|
init_errors();
|
|
105484
105814
|
init_exitCode();
|
|
105485
|
-
import { existsSync as
|
|
105815
|
+
import { existsSync as existsSync46 } from "node:fs";
|
|
105486
105816
|
import { cp, mkdir as mkdir32, readdir as readdir22, readFile as readFile55, rename as rename5, rm as rm20, writeFile as writeFile27 } from "node:fs/promises";
|
|
105487
105817
|
import { execFile as execFile7 } from "node:child_process";
|
|
105488
105818
|
import { homedir as homedir2 } from "node:os";
|
|
105489
|
-
import { dirname as
|
|
105490
|
-
import { fileURLToPath as
|
|
105819
|
+
import { dirname as dirname42, join as join73, resolve as resolve32 } from "node:path";
|
|
105820
|
+
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
105491
105821
|
import { promisify as promisify7 } from "node:util";
|
|
105492
105822
|
var execFileAsync7 = promisify7(execFile7);
|
|
105493
105823
|
var MARKETPLACE_NAME = "c4a";
|
|
@@ -105526,10 +105856,10 @@ function pluginAgentOption(value) {
|
|
|
105526
105856
|
}
|
|
105527
105857
|
function packageCandidateDirs() {
|
|
105528
105858
|
const dirs = [];
|
|
105529
|
-
let dir =
|
|
105859
|
+
let dir = dirname42(fileURLToPath9(import.meta.url));
|
|
105530
105860
|
for (let index2 = 0;index2 < 8; index2++) {
|
|
105531
105861
|
dirs.push(dir);
|
|
105532
|
-
const parent =
|
|
105862
|
+
const parent = dirname42(dir);
|
|
105533
105863
|
if (parent === dir)
|
|
105534
105864
|
break;
|
|
105535
105865
|
dir = parent;
|
|
@@ -105542,13 +105872,13 @@ function pluginRootCandidates() {
|
|
|
105542
105872
|
return [resolve32(envRoot)];
|
|
105543
105873
|
const candidates = [];
|
|
105544
105874
|
for (const dir of packageCandidateDirs()) {
|
|
105545
|
-
candidates.push(
|
|
105546
|
-
candidates.push(
|
|
105875
|
+
candidates.push(join73(dir, "plugins"));
|
|
105876
|
+
candidates.push(join73(dir, "dist", "plugins"));
|
|
105547
105877
|
}
|
|
105548
105878
|
return [...new Set(candidates)];
|
|
105549
105879
|
}
|
|
105550
105880
|
function isInstallablePluginRoot(root2) {
|
|
105551
|
-
return
|
|
105881
|
+
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"));
|
|
105552
105882
|
}
|
|
105553
105883
|
function resolveBundledPluginsRoot() {
|
|
105554
105884
|
const candidates = pluginRootCandidates();
|
|
@@ -105613,14 +105943,14 @@ function failedAgentResult(agent, error) {
|
|
|
105613
105943
|
};
|
|
105614
105944
|
}
|
|
105615
105945
|
function codexHome() {
|
|
105616
|
-
return process.env.CODEX_HOME?.trim() ||
|
|
105946
|
+
return process.env.CODEX_HOME?.trim() || join73(homedir2(), ".codex");
|
|
105617
105947
|
}
|
|
105618
105948
|
function claudePluginCacheRoot() {
|
|
105619
105949
|
const explicitRoot = process.env[CLAUDE_PLUGIN_CACHE_ROOT_ENV2]?.trim();
|
|
105620
105950
|
if (explicitRoot)
|
|
105621
105951
|
return explicitRoot;
|
|
105622
105952
|
const home = process.env[CLAUDE_PLUGIN_CACHE_HOME_ENV2]?.trim() || homedir2();
|
|
105623
|
-
return
|
|
105953
|
+
return join73(home, ".claude", "plugins", "cache");
|
|
105624
105954
|
}
|
|
105625
105955
|
function blockHeader(line) {
|
|
105626
105956
|
const match = line.match(/^\s*\[([^\]]+)\]\s*$/u);
|
|
@@ -105671,7 +106001,7 @@ function pruneLegacyCodexConfigContent(content3) {
|
|
|
105671
106001
|
`), removed };
|
|
105672
106002
|
}
|
|
105673
106003
|
async function pruneLegacyCodexConfig(dryRun, steps) {
|
|
105674
|
-
const configPath =
|
|
106004
|
+
const configPath = join73(codexHome(), "config.toml");
|
|
105675
106005
|
const current2 = await readFile55(configPath, "utf8").catch(() => "");
|
|
105676
106006
|
if (!current2)
|
|
105677
106007
|
return;
|
|
@@ -105688,8 +106018,8 @@ async function pruneLegacyCodexConfig(dryRun, steps) {
|
|
|
105688
106018
|
}
|
|
105689
106019
|
}
|
|
105690
106020
|
async function pruneCodexPluginCacheForName(pluginName, keepVersion, dryRun, steps) {
|
|
105691
|
-
const cacheRoot =
|
|
105692
|
-
if (!
|
|
106021
|
+
const cacheRoot = join73(codexHome(), "plugins", "cache", MARKETPLACE_NAME, pluginName);
|
|
106022
|
+
if (!existsSync46(cacheRoot))
|
|
105693
106023
|
return;
|
|
105694
106024
|
const versions = (await readdir22(cacheRoot, { withFileTypes: true }).catch(() => [])).filter((entry) => entry.isDirectory() && entry.name !== keepVersion).map((entry) => entry.name).sort();
|
|
105695
106025
|
if (versions.length === 0)
|
|
@@ -105700,7 +106030,7 @@ async function pruneCodexPluginCacheForName(pluginName, keepVersion, dryRun, ste
|
|
|
105700
106030
|
status: dryRun ? "planned" : "ran"
|
|
105701
106031
|
});
|
|
105702
106032
|
if (!dryRun)
|
|
105703
|
-
await Promise.all(versions.map((version3) => rm20(
|
|
106033
|
+
await Promise.all(versions.map((version3) => rm20(join73(cacheRoot, version3), { recursive: true, force: true })));
|
|
105704
106034
|
}
|
|
105705
106035
|
async function pruneCodexPluginCache(currentVersion, dryRun, steps) {
|
|
105706
106036
|
await pruneCodexPluginCacheForName(PLUGIN_NAME, currentVersion, dryRun, steps);
|
|
@@ -105717,22 +106047,22 @@ async function isEmptyDir2(dir) {
|
|
|
105717
106047
|
}
|
|
105718
106048
|
async function pruneClaudeOrphanContextCache(dryRun, steps) {
|
|
105719
106049
|
const cacheRoot = claudePluginCacheRoot();
|
|
105720
|
-
if (!
|
|
106050
|
+
if (!existsSync46(cacheRoot))
|
|
105721
106051
|
return;
|
|
105722
106052
|
const removed = [];
|
|
105723
106053
|
const marketplaces = await readdir22(cacheRoot, { withFileTypes: true }).catch(() => []);
|
|
105724
106054
|
for (const marketplace of marketplaces) {
|
|
105725
106055
|
if (!marketplace.isDirectory())
|
|
105726
106056
|
continue;
|
|
105727
|
-
const pluginDir =
|
|
105728
|
-
if (!
|
|
106057
|
+
const pluginDir = join73(cacheRoot, marketplace.name, PLUGIN_NAME);
|
|
106058
|
+
if (!existsSync46(pluginDir))
|
|
105729
106059
|
continue;
|
|
105730
106060
|
const versions = await readdir22(pluginDir, { withFileTypes: true }).catch(() => []);
|
|
105731
106061
|
for (const version3 of versions) {
|
|
105732
106062
|
if (!version3.isDirectory())
|
|
105733
106063
|
continue;
|
|
105734
|
-
const versionDir =
|
|
105735
|
-
if (!
|
|
106064
|
+
const versionDir = join73(pluginDir, version3.name);
|
|
106065
|
+
if (!existsSync46(join73(versionDir, ORPHAN_MARKER2)))
|
|
105736
106066
|
continue;
|
|
105737
106067
|
removed.push(`${marketplace.name}/${PLUGIN_NAME}/${version3.name}`);
|
|
105738
106068
|
if (!dryRun) {
|
|
@@ -105742,7 +106072,7 @@ async function pruneClaudeOrphanContextCache(dryRun, steps) {
|
|
|
105742
106072
|
if (!dryRun && await isEmptyDir2(pluginDir)) {
|
|
105743
106073
|
await rm20(pluginDir, { recursive: true, force: true });
|
|
105744
106074
|
}
|
|
105745
|
-
const marketplaceDir =
|
|
106075
|
+
const marketplaceDir = join73(cacheRoot, marketplace.name);
|
|
105746
106076
|
if (!dryRun && await isEmptyDir2(marketplaceDir)) {
|
|
105747
106077
|
await rm20(marketplaceDir, { recursive: true, force: true });
|
|
105748
106078
|
}
|
|
@@ -105759,12 +106089,12 @@ async function pruneClaudeLegacyPluginCache(dryRun, steps) {
|
|
|
105759
106089
|
if (LEGACY_PLUGIN_NAMES.length === 0)
|
|
105760
106090
|
return;
|
|
105761
106091
|
const cacheRoot = claudePluginCacheRoot();
|
|
105762
|
-
if (!
|
|
106092
|
+
if (!existsSync46(cacheRoot))
|
|
105763
106093
|
return;
|
|
105764
106094
|
const removed = [];
|
|
105765
106095
|
for (const pluginName of LEGACY_PLUGIN_NAMES) {
|
|
105766
|
-
const pluginDir =
|
|
105767
|
-
if (!
|
|
106096
|
+
const pluginDir = join73(cacheRoot, MARKETPLACE_NAME, pluginName);
|
|
106097
|
+
if (!existsSync46(pluginDir))
|
|
105768
106098
|
continue;
|
|
105769
106099
|
removed.push(`${MARKETPLACE_NAME}/${pluginName}`);
|
|
105770
106100
|
if (!dryRun) {
|
|
@@ -105780,11 +106110,11 @@ async function pruneClaudeLegacyPluginCache(dryRun, steps) {
|
|
|
105780
106110
|
}
|
|
105781
106111
|
}
|
|
105782
106112
|
async function pruneClaudeSupersededContextCache(root2, dryRun, steps) {
|
|
105783
|
-
const manifest = await readFile55(
|
|
106113
|
+
const manifest = await readFile55(join73(root2, "claude", ".claude-plugin", "plugin.json"), "utf8").then((content3) => JSON.parse(content3)).catch(() => null);
|
|
105784
106114
|
const currentVersion = typeof manifest?.version === "string" ? manifest.version : null;
|
|
105785
106115
|
if (!currentVersion)
|
|
105786
106116
|
return;
|
|
105787
|
-
const pluginDir =
|
|
106117
|
+
const pluginDir = join73(claudePluginCacheRoot(), MARKETPLACE_NAME, PLUGIN_NAME);
|
|
105788
106118
|
const staleVersions = (await readdir22(pluginDir, { withFileTypes: true }).catch(() => [])).filter((entry) => entry.isDirectory() && entry.name !== currentVersion).map((entry) => entry.name);
|
|
105789
106119
|
if (staleVersions.length === 0)
|
|
105790
106120
|
return;
|
|
@@ -105794,7 +106124,7 @@ async function pruneClaudeSupersededContextCache(root2, dryRun, steps) {
|
|
|
105794
106124
|
status: dryRun ? "planned" : "ran"
|
|
105795
106125
|
});
|
|
105796
106126
|
if (!dryRun) {
|
|
105797
|
-
await Promise.all(staleVersions.map((version3) => rm20(
|
|
106127
|
+
await Promise.all(staleVersions.map((version3) => rm20(join73(pluginDir, version3), { recursive: true, force: true })));
|
|
105798
106128
|
}
|
|
105799
106129
|
}
|
|
105800
106130
|
function enableCodexPluginConfig(content3) {
|
|
@@ -105858,8 +106188,8 @@ source = ${JSON.stringify(root2)}
|
|
|
105858
106188
|
`;
|
|
105859
106189
|
}
|
|
105860
106190
|
async function ensureCodexPluginEnabled() {
|
|
105861
|
-
const configPath =
|
|
105862
|
-
await mkdir32(
|
|
106191
|
+
const configPath = join73(codexHome(), "config.toml");
|
|
106192
|
+
await mkdir32(dirname42(configPath), { recursive: true });
|
|
105863
106193
|
const current2 = await readFile55(configPath, "utf8").catch(() => "");
|
|
105864
106194
|
const next = enableCodexPluginConfig(current2);
|
|
105865
106195
|
if (next !== current2) {
|
|
@@ -105867,8 +106197,8 @@ async function ensureCodexPluginEnabled() {
|
|
|
105867
106197
|
}
|
|
105868
106198
|
}
|
|
105869
106199
|
async function ensureCodexLocalMarketplace(root2) {
|
|
105870
|
-
const configPath =
|
|
105871
|
-
await mkdir32(
|
|
106200
|
+
const configPath = join73(codexHome(), "config.toml");
|
|
106201
|
+
await mkdir32(dirname42(configPath), { recursive: true });
|
|
105872
106202
|
const current2 = await readFile55(configPath, "utf8").catch(() => "");
|
|
105873
106203
|
const next = upsertCodexLocalMarketplaceConfig(current2, root2);
|
|
105874
106204
|
if (next !== current2) {
|
|
@@ -105876,7 +106206,7 @@ async function ensureCodexLocalMarketplace(root2) {
|
|
|
105876
106206
|
}
|
|
105877
106207
|
}
|
|
105878
106208
|
async function codexPluginVersion(root2) {
|
|
105879
|
-
const manifestPath =
|
|
106209
|
+
const manifestPath = join73(root2, "codex", ".codex-plugin", "plugin.json");
|
|
105880
106210
|
const manifest = JSON.parse(await readFile55(manifestPath, "utf8"));
|
|
105881
106211
|
if (typeof manifest.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/u.test(manifest.version)) {
|
|
105882
106212
|
throw new Error(`Codex plugin manifest has an invalid version: ${manifestPath}`);
|
|
@@ -105884,10 +106214,10 @@ async function codexPluginVersion(root2) {
|
|
|
105884
106214
|
return manifest.version;
|
|
105885
106215
|
}
|
|
105886
106216
|
function codexPluginCacheDir(version3) {
|
|
105887
|
-
return
|
|
106217
|
+
return join73(codexHome(), "plugins", "cache", MARKETPLACE_NAME, PLUGIN_NAME, version3);
|
|
105888
106218
|
}
|
|
105889
106219
|
async function materializeCodexPluginCache(root2, version3, dryRun, steps) {
|
|
105890
|
-
const source2 =
|
|
106220
|
+
const source2 = join73(root2, "codex");
|
|
105891
106221
|
const target = codexPluginCacheDir(version3);
|
|
105892
106222
|
steps.push({
|
|
105893
106223
|
agent: "codex",
|
|
@@ -105896,12 +106226,12 @@ async function materializeCodexPluginCache(root2, version3, dryRun, steps) {
|
|
|
105896
106226
|
});
|
|
105897
106227
|
if (dryRun)
|
|
105898
106228
|
return;
|
|
105899
|
-
await mkdir32(
|
|
106229
|
+
await mkdir32(dirname42(target), { recursive: true });
|
|
105900
106230
|
const temporary = `${target}.tmp-${process.pid}-${Date.now()}`;
|
|
105901
106231
|
const previous3 = `${target}.previous-${process.pid}-${Date.now()}`;
|
|
105902
106232
|
await rm20(temporary, { recursive: true, force: true });
|
|
105903
106233
|
await cp(source2, temporary, { recursive: true, force: true });
|
|
105904
|
-
const hadPrevious =
|
|
106234
|
+
const hadPrevious = existsSync46(target);
|
|
105905
106235
|
try {
|
|
105906
106236
|
if (hadPrevious)
|
|
105907
106237
|
await rename5(target, previous3);
|
|
@@ -105910,7 +106240,7 @@ async function materializeCodexPluginCache(root2, version3, dryRun, steps) {
|
|
|
105910
106240
|
await rm20(previous3, { recursive: true, force: true });
|
|
105911
106241
|
} catch (error) {
|
|
105912
106242
|
await rm20(temporary, { recursive: true, force: true });
|
|
105913
|
-
if (hadPrevious && !
|
|
106243
|
+
if (hadPrevious && !existsSync46(target) && existsSync46(previous3))
|
|
105914
106244
|
await rename5(previous3, target);
|
|
105915
106245
|
throw error;
|
|
105916
106246
|
}
|
|
@@ -105945,12 +106275,12 @@ async function installCodex(root2, dryRun, steps) {
|
|
|
105945
106275
|
steps.push({ agent: "codex", command: commandLine("codex", addArgs), status: dryRun ? "planned" : "ran" });
|
|
105946
106276
|
steps.push({
|
|
105947
106277
|
agent: "codex",
|
|
105948
|
-
command: `ensure ${shellQuote9(
|
|
106278
|
+
command: `ensure ${shellQuote9(join73(codexHome(), "config.toml"))} registers local marketplace ${shellQuote9(MARKETPLACE_NAME)}`,
|
|
105949
106279
|
status: dryRun ? "planned" : "ran"
|
|
105950
106280
|
});
|
|
105951
106281
|
steps.push({
|
|
105952
106282
|
agent: "codex",
|
|
105953
|
-
command: `ensure ${shellQuote9(
|
|
106283
|
+
command: `ensure ${shellQuote9(join73(codexHome(), "config.toml"))} enables ${shellQuote9(PLUGIN_ID)}`,
|
|
105954
106284
|
status: dryRun ? "planned" : "ran"
|
|
105955
106285
|
});
|
|
105956
106286
|
if (dryRun) {
|
|
@@ -106061,8 +106391,75 @@ function formatPluginInstallResult(result) {
|
|
|
106061
106391
|
});
|
|
106062
106392
|
}
|
|
106063
106393
|
|
|
106394
|
+
// src/registerPluginCommands.ts
|
|
106395
|
+
function registerPluginCommands(program2) {
|
|
106396
|
+
const plugin = program2.command("plugin").description("Install or inspect global Context agent plugins");
|
|
106397
|
+
plugin.command("path").description("Print the bundled plugin marketplace root used by `context plugin install`").action(async () => {
|
|
106398
|
+
process.stdout.write(formatPluginPathResult(await runPluginPathCommand()));
|
|
106399
|
+
});
|
|
106400
|
+
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) => {
|
|
106401
|
+
const agent = pluginAgentOption(options.agent);
|
|
106402
|
+
process.stdout.write(formatPluginStatusResult(await runPluginStatusCommand({ agent })));
|
|
106403
|
+
});
|
|
106404
|
+
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) => {
|
|
106405
|
+
const agent = pluginAgentOption(options.agent);
|
|
106406
|
+
const result = await runPluginInstallCommand({
|
|
106407
|
+
agent,
|
|
106408
|
+
dryRun: options.dryRun === true
|
|
106409
|
+
});
|
|
106410
|
+
process.stdout.write(formatPluginInstallResult(result));
|
|
106411
|
+
});
|
|
106412
|
+
}
|
|
106413
|
+
|
|
106414
|
+
// src/registerPackageCommands.ts
|
|
106415
|
+
init_cliFeedback();
|
|
106416
|
+
init_errors();
|
|
106417
|
+
init_packageTemplateReview();
|
|
106418
|
+
init_workspace();
|
|
106419
|
+
init_exitCode();
|
|
106420
|
+
function registerPackageCommands(program2) {
|
|
106421
|
+
const packageCommand = program2.command("package").description("Inspect or resolve package output configuration");
|
|
106422
|
+
const packageTemplate = packageCommand.command("template").description("Manage package template review state");
|
|
106423
|
+
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) => {
|
|
106424
|
+
if (packageName === undefined === (options.all !== true)) {
|
|
106425
|
+
throw new ContextError(ExitCode.UserError, "provide one package name or --all", { category: ErrorCategory.UserInputInvalid });
|
|
106426
|
+
}
|
|
106427
|
+
if (options.format !== "text" && options.format !== "json") {
|
|
106428
|
+
throw new ContextError(ExitCode.UserError, "--format must be text or json", {
|
|
106429
|
+
category: ErrorCategory.UserInputInvalid
|
|
106430
|
+
});
|
|
106431
|
+
}
|
|
106432
|
+
const found = findContextProjectRoot(process.cwd());
|
|
106433
|
+
if (!found) {
|
|
106434
|
+
throw new ContextError(ExitCode.WorkspaceStateError, "package template acceptance requires a context project workspace", { category: ErrorCategory.WorkspaceNotFound });
|
|
106435
|
+
}
|
|
106436
|
+
const result = await acceptStarterPackageTemplates({
|
|
106437
|
+
projectRoot: found.projectRoot,
|
|
106438
|
+
...packageName === undefined ? {} : { packageNames: [packageName] }
|
|
106439
|
+
});
|
|
106440
|
+
if (options.format === "json") {
|
|
106441
|
+
process.stdout.write(`${JSON.stringify({
|
|
106442
|
+
action: "package-template-accepted",
|
|
106443
|
+
...result,
|
|
106444
|
+
next_action: {
|
|
106445
|
+
kind: "reevaluate-workspace",
|
|
106446
|
+
command: "context status --format json"
|
|
106447
|
+
}
|
|
106448
|
+
}, null, 2)}
|
|
106449
|
+
`);
|
|
106450
|
+
} else {
|
|
106451
|
+
process.stdout.write(formatFeedback({
|
|
106452
|
+
symbol: "✓",
|
|
106453
|
+
action: "accepted",
|
|
106454
|
+
subject: result.accepted.join(", ") || "package templates",
|
|
106455
|
+
headline: "starter package template",
|
|
106456
|
+
body: result.alreadyResolved.length === 0 ? [] : [`already resolved: ${result.alreadyResolved.join(", ")}`]
|
|
106457
|
+
}));
|
|
106458
|
+
}
|
|
106459
|
+
});
|
|
106460
|
+
}
|
|
106461
|
+
|
|
106064
106462
|
// src/cli.ts
|
|
106065
|
-
init_debugTrace();
|
|
106066
106463
|
var TOP_LEVEL_COMMANDS = new Set([
|
|
106067
106464
|
"init",
|
|
106068
106465
|
"plugin",
|
|
@@ -106098,14 +106495,14 @@ function inferErrorCategory(message) {
|
|
|
106098
106495
|
}
|
|
106099
106496
|
function readPackageVersion() {
|
|
106100
106497
|
try {
|
|
106101
|
-
let dir =
|
|
106498
|
+
let dir = dirname43(fileURLToPath10(import.meta.url));
|
|
106102
106499
|
for (let i2 = 0;i2 < 8; i2++) {
|
|
106103
|
-
const pkg =
|
|
106104
|
-
if (
|
|
106105
|
-
const parsed = JSON.parse(
|
|
106500
|
+
const pkg = join74(dir, "package.json");
|
|
106501
|
+
if (existsSync47(pkg)) {
|
|
106502
|
+
const parsed = JSON.parse(readFileSync10(pkg, "utf8"));
|
|
106106
106503
|
return parsed.version ?? "unknown";
|
|
106107
106504
|
}
|
|
106108
|
-
const parent =
|
|
106505
|
+
const parent = dirname43(dir);
|
|
106109
106506
|
if (parent === dir)
|
|
106110
106507
|
break;
|
|
106111
106508
|
dir = parent;
|
|
@@ -106115,21 +106512,21 @@ function readPackageVersion() {
|
|
|
106115
106512
|
}
|
|
106116
106513
|
function readQuickstartPath() {
|
|
106117
106514
|
try {
|
|
106118
|
-
let dir =
|
|
106515
|
+
let dir = dirname43(fileURLToPath10(import.meta.url));
|
|
106119
106516
|
for (let i2 = 0;i2 < 8; i2++) {
|
|
106120
|
-
const candidate =
|
|
106121
|
-
if (
|
|
106517
|
+
const candidate = join74(dir, "docs", "quickstart.md");
|
|
106518
|
+
if (existsSync47(candidate))
|
|
106122
106519
|
return candidate;
|
|
106123
|
-
const pkg =
|
|
106124
|
-
if (
|
|
106520
|
+
const pkg = join74(dir, "package.json");
|
|
106521
|
+
if (existsSync47(pkg))
|
|
106125
106522
|
return candidate;
|
|
106126
|
-
const parent =
|
|
106523
|
+
const parent = dirname43(dir);
|
|
106127
106524
|
if (parent === dir)
|
|
106128
106525
|
break;
|
|
106129
106526
|
dir = parent;
|
|
106130
106527
|
}
|
|
106131
106528
|
} catch {}
|
|
106132
|
-
return
|
|
106529
|
+
return join74(dirname43(fileURLToPath10(import.meta.url)), "docs", "quickstart.md");
|
|
106133
106530
|
}
|
|
106134
106531
|
var GREEN = "\x1B[32m";
|
|
106135
106532
|
var RESET = "\x1B[0m";
|
|
@@ -106214,94 +106611,12 @@ function createCliProgram() {
|
|
|
106214
106611
|
});
|
|
106215
106612
|
const baseHelpInformation = program2.helpInformation.bind(program2);
|
|
106216
106613
|
program2.helpInformation = () => `${headerHelpText()}${baseHelpInformation()}${quickstartHelpText()}`;
|
|
106217
|
-
program2
|
|
106218
|
-
|
|
106219
|
-
cwd: process.cwd(),
|
|
106220
|
-
...projectDir !== undefined ? { projectDir } : {},
|
|
106221
|
-
...typeof options.name === "string" ? { name: options.name } : {},
|
|
106222
|
-
...typeof options.language === "string" ? { language: projectLanguage(options.language) } : {},
|
|
106223
|
-
...options.dev === true ? { dev: true } : {},
|
|
106224
|
-
...options.debug === true ? { debug: true } : {},
|
|
106225
|
-
...options.allowNonempty === true ? { allowNonempty: true } : {}
|
|
106226
|
-
});
|
|
106227
|
-
process.stdout.write(formatProjectInitResult(result));
|
|
106228
|
-
});
|
|
106229
|
-
const plugin = program2.command("plugin").description("Install or inspect global Context agent plugins");
|
|
106614
|
+
registerProjectInitCommand(program2);
|
|
106615
|
+
registerPluginCommands(program2);
|
|
106230
106616
|
registerDebugCommands(program2);
|
|
106231
|
-
plugin.command("path").description("Print the bundled plugin marketplace root used by `context plugin install`").action(async () => {
|
|
106232
|
-
process.stdout.write(formatPluginPathResult(await runPluginPathCommand()));
|
|
106233
|
-
});
|
|
106234
|
-
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) => {
|
|
106235
|
-
const agent = pluginAgentOption(options.agent);
|
|
106236
|
-
process.stdout.write(formatPluginStatusResult(await runPluginStatusCommand({ agent })));
|
|
106237
|
-
});
|
|
106238
|
-
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) => {
|
|
106239
|
-
const agent = pluginAgentOption(options.agent);
|
|
106240
|
-
const result = await runPluginInstallCommand({
|
|
106241
|
-
agent,
|
|
106242
|
-
dryRun: options.dryRun === true
|
|
106243
|
-
});
|
|
106244
|
-
process.stdout.write(formatPluginInstallResult(result));
|
|
106245
|
-
});
|
|
106246
106617
|
registerContextWorkflowResourceCommands(program2);
|
|
106247
|
-
|
|
106248
|
-
|
|
106249
|
-
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) => {
|
|
106250
|
-
if (packageName === undefined === (options.all !== true)) {
|
|
106251
|
-
throw new ContextError(ExitCode.UserError, "provide one package name or --all", { category: ErrorCategory.UserInputInvalid });
|
|
106252
|
-
}
|
|
106253
|
-
if (options.format !== "text" && options.format !== "json") {
|
|
106254
|
-
throw new ContextError(ExitCode.UserError, "--format must be text or json", {
|
|
106255
|
-
category: ErrorCategory.UserInputInvalid
|
|
106256
|
-
});
|
|
106257
|
-
}
|
|
106258
|
-
const found = findContextProjectRoot(process.cwd());
|
|
106259
|
-
if (!found) {
|
|
106260
|
-
throw new ContextError(ExitCode.WorkspaceStateError, "package template acceptance requires a context project workspace", { category: ErrorCategory.WorkspaceNotFound });
|
|
106261
|
-
}
|
|
106262
|
-
const result = await acceptStarterPackageTemplates({
|
|
106263
|
-
projectRoot: found.projectRoot,
|
|
106264
|
-
...packageName === undefined ? {} : { packageNames: [packageName] }
|
|
106265
|
-
});
|
|
106266
|
-
if (options.format === "json") {
|
|
106267
|
-
process.stdout.write(`${JSON.stringify({
|
|
106268
|
-
action: "package-template-accepted",
|
|
106269
|
-
...result,
|
|
106270
|
-
next_action: {
|
|
106271
|
-
kind: "reevaluate-workspace",
|
|
106272
|
-
command: "context status --format json"
|
|
106273
|
-
}
|
|
106274
|
-
}, null, 2)}
|
|
106275
|
-
`);
|
|
106276
|
-
} else {
|
|
106277
|
-
process.stdout.write(formatFeedback({
|
|
106278
|
-
symbol: "✓",
|
|
106279
|
-
action: "accepted",
|
|
106280
|
-
subject: result.accepted.join(", ") || "package templates",
|
|
106281
|
-
headline: "starter package template",
|
|
106282
|
-
body: result.alreadyResolved.length === 0 ? [] : [`already resolved: ${result.alreadyResolved.join(", ")}`]
|
|
106283
|
-
}));
|
|
106284
|
-
}
|
|
106285
|
-
});
|
|
106286
|
-
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) => {
|
|
106287
|
-
const rootOptions = program2.opts();
|
|
106288
|
-
const resourceReceiptsReference = typeof options.resourceReceipts === "string" ? options.resourceReceipts : typeof rootOptions.workflowResourceReceipts === "string" ? rootOptions.workflowResourceReceipts : undefined;
|
|
106289
|
-
const resourceReceipts = resourceReceiptsReference !== undefined ? await parseWorkflowResourceReceipts(resourceReceiptsReference, process.cwd()) : undefined;
|
|
106290
|
-
if (await runProjectStatusCommand({
|
|
106291
|
-
cwd: process.cwd(),
|
|
106292
|
-
format: options.format === "json" ? "json" : "table",
|
|
106293
|
-
view: options.view === "full" ? "full" : "summary",
|
|
106294
|
-
managed: options.managed === true,
|
|
106295
|
-
authorities: workflowAuthorities(options.authority),
|
|
106296
|
-
...resourceReceipts === undefined ? {} : { resourceReceipts },
|
|
106297
|
-
...resourceReceiptsReference === undefined ? {} : { resourceReceiptsReference }
|
|
106298
|
-
})) {
|
|
106299
|
-
return;
|
|
106300
|
-
}
|
|
106301
|
-
throw new ContextError(ExitCode.WorkspaceStateError, "status requires a context project workspace", {
|
|
106302
|
-
category: ErrorCategory.WorkspaceNotFound
|
|
106303
|
-
});
|
|
106304
|
-
});
|
|
106618
|
+
registerPackageCommands(program2);
|
|
106619
|
+
registerProjectStatusCommand(program2);
|
|
106305
106620
|
registerProjectRunCommand(program2, import.meta.url);
|
|
106306
106621
|
const review = program2.command("review").description("Review draft project candidates and apply approval decisions");
|
|
106307
106622
|
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) => {
|
|
@@ -106449,70 +106764,9 @@ function createCliProgram() {
|
|
|
106449
106764
|
format: options.format === "json" ? "json" : "text"
|
|
106450
106765
|
});
|
|
106451
106766
|
});
|
|
106452
|
-
program2
|
|
106453
|
-
if (options.format !== "text" && options.format !== "json") {
|
|
106454
|
-
throw new ContextError(ExitCode.UserError, "--format must be text or json", {
|
|
106455
|
-
category: ErrorCategory.UserInputInvalid
|
|
106456
|
-
});
|
|
106457
|
-
}
|
|
106458
|
-
if (await runProjectCloseCommand({
|
|
106459
|
-
cwd: process.cwd(),
|
|
106460
|
-
format: options.format === "json" ? "json" : "text"
|
|
106461
|
-
})) {
|
|
106462
|
-
return;
|
|
106463
|
-
}
|
|
106464
|
-
throw new ContextError(ExitCode.WorkspaceStateError, "close requires a context project workspace", {
|
|
106465
|
-
category: ErrorCategory.WorkspaceNotFound
|
|
106466
|
-
});
|
|
106467
|
-
});
|
|
106468
|
-
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) => {
|
|
106469
|
-
if (options.format !== "text" && options.format !== "json") {
|
|
106470
|
-
throw new ContextError(ExitCode.UserError, "--format must be text or json", {
|
|
106471
|
-
category: ErrorCategory.UserInputInvalid
|
|
106472
|
-
});
|
|
106473
|
-
}
|
|
106474
|
-
if (await runProjectBuildCommand({
|
|
106475
|
-
cwd: process.cwd(),
|
|
106476
|
-
format: options.format === "json" ? "json" : "text",
|
|
106477
|
-
verbose: options.verbose === true
|
|
106478
|
-
})) {
|
|
106479
|
-
return;
|
|
106480
|
-
}
|
|
106481
|
-
throw new ContextError(ExitCode.WorkspaceStateError, "build requires a context project workspace", {
|
|
106482
|
-
category: ErrorCategory.WorkspaceNotFound
|
|
106483
|
-
});
|
|
106484
|
-
});
|
|
106767
|
+
registerProjectCloseAndBuildCommands(program2);
|
|
106485
106768
|
registerProjectSourceCommands(program2);
|
|
106486
|
-
program2
|
|
106487
|
-
if (options.format !== "table" && options.format !== "json") {
|
|
106488
|
-
throw new ContextError(ExitCode.UserError, "--format must be table or json", {
|
|
106489
|
-
category: ErrorCategory.UserInputInvalid
|
|
106490
|
-
});
|
|
106491
|
-
}
|
|
106492
|
-
if (options.view !== undefined && options.view !== "diagnostics") {
|
|
106493
|
-
throw new ContextError(ExitCode.UserError, "--view must be diagnostics", {
|
|
106494
|
-
category: ErrorCategory.UserInputInvalid
|
|
106495
|
-
});
|
|
106496
|
-
}
|
|
106497
|
-
if (options.view === "diagnostics" && options.format !== "json") {
|
|
106498
|
-
throw new ContextError(ExitCode.UserError, "--view diagnostics requires --format json", {
|
|
106499
|
-
category: ErrorCategory.UserInputInvalid
|
|
106500
|
-
});
|
|
106501
|
-
}
|
|
106502
|
-
if (await runProjectVerifyCommand({
|
|
106503
|
-
cwd: process.cwd(),
|
|
106504
|
-
format: options.format === "json" ? "json" : "table",
|
|
106505
|
-
...options.compact === true ? { compact: true } : {},
|
|
106506
|
-
...options.view === "diagnostics" ? { view: "diagnostics" } : {},
|
|
106507
|
-
...typeof options.pageSize === "string" ? { pageSize: options.pageSize } : {},
|
|
106508
|
-
...typeof options.pageToken === "string" ? { pageToken: options.pageToken } : {}
|
|
106509
|
-
})) {
|
|
106510
|
-
return;
|
|
106511
|
-
}
|
|
106512
|
-
throw new ContextError(ExitCode.WorkspaceStateError, "verify requires a context project workspace", {
|
|
106513
|
-
category: ErrorCategory.WorkspaceNotFound
|
|
106514
|
-
});
|
|
106515
|
-
});
|
|
106769
|
+
registerProjectVerifyCommand(program2);
|
|
106516
106770
|
const cleanCacheAction = async (options) => {
|
|
106517
106771
|
const dryRun = options.dryRun === true;
|
|
106518
106772
|
await runDoctorCleanClaudePluginCache({ dryRun });
|
|
@@ -106544,10 +106798,12 @@ function createCliProgram() {
|
|
|
106544
106798
|
return program2;
|
|
106545
106799
|
}
|
|
106546
106800
|
async function cli_main(argv = process.argv) {
|
|
106547
|
-
await
|
|
106548
|
-
|
|
106549
|
-
|
|
106550
|
-
|
|
106801
|
+
await withContextRuntimeEventDelivery(async () => {
|
|
106802
|
+
await withDebugCliInvocation(argv, async () => {
|
|
106803
|
+
assertKnownTopLevelCommand(argv);
|
|
106804
|
+
const program2 = createCliProgram();
|
|
106805
|
+
await program2.parseAsync(argv);
|
|
106806
|
+
});
|
|
106551
106807
|
});
|
|
106552
106808
|
}
|
|
106553
106809
|
function isDirectCliInvocation(metaUrl, argv1) {
|