@c4a/context-cli 0.6.5 → 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 +943 -724
- package/package.json +2 -2
- package/plugins/VERSION +1 -1
- package/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/plugins/codex/.codex-plugin/plugin.json +2 -2
- package/plugins/cursor/.cursor-plugin/plugin.json +1 -1
- package/providers/context/manifest.json +3 -3
- package/providers/context/provider.yaml +1 -1
package/cli.js
CHANGED
|
@@ -17720,17 +17720,17 @@ var init_writeLock = __esm(() => {
|
|
|
17720
17720
|
|
|
17721
17721
|
// src/project/packageTemplateReview.ts
|
|
17722
17722
|
import { createHash as createHash12 } from "node:crypto";
|
|
17723
|
-
import { existsSync as
|
|
17723
|
+
import { existsSync as existsSync15 } from "node:fs";
|
|
17724
17724
|
import { mkdir as mkdir13, readFile as readFile20, readdir as readdir8, writeFile as writeFile9 } from "node:fs/promises";
|
|
17725
|
-
import { dirname as
|
|
17725
|
+
import { dirname as dirname18, join as join25, relative as relative10, resolve as resolve14 } from "node:path";
|
|
17726
17726
|
async function templateFiles(root) {
|
|
17727
|
-
if (!
|
|
17727
|
+
if (!existsSync15(root))
|
|
17728
17728
|
return [];
|
|
17729
17729
|
const files = [];
|
|
17730
17730
|
const visit2 = async (dir) => {
|
|
17731
17731
|
const entries = await readdir8(dir, { withFileTypes: true });
|
|
17732
17732
|
for (const entry of entries) {
|
|
17733
|
-
const absolutePath =
|
|
17733
|
+
const absolutePath = join25(dir, entry.name);
|
|
17734
17734
|
if (entry.isDirectory()) {
|
|
17735
17735
|
await visit2(absolutePath);
|
|
17736
17736
|
continue;
|
|
@@ -17757,8 +17757,8 @@ function isMarker(value) {
|
|
|
17757
17757
|
return marker.schema === PACKAGE_TEMPLATE_REVIEW_SCHEMA && /^sha256:[a-f0-9]{64}$/u.test(marker.starter_digest ?? "") && (marker.disposition === "review-required" || marker.disposition === "starter-accepted");
|
|
17758
17758
|
}
|
|
17759
17759
|
async function readMarker(templateRoot) {
|
|
17760
|
-
const markerPath =
|
|
17761
|
-
if (!
|
|
17760
|
+
const markerPath = join25(templateRoot, PACKAGE_TEMPLATE_REVIEW_FILE);
|
|
17761
|
+
if (!existsSync15(markerPath))
|
|
17762
17762
|
return null;
|
|
17763
17763
|
try {
|
|
17764
17764
|
const parsed = JSON.parse(await readFile20(markerPath, "utf8"));
|
|
@@ -17768,15 +17768,15 @@ async function readMarker(templateRoot) {
|
|
|
17768
17768
|
}
|
|
17769
17769
|
}
|
|
17770
17770
|
async function writeStarterTemplateReviewMarker(templateRoot) {
|
|
17771
|
-
const markerPath =
|
|
17772
|
-
if (
|
|
17771
|
+
const markerPath = join25(templateRoot, PACKAGE_TEMPLATE_REVIEW_FILE);
|
|
17772
|
+
if (existsSync15(markerPath))
|
|
17773
17773
|
return false;
|
|
17774
17774
|
const marker = {
|
|
17775
17775
|
schema: PACKAGE_TEMPLATE_REVIEW_SCHEMA,
|
|
17776
17776
|
starter_digest: await templateDigest(templateRoot),
|
|
17777
17777
|
disposition: "review-required"
|
|
17778
17778
|
};
|
|
17779
|
-
await mkdir13(
|
|
17779
|
+
await mkdir13(dirname18(markerPath), { recursive: true });
|
|
17780
17780
|
await writeFile9(markerPath, `${JSON.stringify(marker, null, 2)}
|
|
17781
17781
|
`, "utf8");
|
|
17782
17782
|
return true;
|
|
@@ -17796,7 +17796,7 @@ async function inspectPackageTemplateReview(projectRoot, pkg) {
|
|
|
17796
17796
|
packageName: pkg.name,
|
|
17797
17797
|
templatePath: pkg.template.path,
|
|
17798
17798
|
state: "invalid",
|
|
17799
|
-
diagnostic: `${
|
|
17799
|
+
diagnostic: `${join25(pkg.template.path, PACKAGE_TEMPLATE_REVIEW_FILE)} is invalid`
|
|
17800
17800
|
};
|
|
17801
17801
|
}
|
|
17802
17802
|
const currentDigest = await templateDigest(templateRoot);
|
|
@@ -17837,8 +17837,8 @@ async function acceptStarterPackageTemplates(input) {
|
|
|
17837
17837
|
alreadyResolved.push(pkg.name);
|
|
17838
17838
|
continue;
|
|
17839
17839
|
}
|
|
17840
|
-
const markerPath =
|
|
17841
|
-
const marker = await readMarker(
|
|
17840
|
+
const markerPath = join25(input.projectRoot, pkg.template.path, PACKAGE_TEMPLATE_REVIEW_FILE);
|
|
17841
|
+
const marker = await readMarker(join25(input.projectRoot, pkg.template.path));
|
|
17842
17842
|
if (marker === null || marker === "invalid") {
|
|
17843
17843
|
throw new ContextError(ExitCode.WorkspaceStateError, "package template review marker changed before acceptance", {
|
|
17844
17844
|
category: ErrorCategory.WorkspaceStateInvalid,
|
|
@@ -17866,6 +17866,7 @@ var init_packageTemplateReview = __esm(() => {
|
|
|
17866
17866
|
// src/project/workspace.ts
|
|
17867
17867
|
var exports_workspace = {};
|
|
17868
17868
|
__export(exports_workspace, {
|
|
17869
|
+
resolveContextProjectInitTarget: () => resolveContextProjectInitTarget,
|
|
17869
17870
|
projectLanguage: () => projectLanguage,
|
|
17870
17871
|
loadContextProjectModule: () => loadContextProjectModule,
|
|
17871
17872
|
isContextProjectRoot: () => isContextProjectRoot,
|
|
@@ -17876,30 +17877,30 @@ __export(exports_workspace, {
|
|
|
17876
17877
|
assertContextStatusWorkspaceAllowed: () => assertContextStatusWorkspaceAllowed,
|
|
17877
17878
|
PROJECT_LANGUAGES: () => PROJECT_LANGUAGES
|
|
17878
17879
|
});
|
|
17879
|
-
import { existsSync as
|
|
17880
|
+
import { existsSync as existsSync16, readFileSync as readFileSync6 } from "node:fs";
|
|
17880
17881
|
import { mkdir as mkdir14, readFile as readFile21, readdir as readdir9, writeFile as writeFile10 } from "node:fs/promises";
|
|
17881
17882
|
import { createRequire as createRequire3 } from "node:module";
|
|
17882
|
-
import { basename as basename5, dirname as
|
|
17883
|
-
import { fileURLToPath as
|
|
17883
|
+
import { basename as basename5, dirname as dirname19, isAbsolute as isAbsolute6, join as join26, parse as parse6, relative as relative11, resolve as resolve15 } from "node:path";
|
|
17884
|
+
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
17884
17885
|
import { createJiti } from "jiti";
|
|
17885
|
-
function
|
|
17886
|
+
function isRecord13(value) {
|
|
17886
17887
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
17887
17888
|
}
|
|
17888
17889
|
function readPackageJson(root) {
|
|
17889
|
-
const packagePath =
|
|
17890
|
-
if (!
|
|
17890
|
+
const packagePath = join26(root, "package.json");
|
|
17891
|
+
if (!existsSync16(packagePath))
|
|
17891
17892
|
return null;
|
|
17892
17893
|
try {
|
|
17893
|
-
const parsed = JSON.parse(
|
|
17894
|
-
return
|
|
17894
|
+
const parsed = JSON.parse(readFileSync6(packagePath, "utf8"));
|
|
17895
|
+
return isRecord13(parsed) ? parsed : null;
|
|
17895
17896
|
} catch {
|
|
17896
17897
|
return null;
|
|
17897
17898
|
}
|
|
17898
17899
|
}
|
|
17899
17900
|
function readPackageJsonFile(packageJsonPath) {
|
|
17900
17901
|
try {
|
|
17901
|
-
const parsed = JSON.parse(
|
|
17902
|
-
return
|
|
17902
|
+
const parsed = JSON.parse(readFileSync6(packageJsonPath, "utf8"));
|
|
17903
|
+
return isRecord13(parsed) ? parsed : null;
|
|
17903
17904
|
} catch {
|
|
17904
17905
|
return null;
|
|
17905
17906
|
}
|
|
@@ -17910,22 +17911,22 @@ function resolveExportImportTarget(packageJsonPath) {
|
|
|
17910
17911
|
return null;
|
|
17911
17912
|
const exportsField = parsed.exports;
|
|
17912
17913
|
if (typeof exportsField === "string") {
|
|
17913
|
-
return
|
|
17914
|
+
return join26(dirname19(packageJsonPath), exportsField);
|
|
17914
17915
|
}
|
|
17915
|
-
if (
|
|
17916
|
+
if (isRecord13(exportsField)) {
|
|
17916
17917
|
const rootExport = exportsField["."];
|
|
17917
17918
|
if (typeof rootExport === "string") {
|
|
17918
|
-
return
|
|
17919
|
+
return join26(dirname19(packageJsonPath), rootExport);
|
|
17919
17920
|
}
|
|
17920
|
-
if (
|
|
17921
|
-
return
|
|
17921
|
+
if (isRecord13(rootExport) && typeof rootExport.import === "string") {
|
|
17922
|
+
return join26(dirname19(packageJsonPath), rootExport.import);
|
|
17922
17923
|
}
|
|
17923
17924
|
}
|
|
17924
17925
|
if (typeof parsed.module === "string") {
|
|
17925
|
-
return
|
|
17926
|
+
return join26(dirname19(packageJsonPath), parsed.module);
|
|
17926
17927
|
}
|
|
17927
17928
|
if (typeof parsed.main === "string") {
|
|
17928
|
-
return
|
|
17929
|
+
return join26(dirname19(packageJsonPath), parsed.main);
|
|
17929
17930
|
}
|
|
17930
17931
|
return null;
|
|
17931
17932
|
}
|
|
@@ -17941,16 +17942,16 @@ function resolveContextSdkImportAlias(entryPath) {
|
|
|
17941
17942
|
return "@c4a/context";
|
|
17942
17943
|
}
|
|
17943
17944
|
function readCurrentPackageVersion() {
|
|
17944
|
-
let dir =
|
|
17945
|
+
let dir = dirname19(fileURLToPath6(import.meta.url));
|
|
17945
17946
|
for (let index2 = 0;index2 < 8; index2++) {
|
|
17946
|
-
const packagePath =
|
|
17947
|
-
if (
|
|
17947
|
+
const packagePath = join26(dir, "package.json");
|
|
17948
|
+
if (existsSync16(packagePath)) {
|
|
17948
17949
|
const parsed = readPackageJson(dir);
|
|
17949
17950
|
if (typeof parsed?.version === "string" && parsed.version.trim().length > 0) {
|
|
17950
17951
|
return parsed.version;
|
|
17951
17952
|
}
|
|
17952
17953
|
}
|
|
17953
|
-
const parent =
|
|
17954
|
+
const parent = dirname19(dir);
|
|
17954
17955
|
if (parent === dir)
|
|
17955
17956
|
break;
|
|
17956
17957
|
dir = parent;
|
|
@@ -17959,7 +17960,7 @@ function readCurrentPackageVersion() {
|
|
|
17959
17960
|
}
|
|
17960
17961
|
function readContextProjectPackage(root) {
|
|
17961
17962
|
const parsed = readPackageJson(root);
|
|
17962
|
-
const context =
|
|
17963
|
+
const context = isRecord13(parsed?.context) ? parsed.context : null;
|
|
17963
17964
|
if (context?.project !== true || typeof context.entry !== "string" || context.entry.trim().length === 0) {
|
|
17964
17965
|
return null;
|
|
17965
17966
|
}
|
|
@@ -17970,7 +17971,7 @@ function readContextProjectPackage(root) {
|
|
|
17970
17971
|
}
|
|
17971
17972
|
function readContextWorkspaceDir(root) {
|
|
17972
17973
|
const parsed = readPackageJson(root);
|
|
17973
|
-
const context =
|
|
17974
|
+
const context = isRecord13(parsed?.context) ? parsed.context : null;
|
|
17974
17975
|
const workspaceDir = context?.workspaceDir;
|
|
17975
17976
|
if (typeof workspaceDir !== "string" || workspaceDir.trim().length === 0)
|
|
17976
17977
|
return null;
|
|
@@ -17978,7 +17979,7 @@ function readContextWorkspaceDir(root) {
|
|
|
17978
17979
|
}
|
|
17979
17980
|
function readContextProjectLanguage(root) {
|
|
17980
17981
|
const parsed = readPackageJson(root);
|
|
17981
|
-
const context =
|
|
17982
|
+
const context = isRecord13(parsed?.context) ? parsed.context : null;
|
|
17982
17983
|
return context?.language === "en" || context?.language === "zh-CN" ? context.language : undefined;
|
|
17983
17984
|
}
|
|
17984
17985
|
function isSameOrChildPath(path3, parent) {
|
|
@@ -17999,13 +18000,13 @@ function findContextWorkspaceExpectation(startDir = process.cwd()) {
|
|
|
17999
18000
|
workspaceDir,
|
|
18000
18001
|
workspaceRoot,
|
|
18001
18002
|
cwd,
|
|
18002
|
-
exists:
|
|
18003
|
+
exists: existsSync16(workspaceRoot)
|
|
18003
18004
|
};
|
|
18004
18005
|
}
|
|
18005
18006
|
}
|
|
18006
18007
|
if (dir === root)
|
|
18007
18008
|
return null;
|
|
18008
|
-
const parent =
|
|
18009
|
+
const parent = dirname19(dir);
|
|
18009
18010
|
if (parent === dir)
|
|
18010
18011
|
return null;
|
|
18011
18012
|
dir = parent;
|
|
@@ -18039,7 +18040,7 @@ function findContextProjectRoot(startDir = process.cwd()) {
|
|
|
18039
18040
|
return { projectRoot: dir };
|
|
18040
18041
|
if (dir === root)
|
|
18041
18042
|
return null;
|
|
18042
|
-
const parent =
|
|
18043
|
+
const parent = dirname19(dir);
|
|
18043
18044
|
if (parent === dir)
|
|
18044
18045
|
return null;
|
|
18045
18046
|
dir = parent;
|
|
@@ -18049,6 +18050,9 @@ function normalizeProjectDir(cwd, projectDir) {
|
|
|
18049
18050
|
const raw = projectDir?.trim() || DEFAULT_PROJECT_DIR;
|
|
18050
18051
|
return raw === "." ? resolve15(cwd) : resolve15(cwd, raw);
|
|
18051
18052
|
}
|
|
18053
|
+
function resolveContextProjectInitTarget(cwd, projectDir) {
|
|
18054
|
+
return normalizeProjectDir(cwd, projectDir);
|
|
18055
|
+
}
|
|
18052
18056
|
function slugifyName(value) {
|
|
18053
18057
|
const slug = value.trim().toLowerCase().replace(/[^a-z0-9._-]+/gu, "-").replace(/^-+|-+$/gu, "");
|
|
18054
18058
|
return slug.length > 0 ? slug : "context";
|
|
@@ -18078,7 +18082,7 @@ function initCommand(input, allowNonempty) {
|
|
|
18078
18082
|
return args.map(shellQuote3).join(" ");
|
|
18079
18083
|
}
|
|
18080
18084
|
async function assertInitTargetAllowed(input, projectRoot) {
|
|
18081
|
-
if (!
|
|
18085
|
+
if (!existsSync16(projectRoot) || isContextProjectRoot(projectRoot) || input.allowNonempty === true)
|
|
18082
18086
|
return;
|
|
18083
18087
|
const entries = (await readdir9(projectRoot)).sort();
|
|
18084
18088
|
if (entries.length === 0)
|
|
@@ -18102,11 +18106,11 @@ async function assertInitTargetAllowed(input, projectRoot) {
|
|
|
18102
18106
|
});
|
|
18103
18107
|
}
|
|
18104
18108
|
async function writeIfMissing(path3, content3, result) {
|
|
18105
|
-
if (
|
|
18109
|
+
if (existsSync16(path3)) {
|
|
18106
18110
|
result.kept.push(path3);
|
|
18107
18111
|
return;
|
|
18108
18112
|
}
|
|
18109
|
-
await mkdir14(
|
|
18113
|
+
await mkdir14(dirname19(path3), { recursive: true });
|
|
18110
18114
|
await writeFile10(path3, content3, "utf8");
|
|
18111
18115
|
result.created.push(path3);
|
|
18112
18116
|
}
|
|
@@ -18114,7 +18118,7 @@ async function listStaticTemplateFiles(root, dir = root) {
|
|
|
18114
18118
|
const entries = await readdir9(dir, { withFileTypes: true });
|
|
18115
18119
|
const files = [];
|
|
18116
18120
|
for (const entry of entries) {
|
|
18117
|
-
const absolutePath =
|
|
18121
|
+
const absolutePath = join26(dir, entry.name);
|
|
18118
18122
|
if (entry.isDirectory()) {
|
|
18119
18123
|
files.push(...await listStaticTemplateFiles(root, absolutePath));
|
|
18120
18124
|
continue;
|
|
@@ -18131,8 +18135,8 @@ async function listStaticTemplateFiles(root, dir = root) {
|
|
|
18131
18135
|
function resolveContextPackageTemplatesRoot() {
|
|
18132
18136
|
try {
|
|
18133
18137
|
const packageJsonPath = createRequire3(import.meta.url).resolve("@c4a/context/package.json");
|
|
18134
|
-
const templateRoot =
|
|
18135
|
-
if (
|
|
18138
|
+
const templateRoot = join26(dirname19(packageJsonPath), "templates", "package-templates");
|
|
18139
|
+
if (existsSync16(templateRoot))
|
|
18136
18140
|
return templateRoot;
|
|
18137
18141
|
} catch {}
|
|
18138
18142
|
throw new ContextError(ExitCode.WorkspaceStateError, "missing @c4a/context package templates", {
|
|
@@ -18143,8 +18147,8 @@ function resolveContextPackageTemplatesRoot() {
|
|
|
18143
18147
|
}
|
|
18144
18148
|
async function writeDefaultPackageTemplates(projectRoot, result, language) {
|
|
18145
18149
|
const defaultRoot = resolveContextPackageTemplatesRoot();
|
|
18146
|
-
const templateRoot = language === "zh-CN" ?
|
|
18147
|
-
if (!
|
|
18150
|
+
const templateRoot = language === "zh-CN" ? join26(dirname19(defaultRoot), "package-templates.zh-CN") : defaultRoot;
|
|
18151
|
+
if (!existsSync16(templateRoot)) {
|
|
18148
18152
|
throw new ContextError(ExitCode.WorkspaceStateError, `missing ${language} @c4a/context package templates`, {
|
|
18149
18153
|
category: ErrorCategory.WorkspaceStateInvalid,
|
|
18150
18154
|
path: templateRoot,
|
|
@@ -18153,21 +18157,21 @@ async function writeDefaultPackageTemplates(projectRoot, result, language) {
|
|
|
18153
18157
|
}
|
|
18154
18158
|
const files = await listStaticTemplateFiles(templateRoot);
|
|
18155
18159
|
for (const file of files) {
|
|
18156
|
-
await writeIfMissing(
|
|
18160
|
+
await writeIfMissing(join26(projectRoot, "src", "package-templates", ...file.relativePath.split("/")), await readFile21(file.absolutePath, "utf8"), result);
|
|
18157
18161
|
}
|
|
18158
18162
|
const templateKinds = [...new Set(files.map((file) => file.relativePath.split("/")[0]).filter((value) => value !== undefined && value.length > 0))];
|
|
18159
18163
|
for (const templateKind of templateKinds) {
|
|
18160
|
-
const root =
|
|
18164
|
+
const root = join26(projectRoot, "src", "package-templates", templateKind);
|
|
18161
18165
|
if (await writeStarterTemplateReviewMarker(root)) {
|
|
18162
|
-
result.created.push(
|
|
18166
|
+
result.created.push(join26(root, PACKAGE_TEMPLATE_REVIEW_FILE));
|
|
18163
18167
|
} else {
|
|
18164
|
-
result.kept.push(
|
|
18168
|
+
result.kept.push(join26(root, PACKAGE_TEMPLATE_REVIEW_FILE));
|
|
18165
18169
|
}
|
|
18166
18170
|
}
|
|
18167
18171
|
}
|
|
18168
18172
|
function resolveLocalSdkDependency() {
|
|
18169
18173
|
const packageJsonPath = createRequire3(import.meta.url).resolve("@c4a/context/package.json");
|
|
18170
|
-
return `file:${
|
|
18174
|
+
return `file:${dirname19(packageJsonPath)}`;
|
|
18171
18175
|
}
|
|
18172
18176
|
function resolveSdkDependency(dev, version3) {
|
|
18173
18177
|
return dev === true ? resolveLocalSdkDependency() : version3;
|
|
@@ -18465,20 +18469,20 @@ async function initContextProject(input) {
|
|
|
18465
18469
|
kept: []
|
|
18466
18470
|
};
|
|
18467
18471
|
for (const dir of PROJECT_DIRS) {
|
|
18468
|
-
await mkdir14(
|
|
18472
|
+
await mkdir14(join26(projectRoot, dir), { recursive: true });
|
|
18469
18473
|
}
|
|
18470
|
-
await mkdir14(
|
|
18471
|
-
await mkdir14(
|
|
18472
|
-
await mkdir14(
|
|
18473
|
-
await writeIfMissing(
|
|
18474
|
-
await writeIfMissing(
|
|
18474
|
+
await mkdir14(join26(projectRoot, "sources", "repo"), { recursive: true });
|
|
18475
|
+
await mkdir14(join26(projectRoot, "sources", "file"), { recursive: true });
|
|
18476
|
+
await mkdir14(join26(projectRoot, "sources", "lark"), { recursive: true });
|
|
18477
|
+
await writeIfMissing(join26(projectRoot, "package.json"), renderPackageJson(projectName, readCurrentPackageVersion(), input.dev, language, input.debug), result);
|
|
18478
|
+
await writeIfMissing(join26(projectRoot, "src", "index.ts"), renderProjectEntry(language), result);
|
|
18475
18479
|
await writeDefaultPackageTemplates(projectRoot, result, language);
|
|
18476
|
-
await writeIfMissing(
|
|
18477
|
-
await writeIfMissing(
|
|
18478
|
-
await writeIfMissing(
|
|
18479
|
-
await writeIfMissing(
|
|
18480
|
-
await writeIfMissing(
|
|
18481
|
-
await writeIfMissing(
|
|
18480
|
+
await writeIfMissing(join26(projectRoot, "sources", "repo", "index.yaml"), renderRepoIndex(), result);
|
|
18481
|
+
await writeIfMissing(join26(projectRoot, "sources", "file", "index.yaml"), renderFileIndex(), result);
|
|
18482
|
+
await writeIfMissing(join26(projectRoot, "sources", "lark", "index.yaml"), renderLarkIndex(), result);
|
|
18483
|
+
await writeIfMissing(join26(projectRoot, ".gitignore"), renderGitignore(), result);
|
|
18484
|
+
await writeIfMissing(join26(projectRoot, "README.md"), renderReadme(projectName, language), result);
|
|
18485
|
+
await writeIfMissing(join26(projectRoot, "AGENTS.md"), renderAgents(projectName, language), result);
|
|
18482
18486
|
if (input.debug === true)
|
|
18483
18487
|
await enableContextDebug(projectRoot, "init");
|
|
18484
18488
|
return result;
|
|
@@ -18492,7 +18496,7 @@ async function loadContextProjectModule(root) {
|
|
|
18492
18496
|
next: "Ensure package.json declares context.project=true and context.entry points to src/index.ts, then rerun the command."
|
|
18493
18497
|
});
|
|
18494
18498
|
}
|
|
18495
|
-
const entryPath =
|
|
18499
|
+
const entryPath = join26(root, projectConfig.entry);
|
|
18496
18500
|
const jiti = createJiti(entryPath, {
|
|
18497
18501
|
alias: {
|
|
18498
18502
|
"@c4a/context": resolveContextSdkImportAlias(entryPath)
|
|
@@ -18502,7 +18506,7 @@ async function loadContextProjectModule(root) {
|
|
|
18502
18506
|
moduleCache: false
|
|
18503
18507
|
});
|
|
18504
18508
|
const loadedProject = await jiti.import(entryPath, { default: true });
|
|
18505
|
-
if (!
|
|
18509
|
+
if (!isRecord13(loadedProject) || loadedProject.kind !== "context.project") {
|
|
18506
18510
|
throw new ContextError(ExitCode.WorkspaceStateError, "src/index.ts default export must be a @c4a/context project module", {
|
|
18507
18511
|
category: ErrorCategory.SchemaInvalid,
|
|
18508
18512
|
path: projectConfig.entry,
|
|
@@ -21518,7 +21522,7 @@ var require_util2 = __commonJS((exports) => {
|
|
|
21518
21522
|
return path4;
|
|
21519
21523
|
}
|
|
21520
21524
|
exports.normalize = normalize;
|
|
21521
|
-
function
|
|
21525
|
+
function join47(aRoot, aPath) {
|
|
21522
21526
|
if (aRoot === "") {
|
|
21523
21527
|
aRoot = ".";
|
|
21524
21528
|
}
|
|
@@ -21550,7 +21554,7 @@ var require_util2 = __commonJS((exports) => {
|
|
|
21550
21554
|
}
|
|
21551
21555
|
return joined;
|
|
21552
21556
|
}
|
|
21553
|
-
exports.join =
|
|
21557
|
+
exports.join = join47;
|
|
21554
21558
|
exports.isAbsolute = function(aPath) {
|
|
21555
21559
|
return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
|
|
21556
21560
|
};
|
|
@@ -21723,7 +21727,7 @@ var require_util2 = __commonJS((exports) => {
|
|
|
21723
21727
|
parsed.path = parsed.path.substring(0, index2 + 1);
|
|
21724
21728
|
}
|
|
21725
21729
|
}
|
|
21726
|
-
sourceURL =
|
|
21730
|
+
sourceURL = join47(urlGenerate(parsed), sourceURL);
|
|
21727
21731
|
}
|
|
21728
21732
|
return normalize(sourceURL);
|
|
21729
21733
|
}
|
|
@@ -24123,9 +24127,9 @@ var require_lib = __commonJS((exports, module) => {
|
|
|
24123
24127
|
});
|
|
24124
24128
|
|
|
24125
24129
|
// src/cli.ts
|
|
24126
|
-
import { existsSync as
|
|
24127
|
-
import { dirname as
|
|
24128
|
-
import { fileURLToPath as
|
|
24130
|
+
import { existsSync as existsSync47, readFileSync as readFileSync10, realpathSync } from "node:fs";
|
|
24131
|
+
import { dirname as dirname43, join as join74 } from "node:path";
|
|
24132
|
+
import { fileURLToPath as fileURLToPath10, pathToFileURL as pathToFileURL4 } from "node:url";
|
|
24129
24133
|
|
|
24130
24134
|
// ../../node_modules/.bun/commander@11.1.0/node_modules/commander/esm.mjs
|
|
24131
24135
|
var import__ = __toESM(require_commander(), 1);
|
|
@@ -24189,7 +24193,7 @@ function mergedWorkflowAuthorities(...values) {
|
|
|
24189
24193
|
}
|
|
24190
24194
|
|
|
24191
24195
|
// src/project/workflow/workflowResource.ts
|
|
24192
|
-
import { join as
|
|
24196
|
+
import { join as join56 } from "node:path";
|
|
24193
24197
|
|
|
24194
24198
|
// ../../node_modules/.bun/@c4a+agent-graph@0.2.5/node_modules/@c4a/agent-graph/dist/index.js
|
|
24195
24199
|
import { createRequire as createRequire2 } from "node:module";
|
|
@@ -40402,7 +40406,7 @@ init_errors();
|
|
|
40402
40406
|
init_exitCode();
|
|
40403
40407
|
|
|
40404
40408
|
// src/project/status.ts
|
|
40405
|
-
import { join as
|
|
40409
|
+
import { join as join55 } from "node:path";
|
|
40406
40410
|
|
|
40407
40411
|
// ../context/src/contracts.ts
|
|
40408
40412
|
var DEFAULT_PACKAGE_NAVIGATION = {
|
|
@@ -45289,9 +45293,9 @@ function resolveStructureCompileRoute(input) {
|
|
|
45289
45293
|
// src/project/statusReaders.ts
|
|
45290
45294
|
init_errors();
|
|
45291
45295
|
var import_yaml29 = __toESM(require_dist3(), 1);
|
|
45292
|
-
import { existsSync as
|
|
45296
|
+
import { existsSync as existsSync36, readFileSync as readFileSync8 } from "node:fs";
|
|
45293
45297
|
import { readdir as readdir16 } from "node:fs/promises";
|
|
45294
|
-
import { join as
|
|
45298
|
+
import { join as join53 } from "node:path";
|
|
45295
45299
|
|
|
45296
45300
|
// src/project/documentCapture.ts
|
|
45297
45301
|
import { createHash as createHash4 } from "node:crypto";
|
|
@@ -68944,20 +68948,156 @@ async function readApprovedCodegraphPages(input) {
|
|
|
68944
68948
|
// src/project/close.ts
|
|
68945
68949
|
init_cliFeedback();
|
|
68946
68950
|
init_errors();
|
|
68947
|
-
init_exitCode();
|
|
68948
68951
|
var import_yaml14 = __toESM(require_dist3(), 1);
|
|
68949
|
-
import { existsSync as
|
|
68952
|
+
import { existsSync as existsSync22 } from "node:fs";
|
|
68950
68953
|
import { mkdir as mkdir17, readdir as readdir11, readFile as readFile27, writeFile as writeFile13 } from "node:fs/promises";
|
|
68951
|
-
import { dirname as
|
|
68954
|
+
import { dirname as dirname22, join as join33, relative as relative13 } from "node:path";
|
|
68955
|
+
|
|
68956
|
+
// src/runtimeEvents.ts
|
|
68957
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
68958
|
+
import { 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();
|
|
68952
69092
|
|
|
68953
69093
|
// src/project/approvedStructureEdges.ts
|
|
68954
69094
|
init_cliFeedback();
|
|
68955
69095
|
init_errors();
|
|
68956
69096
|
init_exitCode();
|
|
68957
69097
|
var import_yaml10 = __toESM(require_dist3(), 1);
|
|
68958
|
-
import { existsSync as
|
|
69098
|
+
import { existsSync as existsSync11 } from "node:fs";
|
|
68959
69099
|
import { readFile as readFile17 } from "node:fs/promises";
|
|
68960
|
-
import { join as
|
|
69100
|
+
import { join as join20 } from "node:path";
|
|
68961
69101
|
|
|
68962
69102
|
// src/project/proseAlignTypes.ts
|
|
68963
69103
|
import { createHash as createHash9 } from "node:crypto";
|
|
@@ -69014,21 +69154,21 @@ function slugify2(input, maxLen = 60) {
|
|
|
69014
69154
|
// src/project/semanticRules.ts
|
|
69015
69155
|
var import_yaml8 = __toESM(require_dist3(), 1);
|
|
69016
69156
|
import { createHash as createHash8 } from "node:crypto";
|
|
69017
|
-
import { existsSync as
|
|
69018
|
-
import { basename as basename4, dirname as
|
|
69019
|
-
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";
|
|
69020
69160
|
function sha256(value) {
|
|
69021
69161
|
return `sha256:${createHash8("sha256").update(value).digest("hex")}`;
|
|
69022
69162
|
}
|
|
69023
69163
|
function workflowRootCandidates() {
|
|
69024
|
-
const runtimeDir =
|
|
69164
|
+
const runtimeDir = dirname16(fileURLToPath5(import.meta.url));
|
|
69025
69165
|
return [
|
|
69026
|
-
|
|
69027
|
-
|
|
69166
|
+
join18(runtimeDir, "providers", "context"),
|
|
69167
|
+
join18(runtimeDir, "..", "..", "context-workflow")
|
|
69028
69168
|
];
|
|
69029
69169
|
}
|
|
69030
69170
|
function semanticRuleMetadata(scope, filePath) {
|
|
69031
|
-
const content3 =
|
|
69171
|
+
const content3 = readFileSync5(filePath, "utf8").replaceAll(`\r
|
|
69032
69172
|
`, `
|
|
69033
69173
|
`);
|
|
69034
69174
|
const end = content3.indexOf(`
|
|
@@ -69059,19 +69199,19 @@ function semanticRuleMetadata(scope, filePath) {
|
|
|
69059
69199
|
}
|
|
69060
69200
|
function semanticRuleDescriptors(scope) {
|
|
69061
69201
|
for (const root of workflowRootCandidates()) {
|
|
69062
|
-
const directory =
|
|
69063
|
-
if (!
|
|
69202
|
+
const directory = join18(root, "resources", "semantic", scope);
|
|
69203
|
+
if (!existsSync9(directory))
|
|
69064
69204
|
continue;
|
|
69065
|
-
return readdirSync(directory, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".md")).sort((left, right) => left.name.localeCompare(right.name)).map((entry) => semanticRuleMetadata(scope,
|
|
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)));
|
|
69066
69206
|
}
|
|
69067
69207
|
throw new Error(`Context ${scope} semantic workflow resources are missing. Rebuild or reinstall @c4a/context-cli.`);
|
|
69068
69208
|
}
|
|
69069
69209
|
function ruleContent(rulePath) {
|
|
69070
69210
|
for (const root of workflowRootCandidates()) {
|
|
69071
|
-
const absolute =
|
|
69072
|
-
if (
|
|
69211
|
+
const absolute = join18(root, rulePath);
|
|
69212
|
+
if (existsSync9(absolute)) {
|
|
69073
69213
|
return {
|
|
69074
|
-
content:
|
|
69214
|
+
content: readFileSync5(absolute, "utf8"),
|
|
69075
69215
|
available: true,
|
|
69076
69216
|
filePath: absolute
|
|
69077
69217
|
};
|
|
@@ -69484,15 +69624,15 @@ init_cliFeedback();
|
|
|
69484
69624
|
init_errors();
|
|
69485
69625
|
init_exitCode();
|
|
69486
69626
|
var import_yaml9 = __toESM(require_dist3(), 1);
|
|
69487
|
-
import { existsSync as
|
|
69627
|
+
import { existsSync as existsSync10 } from "node:fs";
|
|
69488
69628
|
import { mkdir as mkdir12, readFile as readFile16, writeFile as writeFile8 } from "node:fs/promises";
|
|
69489
|
-
import { dirname as
|
|
69629
|
+
import { dirname as dirname17, join as join19 } from "node:path";
|
|
69490
69630
|
|
|
69491
69631
|
// src/project/proseAlignPayloadParse.ts
|
|
69492
69632
|
import { createHash as createHash10 } from "node:crypto";
|
|
69493
69633
|
|
|
69494
69634
|
// src/project/proseAlignSchemaUtils.ts
|
|
69495
|
-
function
|
|
69635
|
+
function isRecord9(value) {
|
|
69496
69636
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
69497
69637
|
}
|
|
69498
69638
|
function stringValue2(record, field) {
|
|
@@ -69559,7 +69699,7 @@ function parsePreferredNodes(value, diagnostics) {
|
|
|
69559
69699
|
}
|
|
69560
69700
|
const nodes = [];
|
|
69561
69701
|
for (const [index2, rawNode] of value.entries()) {
|
|
69562
|
-
if (!
|
|
69702
|
+
if (!isRecord9(rawNode)) {
|
|
69563
69703
|
diagnostics.push(diagnostic("error", "schema.preferred_node_object", "schema", "preferred_nodes item must be an object.", `user_or_agent_hints.preferred_nodes[${index2}]`));
|
|
69564
69704
|
continue;
|
|
69565
69705
|
}
|
|
@@ -69584,7 +69724,7 @@ function parsePreferredNodes(value, diagnostics) {
|
|
|
69584
69724
|
function parseUserOrAgentHints(value, diagnostics) {
|
|
69585
69725
|
if (value === undefined)
|
|
69586
69726
|
return;
|
|
69587
|
-
if (!
|
|
69727
|
+
if (!isRecord9(value)) {
|
|
69588
69728
|
diagnostics.push(diagnostic("error", "schema.user_or_agent_hints_object", "schema", "user_or_agent_hints must be an object.", "user_or_agent_hints"));
|
|
69589
69729
|
return;
|
|
69590
69730
|
}
|
|
@@ -69787,7 +69927,7 @@ function parseNodes(value, diagnostics) {
|
|
|
69787
69927
|
diagnostics.push(diagnostic("error", "schema.nodes_missing", "schema", "Payload must include at least one node.", "nodes"));
|
|
69788
69928
|
const nodes = [];
|
|
69789
69929
|
for (const [index2, rawNode] of value.entries()) {
|
|
69790
|
-
if (!
|
|
69930
|
+
if (!isRecord9(rawNode)) {
|
|
69791
69931
|
diagnostics.push(diagnostic("error", "schema.node_object", "schema", `Node ${index2 + 1} must be an object.`, `nodes[${index2}]`));
|
|
69792
69932
|
continue;
|
|
69793
69933
|
}
|
|
@@ -69824,7 +69964,7 @@ function parseSections(input) {
|
|
|
69824
69964
|
const sectionIds = new Set;
|
|
69825
69965
|
for (const [sectionIndex, rawSection] of input.value.entries()) {
|
|
69826
69966
|
const field = `views[${input.viewIndex}].sections[${sectionIndex}]`;
|
|
69827
|
-
if (!
|
|
69967
|
+
if (!isRecord9(rawSection)) {
|
|
69828
69968
|
input.diagnostics.push(diagnostic("error", "schema.section_object", "schema", "Section must be an object.", field));
|
|
69829
69969
|
continue;
|
|
69830
69970
|
}
|
|
@@ -69926,7 +70066,7 @@ function parseViews(value, nodes, diagnostics) {
|
|
|
69926
70066
|
const nodeByRef = new Map(nodes.map((node3) => [node3.node_ref, node3]));
|
|
69927
70067
|
const views = [];
|
|
69928
70068
|
for (const [index2, rawView] of value.entries()) {
|
|
69929
|
-
if (!
|
|
70069
|
+
if (!isRecord9(rawView)) {
|
|
69930
70070
|
diagnostics.push(diagnostic("error", "schema.view_object", "schema", `View ${index2 + 1} must be an object.`, `views[${index2}]`));
|
|
69931
70071
|
continue;
|
|
69932
70072
|
}
|
|
@@ -69945,7 +70085,7 @@ function parseEdges(value, diagnostics) {
|
|
|
69945
70085
|
}
|
|
69946
70086
|
const edges = [];
|
|
69947
70087
|
for (const [index2, rawEdge] of value.entries()) {
|
|
69948
|
-
if (!
|
|
70088
|
+
if (!isRecord9(rawEdge)) {
|
|
69949
70089
|
diagnostics.push(diagnostic("error", "schema.edge_object", "schema", `Edge ${index2 + 1} must be an object.`, `edges[${index2}]`));
|
|
69950
70090
|
continue;
|
|
69951
70091
|
}
|
|
@@ -69992,7 +70132,7 @@ function parseUnresolved(value, diagnostics) {
|
|
|
69992
70132
|
}
|
|
69993
70133
|
const unresolved = [];
|
|
69994
70134
|
for (const [index2, rawIssue] of value.entries()) {
|
|
69995
|
-
if (!
|
|
70135
|
+
if (!isRecord9(rawIssue)) {
|
|
69996
70136
|
diagnostics.push(diagnostic("error", "schema.unresolved_object", "schema", `Unresolved issue ${index2 + 1} must be an object.`, `unresolved[${index2}]`));
|
|
69997
70137
|
continue;
|
|
69998
70138
|
}
|
|
@@ -70015,7 +70155,7 @@ function parseUnresolved(value, diagnostics) {
|
|
|
70015
70155
|
function parseLifecycle(value, diagnostics) {
|
|
70016
70156
|
if (value === undefined)
|
|
70017
70157
|
return { state: "draft" };
|
|
70018
|
-
if (!
|
|
70158
|
+
if (!isRecord9(value)) {
|
|
70019
70159
|
diagnostics.push(diagnostic("error", "schema.lifecycle_object", "schema", "Payload lifecycle must be an object.", "lifecycle"));
|
|
70020
70160
|
return { state: "draft" };
|
|
70021
70161
|
}
|
|
@@ -70073,7 +70213,7 @@ function structureBody(input) {
|
|
|
70073
70213
|
}
|
|
70074
70214
|
function parseAlignPayload(value) {
|
|
70075
70215
|
const diagnostics = [];
|
|
70076
|
-
if (!
|
|
70216
|
+
if (!isRecord9(value)) {
|
|
70077
70217
|
return {
|
|
70078
70218
|
diagnostics: [diagnostic("error", "schema.payload_object", "schema", "Payload must be a YAML/JSON object.", "schema")]
|
|
70079
70219
|
};
|
|
@@ -70158,7 +70298,7 @@ function snapshotPath(projectRoot, structureDigest) {
|
|
|
70158
70298
|
structure_digest: structureDigest
|
|
70159
70299
|
});
|
|
70160
70300
|
}
|
|
70161
|
-
return
|
|
70301
|
+
return join19(projectRoot, STRUCTURE_SNAPSHOT_ROOT, `${match[1]}.yaml`);
|
|
70162
70302
|
}
|
|
70163
70303
|
function normalizedSnapshot(payload) {
|
|
70164
70304
|
const { user_or_agent_hints: _hints, ...body } = payload;
|
|
@@ -70174,8 +70314,8 @@ function normalizedSnapshot(payload) {
|
|
|
70174
70314
|
});
|
|
70175
70315
|
}
|
|
70176
70316
|
async function readSlots(projectRoot) {
|
|
70177
|
-
const path3 =
|
|
70178
|
-
if (!
|
|
70317
|
+
const path3 = join19(projectRoot, STRUCTURE_SLOT_FILE);
|
|
70318
|
+
if (!existsSync10(path3))
|
|
70179
70319
|
return [];
|
|
70180
70320
|
const parsed = import_yaml9.default.parse(await readFile16(path3, "utf8"));
|
|
70181
70321
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
@@ -70223,8 +70363,8 @@ async function updateSlots(projectRoot, payload) {
|
|
|
70223
70363
|
...current2.filter((slot) => !replacements.has(`${slot.source}\x00${slot.collection}`)),
|
|
70224
70364
|
...replacements.values()
|
|
70225
70365
|
].sort((left, right) => left.source.localeCompare(right.source) || left.collection.localeCompare(right.collection));
|
|
70226
|
-
const path3 =
|
|
70227
|
-
await mkdir12(
|
|
70366
|
+
const path3 = join19(projectRoot, STRUCTURE_SLOT_FILE);
|
|
70367
|
+
await mkdir12(dirname17(path3), { recursive: true });
|
|
70228
70368
|
await writeFile8(path3, import_yaml9.default.stringify({ schema_version: STRUCTURE_SLOT_SCHEMA_VERSION, slots }), "utf8");
|
|
70229
70369
|
}
|
|
70230
70370
|
async function writeStructureSnapshot(projectRoot, payload) {
|
|
@@ -70239,7 +70379,7 @@ async function writeStructureSnapshot(projectRoot, payload) {
|
|
|
70239
70379
|
});
|
|
70240
70380
|
}
|
|
70241
70381
|
const content3 = import_yaml9.default.stringify(normalized);
|
|
70242
|
-
if (
|
|
70382
|
+
if (existsSync10(path3)) {
|
|
70243
70383
|
const current2 = await readFile16(path3, "utf8");
|
|
70244
70384
|
const existing = parseAlignPayload(import_yaml9.default.parse(current2)).payload;
|
|
70245
70385
|
if (existing?.structure_digest !== payload.structure_digest) {
|
|
@@ -70255,14 +70395,14 @@ async function writeStructureSnapshot(projectRoot, payload) {
|
|
|
70255
70395
|
await updateSlots(projectRoot, payload);
|
|
70256
70396
|
return path3;
|
|
70257
70397
|
}
|
|
70258
|
-
await mkdir12(
|
|
70398
|
+
await mkdir12(dirname17(path3), { recursive: true });
|
|
70259
70399
|
await writeFile8(path3, content3, "utf8");
|
|
70260
70400
|
await updateSlots(projectRoot, payload);
|
|
70261
70401
|
return path3;
|
|
70262
70402
|
}
|
|
70263
70403
|
async function readStructureSnapshot(projectRoot, structureDigest) {
|
|
70264
70404
|
const path3 = snapshotPath(projectRoot, structureDigest);
|
|
70265
|
-
if (!
|
|
70405
|
+
if (!existsSync10(path3))
|
|
70266
70406
|
return null;
|
|
70267
70407
|
try {
|
|
70268
70408
|
return import_yaml9.default.parse(await readFile16(path3, "utf8"));
|
|
@@ -70290,8 +70430,8 @@ async function readStructureSnapshotPayload(projectRoot, structureDigest) {
|
|
|
70290
70430
|
return { ...record, structure_digest: structureDigest };
|
|
70291
70431
|
}
|
|
70292
70432
|
async function archiveActiveStructure(projectRoot) {
|
|
70293
|
-
const path3 =
|
|
70294
|
-
if (!
|
|
70433
|
+
const path3 = join19(projectRoot, LIFECYCLE_STRUCTURE_FILE);
|
|
70434
|
+
if (!existsSync10(path3))
|
|
70295
70435
|
return null;
|
|
70296
70436
|
let parsed;
|
|
70297
70437
|
try {
|
|
@@ -70319,7 +70459,7 @@ function structureSnapshotRelativePath(structureDigest) {
|
|
|
70319
70459
|
const match = STRUCTURE_DIGEST_PATTERN.exec(structureDigest);
|
|
70320
70460
|
if (match?.[1] === undefined)
|
|
70321
70461
|
return STRUCTURE_SNAPSHOT_ROOT;
|
|
70322
|
-
return
|
|
70462
|
+
return join19(STRUCTURE_SNAPSHOT_ROOT, `${match[1]}.yaml`);
|
|
70323
70463
|
}
|
|
70324
70464
|
async function currentStructureSlotDigest(projectRoot, source2, collection) {
|
|
70325
70465
|
return (await readSlots(projectRoot)).find((slot) => slot.source === source2 && slot.collection === collection)?.structure_digest;
|
|
@@ -70334,9 +70474,9 @@ async function activeStructureSlots(projectRoot, collection) {
|
|
|
70334
70474
|
|
|
70335
70475
|
// src/project/approvedStructureEdges.ts
|
|
70336
70476
|
var KNOWLEDGE_ROOT = "knowledge";
|
|
70337
|
-
var APPROVED_STRUCTURE_PATH =
|
|
70477
|
+
var APPROVED_STRUCTURE_PATH = join20(KNOWLEDGE_ROOT, "structure.yaml");
|
|
70338
70478
|
var STRUCTURE_EDGE_CONFIDENCE_SET = new Set(STRUCTURE_EDGE_CONFIDENCES);
|
|
70339
|
-
function
|
|
70479
|
+
function isRecord10(value) {
|
|
70340
70480
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
70341
70481
|
}
|
|
70342
70482
|
function readEdgeArray(structure) {
|
|
@@ -70346,7 +70486,7 @@ function normalizeApprovedEdges(input) {
|
|
|
70346
70486
|
const allowed = new Set(STRUCTURE_EDGE_TYPES);
|
|
70347
70487
|
const edges = [];
|
|
70348
70488
|
for (const [index2, rawEdge] of input.rawEdges.entries()) {
|
|
70349
|
-
if (!
|
|
70489
|
+
if (!isRecord10(rawEdge)) {
|
|
70350
70490
|
throw new ContextError(ExitCode.WorkspaceStateError, "structure edge must be an object", {
|
|
70351
70491
|
category: ErrorCategory.WorkspaceStateInvalid,
|
|
70352
70492
|
path: input.path,
|
|
@@ -70437,20 +70577,20 @@ function structureEndpointRefs(structure) {
|
|
|
70437
70577
|
const refs = [];
|
|
70438
70578
|
if (Array.isArray(structure.nodes)) {
|
|
70439
70579
|
for (const node3 of structure.nodes) {
|
|
70440
|
-
if (
|
|
70580
|
+
if (isRecord10(node3) && typeof node3.node_ref === "string")
|
|
70441
70581
|
refs.push(node3.node_ref);
|
|
70442
70582
|
}
|
|
70443
70583
|
}
|
|
70444
70584
|
if (Array.isArray(structure.views)) {
|
|
70445
70585
|
for (const view of structure.views) {
|
|
70446
|
-
if (!
|
|
70586
|
+
if (!isRecord10(view))
|
|
70447
70587
|
continue;
|
|
70448
70588
|
if (typeof view.view_ref === "string")
|
|
70449
70589
|
refs.push(view.view_ref);
|
|
70450
70590
|
if (!Array.isArray(view.sections))
|
|
70451
70591
|
continue;
|
|
70452
70592
|
for (const section of view.sections) {
|
|
70453
|
-
if (
|
|
70593
|
+
if (isRecord10(section) && typeof section.section_ref === "string")
|
|
70454
70594
|
refs.push(section.section_ref);
|
|
70455
70595
|
}
|
|
70456
70596
|
}
|
|
@@ -70458,12 +70598,12 @@ function structureEndpointRefs(structure) {
|
|
|
70458
70598
|
return refs;
|
|
70459
70599
|
}
|
|
70460
70600
|
async function readYamlRecord(projectRoot, relPath) {
|
|
70461
|
-
const absPath =
|
|
70462
|
-
if (!
|
|
70601
|
+
const absPath = join20(projectRoot, relPath);
|
|
70602
|
+
if (!existsSync11(absPath))
|
|
70463
70603
|
return null;
|
|
70464
70604
|
try {
|
|
70465
70605
|
const parsed = import_yaml10.default.parse(await readFile17(absPath, "utf8"));
|
|
70466
|
-
return
|
|
70606
|
+
return isRecord10(parsed) ? parsed : null;
|
|
70467
70607
|
} catch (error) {
|
|
70468
70608
|
throw new ContextError(ExitCode.WorkspaceStateError, `${relPath} is invalid YAML`, {
|
|
70469
70609
|
category: ErrorCategory.WorkspaceStateInvalid,
|
|
@@ -70502,7 +70642,7 @@ async function readConfirmedStructureEdgeProjection(projectRoot, approvedEndpoin
|
|
|
70502
70642
|
const snapshotEdges = [];
|
|
70503
70643
|
for (const structureDigest of [...new Set(slots.map((slot) => slot.structureDigest))].sort()) {
|
|
70504
70644
|
const structure2 = await readStructureSnapshot(projectRoot, structureDigest);
|
|
70505
|
-
if (!
|
|
70645
|
+
if (!isRecord10(structure2)) {
|
|
70506
70646
|
throw new ContextError(ExitCode.WorkspaceStateError, "active structure snapshot is missing", {
|
|
70507
70647
|
category: ErrorCategory.WorkspaceStateInvalid,
|
|
70508
70648
|
structure_digest: structureDigest,
|
|
@@ -70543,7 +70683,7 @@ async function readConfirmedStructureEdgeProjection(projectRoot, approvedEndpoin
|
|
|
70543
70683
|
}
|
|
70544
70684
|
if (structure === null)
|
|
70545
70685
|
return null;
|
|
70546
|
-
const lifecycle =
|
|
70686
|
+
const lifecycle = isRecord10(structure.lifecycle) ? structure.lifecycle : {};
|
|
70547
70687
|
if (lifecycle.state !== "confirmed" && lifecycle.state !== "frozen")
|
|
70548
70688
|
return null;
|
|
70549
70689
|
return normalizeApprovedEdges({
|
|
@@ -70559,15 +70699,15 @@ async function readConfirmedStructureEdgeProjection(projectRoot, approvedEndpoin
|
|
|
70559
70699
|
init_cliFeedback();
|
|
70560
70700
|
init_errors();
|
|
70561
70701
|
init_exitCode();
|
|
70562
|
-
import { existsSync as
|
|
70702
|
+
import { existsSync as existsSync18 } from "node:fs";
|
|
70563
70703
|
import { readFile as readFile23 } from "node:fs/promises";
|
|
70564
|
-
import { join as
|
|
70704
|
+
import { join as join28 } from "node:path";
|
|
70565
70705
|
|
|
70566
70706
|
// src/project/verifyApprovedStructure.ts
|
|
70567
70707
|
var import_yaml12 = __toESM(require_dist3(), 1);
|
|
70568
|
-
import { existsSync as
|
|
70708
|
+
import { existsSync as existsSync14 } from "node:fs";
|
|
70569
70709
|
import { readFile as readFile19 } from "node:fs/promises";
|
|
70570
|
-
import { join as
|
|
70710
|
+
import { join as join24 } from "node:path";
|
|
70571
70711
|
|
|
70572
70712
|
// src/project/approvedStructureInputHash.ts
|
|
70573
70713
|
import { createHash as createHash11 } from "node:crypto";
|
|
@@ -70608,11 +70748,11 @@ function approvedStructureInputHash(input) {
|
|
|
70608
70748
|
}
|
|
70609
70749
|
|
|
70610
70750
|
// src/project/verifyApprovedStructureEdges.ts
|
|
70611
|
-
import { join as
|
|
70751
|
+
import { join as join22 } from "node:path";
|
|
70612
70752
|
|
|
70613
70753
|
// src/project/verifyCanonicalSourceRefs.ts
|
|
70614
|
-
import { existsSync as
|
|
70615
|
-
import { join as
|
|
70754
|
+
import { existsSync as existsSync12 } from "node:fs";
|
|
70755
|
+
import { join as join21 } from "node:path";
|
|
70616
70756
|
var CANONICAL_SOURCE_REF = /^repo:([^#]+)#symbol:(.+):([^:@]+):([^:@]+)@([a-f0-9]+)$/iu;
|
|
70617
70757
|
function validateCanonicalSourceRef(input) {
|
|
70618
70758
|
const path3 = input.path ?? ".tmp/context-runtime/lifecycle/candidates.jsonl";
|
|
@@ -70668,7 +70808,7 @@ async function validateCanonicalEvidenceSourceRef(input) {
|
|
|
70668
70808
|
const registryEntry = input.sourceRegistry.loaded ? registeredDocumentSource(input.sourceRegistry, locator.sourceType, locator.sourceName) : undefined;
|
|
70669
70809
|
const materializedAt = registryEntry?.materializedAt ?? defaultDocumentMaterializedAt(locator.sourceType, locator.sourceName);
|
|
70670
70810
|
const manifestPath = registryEntry?.snapshot?.manifest ?? defaultDocumentManifest(materializedAt);
|
|
70671
|
-
if (!
|
|
70811
|
+
if (!existsSync12(join21(input.projectRoot, manifestPath)) && !snapshotRootExists(input.projectRoot, materializedAt)) {
|
|
70672
70812
|
input.issues.push({
|
|
70673
70813
|
severity: unresolvedSeverity,
|
|
70674
70814
|
code: "approved-evidence-unavailable",
|
|
@@ -70741,7 +70881,7 @@ async function validateCanonicalEvidenceSourceRef(input) {
|
|
|
70741
70881
|
}
|
|
70742
70882
|
|
|
70743
70883
|
// src/project/verifyApprovedStructureEdges.ts
|
|
70744
|
-
var APPROVED_STRUCTURE_PATH2 =
|
|
70884
|
+
var APPROVED_STRUCTURE_PATH2 = join22("knowledge", "structure.yaml");
|
|
70745
70885
|
function approvedStructureEdgeRecords(parsed, issues) {
|
|
70746
70886
|
if (parsed.edges === undefined)
|
|
70747
70887
|
return [];
|
|
@@ -70874,7 +71014,7 @@ async function validateApprovedStructureEdgeRecords(input) {
|
|
|
70874
71014
|
init_cliFeedback();
|
|
70875
71015
|
init_errors();
|
|
70876
71016
|
init_exitCode();
|
|
70877
|
-
function
|
|
71017
|
+
function isRecord11(value) {
|
|
70878
71018
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
70879
71019
|
}
|
|
70880
71020
|
function codegraphEdgesFromFrontmatter(frontmatter, path3) {
|
|
@@ -70887,7 +71027,7 @@ function codegraphEdgesFromFrontmatter(frontmatter, path3) {
|
|
|
70887
71027
|
});
|
|
70888
71028
|
}
|
|
70889
71029
|
return frontmatter.code_edges.map((rawEdge, index2) => {
|
|
70890
|
-
if (!
|
|
71030
|
+
if (!isRecord11(rawEdge)) {
|
|
70891
71031
|
throw new ContextError(ExitCode.WorkspaceStateError, "approved code edge must be an object", {
|
|
70892
71032
|
category: ErrorCategory.WorkspaceStateInvalid,
|
|
70893
71033
|
path: path3,
|
|
@@ -70947,17 +71087,17 @@ function codegraphRelationshipCoverage(input) {
|
|
|
70947
71087
|
}
|
|
70948
71088
|
|
|
70949
71089
|
// src/project/approvedStructureInputs.ts
|
|
70950
|
-
import { existsSync as
|
|
71090
|
+
import { existsSync as existsSync13 } from "node:fs";
|
|
70951
71091
|
import { readFile as readFile18 } from "node:fs/promises";
|
|
70952
|
-
import { join as
|
|
71092
|
+
import { join as join23 } from "node:path";
|
|
70953
71093
|
init_cliFeedback();
|
|
70954
71094
|
init_errors();
|
|
70955
71095
|
init_exitCode();
|
|
70956
71096
|
var import_yaml11 = __toESM(require_dist3(), 1);
|
|
70957
|
-
var APPROVED_STRUCTURE_FILE =
|
|
71097
|
+
var APPROVED_STRUCTURE_FILE = join23("knowledge", "structure.yaml");
|
|
70958
71098
|
var COLLECTIONS = new Set(KNOWLEDGE_COLLECTIONS);
|
|
70959
71099
|
var SNAPSHOT_HASH_PATTERN = /^sha256:[a-f0-9]{64}$/u;
|
|
70960
|
-
function
|
|
71100
|
+
function isRecord12(value) {
|
|
70961
71101
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
70962
71102
|
}
|
|
70963
71103
|
function invalidSourceInputs(reason) {
|
|
@@ -70976,14 +71116,14 @@ function sortedSourceInputs(values2) {
|
|
|
70976
71116
|
function parseApprovedStructureSourceInputs(structure) {
|
|
70977
71117
|
if (structure.source_inputs === undefined)
|
|
70978
71118
|
return [];
|
|
70979
|
-
if (!
|
|
71119
|
+
if (!isRecord12(structure.source_inputs)) {
|
|
70980
71120
|
throw invalidSourceInputs("source_inputs must be an object when present");
|
|
70981
71121
|
}
|
|
70982
71122
|
const inputs = new Map;
|
|
70983
71123
|
for (const [source2, collections] of Object.entries(structure.source_inputs)) {
|
|
70984
71124
|
if (source2.trim().length === 0)
|
|
70985
71125
|
throw invalidSourceInputs("source_inputs source key must not be empty");
|
|
70986
|
-
if (!
|
|
71126
|
+
if (!isRecord12(collections)) {
|
|
70987
71127
|
throw invalidSourceInputs(`source_inputs.${source2} must be an object`);
|
|
70988
71128
|
}
|
|
70989
71129
|
for (const [collection, snapshotHash] of Object.entries(collections)) {
|
|
@@ -71008,8 +71148,8 @@ function approvedStructureSourceInputsRecord(inputs) {
|
|
|
71008
71148
|
return result;
|
|
71009
71149
|
}
|
|
71010
71150
|
async function readApprovedStructureSourceInputs(projectRoot) {
|
|
71011
|
-
const path3 =
|
|
71012
|
-
if (!
|
|
71151
|
+
const path3 = join23(projectRoot, APPROVED_STRUCTURE_FILE);
|
|
71152
|
+
if (!existsSync13(path3))
|
|
71013
71153
|
return [];
|
|
71014
71154
|
let parsed;
|
|
71015
71155
|
try {
|
|
@@ -71017,7 +71157,7 @@ async function readApprovedStructureSourceInputs(projectRoot) {
|
|
|
71017
71157
|
} catch {
|
|
71018
71158
|
return [];
|
|
71019
71159
|
}
|
|
71020
|
-
if (!
|
|
71160
|
+
if (!isRecord12(parsed))
|
|
71021
71161
|
return [];
|
|
71022
71162
|
return parseApprovedStructureSourceInputs(parsed);
|
|
71023
71163
|
}
|
|
@@ -71046,14 +71186,14 @@ function approvedStructureSourceInputKey(input) {
|
|
|
71046
71186
|
}
|
|
71047
71187
|
|
|
71048
71188
|
// src/project/verifyApprovedStructure.ts
|
|
71049
|
-
var APPROVED_STRUCTURE_PATH3 =
|
|
71189
|
+
var APPROVED_STRUCTURE_PATH3 = join24("knowledge", "structure.yaml");
|
|
71050
71190
|
var APPROVED_STRUCTURE_SCHEMA_VERSION = "context.approved-structure.v1";
|
|
71051
71191
|
var LOCAL_REF = /^src-(\d+)(#(?:span|symbol):.+)$/u;
|
|
71052
71192
|
async function readApprovedStructureForVerify(input) {
|
|
71053
71193
|
if (input.structureOverride !== undefined)
|
|
71054
71194
|
return input.structureOverride;
|
|
71055
|
-
const structurePath =
|
|
71056
|
-
if (!
|
|
71195
|
+
const structurePath = join24(input.projectRoot, APPROVED_STRUCTURE_PATH3);
|
|
71196
|
+
if (!existsSync14(structurePath))
|
|
71057
71197
|
return;
|
|
71058
71198
|
let rawParsed;
|
|
71059
71199
|
try {
|
|
@@ -71278,7 +71418,7 @@ async function approvedStructureProjection(projectRoot) {
|
|
|
71278
71418
|
const views = [];
|
|
71279
71419
|
const parentIndexes = [];
|
|
71280
71420
|
const codeEdges = [];
|
|
71281
|
-
for (const file of await walkMarkdown(
|
|
71421
|
+
for (const file of await walkMarkdown(join24(projectRoot, "knowledge"))) {
|
|
71282
71422
|
if (isKnowledgeAssetPath(file.relPath))
|
|
71283
71423
|
continue;
|
|
71284
71424
|
const content3 = await readFile19(file.absPath, "utf8");
|
|
@@ -71692,13 +71832,13 @@ async function validateApprovedStructureEdges(input) {
|
|
|
71692
71832
|
init_workspace();
|
|
71693
71833
|
|
|
71694
71834
|
// src/project/reviewDecisions.ts
|
|
71695
|
-
import { existsSync as
|
|
71835
|
+
import { existsSync as existsSync17 } from "node:fs";
|
|
71696
71836
|
import { mkdir as mkdir15, readFile as readFile22, rename as rename3, rm as rm8, writeFile as writeFile11 } from "node:fs/promises";
|
|
71697
|
-
import { dirname as
|
|
71837
|
+
import { dirname as dirname20, join as join27 } from "node:path";
|
|
71698
71838
|
init_cliFeedback();
|
|
71699
71839
|
init_errors();
|
|
71700
71840
|
init_exitCode();
|
|
71701
|
-
var REVIEW_DECISIONS_FILE =
|
|
71841
|
+
var REVIEW_DECISIONS_FILE = join27("knowledge", "decisions.json");
|
|
71702
71842
|
var FINGERPRINT_PATTERN = /^sha256:[a-f0-9]{64}$/u;
|
|
71703
71843
|
var COLLECTIONS2 = new Set(KNOWLEDGE_COLLECTIONS);
|
|
71704
71844
|
function isCandidateId(value) {
|
|
@@ -71713,8 +71853,8 @@ function invalidDecisions(reason) {
|
|
|
71713
71853
|
});
|
|
71714
71854
|
}
|
|
71715
71855
|
async function readRejectedDecisions(projectRoot) {
|
|
71716
|
-
const path3 =
|
|
71717
|
-
if (!
|
|
71856
|
+
const path3 = join27(projectRoot, REVIEW_DECISIONS_FILE);
|
|
71857
|
+
if (!existsSync17(path3))
|
|
71718
71858
|
return new Map;
|
|
71719
71859
|
let parsed;
|
|
71720
71860
|
try {
|
|
@@ -71738,14 +71878,14 @@ async function readRejectedDecisions(projectRoot) {
|
|
|
71738
71878
|
return decisions;
|
|
71739
71879
|
}
|
|
71740
71880
|
async function writeRejectedDecisions(projectRoot, decisions) {
|
|
71741
|
-
const path3 =
|
|
71881
|
+
const path3 = join27(projectRoot, REVIEW_DECISIONS_FILE);
|
|
71742
71882
|
if (decisions.size === 0) {
|
|
71743
71883
|
await rm8(path3, { force: true });
|
|
71744
71884
|
return;
|
|
71745
71885
|
}
|
|
71746
71886
|
const rejected = Object.fromEntries([...decisions.entries()].sort(([left], [right]) => left.localeCompare(right)));
|
|
71747
71887
|
const tempPath = `${path3}.${process.pid}.tmp`;
|
|
71748
|
-
await mkdir15(
|
|
71888
|
+
await mkdir15(dirname20(path3), { recursive: true });
|
|
71749
71889
|
await writeFile11(tempPath, `${JSON.stringify(rejected, null, 2)}
|
|
71750
71890
|
`, "utf8");
|
|
71751
71891
|
await rename3(tempPath, path3);
|
|
@@ -71922,7 +72062,7 @@ async function verifyProjectWorkspace(projectRoot, options = {}) {
|
|
|
71922
72062
|
issues
|
|
71923
72063
|
});
|
|
71924
72064
|
const seenViewRefs = new Set;
|
|
71925
|
-
for (const file of await walkMarkdown(
|
|
72065
|
+
for (const file of await walkMarkdown(join28(projectRoot, "knowledge"))) {
|
|
71926
72066
|
if (isKnowledgeAssetPath(file.relPath))
|
|
71927
72067
|
continue;
|
|
71928
72068
|
const content3 = await readFile23(file.absPath, "utf8");
|
|
@@ -71945,7 +72085,7 @@ async function verifyProjectWorkspace(projectRoot, options = {}) {
|
|
|
71945
72085
|
pageRelPath: `knowledge/${file.relPath}`,
|
|
71946
72086
|
content: content3
|
|
71947
72087
|
})) {
|
|
71948
|
-
if (!
|
|
72088
|
+
if (!existsSync18(join28(projectRoot, assetPath))) {
|
|
71949
72089
|
issues.push({
|
|
71950
72090
|
severity: "error",
|
|
71951
72091
|
code: "approved-resource-missing",
|
|
@@ -72131,9 +72271,9 @@ init_writeLock();
|
|
|
72131
72271
|
|
|
72132
72272
|
// src/project/proseCompileBatch.ts
|
|
72133
72273
|
var import_yaml13 = __toESM(require_dist3(), 1);
|
|
72134
|
-
import { existsSync as
|
|
72274
|
+
import { existsSync as existsSync20 } from "node:fs";
|
|
72135
72275
|
import { readFile as readFile25 } from "node:fs/promises";
|
|
72136
|
-
import { join as
|
|
72276
|
+
import { join as join30 } from "node:path";
|
|
72137
72277
|
init_cliFeedback();
|
|
72138
72278
|
init_errors();
|
|
72139
72279
|
init_exitCode();
|
|
@@ -72142,9 +72282,9 @@ init_exitCode();
|
|
|
72142
72282
|
init_cliFeedback();
|
|
72143
72283
|
init_errors();
|
|
72144
72284
|
init_exitCode();
|
|
72145
|
-
import { existsSync as
|
|
72285
|
+
import { existsSync as existsSync19 } from "node:fs";
|
|
72146
72286
|
import { readFile as readFile24, readdir as readdir10 } from "node:fs/promises";
|
|
72147
|
-
import { basename as basename6, join as
|
|
72287
|
+
import { basename as basename6, join as join29, relative as relative12 } from "node:path";
|
|
72148
72288
|
init_writeLock();
|
|
72149
72289
|
function candidateSourceKey(record) {
|
|
72150
72290
|
return record.source === undefined ? undefined : `${record.source.type}:${record.source.name}`;
|
|
@@ -72156,11 +72296,11 @@ function toPosixPath8(value) {
|
|
|
72156
72296
|
return value.split(/[\\/]+/u).join("/");
|
|
72157
72297
|
}
|
|
72158
72298
|
async function approvedPageIdentities(projectRoot) {
|
|
72159
|
-
const root =
|
|
72299
|
+
const root = join29(projectRoot, "knowledge");
|
|
72160
72300
|
const identities = [];
|
|
72161
72301
|
const visit2 = async (directory) => {
|
|
72162
72302
|
for (const entry of await readdir10(directory, { withFileTypes: true })) {
|
|
72163
|
-
const absolutePath =
|
|
72303
|
+
const absolutePath = join29(directory, entry.name);
|
|
72164
72304
|
if (entry.isDirectory()) {
|
|
72165
72305
|
await visit2(absolutePath);
|
|
72166
72306
|
continue;
|
|
@@ -72178,7 +72318,7 @@ async function approvedPageIdentities(projectRoot) {
|
|
|
72178
72318
|
});
|
|
72179
72319
|
}
|
|
72180
72320
|
};
|
|
72181
|
-
if (
|
|
72321
|
+
if (existsSync19(root))
|
|
72182
72322
|
await visit2(root);
|
|
72183
72323
|
return {
|
|
72184
72324
|
byPath: new Map(identities.map((identity) => [identity.path, identity])),
|
|
@@ -72407,7 +72547,7 @@ async function preserveApprovedPathIdentities(input) {
|
|
|
72407
72547
|
}
|
|
72408
72548
|
|
|
72409
72549
|
// src/project/proseCompileBatch.ts
|
|
72410
|
-
function
|
|
72550
|
+
function isRecord14(value) {
|
|
72411
72551
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
72412
72552
|
}
|
|
72413
72553
|
function stringField2(value, field) {
|
|
@@ -72415,11 +72555,11 @@ function stringField2(value, field) {
|
|
|
72415
72555
|
return typeof candidate === "string" && candidate.trim().length > 0 ? candidate.trim() : undefined;
|
|
72416
72556
|
}
|
|
72417
72557
|
async function readConfirmedStructure(projectRoot) {
|
|
72418
|
-
const path3 =
|
|
72419
|
-
if (!
|
|
72558
|
+
const path3 = join30(projectRoot, LIFECYCLE_STRUCTURE_FILE);
|
|
72559
|
+
if (!existsSync20(path3))
|
|
72420
72560
|
return;
|
|
72421
72561
|
const parsed = import_yaml13.default.parse(await readFile25(path3, "utf8"));
|
|
72422
|
-
if (!
|
|
72562
|
+
if (!isRecord14(parsed) || !isRecord14(parsed.lifecycle))
|
|
72423
72563
|
return;
|
|
72424
72564
|
if (parsed.lifecycle.state !== "confirmed" && parsed.lifecycle.state !== "frozen")
|
|
72425
72565
|
return;
|
|
@@ -72434,7 +72574,7 @@ async function readCurrentSnapshotHashes(projectRoot) {
|
|
|
72434
72574
|
}
|
|
72435
72575
|
async function approvedViewRefs(projectRoot, planned) {
|
|
72436
72576
|
const approved = [];
|
|
72437
|
-
for (const file of await walkMarkdown(
|
|
72577
|
+
for (const file of await walkMarkdown(join30(projectRoot, "knowledge"))) {
|
|
72438
72578
|
if (isKnowledgeAssetPath(file.relPath))
|
|
72439
72579
|
continue;
|
|
72440
72580
|
const content3 = await readFile25(file.absPath, "utf8");
|
|
@@ -72702,7 +72842,7 @@ function proseCompileBatchNextAction(input) {
|
|
|
72702
72842
|
|
|
72703
72843
|
// src/project/lifecycleCleanup.ts
|
|
72704
72844
|
import { rm as rm9 } from "node:fs/promises";
|
|
72705
|
-
import { join as
|
|
72845
|
+
import { join as join31 } from "node:path";
|
|
72706
72846
|
var COMPLETED_RUNTIME_PATHS = [
|
|
72707
72847
|
LIFECYCLE_ROOT,
|
|
72708
72848
|
REVIEW_RUNTIME_ROOT,
|
|
@@ -72711,13 +72851,13 @@ var COMPLETED_RUNTIME_PATHS = [
|
|
|
72711
72851
|
CANDIDATE_SNAPSHOT_ROOT
|
|
72712
72852
|
];
|
|
72713
72853
|
async function clearCompletedLifecycle(projectRoot) {
|
|
72714
|
-
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 })));
|
|
72715
72855
|
}
|
|
72716
72856
|
|
|
72717
72857
|
// src/project/knowledgeAssetRepair.ts
|
|
72718
|
-
import { existsSync as
|
|
72858
|
+
import { existsSync as existsSync21 } from "node:fs";
|
|
72719
72859
|
import { mkdir as mkdir16, readFile as readFile26, writeFile as writeFile12 } from "node:fs/promises";
|
|
72720
|
-
import { dirname as
|
|
72860
|
+
import { dirname as dirname21, join as join32 } from "node:path";
|
|
72721
72861
|
init_cliFeedback();
|
|
72722
72862
|
init_errors();
|
|
72723
72863
|
init_exitCode();
|
|
@@ -72728,14 +72868,14 @@ function sourceLocators(frontmatter) {
|
|
|
72728
72868
|
])];
|
|
72729
72869
|
}
|
|
72730
72870
|
async function bytesEqual(path3, expected) {
|
|
72731
|
-
if (!
|
|
72871
|
+
if (!existsSync21(path3))
|
|
72732
72872
|
return false;
|
|
72733
72873
|
const actual = await readFile26(path3);
|
|
72734
72874
|
return actual.length === expected.length && actual.equals(Buffer.from(expected));
|
|
72735
72875
|
}
|
|
72736
72876
|
async function repairApprovedKnowledgeAssetProjections(projectRoot) {
|
|
72737
72877
|
const affected = [];
|
|
72738
|
-
for (const file of await walkMarkdown(
|
|
72878
|
+
for (const file of await walkMarkdown(join32(projectRoot, "knowledge"))) {
|
|
72739
72879
|
if (isKnowledgeAssetPath(file.relPath))
|
|
72740
72880
|
continue;
|
|
72741
72881
|
const content3 = await readFile26(file.absPath, "utf8");
|
|
@@ -72809,7 +72949,7 @@ async function repairApprovedKnowledgeAssetProjections(projectRoot) {
|
|
|
72809
72949
|
for (const asset of assets.values()) {
|
|
72810
72950
|
if (await bytesEqual(asset.absPath, asset.bytes))
|
|
72811
72951
|
continue;
|
|
72812
|
-
await mkdir16(
|
|
72952
|
+
await mkdir16(dirname21(asset.absPath), { recursive: true });
|
|
72813
72953
|
await writeFile12(asset.absPath, asset.bytes);
|
|
72814
72954
|
writtenAssets.push(asset.relPath);
|
|
72815
72955
|
}
|
|
@@ -72825,7 +72965,7 @@ async function repairApprovedKnowledgeAssetProjections(projectRoot) {
|
|
|
72825
72965
|
|
|
72826
72966
|
// src/project/close.ts
|
|
72827
72967
|
var KNOWLEDGE_ROOT2 = "knowledge";
|
|
72828
|
-
var STRUCTURE_PATH =
|
|
72968
|
+
var STRUCTURE_PATH = join33(KNOWLEDGE_ROOT2, "structure.yaml");
|
|
72829
72969
|
var STRUCTURE_SCHEMA_VERSION2 = "context.approved-structure.v1";
|
|
72830
72970
|
var LOCAL_REF2 = /^src-(\d+)(#(?:span|symbol):.+)$/u;
|
|
72831
72971
|
var APPROVED_NODE_TYPES2 = new Set(["entity", "domain", "action"]);
|
|
@@ -72855,13 +72995,13 @@ function requiredFrontmatterString(frontmatter, field, relPath) {
|
|
|
72855
72995
|
});
|
|
72856
72996
|
}
|
|
72857
72997
|
async function walkFiles2(root) {
|
|
72858
|
-
if (!
|
|
72998
|
+
if (!existsSync22(root))
|
|
72859
72999
|
return [];
|
|
72860
73000
|
const files = [];
|
|
72861
73001
|
const visit2 = async (dir) => {
|
|
72862
73002
|
const entries = await readdir11(dir, { withFileTypes: true });
|
|
72863
73003
|
for (const entry of entries) {
|
|
72864
|
-
const absPath =
|
|
73004
|
+
const absPath = join33(dir, entry.name);
|
|
72865
73005
|
if (entry.isDirectory()) {
|
|
72866
73006
|
await visit2(absPath);
|
|
72867
73007
|
continue;
|
|
@@ -72886,7 +73026,7 @@ function isDeprecated(content3) {
|
|
|
72886
73026
|
return parseFrontmatter3(content3).deprecated === true;
|
|
72887
73027
|
}
|
|
72888
73028
|
async function approvedKnowledgeFiles(projectRoot) {
|
|
72889
|
-
const files = await walkFiles2(
|
|
73029
|
+
const files = await walkFiles2(join33(projectRoot, KNOWLEDGE_ROOT2));
|
|
72890
73030
|
const markdown = await Promise.all(files.filter((file) => file.relPath.endsWith(".md") && !isKnowledgeAssetPath(file.relPath)).map(async (file) => ({
|
|
72891
73031
|
...file,
|
|
72892
73032
|
content: await readFile27(file.absPath, "utf8")
|
|
@@ -73156,11 +73296,11 @@ function referencesReceipt() {
|
|
|
73156
73296
|
}
|
|
73157
73297
|
async function readProjectCloseStatus(projectRoot) {
|
|
73158
73298
|
const approved = await approvedKnowledgeFiles(projectRoot);
|
|
73159
|
-
const structurePath =
|
|
73160
|
-
if (approved.length === 0 && !
|
|
73299
|
+
const structurePath = join33(projectRoot, STRUCTURE_PATH);
|
|
73300
|
+
if (approved.length === 0 && !existsSync22(structurePath))
|
|
73161
73301
|
return { state: "missing", diagnostics: [] };
|
|
73162
73302
|
const inputHash = await approvedKnowledgeInputHash(projectRoot);
|
|
73163
|
-
if (!
|
|
73303
|
+
if (!existsSync22(structurePath))
|
|
73164
73304
|
return { state: "missing", inputHash, diagnostics: [`close structure is missing: ${STRUCTURE_PATH}`] };
|
|
73165
73305
|
try {
|
|
73166
73306
|
const parsed = import_yaml14.default.parse(await readFile27(structurePath, "utf8"));
|
|
@@ -73229,8 +73369,8 @@ async function closeProjectWorkspace(projectRoot) {
|
|
|
73229
73369
|
next: "Fix context verify errors, then rerun context close --format json."
|
|
73230
73370
|
});
|
|
73231
73371
|
}
|
|
73232
|
-
const outputPath =
|
|
73233
|
-
await mkdir17(
|
|
73372
|
+
const outputPath = join33(projectRoot, STRUCTURE_PATH);
|
|
73373
|
+
await mkdir17(dirname22(outputPath), { recursive: true });
|
|
73234
73374
|
await writeFile13(outputPath, `${import_yaml14.default.stringify(structure)}`, "utf8");
|
|
73235
73375
|
await clearCompletedLifecycle(projectRoot);
|
|
73236
73376
|
return {
|
|
@@ -73279,22 +73419,33 @@ async function runProjectCloseCommand(input) {
|
|
|
73279
73419
|
].join(`
|
|
73280
73420
|
`));
|
|
73281
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
|
+
});
|
|
73282
73433
|
return true;
|
|
73283
73434
|
}
|
|
73284
73435
|
|
|
73285
73436
|
// src/project/reviewApply.ts
|
|
73286
|
-
import { existsSync as
|
|
73437
|
+
import { existsSync as existsSync27 } from "node:fs";
|
|
73287
73438
|
import { mkdir as mkdir22, readFile as readFile34, rm as rm11, writeFile as writeFile18 } from "node:fs/promises";
|
|
73288
|
-
import { dirname as
|
|
73439
|
+
import { dirname as dirname27, join as join42 } from "node:path";
|
|
73289
73440
|
init_cliFeedback();
|
|
73290
73441
|
init_errors();
|
|
73291
73442
|
init_exitCode();
|
|
73292
73443
|
|
|
73293
73444
|
// src/project/proseCompileStructure.ts
|
|
73294
73445
|
import { createHash as createHash15 } from "node:crypto";
|
|
73295
|
-
import { existsSync as
|
|
73446
|
+
import { existsSync as existsSync25 } from "node:fs";
|
|
73296
73447
|
import { mkdir as mkdir20, readFile as readFile32, writeFile as writeFile16 } from "node:fs/promises";
|
|
73297
|
-
import { dirname as
|
|
73448
|
+
import { dirname as dirname25, join as join40 } from "node:path";
|
|
73298
73449
|
init_cliFeedback();
|
|
73299
73450
|
init_errors();
|
|
73300
73451
|
init_exitCode();
|
|
@@ -73303,7 +73454,7 @@ var import_yaml20 = __toESM(require_dist3(), 1);
|
|
|
73303
73454
|
// src/project/proseAlignEvidence.ts
|
|
73304
73455
|
import { createHash as createHash13 } from "node:crypto";
|
|
73305
73456
|
import { readFile as readFile28 } from "node:fs/promises";
|
|
73306
|
-
import { join as
|
|
73457
|
+
import { join as join34 } from "node:path";
|
|
73307
73458
|
|
|
73308
73459
|
// src/incremental/rawBlocks.ts
|
|
73309
73460
|
var import_yaml15 = __toESM(require_dist3(), 1);
|
|
@@ -77198,7 +77349,7 @@ async function loadProseEvidence(input) {
|
|
|
77198
77349
|
const documents = [];
|
|
77199
77350
|
const chunks = [];
|
|
77200
77351
|
for (const [documentIndex, document4] of indexResult.index.documents.entries()) {
|
|
77201
|
-
const markdown = await readFile28(
|
|
77352
|
+
const markdown = await readFile28(join34(input.projectRoot, indexResult.index.materialized_at, document4.path), "utf8");
|
|
77202
77353
|
const locator = locatorFor({
|
|
77203
77354
|
sourceType: resolved.sourceType,
|
|
77204
77355
|
sourceName: resolved.sourceName,
|
|
@@ -77673,19 +77824,19 @@ function repairHints(diagnostics, phaseId) {
|
|
|
77673
77824
|
|
|
77674
77825
|
// src/project/proseAlignStructureSummary.ts
|
|
77675
77826
|
import { mkdir as mkdir18, writeFile as writeFile14 } from "node:fs/promises";
|
|
77676
|
-
import { dirname as
|
|
77827
|
+
import { dirname as dirname23, join as join37 } from "node:path";
|
|
77677
77828
|
|
|
77678
77829
|
// src/project/proseAlignExistingApprovedStructure.ts
|
|
77679
77830
|
var import_yaml16 = __toESM(require_dist3(), 1);
|
|
77680
|
-
import { existsSync as
|
|
77831
|
+
import { existsSync as existsSync23 } from "node:fs";
|
|
77681
77832
|
import { readFile as readFile29, readdir as readdir12 } from "node:fs/promises";
|
|
77682
|
-
import { basename as basename7, join as
|
|
77683
|
-
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");
|
|
77684
77835
|
var KNOWLEDGE_ROOT3 = "knowledge";
|
|
77685
77836
|
function uniqueRefs(refs) {
|
|
77686
77837
|
return [...new Set(refs)].sort();
|
|
77687
77838
|
}
|
|
77688
|
-
function
|
|
77839
|
+
function isRecord15(value) {
|
|
77689
77840
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
77690
77841
|
}
|
|
77691
77842
|
function stringField3(record, key) {
|
|
@@ -77702,14 +77853,14 @@ function toPosixPath10(path4) {
|
|
|
77702
77853
|
return path4.split(/[\\/]+/u).join("/");
|
|
77703
77854
|
}
|
|
77704
77855
|
async function approvedMarkdownFiles(projectRoot) {
|
|
77705
|
-
const root2 =
|
|
77706
|
-
if (!
|
|
77856
|
+
const root2 = join35(projectRoot, KNOWLEDGE_ROOT3);
|
|
77857
|
+
if (!existsSync23(root2))
|
|
77707
77858
|
return [];
|
|
77708
77859
|
const files = [];
|
|
77709
77860
|
const visit3 = async (directory) => {
|
|
77710
77861
|
const entries = await readdir12(directory, { withFileTypes: true });
|
|
77711
77862
|
for (const entry of entries) {
|
|
77712
|
-
const absolutePath =
|
|
77863
|
+
const absolutePath = join35(directory, entry.name);
|
|
77713
77864
|
if (entry.isDirectory()) {
|
|
77714
77865
|
await visit3(absolutePath);
|
|
77715
77866
|
continue;
|
|
@@ -77726,7 +77877,7 @@ function frontmatterRecord(markdown) {
|
|
|
77726
77877
|
if (match === null)
|
|
77727
77878
|
return;
|
|
77728
77879
|
const parsed = import_yaml16.default.parse(match[1] ?? "");
|
|
77729
|
-
return
|
|
77880
|
+
return isRecord15(parsed) ? parsed : undefined;
|
|
77730
77881
|
}
|
|
77731
77882
|
function isDeprecatedApprovedPage(markdown) {
|
|
77732
77883
|
return /^deprecated:\s*true\s*$/mu.test(markdown);
|
|
@@ -77775,7 +77926,7 @@ async function parseExistingApprovedMarkdown(projectRoot) {
|
|
|
77775
77926
|
node_type: existingNode?.node_type ?? nodeType,
|
|
77776
77927
|
tags: uniqueRefs([...existingNode?.tags ?? [], ...nodeTags])
|
|
77777
77928
|
});
|
|
77778
|
-
const relPath = toPosixPath10(relative14(
|
|
77929
|
+
const relPath = toPosixPath10(relative14(join35(projectRoot, KNOWLEDGE_ROOT3), filePath));
|
|
77779
77930
|
const location = pathLocation(relPath);
|
|
77780
77931
|
const collection = viewRef.split(":", 1)[0] ?? location.collection;
|
|
77781
77932
|
views.set(viewRef, {
|
|
@@ -77804,8 +77955,8 @@ async function parseExistingApprovedMarkdown(projectRoot) {
|
|
|
77804
77955
|
return { nodes, views, sections, edges: [], diagnostics: [] };
|
|
77805
77956
|
}
|
|
77806
77957
|
async function readFreshApprovedStructureEdges(projectRoot) {
|
|
77807
|
-
const absolutePath =
|
|
77808
|
-
if (!
|
|
77958
|
+
const absolutePath = join35(projectRoot, APPROVED_STRUCTURE_PATH4);
|
|
77959
|
+
if (!existsSync23(absolutePath))
|
|
77809
77960
|
return { edges: [], diagnostics: [] };
|
|
77810
77961
|
let raw;
|
|
77811
77962
|
try {
|
|
@@ -77814,7 +77965,7 @@ async function readFreshApprovedStructureEdges(projectRoot) {
|
|
|
77814
77965
|
const message = error instanceof Error ? error.message : String(error);
|
|
77815
77966
|
return { edges: [], diagnostics: [`knowledge/structure.yaml could not be parsed: ${message}`] };
|
|
77816
77967
|
}
|
|
77817
|
-
if (!
|
|
77968
|
+
if (!isRecord15(raw) || raw.schema_version !== "context.approved-structure.v1") {
|
|
77818
77969
|
return { edges: [], diagnostics: ["knowledge/structure.yaml schema is not current; approved summary uses Markdown projection only."] };
|
|
77819
77970
|
}
|
|
77820
77971
|
const expectedInputHash = await approvedKnowledgeInputHash(projectRoot).catch(() => {
|
|
@@ -77848,7 +77999,7 @@ function emptyExistingApprovedStructureSummary(diagnostics = []) {
|
|
|
77848
77999
|
function parseApprovedEdges(raw) {
|
|
77849
78000
|
const edges = [];
|
|
77850
78001
|
for (const rawEdge of Array.isArray(raw.edges) ? raw.edges : []) {
|
|
77851
|
-
if (!
|
|
78002
|
+
if (!isRecord15(rawEdge))
|
|
77852
78003
|
continue;
|
|
77853
78004
|
const type = stringField3(rawEdge, "type");
|
|
77854
78005
|
const from = stringField3(rawEdge, "from");
|
|
@@ -77918,7 +78069,7 @@ async function readExistingApprovedStructureSummary(input) {
|
|
|
77918
78069
|
const freshStructure = await readFreshApprovedStructureEdges(input.projectRoot);
|
|
77919
78070
|
approved.edges = freshStructure.edges;
|
|
77920
78071
|
approved.diagnostics.push(...freshStructure.diagnostics);
|
|
77921
|
-
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))) {
|
|
77922
78073
|
return emptyExistingApprovedStructureSummary();
|
|
77923
78074
|
}
|
|
77924
78075
|
const endpointRefs = new Set([
|
|
@@ -79026,12 +79177,12 @@ function renderStructureSummaryHtml(input) {
|
|
|
79026
79177
|
|
|
79027
79178
|
// src/project/localHtmlReport.ts
|
|
79028
79179
|
import { execFile as execFile3 } from "node:child_process";
|
|
79029
|
-
import { isAbsolute as isAbsolute7, join as
|
|
79180
|
+
import { isAbsolute as isAbsolute7, join as join36 } from "node:path";
|
|
79030
79181
|
import { pathToFileURL } from "node:url";
|
|
79031
79182
|
import { promisify as promisify3 } from "node:util";
|
|
79032
79183
|
var execFileAsync3 = promisify3(execFile3);
|
|
79033
79184
|
function htmlReportReference(input) {
|
|
79034
|
-
const absolutePath = isAbsolute7(input.path) ? input.path :
|
|
79185
|
+
const absolutePath = isAbsolute7(input.path) ? input.path : join36(input.projectRoot, input.path);
|
|
79035
79186
|
return {
|
|
79036
79187
|
format: "html",
|
|
79037
79188
|
path: input.path,
|
|
@@ -79377,9 +79528,9 @@ function buildStructureSummary(input) {
|
|
|
79377
79528
|
async function writeStructureSummaryReport(input) {
|
|
79378
79529
|
const summary = buildStructureSummary(input);
|
|
79379
79530
|
const shortDigest = summary.structure_digest.replace(/^sha256:/u, "").slice(0, 16);
|
|
79380
|
-
const reportPath =
|
|
79381
|
-
const absolutePath =
|
|
79382
|
-
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 });
|
|
79383
79534
|
await writeFile14(absolutePath, renderStructureSummaryHtml({ summary, diagnostics: input.diagnostics }), "utf8");
|
|
79384
79535
|
return {
|
|
79385
79536
|
summary,
|
|
@@ -79554,9 +79705,9 @@ function withStructureReviewArtifacts(input) {
|
|
|
79554
79705
|
// src/project/proseCompileViews.ts
|
|
79555
79706
|
var import_yaml17 = __toESM(require_dist3(), 1);
|
|
79556
79707
|
import { createHash as createHash14 } from "node:crypto";
|
|
79557
|
-
import { existsSync as
|
|
79708
|
+
import { existsSync as existsSync24 } from "node:fs";
|
|
79558
79709
|
import { readFile as readFile30 } from "node:fs/promises";
|
|
79559
|
-
import { join as
|
|
79710
|
+
import { join as join38 } from "node:path";
|
|
79560
79711
|
|
|
79561
79712
|
// src/project/proseCompileSemanticRules.ts
|
|
79562
79713
|
function compileSemanticRules(input) {
|
|
@@ -79959,8 +80110,8 @@ function canonicalizeApprovedSourceRef2(ref2, sources) {
|
|
|
79959
80110
|
}
|
|
79960
80111
|
async function existingApprovedNodeSections(input) {
|
|
79961
80112
|
const relativePath = `knowledge/${input.node.path}`;
|
|
79962
|
-
const absolutePath =
|
|
79963
|
-
if (!
|
|
80113
|
+
const absolutePath = join38(input.projectRoot, relativePath);
|
|
80114
|
+
if (!existsSync24(absolutePath)) {
|
|
79964
80115
|
return {
|
|
79965
80116
|
path: relativePath,
|
|
79966
80117
|
present: false,
|
|
@@ -80342,7 +80493,7 @@ function parsePayloadText(raw) {
|
|
|
80342
80493
|
// src/project/proseAlignPayloadStage.ts
|
|
80343
80494
|
var import_yaml19 = __toESM(require_dist3(), 1);
|
|
80344
80495
|
import { mkdir as mkdir19, writeFile as writeFile15 } from "node:fs/promises";
|
|
80345
|
-
import { dirname as
|
|
80496
|
+
import { dirname as dirname24, join as join39 } from "node:path";
|
|
80346
80497
|
init_writeLock();
|
|
80347
80498
|
async function resolveStagedPayloadConfirmation(input) {
|
|
80348
80499
|
await archiveActiveStructure(input.projectRoot);
|
|
@@ -80413,7 +80564,7 @@ async function stageAlignPayload(input) {
|
|
|
80413
80564
|
next: readPlanCommand
|
|
80414
80565
|
});
|
|
80415
80566
|
}
|
|
80416
|
-
const structurePath =
|
|
80567
|
+
const structurePath = join39(input.projectRoot, LIFECYCLE_STRUCTURE_FILE);
|
|
80417
80568
|
const resolved = await resolveStagedPayloadConfirmation(input);
|
|
80418
80569
|
const effectivePayload = {
|
|
80419
80570
|
...resolved.payload,
|
|
@@ -80425,7 +80576,7 @@ async function stageAlignPayload(input) {
|
|
|
80425
80576
|
if (effectivePayload.lifecycle.state === "confirmed" || effectivePayload.lifecycle.state === "frozen") {
|
|
80426
80577
|
await writeStructureSnapshot(input.projectRoot, effectivePayload);
|
|
80427
80578
|
}
|
|
80428
|
-
await mkdir19(
|
|
80579
|
+
await mkdir19(dirname24(structurePath), { recursive: true });
|
|
80429
80580
|
await writeFile15(structurePath, import_yaml19.default.stringify(normalizeAlignPayloadForWrite(effectivePayload)), "utf8");
|
|
80430
80581
|
return {
|
|
80431
80582
|
structureFile: LIFECYCLE_STRUCTURE_FILE,
|
|
@@ -80941,7 +81092,7 @@ function canonicalJson2(value) {
|
|
|
80941
81092
|
function digest3(value) {
|
|
80942
81093
|
return `sha256:${createHash15("sha256").update(canonicalJson2(value)).digest("hex")}`;
|
|
80943
81094
|
}
|
|
80944
|
-
function
|
|
81095
|
+
function isRecord16(value) {
|
|
80945
81096
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
80946
81097
|
}
|
|
80947
81098
|
function stringField4(record, field) {
|
|
@@ -80952,8 +81103,8 @@ function stringArray2(value) {
|
|
|
80952
81103
|
return Array.isArray(value) ? value.filter((item) => typeof item === "string" && item.trim().length > 0) : [];
|
|
80953
81104
|
}
|
|
80954
81105
|
async function readStructureFile(projectRoot) {
|
|
80955
|
-
const structurePath =
|
|
80956
|
-
if (!
|
|
81106
|
+
const structurePath = join40(projectRoot, LIFECYCLE_STRUCTURE_FILE);
|
|
81107
|
+
if (!existsSync25(structurePath)) {
|
|
80957
81108
|
return null;
|
|
80958
81109
|
}
|
|
80959
81110
|
let raw;
|
|
@@ -80978,8 +81129,8 @@ async function readStructureFile(projectRoot) {
|
|
|
80978
81129
|
}
|
|
80979
81130
|
}
|
|
80980
81131
|
async function readApprovedStructureFile(projectRoot) {
|
|
80981
|
-
const structurePath =
|
|
80982
|
-
if (!
|
|
81132
|
+
const structurePath = join40(projectRoot, APPROVED_STRUCTURE_FILE2);
|
|
81133
|
+
if (!existsSync25(structurePath))
|
|
80983
81134
|
return null;
|
|
80984
81135
|
try {
|
|
80985
81136
|
return import_yaml20.default.parse(await readFile32(structurePath, "utf8"));
|
|
@@ -80994,13 +81145,13 @@ async function readApprovedStructureFile(projectRoot) {
|
|
|
80994
81145
|
async function compileStructureSlotDigest(input) {
|
|
80995
81146
|
const slotDigest = await currentStructureSlotDigest(input.projectRoot, input.sourceKey, input.collection);
|
|
80996
81147
|
const current2 = await readStructureFile(input.projectRoot);
|
|
80997
|
-
if (current2 === null || !
|
|
81148
|
+
if (current2 === null || !isRecord16(current2) || !Array.isArray(current2.sources) || !Array.isArray(current2.views)) {
|
|
80998
81149
|
return slotDigest;
|
|
80999
81150
|
}
|
|
81000
|
-
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);
|
|
81001
81152
|
if (!currentOwnsTarget)
|
|
81002
81153
|
return slotDigest;
|
|
81003
|
-
const lifecycle =
|
|
81154
|
+
const lifecycle = isRecord16(current2.lifecycle) ? current2.lifecycle : undefined;
|
|
81004
81155
|
const currentDigest = lifecycle === undefined ? undefined : stringField4(lifecycle, "structure_digest");
|
|
81005
81156
|
return slotDigest !== undefined && slotDigest !== currentDigest ? slotDigest : undefined;
|
|
81006
81157
|
}
|
|
@@ -81009,7 +81160,7 @@ function parseApprovedSections(value, viewRef) {
|
|
|
81009
81160
|
return [];
|
|
81010
81161
|
const sections = [];
|
|
81011
81162
|
for (const rawSection of value) {
|
|
81012
|
-
if (!
|
|
81163
|
+
if (!isRecord16(rawSection))
|
|
81013
81164
|
continue;
|
|
81014
81165
|
const id2 = stringField4(rawSection, "id");
|
|
81015
81166
|
const kind = stringField4(rawSection, "kind");
|
|
@@ -81032,7 +81183,7 @@ function parseApprovedNodes(value) {
|
|
|
81032
81183
|
return [];
|
|
81033
81184
|
const nodes = [];
|
|
81034
81185
|
for (const rawNode of value) {
|
|
81035
|
-
if (!
|
|
81186
|
+
if (!isRecord16(rawNode))
|
|
81036
81187
|
continue;
|
|
81037
81188
|
const nodeRef = stringField4(rawNode, "node_ref");
|
|
81038
81189
|
const title = stringField4(rawNode, "title");
|
|
@@ -81056,7 +81207,7 @@ function parseApprovedViews(value, nodes) {
|
|
|
81056
81207
|
const nodeByRef = new Map(nodes.map((node3) => [node3.node_ref, node3]));
|
|
81057
81208
|
const views = [];
|
|
81058
81209
|
for (const rawView of value) {
|
|
81059
|
-
if (!
|
|
81210
|
+
if (!isRecord16(rawView))
|
|
81060
81211
|
continue;
|
|
81061
81212
|
const viewRef = stringField4(rawView, "view_ref");
|
|
81062
81213
|
const nodeRef = stringField4(rawView, "node_ref");
|
|
@@ -81094,7 +81245,7 @@ function parseApprovedEdges2(value) {
|
|
|
81094
81245
|
return [];
|
|
81095
81246
|
const edges = [];
|
|
81096
81247
|
for (const rawEdge of value) {
|
|
81097
|
-
if (!
|
|
81248
|
+
if (!isRecord16(rawEdge))
|
|
81098
81249
|
continue;
|
|
81099
81250
|
const type = stringField4(rawEdge, "type");
|
|
81100
81251
|
const from = stringField4(rawEdge, "from");
|
|
@@ -81158,7 +81309,7 @@ function assertApprovedEdgeContract(value, endpointRefs) {
|
|
|
81158
81309
|
});
|
|
81159
81310
|
}
|
|
81160
81311
|
for (const [index2, rawEdge] of value.entries()) {
|
|
81161
|
-
if (!
|
|
81312
|
+
if (!isRecord16(rawEdge)) {
|
|
81162
81313
|
throw workspaceError("knowledge/structure.yaml edge must be an object", {
|
|
81163
81314
|
path: APPROVED_STRUCTURE_FILE2,
|
|
81164
81315
|
edge_index: index2,
|
|
@@ -81298,7 +81449,7 @@ async function loadConfirmedStructure(input) {
|
|
|
81298
81449
|
let rawStructure = input.structureDigest === undefined ? await readStructureFile(input.projectRoot) : await readStructureSnapshot(input.projectRoot, input.structureDigest);
|
|
81299
81450
|
if (rawStructure === null && input.structureDigest !== undefined) {
|
|
81300
81451
|
const active = await readStructureFile(input.projectRoot);
|
|
81301
|
-
const activeDigest =
|
|
81452
|
+
const activeDigest = isRecord16(active) && isRecord16(active.lifecycle) ? stringField4(active.lifecycle, "structure_digest") : undefined;
|
|
81302
81453
|
if (activeDigest === input.structureDigest) {
|
|
81303
81454
|
rawStructure = active;
|
|
81304
81455
|
} else if (input.readOnly !== true) {
|
|
@@ -81315,7 +81466,7 @@ async function loadConfirmedStructure(input) {
|
|
|
81315
81466
|
});
|
|
81316
81467
|
}
|
|
81317
81468
|
const approvedStructure = await readApprovedStructureFile(input.projectRoot);
|
|
81318
|
-
if (!
|
|
81469
|
+
if (!isRecord16(approvedStructure)) {
|
|
81319
81470
|
throw workspaceError("compileProse requires confirmed .tmp/context-runtime/lifecycle/structure.yaml or approved knowledge/structure.yaml", {
|
|
81320
81471
|
path: LIFECYCLE_STRUCTURE_FILE,
|
|
81321
81472
|
approved_structure: APPROVED_STRUCTURE_FILE2,
|
|
@@ -81411,8 +81562,8 @@ async function freezeStructureIfNeeded(input) {
|
|
|
81411
81562
|
};
|
|
81412
81563
|
await archiveActiveStructure(input.projectRoot);
|
|
81413
81564
|
await writeStructureSnapshot(input.projectRoot, nextStructure);
|
|
81414
|
-
const structurePath =
|
|
81415
|
-
await mkdir20(
|
|
81565
|
+
const structurePath = join40(input.projectRoot, LIFECYCLE_STRUCTURE_FILE);
|
|
81566
|
+
await mkdir20(dirname25(structurePath), { recursive: true });
|
|
81416
81567
|
await writeFile16(structurePath, import_yaml20.default.stringify({
|
|
81417
81568
|
schema_version: nextStructure.schema_version,
|
|
81418
81569
|
sources: nextStructure.sources,
|
|
@@ -81495,9 +81646,9 @@ var import_yaml22 = __toESM(require_dist3(), 1);
|
|
|
81495
81646
|
|
|
81496
81647
|
// src/project/reviewShared.ts
|
|
81497
81648
|
import { createHash as createHash16 } from "node:crypto";
|
|
81498
|
-
import { existsSync as
|
|
81649
|
+
import { existsSync as existsSync26, readdirSync as readdirSync2, readFileSync as readFileSync7 } from "node:fs";
|
|
81499
81650
|
import { mkdir as mkdir21, readFile as readFile33, rm as rm10, rmdir as rmdir2, writeFile as writeFile17 } from "node:fs/promises";
|
|
81500
|
-
import { dirname as
|
|
81651
|
+
import { dirname as dirname26, join as join41 } from "node:path";
|
|
81501
81652
|
init_cliFeedback();
|
|
81502
81653
|
init_errors();
|
|
81503
81654
|
init_exitCode();
|
|
@@ -81527,10 +81678,10 @@ function proseCandidateMarkdown(input) {
|
|
|
81527
81678
|
|
|
81528
81679
|
// src/project/reviewShared.ts
|
|
81529
81680
|
init_workspace();
|
|
81530
|
-
var SNAPSHOT_ROOT2 =
|
|
81531
|
-
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");
|
|
81532
81683
|
var REVIEW_PAYLOAD_SCHEMA = "context.review.decisions.v1";
|
|
81533
|
-
function
|
|
81684
|
+
function isRecord17(value) {
|
|
81534
81685
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
81535
81686
|
}
|
|
81536
81687
|
function assertCollection(value) {
|
|
@@ -81551,26 +81702,26 @@ function assertCollection(value) {
|
|
|
81551
81702
|
}
|
|
81552
81703
|
function snapshotPath2(projectRoot, candidateId) {
|
|
81553
81704
|
assertSafeEntityId(candidateId);
|
|
81554
|
-
return
|
|
81705
|
+
return join41(projectRoot, SNAPSHOT_ROOT2, `${candidateId}.json`);
|
|
81555
81706
|
}
|
|
81556
81707
|
async function readCandidateSnapshot(projectRoot, candidateId) {
|
|
81557
81708
|
const file = snapshotPath2(projectRoot, candidateId);
|
|
81558
|
-
if (!
|
|
81709
|
+
if (!existsSync26(file))
|
|
81559
81710
|
return;
|
|
81560
81711
|
let parsed;
|
|
81561
81712
|
try {
|
|
81562
81713
|
parsed = JSON.parse(await readFile33(file, "utf8"));
|
|
81563
81714
|
} catch (error) {
|
|
81564
81715
|
const message = error instanceof Error ? error.message : String(error);
|
|
81565
|
-
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`)}`, {
|
|
81566
81717
|
category: ErrorCategory.SchemaInvalid,
|
|
81567
81718
|
candidate_id: candidateId,
|
|
81568
81719
|
reason: message,
|
|
81569
81720
|
next: "Rerun the extract phase before reviewing this candidate."
|
|
81570
81721
|
});
|
|
81571
81722
|
}
|
|
81572
|
-
if (!
|
|
81573
|
-
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`)}`, {
|
|
81574
81725
|
category: ErrorCategory.SchemaInvalid,
|
|
81575
81726
|
candidate_id: candidateId,
|
|
81576
81727
|
next: "Rerun the extract phase before reviewing this candidate."
|
|
@@ -81601,15 +81752,15 @@ async function extractCandidateSnapshotIsCurrent(projectRoot, snapshot) {
|
|
|
81601
81752
|
async function removeCandidateSnapshot2(projectRoot, candidateId) {
|
|
81602
81753
|
const file = snapshotPath2(projectRoot, candidateId);
|
|
81603
81754
|
await rm10(file, { force: true });
|
|
81604
|
-
const snapshotRoot =
|
|
81605
|
-
let current2 =
|
|
81755
|
+
const snapshotRoot = join41(projectRoot, SNAPSHOT_ROOT2);
|
|
81756
|
+
let current2 = dirname26(file);
|
|
81606
81757
|
while (current2 !== snapshotRoot && current2.startsWith(snapshotRoot)) {
|
|
81607
81758
|
try {
|
|
81608
81759
|
await rmdir2(current2);
|
|
81609
81760
|
} catch {
|
|
81610
81761
|
break;
|
|
81611
81762
|
}
|
|
81612
|
-
current2 =
|
|
81763
|
+
current2 = dirname26(current2);
|
|
81613
81764
|
}
|
|
81614
81765
|
}
|
|
81615
81766
|
function parseCanonicalSourceRef(ref2) {
|
|
@@ -81730,11 +81881,11 @@ function findApprovedPageForViewRef(projectRoot, viewRef) {
|
|
|
81730
81881
|
}
|
|
81731
81882
|
const nodeRef = viewRef.slice(separator + 1);
|
|
81732
81883
|
assertSafeEntityId(nodeRef);
|
|
81733
|
-
const collectionRoot =
|
|
81734
|
-
if (
|
|
81884
|
+
const collectionRoot = join41(projectRoot, "knowledge", collection);
|
|
81885
|
+
if (existsSync26(collectionRoot)) {
|
|
81735
81886
|
const visit3 = (dir, relDir) => {
|
|
81736
81887
|
for (const entry of readdirSync2(dir, { withFileTypes: true })) {
|
|
81737
|
-
const absPath =
|
|
81888
|
+
const absPath = join41(dir, entry.name);
|
|
81738
81889
|
const rel = relDir.length === 0 ? entry.name : `${relDir}/${entry.name}`;
|
|
81739
81890
|
if (entry.isDirectory()) {
|
|
81740
81891
|
const found2 = visit3(absPath, rel);
|
|
@@ -81744,16 +81895,16 @@ function findApprovedPageForViewRef(projectRoot, viewRef) {
|
|
|
81744
81895
|
}
|
|
81745
81896
|
if (!entry.isFile() || !entry.name.endsWith(".md"))
|
|
81746
81897
|
continue;
|
|
81747
|
-
const block = frontmatterBlock(
|
|
81898
|
+
const block = frontmatterBlock(readFileSync7(absPath, "utf8"));
|
|
81748
81899
|
if (block === null)
|
|
81749
81900
|
continue;
|
|
81750
81901
|
const parsed = import_yaml21.default.parse(block.yaml);
|
|
81751
|
-
if (!
|
|
81902
|
+
if (!isRecord17(parsed) || parsed.view_ref !== viewRef)
|
|
81752
81903
|
continue;
|
|
81753
81904
|
const approvedNodeRef = typeof parsed.node_ref === "string" && parsed.node_ref.trim().length > 0 ? parsed.node_ref.trim() : nodeRef;
|
|
81754
81905
|
return {
|
|
81755
81906
|
path: absPath,
|
|
81756
|
-
relPath:
|
|
81907
|
+
relPath: join41("knowledge", collection, rel),
|
|
81757
81908
|
nodeRef: approvedNodeRef
|
|
81758
81909
|
};
|
|
81759
81910
|
}
|
|
@@ -81794,7 +81945,7 @@ function updateFrontmatter(content3, mutate) {
|
|
|
81794
81945
|
});
|
|
81795
81946
|
}
|
|
81796
81947
|
const parsed = import_yaml21.default.parse(block.yaml);
|
|
81797
|
-
if (!
|
|
81948
|
+
if (!isRecord17(parsed)) {
|
|
81798
81949
|
throw new ContextError(ExitCode.WorkspaceStateError, "approved page frontmatter must be a YAML object", {
|
|
81799
81950
|
category: ErrorCategory.SchemaInvalid
|
|
81800
81951
|
});
|
|
@@ -81809,16 +81960,16 @@ function parseApprovedSources(content3) {
|
|
|
81809
81960
|
if (block === null)
|
|
81810
81961
|
return [];
|
|
81811
81962
|
const parsed = import_yaml21.default.parse(block.yaml);
|
|
81812
|
-
if (!
|
|
81963
|
+
if (!isRecord17(parsed))
|
|
81813
81964
|
return [];
|
|
81814
81965
|
const sources = parsed.sources;
|
|
81815
81966
|
return Array.isArray(sources) ? sources.filter((source2) => typeof source2 === "string") : [];
|
|
81816
81967
|
}
|
|
81817
81968
|
async function writeReviewActionLog(input) {
|
|
81818
81969
|
const stamp = new Date().toISOString().replace(/[-:.TZ]/gu, "");
|
|
81819
|
-
const relPath =
|
|
81820
|
-
const path4 =
|
|
81821
|
-
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 });
|
|
81822
81973
|
await writeFile17(path4, `${JSON.stringify({
|
|
81823
81974
|
action: input.action,
|
|
81824
81975
|
id: input.id,
|
|
@@ -82313,7 +82464,7 @@ async function prepareApprovedPage(input) {
|
|
|
82313
82464
|
if (input.record.candidate_type !== "prose-align") {
|
|
82314
82465
|
assertSafeEntityId(input.record.node_ref);
|
|
82315
82466
|
}
|
|
82316
|
-
relPath =
|
|
82467
|
+
relPath = join42("knowledge", input.record.path);
|
|
82317
82468
|
const existingView = findApprovedPageForViewRef(input.projectRoot, input.record.view_ref);
|
|
82318
82469
|
if (existingView !== undefined && existingView.relPath !== relPath) {
|
|
82319
82470
|
throw new ContextError(ExitCode.WorkspaceStateError, `approved page already exists for view_ref at a different path: ${input.record.view_ref}`, {
|
|
@@ -82325,8 +82476,8 @@ async function prepareApprovedPage(input) {
|
|
|
82325
82476
|
next: "Resolve the approved page path migration explicitly before approving this candidate."
|
|
82326
82477
|
});
|
|
82327
82478
|
}
|
|
82328
|
-
const absPath =
|
|
82329
|
-
const existing =
|
|
82479
|
+
const absPath = join42(input.projectRoot, relPath);
|
|
82480
|
+
const existing = existsSync27(absPath) ? await readFile34(absPath, "utf8") : undefined;
|
|
82330
82481
|
if (existing !== undefined) {
|
|
82331
82482
|
const frontmatter = parseFrontmatterLoose(existing);
|
|
82332
82483
|
const existingViewRef = typeof frontmatter.view_ref === "string" ? frontmatter.view_ref : undefined;
|
|
@@ -82398,11 +82549,11 @@ async function prepareApprovedPage(input) {
|
|
|
82398
82549
|
}
|
|
82399
82550
|
async function writePreparedApprovedPage(page) {
|
|
82400
82551
|
for (const asset of page.assets) {
|
|
82401
|
-
await mkdir22(
|
|
82552
|
+
await mkdir22(dirname27(asset.absPath), { recursive: true });
|
|
82402
82553
|
await writeFile18(asset.absPath, asset.bytes);
|
|
82403
82554
|
}
|
|
82404
82555
|
if (page.changed) {
|
|
82405
|
-
await mkdir22(
|
|
82556
|
+
await mkdir22(dirname27(page.absPath), { recursive: true });
|
|
82406
82557
|
await writeFile18(page.absPath, page.content, "utf8");
|
|
82407
82558
|
}
|
|
82408
82559
|
}
|
|
@@ -82633,18 +82784,18 @@ init_errors();
|
|
|
82633
82784
|
init_exitCode();
|
|
82634
82785
|
|
|
82635
82786
|
// src/project/repoSources.ts
|
|
82636
|
-
import { existsSync as
|
|
82787
|
+
import { existsSync as existsSync30 } from "node:fs";
|
|
82637
82788
|
import { lstat, mkdir as mkdir23, readFile as readFile35, readlink, realpath as realpath2, rm as rm12, symlink } from "node:fs/promises";
|
|
82638
82789
|
import { execFile as execFile4 } from "node:child_process";
|
|
82639
82790
|
import { promisify as promisify4 } from "node:util";
|
|
82640
|
-
import { dirname as
|
|
82791
|
+
import { dirname as dirname28, isAbsolute as isAbsolute8, join as join45, relative as relative15, resolve as resolve17 } from "node:path";
|
|
82641
82792
|
init_cliFeedback();
|
|
82642
82793
|
init_errors();
|
|
82643
82794
|
init_exitCode();
|
|
82644
82795
|
|
|
82645
82796
|
// src/project/repoSourceModules.ts
|
|
82646
|
-
import { existsSync as
|
|
82647
|
-
import { join as
|
|
82797
|
+
import { existsSync as existsSync28 } from "node:fs";
|
|
82798
|
+
import { join as join43, resolve as resolve16 } from "node:path";
|
|
82648
82799
|
function normalizeSubpath(value) {
|
|
82649
82800
|
if (value === undefined)
|
|
82650
82801
|
return;
|
|
@@ -82671,8 +82822,8 @@ function suggestedModuleName(module) {
|
|
|
82671
82822
|
return slug || "module";
|
|
82672
82823
|
}
|
|
82673
82824
|
async function inspectRepoSourceModules(input) {
|
|
82674
|
-
const inspectPath = input.scopedAbs !== null &&
|
|
82675
|
-
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) : [];
|
|
82676
82827
|
const recommended_sources = modules.filter((module) => module.path !== "." || modules.length === 1).map((module) => {
|
|
82677
82828
|
const local = sourceModuleLocalForDisplay({ source: input.source, status: input.status, module });
|
|
82678
82829
|
return {
|
|
@@ -82703,8 +82854,8 @@ function resolveRepoSourceScopedPath(localAbs, subpath) {
|
|
|
82703
82854
|
|
|
82704
82855
|
// src/project/repoSourceRegistry.ts
|
|
82705
82856
|
var import_yaml24 = __toESM(require_dist3(), 1);
|
|
82706
|
-
import { existsSync as
|
|
82707
|
-
import { join as
|
|
82857
|
+
import { existsSync as existsSync29 } from "node:fs";
|
|
82858
|
+
import { join as join44 } from "node:path";
|
|
82708
82859
|
init_cliFeedback();
|
|
82709
82860
|
init_errors();
|
|
82710
82861
|
init_exitCode();
|
|
@@ -82761,14 +82912,14 @@ function registryEntryToRecord(entry) {
|
|
|
82761
82912
|
};
|
|
82762
82913
|
}
|
|
82763
82914
|
function registryPath(projectRoot) {
|
|
82764
|
-
return
|
|
82915
|
+
return join44(projectRoot, DEFAULT_REPO_SOURCES_REGISTRY_PATH);
|
|
82765
82916
|
}
|
|
82766
82917
|
function defaultRepoMaterializedAt(source2) {
|
|
82767
82918
|
return `sources/repo/${source2.namespace}/${source2.module}`;
|
|
82768
82919
|
}
|
|
82769
82920
|
async function readRepoRegistry(projectRoot) {
|
|
82770
82921
|
const path4 = registryPath(projectRoot);
|
|
82771
|
-
if (!
|
|
82922
|
+
if (!existsSync29(path4))
|
|
82772
82923
|
return { repos: [] };
|
|
82773
82924
|
const registry2 = await loadSourcesRegistry({ rootDir: projectRoot });
|
|
82774
82925
|
return {
|
|
@@ -82844,13 +82995,13 @@ async function gitOutput(cwd, args) {
|
|
|
82844
82995
|
}
|
|
82845
82996
|
}
|
|
82846
82997
|
async function readGitOriginRemote(cwd) {
|
|
82847
|
-
const directConfigPath =
|
|
82998
|
+
const directConfigPath = join45(cwd, ".git", "config");
|
|
82848
82999
|
let config = await readFile35(directConfigPath, "utf8").catch(() => "");
|
|
82849
83000
|
if (config.length === 0) {
|
|
82850
83001
|
const gitDir = await resolveGitDir(cwd);
|
|
82851
83002
|
if (gitDir === null)
|
|
82852
83003
|
return null;
|
|
82853
|
-
config = await readFile35(
|
|
83004
|
+
config = await readFile35(join45(gitDir, "config"), "utf8").catch(() => "");
|
|
82854
83005
|
}
|
|
82855
83006
|
let inOriginBlock = false;
|
|
82856
83007
|
for (const line of config.split(/\r?\n/u)) {
|
|
@@ -82870,17 +83021,17 @@ async function readGitOriginRemote(cwd) {
|
|
|
82870
83021
|
async function resolveGitRoot(cwd) {
|
|
82871
83022
|
let current2 = resolve17(cwd);
|
|
82872
83023
|
while (true) {
|
|
82873
|
-
if (
|
|
83024
|
+
if (existsSync30(join45(current2, ".git")))
|
|
82874
83025
|
return current2;
|
|
82875
|
-
const parent =
|
|
83026
|
+
const parent = dirname28(current2);
|
|
82876
83027
|
if (parent === current2)
|
|
82877
83028
|
return null;
|
|
82878
83029
|
current2 = parent;
|
|
82879
83030
|
}
|
|
82880
83031
|
}
|
|
82881
83032
|
async function resolveGitDir(cwd) {
|
|
82882
|
-
const dotGit =
|
|
82883
|
-
if (!
|
|
83033
|
+
const dotGit = join45(cwd, ".git");
|
|
83034
|
+
if (!existsSync30(dotGit))
|
|
82884
83035
|
return null;
|
|
82885
83036
|
const stats = await lstat(dotGit);
|
|
82886
83037
|
if (stats.isDirectory())
|
|
@@ -82897,17 +83048,17 @@ async function readGitHead(cwd) {
|
|
|
82897
83048
|
const gitDir = await resolveGitDir(cwd);
|
|
82898
83049
|
if (gitDir === null)
|
|
82899
83050
|
return null;
|
|
82900
|
-
const headRaw = (await readFile35(
|
|
83051
|
+
const headRaw = (await readFile35(join45(gitDir, "HEAD"), "utf8").catch(() => "")).trim();
|
|
82901
83052
|
if (/^[a-f0-9]{40}$/iu.test(headRaw))
|
|
82902
83053
|
return headRaw.toLowerCase();
|
|
82903
83054
|
const match = /^ref:\s*(.+)\s*$/iu.exec(headRaw);
|
|
82904
83055
|
const refPath = match?.[1];
|
|
82905
83056
|
if (refPath === undefined)
|
|
82906
83057
|
return null;
|
|
82907
|
-
const looseRef = (await readFile35(
|
|
83058
|
+
const looseRef = (await readFile35(join45(gitDir, refPath), "utf8").catch(() => "")).trim();
|
|
82908
83059
|
if (/^[a-f0-9]{40}$/iu.test(looseRef))
|
|
82909
83060
|
return looseRef.toLowerCase();
|
|
82910
|
-
const packedRefs = await readFile35(
|
|
83061
|
+
const packedRefs = await readFile35(join45(gitDir, "packed-refs"), "utf8").catch(() => "");
|
|
82911
83062
|
for (const line of packedRefs.split(/\r?\n/u)) {
|
|
82912
83063
|
if (line.startsWith("#") || line.startsWith("^"))
|
|
82913
83064
|
continue;
|
|
@@ -82918,27 +83069,27 @@ async function readGitHead(cwd) {
|
|
|
82918
83069
|
return null;
|
|
82919
83070
|
}
|
|
82920
83071
|
async function ensureMaterializedSymlink(input) {
|
|
82921
|
-
const linkPath =
|
|
82922
|
-
await mkdir23(
|
|
82923
|
-
if (
|
|
83072
|
+
const linkPath = join45(input.projectRoot, input.materializedAt);
|
|
83073
|
+
await mkdir23(dirname28(linkPath), { recursive: true });
|
|
83074
|
+
if (existsSync30(linkPath)) {
|
|
82924
83075
|
const stats = await lstat(linkPath);
|
|
82925
83076
|
if (!stats.isSymbolicLink()) {
|
|
82926
83077
|
input.diagnostics.push(`materialized path exists and is not a symlink: ${input.materializedAt}`);
|
|
82927
83078
|
return false;
|
|
82928
83079
|
}
|
|
82929
83080
|
const current2 = await readlink(linkPath);
|
|
82930
|
-
const currentAbs = resolve17(
|
|
83081
|
+
const currentAbs = resolve17(dirname28(linkPath), current2);
|
|
82931
83082
|
if (currentAbs === input.localAbs)
|
|
82932
83083
|
return true;
|
|
82933
83084
|
await rm12(linkPath);
|
|
82934
83085
|
}
|
|
82935
|
-
const relTarget = relative15(
|
|
83086
|
+
const relTarget = relative15(dirname28(linkPath), input.localAbs) || ".";
|
|
82936
83087
|
await symlink(relTarget, linkPath);
|
|
82937
83088
|
return true;
|
|
82938
83089
|
}
|
|
82939
83090
|
async function diagnoseMaterializedSymlink(input) {
|
|
82940
|
-
const linkPath =
|
|
82941
|
-
if (!
|
|
83091
|
+
const linkPath = join45(input.projectRoot, input.materializedAt);
|
|
83092
|
+
if (!existsSync30(linkPath)) {
|
|
82942
83093
|
input.diagnostics.push(`materialized path is missing: ${input.materializedAt}`);
|
|
82943
83094
|
input.agent_hints.push(`Run context source ensure ${input.sourceName} to materialize the local source link.`);
|
|
82944
83095
|
return false;
|
|
@@ -82949,9 +83100,9 @@ async function diagnoseMaterializedSymlink(input) {
|
|
|
82949
83100
|
return false;
|
|
82950
83101
|
}
|
|
82951
83102
|
const current2 = await readlink(linkPath);
|
|
82952
|
-
const currentAbs = resolve17(
|
|
83103
|
+
const currentAbs = resolve17(dirname28(linkPath), current2);
|
|
82953
83104
|
if (currentAbs !== input.localAbs) {
|
|
82954
|
-
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) || "."}`);
|
|
82955
83106
|
input.agent_hints.push(`Run context source ensure ${input.sourceName} to refresh the local source link.`);
|
|
82956
83107
|
return false;
|
|
82957
83108
|
}
|
|
@@ -82983,7 +83134,7 @@ async function normalizeInputRef(input) {
|
|
|
82983
83134
|
next: "Pass --local <path> with a git checkout, or use a full 40-character commit sha."
|
|
82984
83135
|
});
|
|
82985
83136
|
}
|
|
82986
|
-
if (!
|
|
83137
|
+
if (!existsSync30(localAbs)) {
|
|
82987
83138
|
throw new ContextError(ExitCode.UserError, `short repo source ref cannot be resolved because local path is missing: ${input.local}`, {
|
|
82988
83139
|
category: ErrorCategory.UserInputInvalid,
|
|
82989
83140
|
sourceName: input.sourceName,
|
|
@@ -83035,7 +83186,7 @@ async function normalizeAddInput(input, existing) {
|
|
|
83035
83186
|
let gitRootAbs = null;
|
|
83036
83187
|
if (originalLocal !== undefined) {
|
|
83037
83188
|
const originalLocalAbs = resolveLocalPath(input.projectRoot, originalLocal);
|
|
83038
|
-
if (originalLocalAbs !== null &&
|
|
83189
|
+
if (originalLocalAbs !== null && existsSync30(originalLocalAbs)) {
|
|
83039
83190
|
gitRootAbs = await resolveGitRoot(originalLocalAbs);
|
|
83040
83191
|
if (gitRootAbs !== null && input.local !== undefined) {
|
|
83041
83192
|
const detectedSubpath = normalizeSubpath2(relative15(gitRootAbs, originalLocalAbs));
|
|
@@ -83131,11 +83282,11 @@ async function inspectRepoSource(input) {
|
|
|
83131
83282
|
const diagnostics = [];
|
|
83132
83283
|
const agent_hints = [];
|
|
83133
83284
|
const localAbs = resolveLocalPath(input.projectRoot, source2.local);
|
|
83134
|
-
const localExists = localAbs !== null &&
|
|
83285
|
+
const localExists = localAbs !== null && existsSync30(localAbs);
|
|
83135
83286
|
const subpath = normalizeSubpath2(source2.subpath);
|
|
83136
83287
|
const scopedAbs = localAbs === null ? null : scopedLocalPath(localAbs, subpath);
|
|
83137
|
-
const scopeExists = scopedAbs !== null &&
|
|
83138
|
-
let materialized =
|
|
83288
|
+
const scopeExists = scopedAbs !== null && existsSync30(scopedAbs);
|
|
83289
|
+
let materialized = existsSync30(join45(input.projectRoot, materializedAt));
|
|
83139
83290
|
const checkout = await inspectRepoCheckout({
|
|
83140
83291
|
source: source2,
|
|
83141
83292
|
localAbs,
|
|
@@ -83784,24 +83935,24 @@ The approved symbol is no longer present in the current code extraction.
|
|
|
83784
83935
|
// src/project/packageBuilder.ts
|
|
83785
83936
|
init_cliFeedback();
|
|
83786
83937
|
init_errors();
|
|
83787
|
-
init_exitCode();
|
|
83788
83938
|
var import_yaml28 = __toESM(require_dist3(), 1);
|
|
83789
83939
|
import { createHash as createHash20 } from "node:crypto";
|
|
83790
|
-
import { existsSync as
|
|
83940
|
+
import { existsSync as existsSync35 } from "node:fs";
|
|
83791
83941
|
import { mkdir as mkdir27, readdir as readdir15, readFile as readFile41, rm as rm13, writeFile as writeFile22 } from "node:fs/promises";
|
|
83792
|
-
import { dirname as
|
|
83942
|
+
import { dirname as dirname34, join as join52, resolve as resolve19 } from "node:path";
|
|
83943
|
+
init_exitCode();
|
|
83793
83944
|
|
|
83794
83945
|
// src/project/packageBuildInventory.ts
|
|
83795
83946
|
var import_yaml26 = __toESM(require_dist3(), 1);
|
|
83796
83947
|
import { createHash as createHash17 } from "node:crypto";
|
|
83797
|
-
import { existsSync as
|
|
83948
|
+
import { existsSync as existsSync32 } from "node:fs";
|
|
83798
83949
|
import { mkdir as mkdir25, readFile as readFile37, writeFile as writeFile20 } from "node:fs/promises";
|
|
83799
|
-
import { dirname as
|
|
83950
|
+
import { dirname as dirname30, join as join47 } from "node:path";
|
|
83800
83951
|
|
|
83801
83952
|
// src/project/packageIndexes.ts
|
|
83802
|
-
import { existsSync as
|
|
83953
|
+
import { existsSync as existsSync31, statSync } from "node:fs";
|
|
83803
83954
|
import { mkdir as mkdir24, readdir as readdir13, readFile as readFile36, writeFile as writeFile19 } from "node:fs/promises";
|
|
83804
|
-
import { dirname as
|
|
83955
|
+
import { dirname as dirname29, join as join46, posix as pathPosix, relative as relative16 } from "node:path";
|
|
83805
83956
|
init_cliFeedback();
|
|
83806
83957
|
init_errors();
|
|
83807
83958
|
init_exitCode();
|
|
@@ -83955,7 +84106,7 @@ var PACKAGE_INVENTORY_FIELDS = [
|
|
|
83955
84106
|
"candidate_fingerprint"
|
|
83956
84107
|
];
|
|
83957
84108
|
var COMPILER_ONLY_TAGS = new Set(["docs", "prose", "parent-index"]);
|
|
83958
|
-
function
|
|
84109
|
+
function isRecord18(value) {
|
|
83959
84110
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
83960
84111
|
}
|
|
83961
84112
|
function stringList2(value) {
|
|
@@ -83969,7 +84120,7 @@ function parseKnowledgeFrontmatter(content3) {
|
|
|
83969
84120
|
return {};
|
|
83970
84121
|
try {
|
|
83971
84122
|
const parsed = import_yaml25.parse(match[1]);
|
|
83972
|
-
return
|
|
84123
|
+
return isRecord18(parsed) ? parsed : {};
|
|
83973
84124
|
} catch {
|
|
83974
84125
|
return {};
|
|
83975
84126
|
}
|
|
@@ -84064,13 +84215,13 @@ function packageKind(pkg) {
|
|
|
84064
84215
|
return pkg.kind === "package.kb" ? "kb" : "llms";
|
|
84065
84216
|
}
|
|
84066
84217
|
async function walkFiles3(root2) {
|
|
84067
|
-
if (!
|
|
84218
|
+
if (!existsSync31(root2))
|
|
84068
84219
|
return [];
|
|
84069
84220
|
const files = [];
|
|
84070
84221
|
const visit3 = async (dir) => {
|
|
84071
84222
|
const entries = await readdir13(dir, { withFileTypes: true });
|
|
84072
84223
|
for (const entry of entries) {
|
|
84073
|
-
const absPath =
|
|
84224
|
+
const absPath = join46(dir, entry.name);
|
|
84074
84225
|
if (entry.isDirectory()) {
|
|
84075
84226
|
await visit3(absPath);
|
|
84076
84227
|
continue;
|
|
@@ -84362,10 +84513,10 @@ async function writeKnowledgeDirectoryIndexes(input) {
|
|
|
84362
84513
|
let written = 0;
|
|
84363
84514
|
for (const directory of collectKnowledgeDirectoryIndexes(input.pkg, input.selected)) {
|
|
84364
84515
|
assertSafeRenderedPath(directory.relPath, "knowledge directory index path");
|
|
84365
|
-
const outputPath =
|
|
84366
|
-
if (
|
|
84516
|
+
const outputPath = join46(input.projectRoot, input.pkg.outDir, directory.relPath);
|
|
84517
|
+
if (existsSync31(outputPath))
|
|
84367
84518
|
continue;
|
|
84368
|
-
await mkdir24(
|
|
84519
|
+
await mkdir24(dirname29(outputPath), { recursive: true });
|
|
84369
84520
|
await writeFile19(outputPath, renderKnowledgeDirectoryIndex({
|
|
84370
84521
|
pkg: input.pkg,
|
|
84371
84522
|
directory,
|
|
@@ -84411,23 +84562,23 @@ function packageLinkTargetExists(packageRoot, targetRelPath) {
|
|
|
84411
84562
|
return false;
|
|
84412
84563
|
}
|
|
84413
84564
|
const normalized = targetRelPath.endsWith("/") ? `${targetRelPath}index.md` : targetRelPath;
|
|
84414
|
-
const targetPath =
|
|
84415
|
-
if (
|
|
84565
|
+
const targetPath = join46(packageRoot, normalized);
|
|
84566
|
+
if (existsSync31(targetPath)) {
|
|
84416
84567
|
const stat6 = statSync(targetPath);
|
|
84417
84568
|
if (stat6.isFile())
|
|
84418
84569
|
return true;
|
|
84419
84570
|
if (stat6.isDirectory())
|
|
84420
|
-
return
|
|
84571
|
+
return existsSync31(join46(targetPath, "index.md"));
|
|
84421
84572
|
return false;
|
|
84422
84573
|
}
|
|
84423
|
-
if (!pathPosix.extname(normalized) &&
|
|
84574
|
+
if (!pathPosix.extname(normalized) && existsSync31(join46(packageRoot, normalized, "index.md")))
|
|
84424
84575
|
return true;
|
|
84425
84576
|
return false;
|
|
84426
84577
|
}
|
|
84427
84578
|
async function validatePackageIndexLinks(input) {
|
|
84428
84579
|
if (packageKind(input.pkg) !== "kb")
|
|
84429
84580
|
return;
|
|
84430
|
-
const packageRoot =
|
|
84581
|
+
const packageRoot = join46(input.projectRoot, input.pkg.outDir);
|
|
84431
84582
|
const files = await walkFiles3(packageRoot);
|
|
84432
84583
|
for (const file of files) {
|
|
84433
84584
|
if (file.relPath !== "index.md" && !file.relPath.endsWith("/index.md"))
|
|
@@ -84498,10 +84649,10 @@ function packageKind2(pkg) {
|
|
|
84498
84649
|
// src/project/packageBuildInventory.ts
|
|
84499
84650
|
var PACKAGE_BUILD_INVENTORY_PATH = "context-build-inventory.json";
|
|
84500
84651
|
function knowledgeStructurePath(projectRoot) {
|
|
84501
|
-
return
|
|
84652
|
+
return join47(projectRoot, "knowledge", "structure.yaml");
|
|
84502
84653
|
}
|
|
84503
84654
|
async function readOptionalText(path4) {
|
|
84504
|
-
if (!
|
|
84655
|
+
if (!existsSync32(path4))
|
|
84505
84656
|
return null;
|
|
84506
84657
|
return readFile37(path4, "utf8");
|
|
84507
84658
|
}
|
|
@@ -84880,8 +85031,8 @@ function packageBuildInventory(input) {
|
|
|
84880
85031
|
};
|
|
84881
85032
|
}
|
|
84882
85033
|
async function writePackageBuildInventory(input) {
|
|
84883
|
-
const outputPath =
|
|
84884
|
-
await mkdir25(
|
|
85034
|
+
const outputPath = join47(input.projectRoot, input.pkg.outDir, PACKAGE_BUILD_INVENTORY_PATH);
|
|
85035
|
+
await mkdir25(dirname30(outputPath), { recursive: true });
|
|
84885
85036
|
await writeFile20(outputPath, `${JSON.stringify(input.inventory, null, 2)}
|
|
84886
85037
|
`, "utf8");
|
|
84887
85038
|
return 1;
|
|
@@ -84889,12 +85040,12 @@ async function writePackageBuildInventory(input) {
|
|
|
84889
85040
|
|
|
84890
85041
|
// src/project/packageBuildReceipt.ts
|
|
84891
85042
|
import { createHash as createHash18 } from "node:crypto";
|
|
84892
|
-
import { existsSync as
|
|
85043
|
+
import { existsSync as existsSync33 } from "node:fs";
|
|
84893
85044
|
import { readdir as readdir14, readFile as readFile38 } from "node:fs/promises";
|
|
84894
|
-
import { join as
|
|
85045
|
+
import { join as join48, relative as relative17 } from "node:path";
|
|
84895
85046
|
var IGNORED_PACKAGE_FS_ENTRIES = new Set([".DS_Store"]);
|
|
84896
85047
|
async function walkPackageFiles(root2) {
|
|
84897
|
-
if (!
|
|
85048
|
+
if (!existsSync33(root2))
|
|
84898
85049
|
return [];
|
|
84899
85050
|
const files = [];
|
|
84900
85051
|
const visit3 = async (dir) => {
|
|
@@ -84902,7 +85053,7 @@ async function walkPackageFiles(root2) {
|
|
|
84902
85053
|
for (const entry of entries) {
|
|
84903
85054
|
if (IGNORED_PACKAGE_FS_ENTRIES.has(entry.name))
|
|
84904
85055
|
continue;
|
|
84905
|
-
const absPath =
|
|
85056
|
+
const absPath = join48(dir, entry.name);
|
|
84906
85057
|
if (entry.isDirectory()) {
|
|
84907
85058
|
await visit3(absPath);
|
|
84908
85059
|
continue;
|
|
@@ -84933,7 +85084,7 @@ function classifyOutputFile(path4, knowledgeGroups) {
|
|
|
84933
85084
|
}
|
|
84934
85085
|
async function packageOutputSnapshot(projectRoot, pkg, knowledgeGroups, previousOutputs = []) {
|
|
84935
85086
|
const previousByPath = new Map(previousOutputs.map((file) => [file.path, file]));
|
|
84936
|
-
return Promise.all((await walkPackageFiles(
|
|
85087
|
+
return Promise.all((await walkPackageFiles(join48(projectRoot, pkg.outDir))).map(async (file) => {
|
|
84937
85088
|
const current2 = classifyOutputFile(file.relPath, knowledgeGroups);
|
|
84938
85089
|
const previous3 = previousByPath.get(file.relPath);
|
|
84939
85090
|
const classification = current2.kind === "file" && previous3 !== undefined ? { path: file.relPath, kind: previous3.kind, ...previous3.group === undefined ? {} : { group: previous3.group } } : current2;
|
|
@@ -84947,7 +85098,7 @@ async function packageOutputFingerprint(projectRoot, pkg) {
|
|
|
84947
85098
|
const snapshot = await packageOutputSnapshot(projectRoot, pkg, new Map);
|
|
84948
85099
|
return {
|
|
84949
85100
|
fingerprint: createHash18("sha256").update(JSON.stringify({
|
|
84950
|
-
outDirExists:
|
|
85101
|
+
outDirExists: existsSync33(join48(projectRoot, pkg.outDir)),
|
|
84951
85102
|
files: snapshot.map(({ path: path4, sha256: sha2564 }) => ({ path: path4, sha256: sha2564 }))
|
|
84952
85103
|
})).digest("hex"),
|
|
84953
85104
|
files: snapshot.length
|
|
@@ -85021,16 +85172,16 @@ function formatPackageBuildSummary(pkg) {
|
|
|
85021
85172
|
}
|
|
85022
85173
|
|
|
85023
85174
|
// src/project/packageBuildContent.ts
|
|
85024
|
-
import { existsSync as
|
|
85175
|
+
import { existsSync as existsSync34 } from "node:fs";
|
|
85025
85176
|
import { mkdir as mkdir26, readFile as readFile40, writeFile as writeFile21 } from "node:fs/promises";
|
|
85026
|
-
import { dirname as
|
|
85177
|
+
import { dirname as dirname33, join as join51 } from "node:path";
|
|
85027
85178
|
|
|
85028
85179
|
// src/project/packageAssets.ts
|
|
85029
85180
|
init_errors();
|
|
85030
85181
|
init_cliFeedback();
|
|
85031
85182
|
init_exitCode();
|
|
85032
85183
|
import { readFile as readFile39 } from "node:fs/promises";
|
|
85033
|
-
import { dirname as
|
|
85184
|
+
import { dirname as dirname31, relative as relative18, sep as sep3 } from "node:path";
|
|
85034
85185
|
function posixPath2(value) {
|
|
85035
85186
|
return value.split(sep3).join("/");
|
|
85036
85187
|
}
|
|
@@ -85052,7 +85203,7 @@ function packageAssetPath(projectRoot, absolute) {
|
|
|
85052
85203
|
};
|
|
85053
85204
|
}
|
|
85054
85205
|
function packageMarkdownTarget(pageOutputPath, assetOutputPath) {
|
|
85055
|
-
const target = posixPath2(relative18(
|
|
85206
|
+
const target = posixPath2(relative18(dirname31(pageOutputPath), assetOutputPath));
|
|
85056
85207
|
return target.startsWith(".") ? target : `./${target}`;
|
|
85057
85208
|
}
|
|
85058
85209
|
async function projectPackageKnowledgeAssets(input) {
|
|
@@ -85092,7 +85243,7 @@ init_errors();
|
|
|
85092
85243
|
init_exitCode();
|
|
85093
85244
|
import { execFile as execFile5 } from "node:child_process";
|
|
85094
85245
|
import { realpath as realpath3 } from "node:fs/promises";
|
|
85095
|
-
import { join as
|
|
85246
|
+
import { join as join50, relative as relative19, sep as sep4 } from "node:path";
|
|
85096
85247
|
import { promisify as promisify5 } from "node:util";
|
|
85097
85248
|
|
|
85098
85249
|
// src/project/packageAssetOptimization.ts
|
|
@@ -85101,7 +85252,7 @@ init_errors();
|
|
|
85101
85252
|
init_exitCode();
|
|
85102
85253
|
import { createHash as createHash19 } from "node:crypto";
|
|
85103
85254
|
import { createRequire as createRequire4 } from "node:module";
|
|
85104
|
-
import { dirname as
|
|
85255
|
+
import { dirname as dirname32, extname as extname10, join as join49 } from "node:path";
|
|
85105
85256
|
import { pathToFileURL as pathToFileURL2 } from "node:url";
|
|
85106
85257
|
var PACKAGE_ASSET_OPTIMIZATION_THRESHOLD_BYTES = 20 * 1024 * 1024;
|
|
85107
85258
|
function isPng(bytes) {
|
|
@@ -85123,10 +85274,10 @@ function isWebp(bytes) {
|
|
|
85123
85274
|
}
|
|
85124
85275
|
function contentAddressedWebpPath(asset, bytes) {
|
|
85125
85276
|
const digest4 = createHash19("sha256").update(bytes).digest("hex");
|
|
85126
|
-
return `${
|
|
85277
|
+
return `${dirname32(asset.packageRelPath)}/${digest4}.webp`;
|
|
85127
85278
|
}
|
|
85128
85279
|
async function loadSharpProcessor(projectRoot) {
|
|
85129
|
-
const requireFromWorkspace = createRequire4(
|
|
85280
|
+
const requireFromWorkspace = createRequire4(join49(projectRoot, "package.json"));
|
|
85130
85281
|
let resolved;
|
|
85131
85282
|
try {
|
|
85132
85283
|
resolved = requireFromWorkspace.resolve("sharp");
|
|
@@ -85246,7 +85397,7 @@ async function git(projectRoot, args) {
|
|
|
85246
85397
|
}
|
|
85247
85398
|
}
|
|
85248
85399
|
function repositoryPath(repoRoot, projectRoot, asset) {
|
|
85249
|
-
const path4 = relative19(repoRoot,
|
|
85400
|
+
const path4 = relative19(repoRoot, join50(projectRoot, asset.knowledgeRelPath)).split(sep4).join("/");
|
|
85250
85401
|
if (path4 === ".." || path4.startsWith("../") || path4.startsWith("/")) {
|
|
85251
85402
|
throw new ContextError(ExitCode.WorkspaceStateError, "knowledge asset is outside the current Git repository", {
|
|
85252
85403
|
category: ErrorCategory.WorkspaceStateInvalid,
|
|
@@ -85553,8 +85704,8 @@ async function writeRenderedPackageTemplate(input) {
|
|
|
85553
85704
|
templateRelPath: renderedRelPath,
|
|
85554
85705
|
logicalTemplateRelPath: renderedLogicalRelPath
|
|
85555
85706
|
});
|
|
85556
|
-
const outputPath =
|
|
85557
|
-
await mkdir26(
|
|
85707
|
+
const outputPath = join51(input.projectRoot, input.pkg.outDir, renderedRelPath);
|
|
85708
|
+
await mkdir26(dirname33(outputPath), { recursive: true });
|
|
85558
85709
|
await writeFile21(outputPath, renderTemplateText(file.content, contentVars), "utf8");
|
|
85559
85710
|
written++;
|
|
85560
85711
|
}
|
|
@@ -85580,7 +85731,7 @@ async function writeSelectedPackageKnowledge(input) {
|
|
|
85580
85731
|
const { projectedPages, delivered } = input.prepared ?? await prepareSelectedPackageKnowledge(input);
|
|
85581
85732
|
for (const projected of projectedPages) {
|
|
85582
85733
|
assertSafeRenderedPath2(projected.pageOutputPath, "knowledge path");
|
|
85583
|
-
const outputPath =
|
|
85734
|
+
const outputPath = join51(input.projectRoot, input.pkg.outDir, projected.pageOutputPath);
|
|
85584
85735
|
const rewritten = replaceMarkdownInlineLinkTargets(projected.content, (link2) => {
|
|
85585
85736
|
for (const [inputPath, outputPath2] of delivered.targetByOriginal) {
|
|
85586
85737
|
if (link2.target === packageMarkdownTarget(projected.pageOutputPath, inputPath)) {
|
|
@@ -85589,14 +85740,14 @@ async function writeSelectedPackageKnowledge(input) {
|
|
|
85589
85740
|
}
|
|
85590
85741
|
return;
|
|
85591
85742
|
});
|
|
85592
|
-
await mkdir26(
|
|
85743
|
+
await mkdir26(dirname33(outputPath), { recursive: true });
|
|
85593
85744
|
await writeFile21(outputPath, projectPackageKnowledgeMarkdown(rewritten), "utf8");
|
|
85594
85745
|
}
|
|
85595
85746
|
const deliveredAssets = new Map(delivered.assets.map((asset) => [asset.packageRelPath, asset]));
|
|
85596
85747
|
for (const asset of deliveredAssets.values()) {
|
|
85597
85748
|
assertSafeRenderedPath2(asset.packageRelPath, "package resource path");
|
|
85598
|
-
const outputPath =
|
|
85599
|
-
await mkdir26(
|
|
85749
|
+
const outputPath = join51(input.projectRoot, input.pkg.outDir, asset.packageRelPath);
|
|
85750
|
+
await mkdir26(dirname33(outputPath), { recursive: true });
|
|
85600
85751
|
await writeFile21(outputPath, asset.bytes);
|
|
85601
85752
|
}
|
|
85602
85753
|
return {
|
|
@@ -85609,8 +85760,8 @@ async function writeSelectedPackageKnowledge(input) {
|
|
|
85609
85760
|
async function appendLlmsKnowledge(input) {
|
|
85610
85761
|
if (packageKind2(input.pkg) !== "llms" || input.templateConsumesKnowledge || input.knowledgeCount === 0)
|
|
85611
85762
|
return 0;
|
|
85612
|
-
const outputPath =
|
|
85613
|
-
const existed =
|
|
85763
|
+
const outputPath = join51(input.projectRoot, input.pkg.outDir, "llms.txt");
|
|
85764
|
+
const existed = existsSync34(outputPath);
|
|
85614
85765
|
const existing = existed ? await readFile40(outputPath, "utf8") : "";
|
|
85615
85766
|
const content3 = existing.trim().length > 0 ? `${existing.trimEnd()}
|
|
85616
85767
|
|
|
@@ -85619,7 +85770,7 @@ async function appendLlmsKnowledge(input) {
|
|
|
85619
85770
|
${input.bundle}
|
|
85620
85771
|
` : `${input.bundle}
|
|
85621
85772
|
`;
|
|
85622
|
-
await mkdir26(
|
|
85773
|
+
await mkdir26(dirname33(outputPath), { recursive: true });
|
|
85623
85774
|
await writeFile21(outputPath, content3, "utf8");
|
|
85624
85775
|
return existed ? 0 : 1;
|
|
85625
85776
|
}
|
|
@@ -85805,7 +85956,7 @@ function validateRenderedSkillDefinition(input) {
|
|
|
85805
85956
|
init_workspace();
|
|
85806
85957
|
init_packageTemplateReview();
|
|
85807
85958
|
var KNOWLEDGE_ROOT4 = "knowledge";
|
|
85808
|
-
var PACKAGE_FINGERPRINT_ROOT =
|
|
85959
|
+
var PACKAGE_FINGERPRINT_ROOT = join52(".tmp", "context-runtime", "packages");
|
|
85809
85960
|
var PACKAGE_BUILDER_PROTOCOL_VERSION = "v14-git-asset-identity";
|
|
85810
85961
|
function packageAssetDeliverySummary(value) {
|
|
85811
85962
|
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
@@ -85828,10 +85979,10 @@ function assertPackageOutputDir(pkg) {
|
|
|
85828
85979
|
}
|
|
85829
85980
|
function packageFingerprintPath(projectRoot, pkg) {
|
|
85830
85981
|
assertSafeRenderedPath2(`${pkg.name}.json`, "package fingerprint path");
|
|
85831
|
-
return
|
|
85982
|
+
return join52(projectRoot, PACKAGE_FINGERPRINT_ROOT, `${pkg.name}.json`);
|
|
85832
85983
|
}
|
|
85833
85984
|
async function listApprovedKnowledge(projectRoot) {
|
|
85834
|
-
const files = await walkPackageFiles(
|
|
85985
|
+
const files = await walkPackageFiles(join52(projectRoot, KNOWLEDGE_ROOT4));
|
|
85835
85986
|
const knowledge = await Promise.all(files.filter((file) => file.relPath.endsWith(".md") && !file.relPath.startsWith("assets/")).map(async (file) => ({
|
|
85836
85987
|
...file,
|
|
85837
85988
|
content: await readFile41(file.absPath, "utf8")
|
|
@@ -85852,7 +86003,7 @@ function isDeprecatedKnowledge(content3) {
|
|
|
85852
86003
|
async function listTemplateFiles(projectRoot, templatePath) {
|
|
85853
86004
|
assertSafeRenderedPath2(templatePath, "package template path");
|
|
85854
86005
|
const templateRoot = resolve19(projectRoot, templatePath);
|
|
85855
|
-
if (!
|
|
86006
|
+
if (!existsSync35(templateRoot)) {
|
|
85856
86007
|
throw new ContextError(ExitCode.WorkspaceStateError, `package template path is missing: ${templatePath}`, {
|
|
85857
86008
|
category: ErrorCategory.WorkspaceStateInvalid,
|
|
85858
86009
|
path: templatePath,
|
|
@@ -85914,7 +86065,7 @@ async function packageInputFingerprint(input) {
|
|
|
85914
86065
|
}
|
|
85915
86066
|
async function readPackageManifest(projectRoot, pkg) {
|
|
85916
86067
|
const filePath = packageFingerprintPath(projectRoot, pkg);
|
|
85917
|
-
if (!
|
|
86068
|
+
if (!existsSync35(filePath))
|
|
85918
86069
|
return null;
|
|
85919
86070
|
try {
|
|
85920
86071
|
const parsed = JSON.parse(await readFile41(filePath, "utf8"));
|
|
@@ -85947,7 +86098,7 @@ async function readPackageManifest(projectRoot, pkg) {
|
|
|
85947
86098
|
}
|
|
85948
86099
|
async function writePackageFingerprint(input) {
|
|
85949
86100
|
const filePath = packageFingerprintPath(input.projectRoot, input.pkg);
|
|
85950
|
-
await mkdir27(
|
|
86101
|
+
await mkdir27(dirname34(filePath), { recursive: true });
|
|
85951
86102
|
await writeFile22(filePath, `${JSON.stringify({
|
|
85952
86103
|
package: input.pkg.name,
|
|
85953
86104
|
kind: packageKind2(input.pkg),
|
|
@@ -85962,12 +86113,12 @@ async function writePackageFingerprint(input) {
|
|
|
85962
86113
|
`, "utf8");
|
|
85963
86114
|
}
|
|
85964
86115
|
async function removeOrphanPackageDirs(projectRoot, packages) {
|
|
85965
|
-
const distRoot =
|
|
85966
|
-
if (!
|
|
86116
|
+
const distRoot = join52(projectRoot, "dist");
|
|
86117
|
+
if (!existsSync35(distRoot))
|
|
85967
86118
|
return;
|
|
85968
86119
|
const declaredNames = new Set(packages.map((pkg) => pkg.name));
|
|
85969
86120
|
const entries = await readdir15(distRoot, { withFileTypes: true });
|
|
85970
|
-
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 })));
|
|
85971
86122
|
}
|
|
85972
86123
|
async function collectPackageFreshness(projectRoot, packages) {
|
|
85973
86124
|
const approved = await listApprovedKnowledge(projectRoot);
|
|
@@ -85975,8 +86126,8 @@ async function collectPackageFreshness(projectRoot, packages) {
|
|
|
85975
86126
|
assertPackageOutputDir(pkg);
|
|
85976
86127
|
const selected = selectPackageKnowledge(approved, pkg);
|
|
85977
86128
|
assertSafeRenderedPath2(pkg.template.path, "package template path");
|
|
85978
|
-
const templateRoot =
|
|
85979
|
-
const templateExists =
|
|
86129
|
+
const templateRoot = join52(projectRoot, pkg.template.path);
|
|
86130
|
+
const templateExists = existsSync35(templateRoot);
|
|
85980
86131
|
if (!templateExists) {
|
|
85981
86132
|
throw new ContextError(ExitCode.WorkspaceStateError, `package template path is missing: ${pkg.template.path}`, {
|
|
85982
86133
|
category: ErrorCategory.WorkspaceStateInvalid,
|
|
@@ -86110,8 +86261,8 @@ async function buildProjectPackages(projectRoot) {
|
|
|
86110
86261
|
files: selected,
|
|
86111
86262
|
...assetProcessor === undefined ? {} : { assetProcessor }
|
|
86112
86263
|
});
|
|
86113
|
-
await rm13(
|
|
86114
|
-
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 });
|
|
86115
86266
|
const rendered = await writeRenderedPackageTemplate({
|
|
86116
86267
|
projectRoot,
|
|
86117
86268
|
pkg,
|
|
@@ -86249,20 +86400,32 @@ async function runProjectBuildCommand(input) {
|
|
|
86249
86400
|
return false;
|
|
86250
86401
|
const result = await buildProjectPackages(found.projectRoot);
|
|
86251
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
|
+
});
|
|
86252
86415
|
return true;
|
|
86253
86416
|
}
|
|
86254
86417
|
|
|
86255
86418
|
// src/project/statusReaders.ts
|
|
86256
86419
|
init_workspace();
|
|
86257
86420
|
async function countFiles(root2, predicate) {
|
|
86258
|
-
if (!
|
|
86421
|
+
if (!existsSync36(root2))
|
|
86259
86422
|
return 0;
|
|
86260
86423
|
let count = 0;
|
|
86261
86424
|
const visit3 = async (dir, prefix = "") => {
|
|
86262
86425
|
const entries = await readdir16(dir, { withFileTypes: true });
|
|
86263
86426
|
for (const entry of entries) {
|
|
86264
86427
|
const rel = prefix.length === 0 ? entry.name : `${prefix}/${entry.name}`;
|
|
86265
|
-
const abs =
|
|
86428
|
+
const abs = join53(dir, entry.name);
|
|
86266
86429
|
if (entry.isDirectory())
|
|
86267
86430
|
await visit3(abs, rel);
|
|
86268
86431
|
else if (entry.isFile() && predicate(rel))
|
|
@@ -86304,14 +86467,14 @@ async function readDraftCandidateStatus(projectRoot) {
|
|
|
86304
86467
|
throw error;
|
|
86305
86468
|
}
|
|
86306
86469
|
}
|
|
86307
|
-
function
|
|
86470
|
+
function isRecord19(value) {
|
|
86308
86471
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
86309
86472
|
}
|
|
86310
86473
|
function stagedStructureCounts(parsed) {
|
|
86311
86474
|
const views = Array.isArray(parsed.views) ? parsed.views : [];
|
|
86312
|
-
const sections = views.flatMap((view) =>
|
|
86475
|
+
const sections = views.flatMap((view) => isRecord19(view) && Array.isArray(view.sections) ? view.sections : []);
|
|
86313
86476
|
const sourceRefs = new Set(sections.flatMap((section) => {
|
|
86314
|
-
if (!
|
|
86477
|
+
if (!isRecord19(section))
|
|
86315
86478
|
return [];
|
|
86316
86479
|
return [
|
|
86317
86480
|
...typeof section.source_ref === "string" ? [section.source_ref] : [],
|
|
@@ -86328,12 +86491,12 @@ function stagedStructureCounts(parsed) {
|
|
|
86328
86491
|
};
|
|
86329
86492
|
}
|
|
86330
86493
|
function readStructureDraftStatus(projectRoot) {
|
|
86331
|
-
const structurePath =
|
|
86332
|
-
if (!
|
|
86494
|
+
const structurePath = join53(projectRoot, LIFECYCLE_STRUCTURE_FILE);
|
|
86495
|
+
if (!existsSync36(structurePath))
|
|
86333
86496
|
return { state: "missing", sourceKeys: [], collections: [], diagnostics: [] };
|
|
86334
86497
|
try {
|
|
86335
|
-
const parsed = import_yaml29.default.parse(
|
|
86336
|
-
if (!
|
|
86498
|
+
const parsed = import_yaml29.default.parse(readFileSync8(structurePath, "utf8"));
|
|
86499
|
+
if (!isRecord19(parsed)) {
|
|
86337
86500
|
return {
|
|
86338
86501
|
state: "invalid",
|
|
86339
86502
|
sourceKeys: [],
|
|
@@ -86341,7 +86504,7 @@ function readStructureDraftStatus(projectRoot) {
|
|
|
86341
86504
|
diagnostics: [`${LIFECYCLE_STRUCTURE_FILE} must be a YAML object`]
|
|
86342
86505
|
};
|
|
86343
86506
|
}
|
|
86344
|
-
const lifecycle =
|
|
86507
|
+
const lifecycle = isRecord19(parsed.lifecycle) ? parsed.lifecycle : {};
|
|
86345
86508
|
const lifecycleState = lifecycle.state;
|
|
86346
86509
|
if (lifecycleState === "draft" || lifecycleState === "confirmed" || lifecycleState === "frozen") {
|
|
86347
86510
|
const structureDigest = typeof parsed.structure_digest === "string" ? parsed.structure_digest : typeof lifecycle.structure_digest === "string" ? lifecycle.structure_digest : undefined;
|
|
@@ -86351,7 +86514,7 @@ function readStructureDraftStatus(projectRoot) {
|
|
|
86351
86514
|
lifecycleState,
|
|
86352
86515
|
...typeof lifecycle.phase_collection === "string" ? { phaseCollection: lifecycle.phase_collection } : {},
|
|
86353
86516
|
sourceKeys: Array.isArray(parsed.sources) ? parsed.sources.filter((item) => typeof item === "string") : [],
|
|
86354
|
-
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() : [],
|
|
86355
86518
|
...structureDigest === undefined ? {} : { structureDigest },
|
|
86356
86519
|
...evidenceSnapshotHash === undefined ? {} : { evidenceSnapshotHash },
|
|
86357
86520
|
...stagedStructureCounts(parsed),
|
|
@@ -86528,8 +86691,8 @@ async function documentSourceSiteHint(input) {
|
|
|
86528
86691
|
});
|
|
86529
86692
|
}
|
|
86530
86693
|
function documentSnapshotReadiness(input) {
|
|
86531
|
-
const manifestPath =
|
|
86532
|
-
if (!
|
|
86694
|
+
const manifestPath = join53(input.projectRoot, input.manifest);
|
|
86695
|
+
if (!existsSync36(manifestPath)) {
|
|
86533
86696
|
return {
|
|
86534
86697
|
ready: false,
|
|
86535
86698
|
diagnostics: [`snapshot is missing: ${input.manifest}`],
|
|
@@ -86537,7 +86700,7 @@ function documentSnapshotReadiness(input) {
|
|
|
86537
86700
|
};
|
|
86538
86701
|
}
|
|
86539
86702
|
try {
|
|
86540
|
-
const manifest = findDocumentSnapshotForSource(JSON.parse(
|
|
86703
|
+
const manifest = findDocumentSnapshotForSource(JSON.parse(readFileSync8(manifestPath, "utf8")), input.sourceName);
|
|
86541
86704
|
if (manifest === null) {
|
|
86542
86705
|
return {
|
|
86543
86706
|
ready: false,
|
|
@@ -86598,7 +86761,7 @@ function documentSnapshotReadiness(input) {
|
|
|
86598
86761
|
const missingFiles = [
|
|
86599
86762
|
...manifest.files.map((file) => file.path),
|
|
86600
86763
|
...(manifest.assets ?? []).filter((asset) => asset.content_hash !== undefined).map((asset) => asset.path)
|
|
86601
|
-
].filter((path4) => !
|
|
86764
|
+
].filter((path4) => !existsSync36(join53(input.projectRoot, input.materializedAt, path4)));
|
|
86602
86765
|
if (missingFiles.length > 0) {
|
|
86603
86766
|
return {
|
|
86604
86767
|
ready: false,
|
|
@@ -86845,9 +87008,9 @@ async function readActiveStructuresStatus(projectRoot, currentSnapshotHashes) {
|
|
|
86845
87008
|
init_packageTemplateReview();
|
|
86846
87009
|
|
|
86847
87010
|
// src/project/workflow/workflowProvider.ts
|
|
86848
|
-
import { existsSync as
|
|
86849
|
-
import { dirname as
|
|
86850
|
-
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";
|
|
86851
87014
|
|
|
86852
87015
|
// src/project/workflow/verifyFacts.ts
|
|
86853
87016
|
var CLOSE_REPAIRABLE_APPROVED_STRUCTURE_CODES = new Set([
|
|
@@ -87419,7 +87582,7 @@ function planForResolvedCommandPlan(commandPlan, observation) {
|
|
|
87419
87582
|
|
|
87420
87583
|
// src/project/workflow/workflowEvidenceResources.ts
|
|
87421
87584
|
import { createHash as createHash21 } from "node:crypto";
|
|
87422
|
-
import { join as
|
|
87585
|
+
import { join as join54 } from "node:path";
|
|
87423
87586
|
function sourceKeysForRoute(node3, observation) {
|
|
87424
87587
|
if (node3 === "classify-document") {
|
|
87425
87588
|
return observation.unclassifiedDocumentTargets.map((target) => target.sourceKey);
|
|
@@ -87471,7 +87634,7 @@ async function currentSourceBodyResources(input) {
|
|
|
87471
87634
|
kind: "context-view",
|
|
87472
87635
|
media_type: "text/markdown",
|
|
87473
87636
|
digest: document4.content_hash,
|
|
87474
|
-
path:
|
|
87637
|
+
path: join54(input.observation.projectRoot, source2.materializedAt, document4.path),
|
|
87475
87638
|
read_state: isCurrent(id2, document4.content_hash, input.receipts) ? "current" : "read-required"
|
|
87476
87639
|
});
|
|
87477
87640
|
}
|
|
@@ -87483,7 +87646,7 @@ async function currentSourceBodyResources(input) {
|
|
|
87483
87646
|
// src/project/workflow/workflowProvider.ts
|
|
87484
87647
|
var providerPromise;
|
|
87485
87648
|
function providerCandidates() {
|
|
87486
|
-
const moduleDir2 =
|
|
87649
|
+
const moduleDir2 = dirname35(fileURLToPath7(import.meta.url));
|
|
87487
87650
|
return [
|
|
87488
87651
|
...process.env.C4A_CONTEXT_WORKFLOW_PROVIDER ? [resolve20(process.env.C4A_CONTEXT_WORKFLOW_PROVIDER)] : [],
|
|
87489
87652
|
resolve20(moduleDir2, "providers", "context", "manifest.json"),
|
|
@@ -87491,7 +87654,7 @@ function providerCandidates() {
|
|
|
87491
87654
|
];
|
|
87492
87655
|
}
|
|
87493
87656
|
function contextWorkflowProviderPath() {
|
|
87494
|
-
const candidate = providerCandidates().find((path4) =>
|
|
87657
|
+
const candidate = providerCandidates().find((path4) => existsSync37(path4));
|
|
87495
87658
|
if (candidate === undefined) {
|
|
87496
87659
|
throw new Error("Context workflow Provider is missing. Rebuild @c4a/context-cli or reinstall the published package.");
|
|
87497
87660
|
}
|
|
@@ -88505,13 +88668,13 @@ async function collectProjectStatusSnapshot(projectRoot, options = {}) {
|
|
|
88505
88668
|
requestedCollections: [...new Set(alignTargets.map((target) => target.collection))],
|
|
88506
88669
|
requestedGroups: alignGroups
|
|
88507
88670
|
});
|
|
88508
|
-
const approvedPages = await countFiles(
|
|
88671
|
+
const approvedPages = await countFiles(join55(projectRoot, "knowledge"), (rel) => rel.endsWith(".md") && !rel.startsWith("assets/"));
|
|
88509
88672
|
const approvedCollections = (await Promise.all(KNOWLEDGE_COLLECTIONS.map(async (collection) => ({
|
|
88510
88673
|
collection,
|
|
88511
|
-
count: await countFiles(
|
|
88674
|
+
count: await countFiles(join55(projectRoot, "knowledge", collection), (rel) => rel.endsWith(".md"))
|
|
88512
88675
|
})))).filter((item) => item.count > 0).map((item) => item.collection);
|
|
88513
88676
|
const closeStatus = await readCloseStatus(projectRoot);
|
|
88514
|
-
const distFiles = await countFiles(
|
|
88677
|
+
const distFiles = await countFiles(join55(projectRoot, "dist"), () => true);
|
|
88515
88678
|
const sourceFreshness = phaseStatus.projectEntryValid ? await collectSourceFreshness({
|
|
88516
88679
|
projectRoot,
|
|
88517
88680
|
phases,
|
|
@@ -88875,6 +89038,7 @@ async function runProjectStatusCommand(input) {
|
|
|
88875
89038
|
} else {
|
|
88876
89039
|
process.stdout.write(formatProjectStatus(status));
|
|
88877
89040
|
}
|
|
89041
|
+
input.onSuccess?.(status);
|
|
88878
89042
|
return true;
|
|
88879
89043
|
}
|
|
88880
89044
|
async function assertProjectWorkflowRevision(input) {
|
|
@@ -88931,11 +89095,11 @@ function shellQuote6(value) {
|
|
|
88931
89095
|
}
|
|
88932
89096
|
function receiptSetPath(receipts) {
|
|
88933
89097
|
const token = digestText(JSON.stringify(receipts)).slice("sha256:".length);
|
|
88934
|
-
return
|
|
89098
|
+
return join56(".tmp", "context-runtime", "workflow", "read-receipts", `${token}.json`);
|
|
88935
89099
|
}
|
|
88936
89100
|
async function writeReceiptContinuation(input) {
|
|
88937
89101
|
const path4 = receiptSetPath(input.receipts);
|
|
88938
|
-
await writeJsonAtomic(
|
|
89102
|
+
await writeJsonAtomic(join56(input.projectRoot, path4), input.receipts);
|
|
88939
89103
|
const command2 = input.managed ? [
|
|
88940
89104
|
"context",
|
|
88941
89105
|
"--workflow-resource-receipts",
|
|
@@ -88996,7 +89160,7 @@ async function materializeContextWorkflowResource(input) {
|
|
|
88996
89160
|
}
|
|
88997
89161
|
const content3 = renderContextWorkflowResource(resourceId2, status);
|
|
88998
89162
|
const location = await materializeResource(await loadContextWorkflowProvider(), resourceId2, {
|
|
88999
|
-
cache:
|
|
89163
|
+
cache: join56(found.projectRoot, ".tmp", "context-runtime", "workflow", "resources"),
|
|
89000
89164
|
workspace: found.projectRoot,
|
|
89001
89165
|
revision: input.revision,
|
|
89002
89166
|
input: {
|
|
@@ -89222,7 +89386,7 @@ function registerContextWorkflowResourceCommands(program2) {
|
|
|
89222
89386
|
}
|
|
89223
89387
|
|
|
89224
89388
|
// src/commands/runProject.ts
|
|
89225
|
-
import { fileURLToPath as
|
|
89389
|
+
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
89226
89390
|
init_cliFeedback();
|
|
89227
89391
|
init_errors();
|
|
89228
89392
|
|
|
@@ -89233,11 +89397,11 @@ init_exitCode();
|
|
|
89233
89397
|
|
|
89234
89398
|
// src/project/documentCaptureLark.ts
|
|
89235
89399
|
import { readdir as readdir18, readFile as readFile44 } from "node:fs/promises";
|
|
89236
|
-
import { basename as basename8, extname as extname12, join as
|
|
89400
|
+
import { basename as basename8, extname as extname12, join as join59 } from "node:path";
|
|
89237
89401
|
|
|
89238
89402
|
// src/lib/atomicFileBatch.ts
|
|
89239
89403
|
import { lstat as lstat2, mkdir as mkdir28, mkdtemp, rename as rename4, rm as rm14, writeFile as writeFile23 } from "node:fs/promises";
|
|
89240
|
-
import { dirname as
|
|
89404
|
+
import { dirname as dirname36, join as join57, resolve as resolve22 } from "node:path";
|
|
89241
89405
|
async function existingFileKind(path4) {
|
|
89242
89406
|
try {
|
|
89243
89407
|
const stats = await lstat2(path4);
|
|
@@ -89267,9 +89431,9 @@ async function applyAtomicFileBatch(input) {
|
|
|
89267
89431
|
for (const path4 of writesByPath.keys())
|
|
89268
89432
|
removalPaths.delete(path4);
|
|
89269
89433
|
await mkdir28(input.transactionRoot, { recursive: true });
|
|
89270
|
-
const transactionDir = await mkdtemp(
|
|
89271
|
-
const stagedRoot =
|
|
89272
|
-
const backupRoot =
|
|
89434
|
+
const transactionDir = await mkdtemp(join57(input.transactionRoot, "batch-"));
|
|
89435
|
+
const stagedRoot = join57(transactionDir, "staged");
|
|
89436
|
+
const backupRoot = join57(transactionDir, "backup");
|
|
89273
89437
|
const writes = [...writesByPath.values()].sort((left, right) => left.path.localeCompare(right.path));
|
|
89274
89438
|
const affectedPaths = [...new Set([...writesByPath.keys(), ...removalPaths])].sort();
|
|
89275
89439
|
const staged = new Map;
|
|
@@ -89279,20 +89443,20 @@ async function applyAtomicFileBatch(input) {
|
|
|
89279
89443
|
try {
|
|
89280
89444
|
await mkdir28(stagedRoot, { recursive: true });
|
|
89281
89445
|
for (const [index2, write] of writes.entries()) {
|
|
89282
|
-
const path4 =
|
|
89446
|
+
const path4 = join57(stagedRoot, String(index2));
|
|
89283
89447
|
await writeFile23(path4, write.bytes);
|
|
89284
89448
|
staged.set(write.path, path4);
|
|
89285
89449
|
}
|
|
89286
89450
|
for (const [index2, path4] of affectedPaths.entries()) {
|
|
89287
89451
|
if (await existingFileKind(path4) === "missing")
|
|
89288
89452
|
continue;
|
|
89289
|
-
const backupPath =
|
|
89290
|
-
await mkdir28(
|
|
89453
|
+
const backupPath = join57(backupRoot, String(index2));
|
|
89454
|
+
await mkdir28(dirname36(backupPath), { recursive: true });
|
|
89291
89455
|
await rename4(path4, backupPath);
|
|
89292
89456
|
backups.set(path4, backupPath);
|
|
89293
89457
|
}
|
|
89294
89458
|
for (const write of writes) {
|
|
89295
|
-
await mkdir28(
|
|
89459
|
+
await mkdir28(dirname36(write.path), { recursive: true });
|
|
89296
89460
|
await rename4(staged.get(write.path), write.path);
|
|
89297
89461
|
installed.push(write.path);
|
|
89298
89462
|
}
|
|
@@ -89304,7 +89468,7 @@ async function applyAtomicFileBatch(input) {
|
|
|
89304
89468
|
});
|
|
89305
89469
|
}
|
|
89306
89470
|
for (const [path4, backupPath] of [...backups.entries()].reverse()) {
|
|
89307
|
-
await mkdir28(
|
|
89471
|
+
await mkdir28(dirname36(path4), { recursive: true });
|
|
89308
89472
|
await rename4(backupPath, path4).catch((rollbackError) => {
|
|
89309
89473
|
rollbackFailures.push(`restore ${path4}: ${String(rollbackError)}`);
|
|
89310
89474
|
});
|
|
@@ -89341,7 +89505,7 @@ function detectExternalEnvironmentIssue(value) {
|
|
|
89341
89505
|
}
|
|
89342
89506
|
|
|
89343
89507
|
// src/lib/feishu.ts
|
|
89344
|
-
import { spawn as
|
|
89508
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
89345
89509
|
|
|
89346
89510
|
// src/lib/larkDocxXml.ts
|
|
89347
89511
|
import { createHash as createHash23 } from "node:crypto";
|
|
@@ -93626,7 +93790,7 @@ function projectLarkDocxXmlBlock(input) {
|
|
|
93626
93790
|
// src/lib/larkResourceMaterialization.ts
|
|
93627
93791
|
import { createHash as createHash24 } from "node:crypto";
|
|
93628
93792
|
import { mkdtemp as mkdtemp2, readFile as readFile43, readdir as readdir17, rm as rm15 } from "node:fs/promises";
|
|
93629
|
-
import { extname as extname11, join as
|
|
93793
|
+
import { extname as extname11, join as join58 } from "node:path";
|
|
93630
93794
|
import { tmpdir } from "node:os";
|
|
93631
93795
|
|
|
93632
93796
|
// src/lib/larkResourceCommand.ts
|
|
@@ -93825,7 +93989,7 @@ function findBooleanField(value, name2) {
|
|
|
93825
93989
|
return;
|
|
93826
93990
|
}
|
|
93827
93991
|
async function downloadedFile(input) {
|
|
93828
|
-
const tempRoot = await mkdtemp2(
|
|
93992
|
+
const tempRoot = await mkdtemp2(join58(tmpdir(), "context-lark-resource-"));
|
|
93829
93993
|
try {
|
|
93830
93994
|
await runLarkResourceCommand(input.runner, [
|
|
93831
93995
|
"docs",
|
|
@@ -93846,7 +94010,7 @@ async function downloadedFile(input) {
|
|
|
93846
94010
|
if (entries.length !== 1)
|
|
93847
94011
|
throw new Error(`media download produced ${entries.length} files, expected exactly one`);
|
|
93848
94012
|
const path4 = entries[0]?.name ?? "resource.bin";
|
|
93849
|
-
const bytes = await readFile43(
|
|
94013
|
+
const bytes = await readFile43(join58(tempRoot, path4));
|
|
93850
94014
|
return { path: path4, bytes, mediaType: mediaTypeFor(path4, bytes) };
|
|
93851
94015
|
} finally {
|
|
93852
94016
|
await rm15(tempRoot, { recursive: true, force: true });
|
|
@@ -93937,9 +94101,9 @@ async function sheetMaterialization(resource, runner2) {
|
|
|
93937
94101
|
const sheetId = resource.attributes["sheet-id"];
|
|
93938
94102
|
if (token === undefined || sheetId === undefined)
|
|
93939
94103
|
throw new Error("embedded Sheet requires token and sheet-id");
|
|
93940
|
-
const tempRoot = await mkdtemp2(
|
|
94104
|
+
const tempRoot = await mkdtemp2(join58(tmpdir(), "context-lark-sheet-"));
|
|
93941
94105
|
try {
|
|
93942
|
-
const outputPath =
|
|
94106
|
+
const outputPath = join58(tempRoot, "sheet.json");
|
|
93943
94107
|
const stdout = await runLarkResourceCommand(runner2, [
|
|
93944
94108
|
"sheets",
|
|
93945
94109
|
"+csv-get",
|
|
@@ -94095,7 +94259,7 @@ async function whiteboardMaterialization(resource, runner2) {
|
|
|
94095
94259
|
if (token === undefined)
|
|
94096
94260
|
throw new Error(`${resource.kind} has no whiteboard token`);
|
|
94097
94261
|
const preview = await downloadedFile({ runner: runner2, token, type: "whiteboard" });
|
|
94098
|
-
const tempRoot = await mkdtemp2(
|
|
94262
|
+
const tempRoot = await mkdtemp2(join58(tmpdir(), "context-lark-whiteboard-"));
|
|
94099
94263
|
let rawPayload;
|
|
94100
94264
|
try {
|
|
94101
94265
|
await runLarkResourceCommand(runner2, [
|
|
@@ -94113,7 +94277,7 @@ async function whiteboardMaterialization(resource, runner2) {
|
|
|
94113
94277
|
"--format",
|
|
94114
94278
|
"json"
|
|
94115
94279
|
], { cwd: tempRoot });
|
|
94116
|
-
rawPayload = JSON.parse(await readFile43(
|
|
94280
|
+
rawPayload = JSON.parse(await readFile43(join58(tempRoot, "raw.json"), "utf8"));
|
|
94117
94281
|
} finally {
|
|
94118
94282
|
await rm15(tempRoot, { recursive: true, force: true });
|
|
94119
94283
|
}
|
|
@@ -94386,7 +94550,7 @@ class LarkCliError extends Error {
|
|
|
94386
94550
|
}
|
|
94387
94551
|
}
|
|
94388
94552
|
var defaultRunner = (args, options) => new Promise((resolve8, reject) => {
|
|
94389
|
-
const child =
|
|
94553
|
+
const child = spawn3(LARK_BIN, args, {
|
|
94390
94554
|
...options?.cwd === undefined ? {} : { cwd: options.cwd },
|
|
94391
94555
|
stdio: ["ignore", "pipe", "pipe"]
|
|
94392
94556
|
});
|
|
@@ -94793,7 +94957,7 @@ async function fileContentMatches(path4, content3) {
|
|
|
94793
94957
|
}
|
|
94794
94958
|
}
|
|
94795
94959
|
function sourceManifestPath2(entry) {
|
|
94796
|
-
return entry.snapshot?.manifest ??
|
|
94960
|
+
return entry.snapshot?.manifest ?? join59(entry.materializedAt, "manifest.json");
|
|
94797
94961
|
}
|
|
94798
94962
|
function larkRuntimeError(message, detail) {
|
|
94799
94963
|
return new ContextError(ExitCode.ExternalToolError, message, {
|
|
@@ -94919,7 +95083,7 @@ function assetManifestEntry(asset, assetRoot) {
|
|
|
94919
95083
|
};
|
|
94920
95084
|
}
|
|
94921
95085
|
async function listSnapshotAssetFiles(root2, assetRoot) {
|
|
94922
|
-
const assetsRoot =
|
|
95086
|
+
const assetsRoot = join59(root2, assetRoot);
|
|
94923
95087
|
const files = [];
|
|
94924
95088
|
const visit3 = async (dir, prefix = assetRoot) => {
|
|
94925
95089
|
let entries;
|
|
@@ -94932,7 +95096,7 @@ async function listSnapshotAssetFiles(root2, assetRoot) {
|
|
|
94932
95096
|
}
|
|
94933
95097
|
for (const entry of entries) {
|
|
94934
95098
|
const relPath = `${prefix}/${entry.name}`;
|
|
94935
|
-
const absolutePath =
|
|
95099
|
+
const absolutePath = join59(dir, entry.name);
|
|
94936
95100
|
if (entry.isDirectory()) {
|
|
94937
95101
|
await visit3(absolutePath, relPath);
|
|
94938
95102
|
continue;
|
|
@@ -94947,7 +95111,7 @@ async function listSnapshotAssetFiles(root2, assetRoot) {
|
|
|
94947
95111
|
}
|
|
94948
95112
|
async function staleSnapshotAssetPaths(input) {
|
|
94949
95113
|
const existingPaths = await listSnapshotAssetFiles(input.materializedAtAbsPath, input.assetRoot);
|
|
94950
|
-
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));
|
|
94951
95115
|
}
|
|
94952
95116
|
function normalizeLarkError(error, sourceName) {
|
|
94953
95117
|
if (error instanceof ContextError)
|
|
@@ -95021,9 +95185,9 @@ async function runCaptureLarkPhaseUnlocked(input) {
|
|
|
95021
95185
|
locator
|
|
95022
95186
|
}];
|
|
95023
95187
|
const manifestPath = sourceManifestPath2(entry);
|
|
95024
|
-
const manifestAbsPath =
|
|
95188
|
+
const manifestAbsPath = join59(input.projectRoot, manifestPath);
|
|
95025
95189
|
const materializedAt = entry.materializedAt;
|
|
95026
|
-
const materializedAtAbsPath =
|
|
95190
|
+
const materializedAtAbsPath = join59(input.projectRoot, materializedAt);
|
|
95027
95191
|
const manifest = createDocumentSnapshotManifest({
|
|
95028
95192
|
sourceType: "lark",
|
|
95029
95193
|
sourceName: resolved.sourceName,
|
|
@@ -95053,13 +95217,13 @@ async function runCaptureLarkPhaseUnlocked(input) {
|
|
|
95053
95217
|
}));
|
|
95054
95218
|
try {
|
|
95055
95219
|
const requestedWrites = [{
|
|
95056
|
-
path:
|
|
95220
|
+
path: join59(materializedAtAbsPath, documentPath),
|
|
95057
95221
|
bytes: normalized
|
|
95058
95222
|
}];
|
|
95059
95223
|
for (const asset of assets) {
|
|
95060
95224
|
if (asset.bytes !== undefined) {
|
|
95061
95225
|
requestedWrites.push({
|
|
95062
|
-
path:
|
|
95226
|
+
path: join59(materializedAtAbsPath, asset.entry.path),
|
|
95063
95227
|
bytes: asset.bytes
|
|
95064
95228
|
});
|
|
95065
95229
|
}
|
|
@@ -95076,7 +95240,7 @@ async function runCaptureLarkPhaseUnlocked(input) {
|
|
|
95076
95240
|
currentPaths: new Set(assets.filter((asset) => asset.bytes !== undefined).map((asset) => asset.entry.path))
|
|
95077
95241
|
});
|
|
95078
95242
|
await applyAtomicFileBatch({
|
|
95079
|
-
transactionRoot:
|
|
95243
|
+
transactionRoot: join59(input.projectRoot, ".tmp", "context-runtime", "capture-transactions"),
|
|
95080
95244
|
writes,
|
|
95081
95245
|
removals
|
|
95082
95246
|
});
|
|
@@ -97499,7 +97663,7 @@ function compileDiagnostic(severity, code3, family, message, field, extra = {})
|
|
|
97499
97663
|
...extra
|
|
97500
97664
|
};
|
|
97501
97665
|
}
|
|
97502
|
-
function
|
|
97666
|
+
function isRecord20(value) {
|
|
97503
97667
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
97504
97668
|
}
|
|
97505
97669
|
|
|
@@ -97894,7 +98058,7 @@ function compileActionFromFields(fields) {
|
|
|
97894
98058
|
return action;
|
|
97895
98059
|
}
|
|
97896
98060
|
function parseCompileAction(raw, index2, diagnostics) {
|
|
97897
|
-
if (!
|
|
98061
|
+
if (!isRecord20(raw)) {
|
|
97898
98062
|
diagnostics.push(compileDiagnostic("error", "schema.action_object", "schema", "Each action must be an object.", `actions[${index2}]`));
|
|
97899
98063
|
return;
|
|
97900
98064
|
}
|
|
@@ -97906,7 +98070,7 @@ function parseCompileAction(raw, index2, diagnostics) {
|
|
|
97906
98070
|
}
|
|
97907
98071
|
function parseCompilePayload(value) {
|
|
97908
98072
|
const diagnostics = [];
|
|
97909
|
-
if (!
|
|
98073
|
+
if (!isRecord20(value)) {
|
|
97910
98074
|
return {
|
|
97911
98075
|
diagnostics: [compileDiagnostic("error", "schema.payload_object", "schema", "Compile action payload must be an object.", "schema")]
|
|
97912
98076
|
};
|
|
@@ -98869,9 +99033,9 @@ init_atomicWrite();
|
|
|
98869
99033
|
init_cliFeedback();
|
|
98870
99034
|
init_errors();
|
|
98871
99035
|
init_exitCode();
|
|
98872
|
-
import { existsSync as
|
|
99036
|
+
import { existsSync as existsSync38 } from "node:fs";
|
|
98873
99037
|
import { readFile as readFile46 } from "node:fs/promises";
|
|
98874
|
-
import { join as
|
|
99038
|
+
import { join as join60 } from "node:path";
|
|
98875
99039
|
init_writeLock();
|
|
98876
99040
|
var CUSTOM_PHASE_MANIFEST = ".tmp/context-runtime/extract/custom-phase-candidates.json";
|
|
98877
99041
|
function customInputError(phaseId, message, detail = {}) {
|
|
@@ -99025,8 +99189,8 @@ function candidateFromCustom(input) {
|
|
|
99025
99189
|
};
|
|
99026
99190
|
}
|
|
99027
99191
|
async function readManifest(projectRoot) {
|
|
99028
|
-
const path4 =
|
|
99029
|
-
if (!
|
|
99192
|
+
const path4 = join60(projectRoot, CUSTOM_PHASE_MANIFEST);
|
|
99193
|
+
if (!existsSync38(path4))
|
|
99030
99194
|
return { version: 2, phases: {} };
|
|
99031
99195
|
try {
|
|
99032
99196
|
const parsed = JSON.parse(await readFile46(path4, "utf8"));
|
|
@@ -99126,7 +99290,7 @@ async function runExtractCustomPhase(input) {
|
|
|
99126
99290
|
symbols: built.flatMap((item) => item.symbols),
|
|
99127
99291
|
removeSymbols: previousOwned?.symbols ?? []
|
|
99128
99292
|
});
|
|
99129
|
-
await atomicWriteFile(
|
|
99293
|
+
await atomicWriteFile(join60(input.projectRoot, CUSTOM_PHASE_MANIFEST), `${JSON.stringify({
|
|
99130
99294
|
version: 2,
|
|
99131
99295
|
phases: {
|
|
99132
99296
|
...manifest.phases,
|
|
@@ -99186,7 +99350,7 @@ async function runExtractCustomPhase(input) {
|
|
|
99186
99350
|
|
|
99187
99351
|
// src/project/reviewHtml.ts
|
|
99188
99352
|
import { mkdir as mkdir29, writeFile as writeFile24 } from "node:fs/promises";
|
|
99189
|
-
import { dirname as
|
|
99353
|
+
import { dirname as dirname37, isAbsolute as isAbsolute9, join as join62, resolve as resolve23 } from "node:path";
|
|
99190
99354
|
import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
99191
99355
|
|
|
99192
99356
|
// src/project/reviewSourceExcerpts.ts
|
|
@@ -99296,9 +99460,9 @@ async function collectReviewSourceExcerpts(projectRoot, candidates) {
|
|
|
99296
99460
|
}
|
|
99297
99461
|
|
|
99298
99462
|
// src/project/reviewHtmlPresentation.ts
|
|
99299
|
-
import { existsSync as
|
|
99463
|
+
import { existsSync as existsSync39 } from "node:fs";
|
|
99300
99464
|
import { readFile as readFile47 } from "node:fs/promises";
|
|
99301
|
-
import { join as
|
|
99465
|
+
import { join as join61 } from "node:path";
|
|
99302
99466
|
var import_yaml31 = __toESM(require_dist3(), 1);
|
|
99303
99467
|
function escapeHtml3(value) {
|
|
99304
99468
|
return value.replace(/&/gu, "&").replace(/</gu, "<").replace(/>/gu, ">").replace(/"/gu, """);
|
|
@@ -99379,8 +99543,8 @@ function filterEdgePreviewForCandidate(record, edges) {
|
|
|
99379
99543
|
return edges.filter((edge2) => endpoints.has(edge2.from) || endpoints.has(edge2.to));
|
|
99380
99544
|
}
|
|
99381
99545
|
async function readEdgePreview(projectRoot) {
|
|
99382
|
-
const filePath =
|
|
99383
|
-
if (!
|
|
99546
|
+
const filePath = join61(projectRoot, LIFECYCLE_STRUCTURE_FILE);
|
|
99547
|
+
if (!existsSync39(filePath))
|
|
99384
99548
|
return [];
|
|
99385
99549
|
try {
|
|
99386
99550
|
const parsed = import_yaml31.default.parse(await readFile47(filePath, "utf8"));
|
|
@@ -99557,7 +99721,7 @@ var REVIEW_HTML_STYLES = `
|
|
|
99557
99721
|
`;
|
|
99558
99722
|
|
|
99559
99723
|
// src/project/reviewHtml.ts
|
|
99560
|
-
var REVIEW_HTML_ROOT =
|
|
99724
|
+
var REVIEW_HTML_ROOT = join62(".tmp", "context-runtime", "review");
|
|
99561
99725
|
function decodedLinkTarget(value) {
|
|
99562
99726
|
try {
|
|
99563
99727
|
return decodeURIComponent(value);
|
|
@@ -99571,7 +99735,7 @@ function linkedResourcePreviews(input) {
|
|
|
99571
99735
|
const target = link2.target;
|
|
99572
99736
|
if (/^[a-z][a-z0-9+.-]*:/iu.test(target) || target.startsWith("/"))
|
|
99573
99737
|
continue;
|
|
99574
|
-
const assetPath =
|
|
99738
|
+
const assetPath = join62(dirname37(input.documentPath), decodedLinkTarget(target)).split("\\").join("/");
|
|
99575
99739
|
const asset = input.assetsByPath.get(assetPath);
|
|
99576
99740
|
if (asset?.content_hash === undefined || asset.role === "audit")
|
|
99577
99741
|
continue;
|
|
@@ -99579,7 +99743,7 @@ function linkedResourcePreviews(input) {
|
|
|
99579
99743
|
label: link2.label || "Resource",
|
|
99580
99744
|
kind: asset.source?.kind ?? "resource",
|
|
99581
99745
|
status: "materialized",
|
|
99582
|
-
url: pathToFileURL3(
|
|
99746
|
+
url: pathToFileURL3(join62(input.projectRoot, input.materializedAt, asset.path)).href,
|
|
99583
99747
|
media_type: asset.media_type ?? "application/octet-stream",
|
|
99584
99748
|
image: asset.media_type?.startsWith("image/") === true
|
|
99585
99749
|
});
|
|
@@ -99588,7 +99752,7 @@ function linkedResourcePreviews(input) {
|
|
|
99588
99752
|
}
|
|
99589
99753
|
function materializationPreview(input) {
|
|
99590
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");
|
|
99591
|
-
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);
|
|
99592
99756
|
return {
|
|
99593
99757
|
key: linkedAsset?.path ?? input.item.locator,
|
|
99594
99758
|
preview: {
|
|
@@ -100132,7 +100296,7 @@ function renderReviewHtml(candidates, reviewScope, edgePreview, sourceExcerpts,
|
|
|
100132
100296
|
}
|
|
100133
100297
|
function resolveOutputPath(projectRoot, outPath, reviewScope) {
|
|
100134
100298
|
if (outPath === undefined)
|
|
100135
|
-
return
|
|
100299
|
+
return join62(projectRoot, REVIEW_HTML_ROOT, `${reviewScope}.html`);
|
|
100136
100300
|
return isAbsolute9(outPath) ? outPath : resolve23(projectRoot, outPath);
|
|
100137
100301
|
}
|
|
100138
100302
|
async function writeReviewHtml(input) {
|
|
@@ -100145,7 +100309,7 @@ async function writeReviewHtml(input) {
|
|
|
100145
100309
|
const sourceExcerpts = await collectReviewSourceExcerpts(input.projectRoot, candidates);
|
|
100146
100310
|
const resourcePreviews = await collectReviewResourcePreviews(input.projectRoot, candidates);
|
|
100147
100311
|
const outPath = resolveOutputPath(input.projectRoot, input.out, reviewScope);
|
|
100148
|
-
await mkdir29(
|
|
100312
|
+
await mkdir29(dirname37(outPath), { recursive: true });
|
|
100149
100313
|
await writeFile24(outPath, renderReviewHtml(candidates, reviewScope, edgePreview, sourceExcerpts, resourcePreviews), "utf8");
|
|
100150
100314
|
return {
|
|
100151
100315
|
path: outPath,
|
|
@@ -100560,17 +100724,17 @@ function compactJsonResult(result, verbose) {
|
|
|
100560
100724
|
}
|
|
100561
100725
|
|
|
100562
100726
|
// src/project/runLog.ts
|
|
100563
|
-
import { randomUUID as
|
|
100727
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
100564
100728
|
import { mkdir as mkdir30, writeFile as writeFile25 } from "node:fs/promises";
|
|
100565
|
-
import { dirname as
|
|
100729
|
+
import { dirname as dirname38, join as join63 } from "node:path";
|
|
100566
100730
|
var createPhaseRunId = () => {
|
|
100567
100731
|
const timestamp = new Date().toISOString().replace(/[-:.TZ]/gu, "");
|
|
100568
|
-
return `run_${timestamp}_${
|
|
100732
|
+
return `run_${timestamp}_${randomUUID3().slice(0, 8)}`;
|
|
100569
100733
|
};
|
|
100570
100734
|
async function writePhaseRunLog(input) {
|
|
100571
|
-
const relPath =
|
|
100572
|
-
const absPath =
|
|
100573
|
-
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 });
|
|
100574
100738
|
await writeFile25(absPath, `${JSON.stringify({
|
|
100575
100739
|
run_id: input.runId,
|
|
100576
100740
|
phase_id: input.phase.id,
|
|
@@ -101271,14 +101435,14 @@ init_exitCode();
|
|
|
101271
101435
|
import { resolve as resolve24 } from "node:path";
|
|
101272
101436
|
init_workspace();
|
|
101273
101437
|
var PROSE_STRUCTURE_BATCH_SCHEMA = "context.prose.structure-batch.v1";
|
|
101274
|
-
function
|
|
101438
|
+
function isRecord21(value) {
|
|
101275
101439
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
101276
101440
|
}
|
|
101277
101441
|
function shellQuote8(value) {
|
|
101278
101442
|
return /^[A-Za-z0-9._/=-]+$/u.test(value) ? value : `'${value.replace(/'/gu, `'"'"'`)}'`;
|
|
101279
101443
|
}
|
|
101280
101444
|
function parseBatchPayload(value) {
|
|
101281
|
-
if (!
|
|
101445
|
+
if (!isRecord21(value) || value.schema !== PROSE_STRUCTURE_BATCH_SCHEMA || !Array.isArray(value.items)) {
|
|
101282
101446
|
throw new ContextError(ExitCode.UserError, `batch input must match ${PROSE_STRUCTURE_BATCH_SCHEMA}`, {
|
|
101283
101447
|
category: ErrorCategory.UserInputInvalid,
|
|
101284
101448
|
next: "Read the current Route action input_schema and provide one phase_id/input pair per pending structure slot."
|
|
@@ -101291,7 +101455,7 @@ function parseBatchPayload(value) {
|
|
|
101291
101455
|
}
|
|
101292
101456
|
const seen = new Set;
|
|
101293
101457
|
return value.items.map((item, index2) => {
|
|
101294
|
-
if (!
|
|
101458
|
+
if (!isRecord21(item) || typeof item.phase_id !== "string" || typeof item.input !== "string") {
|
|
101295
101459
|
throw new ContextError(ExitCode.UserError, `structure batch items[${index2}] requires phase_id and input`, {
|
|
101296
101460
|
category: ErrorCategory.UserInputInvalid
|
|
101297
101461
|
});
|
|
@@ -101323,7 +101487,7 @@ function alignPhase(phases, phaseId) {
|
|
|
101323
101487
|
return phase;
|
|
101324
101488
|
}
|
|
101325
101489
|
function validationSummary(phaseId, input, result) {
|
|
101326
|
-
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;
|
|
101327
101491
|
return {
|
|
101328
101492
|
phase_id: phaseId,
|
|
101329
101493
|
input,
|
|
@@ -101817,7 +101981,7 @@ init_debugTrace();
|
|
|
101817
101981
|
// src/project/workflow/workflowExecutionRuntime.ts
|
|
101818
101982
|
init_debugTrace();
|
|
101819
101983
|
import { createHash as createHash26 } from "node:crypto";
|
|
101820
|
-
import { spawn as
|
|
101984
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
101821
101985
|
function digestText2(value, includeTail) {
|
|
101822
101986
|
const bytes = Buffer.byteLength(value);
|
|
101823
101987
|
return {
|
|
@@ -101967,7 +102131,7 @@ execution scope cleanup failed`, true)
|
|
|
101967
102131
|
try {
|
|
101968
102132
|
receipt = await new Promise((resolve8, reject) => {
|
|
101969
102133
|
let settled = false;
|
|
101970
|
-
const child =
|
|
102134
|
+
const child = spawn4(process.execPath, [this.cliEntryPath, ...args], {
|
|
101971
102135
|
cwd: input.cwd,
|
|
101972
102136
|
env: { ...process.env, ...debugChildEnvironment() },
|
|
101973
102137
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -102332,7 +102496,7 @@ function requirePayloadHeaderField(value, field) {
|
|
|
102332
102496
|
return value;
|
|
102333
102497
|
}
|
|
102334
102498
|
function parsePayloadLineDecision(value, index2) {
|
|
102335
|
-
if (!
|
|
102499
|
+
if (!isRecord17(value) || typeof value.candidate_id !== "string") {
|
|
102336
102500
|
throw new ContextError(ExitCode.UserError, `review payload line ${index2} must contain candidate_id and status`, {
|
|
102337
102501
|
category: ErrorCategory.UserInputInvalid
|
|
102338
102502
|
});
|
|
@@ -102345,7 +102509,7 @@ function parsePayloadLineDecision(value, index2) {
|
|
|
102345
102509
|
function parsePayloadScope(value) {
|
|
102346
102510
|
if (value === undefined)
|
|
102347
102511
|
return;
|
|
102348
|
-
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)) {
|
|
102349
102513
|
throw new ContextError(ExitCode.UserError, "review payload scope must contain count and ids_sha256", {
|
|
102350
102514
|
category: ErrorCategory.UserInputInvalid
|
|
102351
102515
|
});
|
|
@@ -102384,7 +102548,7 @@ function parsePayloadScope(value) {
|
|
|
102384
102548
|
}
|
|
102385
102549
|
function parsePayloadValues(parsed) {
|
|
102386
102550
|
const first = parsed[0];
|
|
102387
|
-
if (!
|
|
102551
|
+
if (!isRecord17(first)) {
|
|
102388
102552
|
throw new ContextError(ExitCode.UserError, "review payload header must be a JSON object", {
|
|
102389
102553
|
category: ErrorCategory.UserInputInvalid
|
|
102390
102554
|
});
|
|
@@ -103296,7 +103460,7 @@ async function runManagedUntil(input) {
|
|
|
103296
103460
|
const resourceReceipts = input.resourceReceiptsReference === undefined ? undefined : await parseWorkflowResourceReceipts(input.resourceReceiptsReference, found.projectRoot);
|
|
103297
103461
|
const runtime = new WorkspaceExecutionRuntime({
|
|
103298
103462
|
projectRoot: found.projectRoot,
|
|
103299
|
-
cliEntryPath:
|
|
103463
|
+
cliEntryPath: fileURLToPath8(input.cliModuleUrl),
|
|
103300
103464
|
inProcess: createWorkflowInProcessExecutor()
|
|
103301
103465
|
});
|
|
103302
103466
|
let result;
|
|
@@ -103441,10 +103605,10 @@ function registerDebugCommands(program2) {
|
|
|
103441
103605
|
|
|
103442
103606
|
// src/commands/cleanClaudePluginCache.ts
|
|
103443
103607
|
init_cliFeedback();
|
|
103444
|
-
import { existsSync as
|
|
103608
|
+
import { existsSync as existsSync40 } from "node:fs";
|
|
103445
103609
|
import { readdir as readdir19, rm as rm16 } from "node:fs/promises";
|
|
103446
103610
|
import { homedir } from "node:os";
|
|
103447
|
-
import { join as
|
|
103611
|
+
import { join as join64 } from "node:path";
|
|
103448
103612
|
var ORPHAN_MARKER = ".orphaned_at";
|
|
103449
103613
|
var CLAUDE_PLUGIN_CACHE_ROOT_ENV = "C4A_CLAUDE_PLUGIN_CACHE_ROOT";
|
|
103450
103614
|
var CLAUDE_PLUGIN_CACHE_HOME_ENV = "C4A_CLAUDE_PLUGIN_CACHE_HOME";
|
|
@@ -103453,7 +103617,7 @@ async function cleanClaudePluginCache(opts = {}) {
|
|
|
103453
103617
|
const lines = [];
|
|
103454
103618
|
let removed = 0;
|
|
103455
103619
|
let scanned = 0;
|
|
103456
|
-
if (!
|
|
103620
|
+
if (!existsSync40(cacheRoot)) {
|
|
103457
103621
|
lines.push("· claude plugin cache: missing — nothing to clean");
|
|
103458
103622
|
return { lines, removed, scanned };
|
|
103459
103623
|
}
|
|
@@ -103461,20 +103625,20 @@ async function cleanClaudePluginCache(opts = {}) {
|
|
|
103461
103625
|
for (const mp of marketplaces) {
|
|
103462
103626
|
if (!mp.isDirectory())
|
|
103463
103627
|
continue;
|
|
103464
|
-
const mpDir =
|
|
103628
|
+
const mpDir = join64(cacheRoot, mp.name);
|
|
103465
103629
|
const plugins = await readdir19(mpDir, { withFileTypes: true });
|
|
103466
103630
|
for (const pl of plugins) {
|
|
103467
103631
|
if (!pl.isDirectory())
|
|
103468
103632
|
continue;
|
|
103469
|
-
const plDir =
|
|
103633
|
+
const plDir = join64(mpDir, pl.name);
|
|
103470
103634
|
const versions = await readdir19(plDir, { withFileTypes: true });
|
|
103471
103635
|
for (const ver of versions) {
|
|
103472
103636
|
if (!ver.isDirectory())
|
|
103473
103637
|
continue;
|
|
103474
103638
|
scanned += 1;
|
|
103475
|
-
const verDir =
|
|
103476
|
-
const markerPath =
|
|
103477
|
-
if (!
|
|
103639
|
+
const verDir = join64(plDir, ver.name);
|
|
103640
|
+
const markerPath = join64(verDir, ORPHAN_MARKER);
|
|
103641
|
+
if (!existsSync40(markerPath))
|
|
103478
103642
|
continue;
|
|
103479
103643
|
const label3 = `${mp.name}/${pl.name}/${ver.name}`;
|
|
103480
103644
|
if (opts.dryRun) {
|
|
@@ -103505,7 +103669,7 @@ function resolveClaudePluginCacheRoot(opts) {
|
|
|
103505
103669
|
if (explicitRoot)
|
|
103506
103670
|
return explicitRoot;
|
|
103507
103671
|
const home = opts.home ?? process.env[CLAUDE_PLUGIN_CACHE_HOME_ENV] ?? homedir();
|
|
103508
|
-
return
|
|
103672
|
+
return join64(home, ".claude", "plugins", "cache");
|
|
103509
103673
|
}
|
|
103510
103674
|
async function isEmptyDir(dir) {
|
|
103511
103675
|
try {
|
|
@@ -103531,17 +103695,17 @@ async function runDoctorCleanClaudePluginCache(opts = {}) {
|
|
|
103531
103695
|
}
|
|
103532
103696
|
|
|
103533
103697
|
// src/commands/cleanCache.ts
|
|
103534
|
-
import { existsSync as
|
|
103698
|
+
import { existsSync as existsSync42 } from "node:fs";
|
|
103535
103699
|
import { readdir as readdir20, rm as rm17 } from "node:fs/promises";
|
|
103536
|
-
import { join as
|
|
103700
|
+
import { join as join68 } from "node:path";
|
|
103537
103701
|
|
|
103538
103702
|
// src/incremental/cache.ts
|
|
103539
|
-
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";
|
|
103540
103704
|
|
|
103541
103705
|
// src/lib/workspaceLayout.ts
|
|
103542
103706
|
var import_yaml32 = __toESM(require_dist3(), 1);
|
|
103543
|
-
import { existsSync as
|
|
103544
|
-
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";
|
|
103545
103709
|
function isDirectorySafe(path4) {
|
|
103546
103710
|
try {
|
|
103547
103711
|
return statSync2(path4).isDirectory();
|
|
@@ -103550,11 +103714,11 @@ function isDirectorySafe(path4) {
|
|
|
103550
103714
|
}
|
|
103551
103715
|
}
|
|
103552
103716
|
function hasRootLayoutMarker(dir) {
|
|
103553
|
-
const configPath =
|
|
103554
|
-
if (!
|
|
103717
|
+
const configPath = join65(dir, "config.yaml");
|
|
103718
|
+
if (!existsSync41(configPath))
|
|
103555
103719
|
return false;
|
|
103556
103720
|
try {
|
|
103557
|
-
const parsed = import_yaml32.default.parse(
|
|
103721
|
+
const parsed = import_yaml32.default.parse(readFileSync9(configPath, "utf8"));
|
|
103558
103722
|
if (!parsed || typeof parsed !== "object")
|
|
103559
103723
|
return false;
|
|
103560
103724
|
const workspace = parsed.workspace;
|
|
@@ -103567,8 +103731,8 @@ function hasRootLayoutMarker(dir) {
|
|
|
103567
103731
|
}
|
|
103568
103732
|
function findWorkspaceAt(dir) {
|
|
103569
103733
|
const root2 = resolve26(dir);
|
|
103570
|
-
const embedded =
|
|
103571
|
-
if (
|
|
103734
|
+
const embedded = join65(root2, ".context");
|
|
103735
|
+
if (existsSync41(join65(embedded, "config.yaml")) && isDirectorySafe(embedded)) {
|
|
103572
103736
|
return { ctxDir: embedded, workspaceRoot: root2, layout: "embedded" };
|
|
103573
103737
|
}
|
|
103574
103738
|
if (hasRootLayoutMarker(root2)) {
|
|
@@ -103585,7 +103749,7 @@ function findNearestWorkspace(startDir = process.cwd()) {
|
|
|
103585
103749
|
return found;
|
|
103586
103750
|
if (dir === root2)
|
|
103587
103751
|
return null;
|
|
103588
|
-
const parent =
|
|
103752
|
+
const parent = dirname39(dir);
|
|
103589
103753
|
if (parent === dir)
|
|
103590
103754
|
return null;
|
|
103591
103755
|
dir = parent;
|
|
@@ -103593,9 +103757,9 @@ function findNearestWorkspace(startDir = process.cwd()) {
|
|
|
103593
103757
|
}
|
|
103594
103758
|
|
|
103595
103759
|
// src/lib/userCache.ts
|
|
103596
|
-
import { basename as basename9, join as
|
|
103760
|
+
import { basename as basename9, join as join66 } from "node:path";
|
|
103597
103761
|
function workspaceLocalUserCacheRoot(ctxDir) {
|
|
103598
|
-
return
|
|
103762
|
+
return join66(ctxDir, ".tmp", "context-cli");
|
|
103599
103763
|
}
|
|
103600
103764
|
|
|
103601
103765
|
// src/incremental/cache.ts
|
|
@@ -103605,7 +103769,7 @@ function resolveCachePath(value) {
|
|
|
103605
103769
|
}
|
|
103606
103770
|
function workspaceCacheHome(workspaceRoot) {
|
|
103607
103771
|
const location = findWorkspaceAt(workspaceRoot);
|
|
103608
|
-
return workspaceLocalUserCacheRoot(location?.ctxDir ??
|
|
103772
|
+
return workspaceLocalUserCacheRoot(location?.ctxDir ?? join67(workspaceRoot, ".context"));
|
|
103609
103773
|
}
|
|
103610
103774
|
function resolveCacheHome(input = {}) {
|
|
103611
103775
|
const explicit = input.cacheHome ?? process.env.C4A_CONTEXT_CACHE_HOME;
|
|
@@ -103614,24 +103778,24 @@ function resolveCacheHome(input = {}) {
|
|
|
103614
103778
|
if (input.workspaceRoot !== undefined)
|
|
103615
103779
|
return workspaceCacheHome(resolveCachePath(input.workspaceRoot));
|
|
103616
103780
|
const nearest = findNearestWorkspace(process.cwd());
|
|
103617
|
-
return workspaceLocalUserCacheRoot(nearest?.ctxDir ??
|
|
103781
|
+
return workspaceLocalUserCacheRoot(nearest?.ctxDir ?? join67(process.cwd(), ".context"));
|
|
103618
103782
|
}
|
|
103619
103783
|
|
|
103620
103784
|
// src/commands/cleanCache.ts
|
|
103621
103785
|
async function countFiles2(dir) {
|
|
103622
|
-
if (!
|
|
103786
|
+
if (!existsSync42(dir))
|
|
103623
103787
|
return 0;
|
|
103624
103788
|
let count = 0;
|
|
103625
103789
|
for (const entry of await readdir20(dir, { withFileTypes: true })) {
|
|
103626
|
-
const full =
|
|
103790
|
+
const full = join68(dir, entry.name);
|
|
103627
103791
|
count += entry.isDirectory() ? await countFiles2(full) : 1;
|
|
103628
103792
|
}
|
|
103629
103793
|
return count;
|
|
103630
103794
|
}
|
|
103631
103795
|
async function inspectAllRetrievalCache() {
|
|
103632
103796
|
const cacheHome = resolveCacheHome();
|
|
103633
|
-
const cacheRoot =
|
|
103634
|
-
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() : [];
|
|
103635
103799
|
const files = await countFiles2(cacheRoot);
|
|
103636
103800
|
return { cacheRoot, projects: projectIds.length, files, projectIds };
|
|
103637
103801
|
}
|
|
@@ -103649,8 +103813,6 @@ async function cleanAllRetrievalCache() {
|
|
|
103649
103813
|
init_errors();
|
|
103650
103814
|
init_cliFeedback();
|
|
103651
103815
|
init_exitCode();
|
|
103652
|
-
init_workspace();
|
|
103653
|
-
init_packageTemplateReview();
|
|
103654
103816
|
|
|
103655
103817
|
// src/project/sourceCommands.ts
|
|
103656
103818
|
import { readFile as readFile54 } from "node:fs/promises";
|
|
@@ -103665,9 +103827,9 @@ init_cliFeedback();
|
|
|
103665
103827
|
init_errors();
|
|
103666
103828
|
init_exitCode();
|
|
103667
103829
|
import { execFile as execFile6 } from "node:child_process";
|
|
103668
|
-
import { existsSync as
|
|
103830
|
+
import { existsSync as existsSync43 } from "node:fs";
|
|
103669
103831
|
import { lstat as lstat3, mkdir as mkdir31, readlink as readlink2, realpath as realpath4, rm as rm18, symlink as symlink2 } from "node:fs/promises";
|
|
103670
|
-
import { basename as basename11, dirname as
|
|
103832
|
+
import { basename as basename11, dirname as dirname41, isAbsolute as isAbsolute12, relative as relative20, resolve as resolve28 } from "node:path";
|
|
103671
103833
|
import { promisify as promisify6 } from "node:util";
|
|
103672
103834
|
init_writeLock();
|
|
103673
103835
|
var execFileAsync6 = promisify6(execFile6);
|
|
@@ -103809,7 +103971,7 @@ async function git2(cwd, args) {
|
|
|
103809
103971
|
}
|
|
103810
103972
|
async function resolveGitRoot2(path4) {
|
|
103811
103973
|
const root2 = await git2(path4, ["rev-parse", "--show-toplevel"]);
|
|
103812
|
-
if (root2.length === 0 || !
|
|
103974
|
+
if (root2.length === 0 || !existsSync43(root2)) {
|
|
103813
103975
|
throw userInputError3(`local repository path is not a Git checkout: ${path4}`, { path: path4 });
|
|
103814
103976
|
}
|
|
103815
103977
|
return realpath4(root2);
|
|
@@ -103830,13 +103992,13 @@ async function verifyCheckout(input) {
|
|
|
103830
103992
|
}
|
|
103831
103993
|
async function cloneCheckout(input) {
|
|
103832
103994
|
const target = resolve28(input.projectRoot, input.target ?? `.tmp/repo/${repositorySlug(input.remote)}-${input.ref.slice(0, 12)}`);
|
|
103833
|
-
if (
|
|
103995
|
+
if (existsSync43(target)) {
|
|
103834
103996
|
throw userInputError3(`clone target already exists: ${target}`, {
|
|
103835
103997
|
target,
|
|
103836
103998
|
next: `Use local mode with path ${JSON.stringify(target)} after inspecting the existing checkout.`
|
|
103837
103999
|
});
|
|
103838
104000
|
}
|
|
103839
|
-
await mkdir31(
|
|
104001
|
+
await mkdir31(dirname41(target), { recursive: true });
|
|
103840
104002
|
const cloneArgs = ["clone", "--no-checkout", "--depth=1", "--filter=blob:none", input.remote, target];
|
|
103841
104003
|
try {
|
|
103842
104004
|
await execFileAsync6("git", cloneArgs, { encoding: "utf8", maxBuffer: 4 * 1024 * 1024 });
|
|
@@ -103885,7 +104047,7 @@ async function bindLocalAlias(input) {
|
|
|
103885
104047
|
const stats = await lstat3(alias).catch(() => null);
|
|
103886
104048
|
if (stats !== null) {
|
|
103887
104049
|
if (stats.isSymbolicLink()) {
|
|
103888
|
-
const actual = resolve28(
|
|
104050
|
+
const actual = resolve28(dirname41(alias), await readlink2(alias));
|
|
103889
104051
|
const actualReal = await realpath4(actual).catch(() => null);
|
|
103890
104052
|
if (actualReal !== null && actualReal === await realpath4(input.checkout))
|
|
103891
104053
|
return;
|
|
@@ -103901,8 +104063,8 @@ async function bindLocalAlias(input) {
|
|
|
103901
104063
|
});
|
|
103902
104064
|
}
|
|
103903
104065
|
}
|
|
103904
|
-
await mkdir31(
|
|
103905
|
-
await symlink2(relative20(
|
|
104066
|
+
await mkdir31(dirname41(alias), { recursive: true });
|
|
104067
|
+
await symlink2(relative20(dirname41(alias), input.checkout) || ".", alias);
|
|
103906
104068
|
}
|
|
103907
104069
|
function selectPhysicalGroup(sources, selector) {
|
|
103908
104070
|
const direct = selectRepoSources(sources, selector);
|
|
@@ -103989,13 +104151,13 @@ async function restoreRepositorySources(input) {
|
|
|
103989
104151
|
}
|
|
103990
104152
|
|
|
103991
104153
|
// src/project/sourceDocumentStatus.ts
|
|
103992
|
-
import { existsSync as
|
|
104154
|
+
import { existsSync as existsSync44 } from "node:fs";
|
|
103993
104155
|
import { readFile as readFile51 } from "node:fs/promises";
|
|
103994
|
-
import { join as
|
|
104156
|
+
import { join as join70 } from "node:path";
|
|
103995
104157
|
|
|
103996
104158
|
// src/project/sourceCommandViews.ts
|
|
103997
104159
|
import { readFile as readFile50 } from "node:fs/promises";
|
|
103998
|
-
import { join as
|
|
104160
|
+
import { join as join69 } from "node:path";
|
|
103999
104161
|
init_workspace();
|
|
104000
104162
|
function repoSourceAgentView(source2) {
|
|
104001
104163
|
return {
|
|
@@ -104057,7 +104219,7 @@ async function fileSourceAgentViewWithNextAction(input) {
|
|
|
104057
104219
|
};
|
|
104058
104220
|
}
|
|
104059
104221
|
function documentSourceManifestPath(source2) {
|
|
104060
|
-
return source2.snapshot?.manifest ??
|
|
104222
|
+
return source2.snapshot?.manifest ?? join69(source2.materializedAt, "manifest.json");
|
|
104061
104223
|
}
|
|
104062
104224
|
async function fileSourceDocumentSiteHint(input) {
|
|
104063
104225
|
const detection = await detectDocumentSiteFiles({
|
|
@@ -104067,7 +104229,7 @@ async function fileSourceDocumentSiteHint(input) {
|
|
|
104067
104229
|
let snapshotConfigured = false;
|
|
104068
104230
|
const manifest = documentSourceManifestPath(input.source);
|
|
104069
104231
|
try {
|
|
104070
|
-
const parsed = parseDocumentSnapshotForSource(JSON.parse(await readFile50(
|
|
104232
|
+
const parsed = parseDocumentSnapshotForSource(JSON.parse(await readFile50(join69(input.projectRoot, manifest), "utf8")), input.source.name);
|
|
104071
104233
|
snapshotConfigured = manifestUsesMdxJsonDocs(parsed);
|
|
104072
104234
|
} catch {
|
|
104073
104235
|
snapshotConfigured = false;
|
|
@@ -104098,12 +104260,12 @@ async function larkSourceAgentViewWithNextAction(input) {
|
|
|
104098
104260
|
|
|
104099
104261
|
// src/project/sourceDocumentStatus.ts
|
|
104100
104262
|
function documentSourceManifestPath2(source2) {
|
|
104101
|
-
return source2.snapshot?.manifest ??
|
|
104263
|
+
return source2.snapshot?.manifest ?? join70(source2.materializedAt, "manifest.json");
|
|
104102
104264
|
}
|
|
104103
104265
|
async function documentSnapshotState(input) {
|
|
104104
104266
|
const manifest = documentSourceManifestPath2(input.source);
|
|
104105
|
-
const manifestPath =
|
|
104106
|
-
if (!
|
|
104267
|
+
const manifestPath = join70(input.projectRoot, manifest);
|
|
104268
|
+
if (!existsSync44(manifestPath)) {
|
|
104107
104269
|
return {
|
|
104108
104270
|
snapshotReady: false,
|
|
104109
104271
|
state: "needs-capture",
|
|
@@ -104181,7 +104343,7 @@ async function documentSnapshotState(input) {
|
|
|
104181
104343
|
const missing = [
|
|
104182
104344
|
...parsed.files.map((file) => file.path),
|
|
104183
104345
|
...(parsed.assets ?? []).filter((asset) => asset.content_hash !== undefined).map((asset) => asset.path)
|
|
104184
|
-
].find((path4) => !
|
|
104346
|
+
].find((path4) => !existsSync44(join70(input.projectRoot, input.source.materializedAt, path4)));
|
|
104185
104347
|
if (missing !== undefined) {
|
|
104186
104348
|
return {
|
|
104187
104349
|
snapshotReady: false,
|
|
@@ -104253,7 +104415,7 @@ async function inspectDocumentSources(input) {
|
|
|
104253
104415
|
// src/project/documentSourceRegistration.ts
|
|
104254
104416
|
import { createHash as createHash27 } from "node:crypto";
|
|
104255
104417
|
import { readFile as readFile52, realpath as realpath5 } from "node:fs/promises";
|
|
104256
|
-
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";
|
|
104257
104419
|
init_atomicWrite();
|
|
104258
104420
|
init_cliFeedback();
|
|
104259
104421
|
init_errors();
|
|
@@ -104354,7 +104516,7 @@ function assertSafeFileInclude(value) {
|
|
|
104354
104516
|
}
|
|
104355
104517
|
async function readRegistryDocument(projectRoot, registryPath2) {
|
|
104356
104518
|
try {
|
|
104357
|
-
const content3 = await readFile52(
|
|
104519
|
+
const content3 = await readFile52(join71(projectRoot, registryPath2), "utf8");
|
|
104358
104520
|
return content3.trim().length === 0 ? { sources: [] } : import_yaml33.default.parse(content3);
|
|
104359
104521
|
} catch (error) {
|
|
104360
104522
|
if (error instanceof Error && "code" in error && error.code === "ENOENT")
|
|
@@ -104472,7 +104634,7 @@ async function addFileSourceUnlocked(input) {
|
|
|
104472
104634
|
const record2 = entry2;
|
|
104473
104635
|
return record2.name !== input.name && record2.id !== input.name;
|
|
104474
104636
|
}), nextEntry];
|
|
104475
|
-
await atomicWriteFile(
|
|
104637
|
+
await atomicWriteFile(join71(input.projectRoot, DEFAULT_FILE_SOURCES_REGISTRY_PATH), import_yaml33.default.stringify({ sources: nextSources }));
|
|
104476
104638
|
const updated = await loadSourcesRegistry({ rootDir: input.projectRoot });
|
|
104477
104639
|
const entry = updated.files.find((source2) => source2.name === input.name || source2.id === input.name);
|
|
104478
104640
|
if (entry === undefined) {
|
|
@@ -104528,7 +104690,7 @@ async function addLarkSourceUnlocked(input) {
|
|
|
104528
104690
|
const record2 = entry2;
|
|
104529
104691
|
return record2.name !== input.name && record2.id !== input.name;
|
|
104530
104692
|
}), nextEntry];
|
|
104531
|
-
await atomicWriteFile(
|
|
104693
|
+
await atomicWriteFile(join71(input.projectRoot, DEFAULT_LARK_SOURCES_REGISTRY_PATH), import_yaml33.default.stringify({ sources: nextSources }));
|
|
104532
104694
|
const updated = await loadSourcesRegistry({ rootDir: input.projectRoot });
|
|
104533
104695
|
const entry = updated.larks.find((source2) => source2.name === input.name || source2.id === input.name);
|
|
104534
104696
|
if (entry === undefined) {
|
|
@@ -104716,10 +104878,10 @@ async function registerSourceBatch(input) {
|
|
|
104716
104878
|
}
|
|
104717
104879
|
|
|
104718
104880
|
// src/project/sourceRemoval.ts
|
|
104719
|
-
import { existsSync as
|
|
104881
|
+
import { existsSync as existsSync45 } from "node:fs";
|
|
104720
104882
|
import { createHash as createHash28 } from "node:crypto";
|
|
104721
104883
|
import { readFile as readFile53, readdir as readdir21, rm as rm19 } from "node:fs/promises";
|
|
104722
|
-
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";
|
|
104723
104885
|
var import_yaml34 = __toESM(require_dist3(), 1);
|
|
104724
104886
|
init_atomicWrite();
|
|
104725
104887
|
init_cliFeedback();
|
|
@@ -104758,8 +104920,8 @@ function collectStrings(value, output) {
|
|
|
104758
104920
|
}
|
|
104759
104921
|
}
|
|
104760
104922
|
async function yamlReferences(input) {
|
|
104761
|
-
const absolutePath =
|
|
104762
|
-
if (!
|
|
104923
|
+
const absolutePath = join72(input.projectRoot, input.path);
|
|
104924
|
+
if (!existsSync45(absolutePath))
|
|
104763
104925
|
return false;
|
|
104764
104926
|
const parsed = import_yaml34.default.parse(await readFile53(absolutePath, "utf8"));
|
|
104765
104927
|
const strings = [];
|
|
@@ -104866,8 +105028,8 @@ function removeDocumentEntry(document4, source2) {
|
|
|
104866
105028
|
}
|
|
104867
105029
|
async function registryRemovalWrite(projectRoot, source2) {
|
|
104868
105030
|
const path4 = registryPath2(source2.type);
|
|
104869
|
-
const absolutePath =
|
|
104870
|
-
const document4 =
|
|
105031
|
+
const absolutePath = join72(projectRoot, path4);
|
|
105032
|
+
const document4 = existsSync45(absolutePath) ? import_yaml34.default.parse(await readFile53(absolutePath, "utf8")) : { sources: [] };
|
|
104871
105033
|
return {
|
|
104872
105034
|
path: absolutePath,
|
|
104873
105035
|
bytes: import_yaml34.default.stringify(removeDocumentEntry(document4, source2))
|
|
@@ -104885,7 +105047,7 @@ function safeManagedMaterializedPath(projectRoot, source2) {
|
|
|
104885
105047
|
return absolute;
|
|
104886
105048
|
}
|
|
104887
105049
|
function safeManagedManifestPath(projectRoot, source2) {
|
|
104888
|
-
const manifest = source2.manifest ??
|
|
105050
|
+
const manifest = source2.manifest ?? join72(source2.materializedAt, "manifest.json");
|
|
104889
105051
|
if (isAbsolute14(manifest))
|
|
104890
105052
|
throw unsafeOwnership(source2, manifest);
|
|
104891
105053
|
const absolute = resolve30(projectRoot, manifest);
|
|
@@ -104991,7 +105153,7 @@ async function createRemovalPlan(projectRoot, selector) {
|
|
|
104991
105153
|
}
|
|
104992
105154
|
} else {
|
|
104993
105155
|
const materializedPath = safeManagedMaterializedPath(projectRoot, source2);
|
|
104994
|
-
if (materializedPath !== undefined && sharedMaterializedBy.length === 0 &&
|
|
105156
|
+
if (materializedPath !== undefined && sharedMaterializedBy.length === 0 && existsSync45(materializedPath)) {
|
|
104995
105157
|
absoluteRemovals.push(materializedPath);
|
|
104996
105158
|
cleanup = {
|
|
104997
105159
|
mode: "exclusive-materialization",
|
|
@@ -105037,9 +105199,9 @@ function publicRemovalResult(plan, action) {
|
|
|
105037
105199
|
};
|
|
105038
105200
|
}
|
|
105039
105201
|
async function pruneExtractRuntime(projectRoot, source2) {
|
|
105040
|
-
const fingerprintPath =
|
|
105202
|
+
const fingerprintPath = join72(projectRoot, ".tmp/context-runtime/extract/source-fingerprints.json");
|
|
105041
105203
|
const removedPhaseIds = new Set;
|
|
105042
|
-
if (
|
|
105204
|
+
if (existsSync45(fingerprintPath)) {
|
|
105043
105205
|
const parsed = JSON.parse(await readFile53(fingerprintPath, "utf8"));
|
|
105044
105206
|
const phases = parsed.phases ?? {};
|
|
105045
105207
|
const next = Object.fromEntries(Object.entries(phases).filter(([phaseId, raw]) => {
|
|
@@ -105054,20 +105216,20 @@ async function pruneExtractRuntime(projectRoot, source2) {
|
|
|
105054
105216
|
await atomicWriteFile(fingerprintPath, `${JSON.stringify({ ...parsed, phases: next }, null, 2)}
|
|
105055
105217
|
`);
|
|
105056
105218
|
}
|
|
105057
|
-
const symbolPath =
|
|
105058
|
-
if (
|
|
105219
|
+
const symbolPath = join72(projectRoot, ".tmp/context-runtime/extract/source-symbols.json");
|
|
105220
|
+
if (existsSync45(symbolPath)) {
|
|
105059
105221
|
const parsed = JSON.parse(await readFile53(symbolPath, "utf8"));
|
|
105060
105222
|
const symbols = Array.isArray(parsed.symbols) ? parsed.symbols.filter((entry) => entry === null || typeof entry !== "object" || Array.isArray(entry) || entry.source !== source2.name) : [];
|
|
105061
105223
|
const phaseFingerprints = Object.fromEntries(Object.entries(parsed.phaseFingerprints ?? {}).filter(([phaseId]) => !removedPhaseIds.has(phaseId)));
|
|
105062
105224
|
await atomicWriteFile(symbolPath, `${JSON.stringify({ ...parsed, phaseFingerprints, symbols }, null, 2)}
|
|
105063
105225
|
`);
|
|
105064
105226
|
}
|
|
105065
|
-
const snapshotRoot =
|
|
105227
|
+
const snapshotRoot = join72(projectRoot, ".tmp/context-runtime/extract/candidates");
|
|
105066
105228
|
const visit3 = async (directory) => {
|
|
105067
|
-
if (!
|
|
105229
|
+
if (!existsSync45(directory))
|
|
105068
105230
|
return;
|
|
105069
105231
|
for (const entry of await readdir21(directory, { withFileTypes: true })) {
|
|
105070
|
-
const path4 =
|
|
105232
|
+
const path4 = join72(directory, entry.name);
|
|
105071
105233
|
if (entry.isDirectory()) {
|
|
105072
105234
|
await visit3(path4);
|
|
105073
105235
|
continue;
|
|
@@ -105117,7 +105279,7 @@ async function removeProjectSource(input) {
|
|
|
105117
105279
|
});
|
|
105118
105280
|
}
|
|
105119
105281
|
await applyAtomicFileBatch({
|
|
105120
|
-
transactionRoot:
|
|
105282
|
+
transactionRoot: join72(input.projectRoot, ".tmp", "context-runtime", "source-remove-transactions"),
|
|
105121
105283
|
writes: [plan.registryWrite, ...plan.manifestWrite !== undefined ? [plan.manifestWrite] : []],
|
|
105122
105284
|
removals: plan.absoluteRemovals
|
|
105123
105285
|
});
|
|
@@ -105515,16 +105677,147 @@ the CLI derives a lowercase path-safe module and rejects duplicate batch identit
|
|
|
105515
105677
|
});
|
|
105516
105678
|
}
|
|
105517
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
|
+
|
|
105518
105811
|
// src/project/pluginInstall.ts
|
|
105519
105812
|
init_cliFeedback();
|
|
105520
105813
|
init_errors();
|
|
105521
105814
|
init_exitCode();
|
|
105522
|
-
import { existsSync as
|
|
105815
|
+
import { existsSync as existsSync46 } from "node:fs";
|
|
105523
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";
|
|
105524
105817
|
import { execFile as execFile7 } from "node:child_process";
|
|
105525
105818
|
import { homedir as homedir2 } from "node:os";
|
|
105526
|
-
import { dirname as
|
|
105527
|
-
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";
|
|
105528
105821
|
import { promisify as promisify7 } from "node:util";
|
|
105529
105822
|
var execFileAsync7 = promisify7(execFile7);
|
|
105530
105823
|
var MARKETPLACE_NAME = "c4a";
|
|
@@ -105563,10 +105856,10 @@ function pluginAgentOption(value) {
|
|
|
105563
105856
|
}
|
|
105564
105857
|
function packageCandidateDirs() {
|
|
105565
105858
|
const dirs = [];
|
|
105566
|
-
let dir =
|
|
105859
|
+
let dir = dirname42(fileURLToPath9(import.meta.url));
|
|
105567
105860
|
for (let index2 = 0;index2 < 8; index2++) {
|
|
105568
105861
|
dirs.push(dir);
|
|
105569
|
-
const parent =
|
|
105862
|
+
const parent = dirname42(dir);
|
|
105570
105863
|
if (parent === dir)
|
|
105571
105864
|
break;
|
|
105572
105865
|
dir = parent;
|
|
@@ -105579,13 +105872,13 @@ function pluginRootCandidates() {
|
|
|
105579
105872
|
return [resolve32(envRoot)];
|
|
105580
105873
|
const candidates = [];
|
|
105581
105874
|
for (const dir of packageCandidateDirs()) {
|
|
105582
|
-
candidates.push(
|
|
105583
|
-
candidates.push(
|
|
105875
|
+
candidates.push(join73(dir, "plugins"));
|
|
105876
|
+
candidates.push(join73(dir, "dist", "plugins"));
|
|
105584
105877
|
}
|
|
105585
105878
|
return [...new Set(candidates)];
|
|
105586
105879
|
}
|
|
105587
105880
|
function isInstallablePluginRoot(root2) {
|
|
105588
|
-
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"));
|
|
105589
105882
|
}
|
|
105590
105883
|
function resolveBundledPluginsRoot() {
|
|
105591
105884
|
const candidates = pluginRootCandidates();
|
|
@@ -105650,14 +105943,14 @@ function failedAgentResult(agent, error) {
|
|
|
105650
105943
|
};
|
|
105651
105944
|
}
|
|
105652
105945
|
function codexHome() {
|
|
105653
|
-
return process.env.CODEX_HOME?.trim() ||
|
|
105946
|
+
return process.env.CODEX_HOME?.trim() || join73(homedir2(), ".codex");
|
|
105654
105947
|
}
|
|
105655
105948
|
function claudePluginCacheRoot() {
|
|
105656
105949
|
const explicitRoot = process.env[CLAUDE_PLUGIN_CACHE_ROOT_ENV2]?.trim();
|
|
105657
105950
|
if (explicitRoot)
|
|
105658
105951
|
return explicitRoot;
|
|
105659
105952
|
const home = process.env[CLAUDE_PLUGIN_CACHE_HOME_ENV2]?.trim() || homedir2();
|
|
105660
|
-
return
|
|
105953
|
+
return join73(home, ".claude", "plugins", "cache");
|
|
105661
105954
|
}
|
|
105662
105955
|
function blockHeader(line) {
|
|
105663
105956
|
const match = line.match(/^\s*\[([^\]]+)\]\s*$/u);
|
|
@@ -105708,7 +106001,7 @@ function pruneLegacyCodexConfigContent(content3) {
|
|
|
105708
106001
|
`), removed };
|
|
105709
106002
|
}
|
|
105710
106003
|
async function pruneLegacyCodexConfig(dryRun, steps) {
|
|
105711
|
-
const configPath =
|
|
106004
|
+
const configPath = join73(codexHome(), "config.toml");
|
|
105712
106005
|
const current2 = await readFile55(configPath, "utf8").catch(() => "");
|
|
105713
106006
|
if (!current2)
|
|
105714
106007
|
return;
|
|
@@ -105725,8 +106018,8 @@ async function pruneLegacyCodexConfig(dryRun, steps) {
|
|
|
105725
106018
|
}
|
|
105726
106019
|
}
|
|
105727
106020
|
async function pruneCodexPluginCacheForName(pluginName, keepVersion, dryRun, steps) {
|
|
105728
|
-
const cacheRoot =
|
|
105729
|
-
if (!
|
|
106021
|
+
const cacheRoot = join73(codexHome(), "plugins", "cache", MARKETPLACE_NAME, pluginName);
|
|
106022
|
+
if (!existsSync46(cacheRoot))
|
|
105730
106023
|
return;
|
|
105731
106024
|
const versions = (await readdir22(cacheRoot, { withFileTypes: true }).catch(() => [])).filter((entry) => entry.isDirectory() && entry.name !== keepVersion).map((entry) => entry.name).sort();
|
|
105732
106025
|
if (versions.length === 0)
|
|
@@ -105737,7 +106030,7 @@ async function pruneCodexPluginCacheForName(pluginName, keepVersion, dryRun, ste
|
|
|
105737
106030
|
status: dryRun ? "planned" : "ran"
|
|
105738
106031
|
});
|
|
105739
106032
|
if (!dryRun)
|
|
105740
|
-
await Promise.all(versions.map((version3) => rm20(
|
|
106033
|
+
await Promise.all(versions.map((version3) => rm20(join73(cacheRoot, version3), { recursive: true, force: true })));
|
|
105741
106034
|
}
|
|
105742
106035
|
async function pruneCodexPluginCache(currentVersion, dryRun, steps) {
|
|
105743
106036
|
await pruneCodexPluginCacheForName(PLUGIN_NAME, currentVersion, dryRun, steps);
|
|
@@ -105754,22 +106047,22 @@ async function isEmptyDir2(dir) {
|
|
|
105754
106047
|
}
|
|
105755
106048
|
async function pruneClaudeOrphanContextCache(dryRun, steps) {
|
|
105756
106049
|
const cacheRoot = claudePluginCacheRoot();
|
|
105757
|
-
if (!
|
|
106050
|
+
if (!existsSync46(cacheRoot))
|
|
105758
106051
|
return;
|
|
105759
106052
|
const removed = [];
|
|
105760
106053
|
const marketplaces = await readdir22(cacheRoot, { withFileTypes: true }).catch(() => []);
|
|
105761
106054
|
for (const marketplace of marketplaces) {
|
|
105762
106055
|
if (!marketplace.isDirectory())
|
|
105763
106056
|
continue;
|
|
105764
|
-
const pluginDir =
|
|
105765
|
-
if (!
|
|
106057
|
+
const pluginDir = join73(cacheRoot, marketplace.name, PLUGIN_NAME);
|
|
106058
|
+
if (!existsSync46(pluginDir))
|
|
105766
106059
|
continue;
|
|
105767
106060
|
const versions = await readdir22(pluginDir, { withFileTypes: true }).catch(() => []);
|
|
105768
106061
|
for (const version3 of versions) {
|
|
105769
106062
|
if (!version3.isDirectory())
|
|
105770
106063
|
continue;
|
|
105771
|
-
const versionDir =
|
|
105772
|
-
if (!
|
|
106064
|
+
const versionDir = join73(pluginDir, version3.name);
|
|
106065
|
+
if (!existsSync46(join73(versionDir, ORPHAN_MARKER2)))
|
|
105773
106066
|
continue;
|
|
105774
106067
|
removed.push(`${marketplace.name}/${PLUGIN_NAME}/${version3.name}`);
|
|
105775
106068
|
if (!dryRun) {
|
|
@@ -105779,7 +106072,7 @@ async function pruneClaudeOrphanContextCache(dryRun, steps) {
|
|
|
105779
106072
|
if (!dryRun && await isEmptyDir2(pluginDir)) {
|
|
105780
106073
|
await rm20(pluginDir, { recursive: true, force: true });
|
|
105781
106074
|
}
|
|
105782
|
-
const marketplaceDir =
|
|
106075
|
+
const marketplaceDir = join73(cacheRoot, marketplace.name);
|
|
105783
106076
|
if (!dryRun && await isEmptyDir2(marketplaceDir)) {
|
|
105784
106077
|
await rm20(marketplaceDir, { recursive: true, force: true });
|
|
105785
106078
|
}
|
|
@@ -105796,12 +106089,12 @@ async function pruneClaudeLegacyPluginCache(dryRun, steps) {
|
|
|
105796
106089
|
if (LEGACY_PLUGIN_NAMES.length === 0)
|
|
105797
106090
|
return;
|
|
105798
106091
|
const cacheRoot = claudePluginCacheRoot();
|
|
105799
|
-
if (!
|
|
106092
|
+
if (!existsSync46(cacheRoot))
|
|
105800
106093
|
return;
|
|
105801
106094
|
const removed = [];
|
|
105802
106095
|
for (const pluginName of LEGACY_PLUGIN_NAMES) {
|
|
105803
|
-
const pluginDir =
|
|
105804
|
-
if (!
|
|
106096
|
+
const pluginDir = join73(cacheRoot, MARKETPLACE_NAME, pluginName);
|
|
106097
|
+
if (!existsSync46(pluginDir))
|
|
105805
106098
|
continue;
|
|
105806
106099
|
removed.push(`${MARKETPLACE_NAME}/${pluginName}`);
|
|
105807
106100
|
if (!dryRun) {
|
|
@@ -105817,11 +106110,11 @@ async function pruneClaudeLegacyPluginCache(dryRun, steps) {
|
|
|
105817
106110
|
}
|
|
105818
106111
|
}
|
|
105819
106112
|
async function pruneClaudeSupersededContextCache(root2, dryRun, steps) {
|
|
105820
|
-
const manifest = await readFile55(
|
|
106113
|
+
const manifest = await readFile55(join73(root2, "claude", ".claude-plugin", "plugin.json"), "utf8").then((content3) => JSON.parse(content3)).catch(() => null);
|
|
105821
106114
|
const currentVersion = typeof manifest?.version === "string" ? manifest.version : null;
|
|
105822
106115
|
if (!currentVersion)
|
|
105823
106116
|
return;
|
|
105824
|
-
const pluginDir =
|
|
106117
|
+
const pluginDir = join73(claudePluginCacheRoot(), MARKETPLACE_NAME, PLUGIN_NAME);
|
|
105825
106118
|
const staleVersions = (await readdir22(pluginDir, { withFileTypes: true }).catch(() => [])).filter((entry) => entry.isDirectory() && entry.name !== currentVersion).map((entry) => entry.name);
|
|
105826
106119
|
if (staleVersions.length === 0)
|
|
105827
106120
|
return;
|
|
@@ -105831,7 +106124,7 @@ async function pruneClaudeSupersededContextCache(root2, dryRun, steps) {
|
|
|
105831
106124
|
status: dryRun ? "planned" : "ran"
|
|
105832
106125
|
});
|
|
105833
106126
|
if (!dryRun) {
|
|
105834
|
-
await Promise.all(staleVersions.map((version3) => rm20(
|
|
106127
|
+
await Promise.all(staleVersions.map((version3) => rm20(join73(pluginDir, version3), { recursive: true, force: true })));
|
|
105835
106128
|
}
|
|
105836
106129
|
}
|
|
105837
106130
|
function enableCodexPluginConfig(content3) {
|
|
@@ -105895,8 +106188,8 @@ source = ${JSON.stringify(root2)}
|
|
|
105895
106188
|
`;
|
|
105896
106189
|
}
|
|
105897
106190
|
async function ensureCodexPluginEnabled() {
|
|
105898
|
-
const configPath =
|
|
105899
|
-
await mkdir32(
|
|
106191
|
+
const configPath = join73(codexHome(), "config.toml");
|
|
106192
|
+
await mkdir32(dirname42(configPath), { recursive: true });
|
|
105900
106193
|
const current2 = await readFile55(configPath, "utf8").catch(() => "");
|
|
105901
106194
|
const next = enableCodexPluginConfig(current2);
|
|
105902
106195
|
if (next !== current2) {
|
|
@@ -105904,8 +106197,8 @@ async function ensureCodexPluginEnabled() {
|
|
|
105904
106197
|
}
|
|
105905
106198
|
}
|
|
105906
106199
|
async function ensureCodexLocalMarketplace(root2) {
|
|
105907
|
-
const configPath =
|
|
105908
|
-
await mkdir32(
|
|
106200
|
+
const configPath = join73(codexHome(), "config.toml");
|
|
106201
|
+
await mkdir32(dirname42(configPath), { recursive: true });
|
|
105909
106202
|
const current2 = await readFile55(configPath, "utf8").catch(() => "");
|
|
105910
106203
|
const next = upsertCodexLocalMarketplaceConfig(current2, root2);
|
|
105911
106204
|
if (next !== current2) {
|
|
@@ -105913,7 +106206,7 @@ async function ensureCodexLocalMarketplace(root2) {
|
|
|
105913
106206
|
}
|
|
105914
106207
|
}
|
|
105915
106208
|
async function codexPluginVersion(root2) {
|
|
105916
|
-
const manifestPath =
|
|
106209
|
+
const manifestPath = join73(root2, "codex", ".codex-plugin", "plugin.json");
|
|
105917
106210
|
const manifest = JSON.parse(await readFile55(manifestPath, "utf8"));
|
|
105918
106211
|
if (typeof manifest.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/u.test(manifest.version)) {
|
|
105919
106212
|
throw new Error(`Codex plugin manifest has an invalid version: ${manifestPath}`);
|
|
@@ -105921,10 +106214,10 @@ async function codexPluginVersion(root2) {
|
|
|
105921
106214
|
return manifest.version;
|
|
105922
106215
|
}
|
|
105923
106216
|
function codexPluginCacheDir(version3) {
|
|
105924
|
-
return
|
|
106217
|
+
return join73(codexHome(), "plugins", "cache", MARKETPLACE_NAME, PLUGIN_NAME, version3);
|
|
105925
106218
|
}
|
|
105926
106219
|
async function materializeCodexPluginCache(root2, version3, dryRun, steps) {
|
|
105927
|
-
const source2 =
|
|
106220
|
+
const source2 = join73(root2, "codex");
|
|
105928
106221
|
const target = codexPluginCacheDir(version3);
|
|
105929
106222
|
steps.push({
|
|
105930
106223
|
agent: "codex",
|
|
@@ -105933,12 +106226,12 @@ async function materializeCodexPluginCache(root2, version3, dryRun, steps) {
|
|
|
105933
106226
|
});
|
|
105934
106227
|
if (dryRun)
|
|
105935
106228
|
return;
|
|
105936
|
-
await mkdir32(
|
|
106229
|
+
await mkdir32(dirname42(target), { recursive: true });
|
|
105937
106230
|
const temporary = `${target}.tmp-${process.pid}-${Date.now()}`;
|
|
105938
106231
|
const previous3 = `${target}.previous-${process.pid}-${Date.now()}`;
|
|
105939
106232
|
await rm20(temporary, { recursive: true, force: true });
|
|
105940
106233
|
await cp(source2, temporary, { recursive: true, force: true });
|
|
105941
|
-
const hadPrevious =
|
|
106234
|
+
const hadPrevious = existsSync46(target);
|
|
105942
106235
|
try {
|
|
105943
106236
|
if (hadPrevious)
|
|
105944
106237
|
await rename5(target, previous3);
|
|
@@ -105947,7 +106240,7 @@ async function materializeCodexPluginCache(root2, version3, dryRun, steps) {
|
|
|
105947
106240
|
await rm20(previous3, { recursive: true, force: true });
|
|
105948
106241
|
} catch (error) {
|
|
105949
106242
|
await rm20(temporary, { recursive: true, force: true });
|
|
105950
|
-
if (hadPrevious && !
|
|
106243
|
+
if (hadPrevious && !existsSync46(target) && existsSync46(previous3))
|
|
105951
106244
|
await rename5(previous3, target);
|
|
105952
106245
|
throw error;
|
|
105953
106246
|
}
|
|
@@ -105982,12 +106275,12 @@ async function installCodex(root2, dryRun, steps) {
|
|
|
105982
106275
|
steps.push({ agent: "codex", command: commandLine("codex", addArgs), status: dryRun ? "planned" : "ran" });
|
|
105983
106276
|
steps.push({
|
|
105984
106277
|
agent: "codex",
|
|
105985
|
-
command: `ensure ${shellQuote9(
|
|
106278
|
+
command: `ensure ${shellQuote9(join73(codexHome(), "config.toml"))} registers local marketplace ${shellQuote9(MARKETPLACE_NAME)}`,
|
|
105986
106279
|
status: dryRun ? "planned" : "ran"
|
|
105987
106280
|
});
|
|
105988
106281
|
steps.push({
|
|
105989
106282
|
agent: "codex",
|
|
105990
|
-
command: `ensure ${shellQuote9(
|
|
106283
|
+
command: `ensure ${shellQuote9(join73(codexHome(), "config.toml"))} enables ${shellQuote9(PLUGIN_ID)}`,
|
|
105991
106284
|
status: dryRun ? "planned" : "ran"
|
|
105992
106285
|
});
|
|
105993
106286
|
if (dryRun) {
|
|
@@ -106098,8 +106391,75 @@ function formatPluginInstallResult(result) {
|
|
|
106098
106391
|
});
|
|
106099
106392
|
}
|
|
106100
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
|
+
|
|
106101
106462
|
// src/cli.ts
|
|
106102
|
-
init_debugTrace();
|
|
106103
106463
|
var TOP_LEVEL_COMMANDS = new Set([
|
|
106104
106464
|
"init",
|
|
106105
106465
|
"plugin",
|
|
@@ -106135,14 +106495,14 @@ function inferErrorCategory(message) {
|
|
|
106135
106495
|
}
|
|
106136
106496
|
function readPackageVersion() {
|
|
106137
106497
|
try {
|
|
106138
|
-
let dir =
|
|
106498
|
+
let dir = dirname43(fileURLToPath10(import.meta.url));
|
|
106139
106499
|
for (let i2 = 0;i2 < 8; i2++) {
|
|
106140
|
-
const pkg =
|
|
106141
|
-
if (
|
|
106142
|
-
const parsed = JSON.parse(
|
|
106500
|
+
const pkg = join74(dir, "package.json");
|
|
106501
|
+
if (existsSync47(pkg)) {
|
|
106502
|
+
const parsed = JSON.parse(readFileSync10(pkg, "utf8"));
|
|
106143
106503
|
return parsed.version ?? "unknown";
|
|
106144
106504
|
}
|
|
106145
|
-
const parent =
|
|
106505
|
+
const parent = dirname43(dir);
|
|
106146
106506
|
if (parent === dir)
|
|
106147
106507
|
break;
|
|
106148
106508
|
dir = parent;
|
|
@@ -106152,21 +106512,21 @@ function readPackageVersion() {
|
|
|
106152
106512
|
}
|
|
106153
106513
|
function readQuickstartPath() {
|
|
106154
106514
|
try {
|
|
106155
|
-
let dir =
|
|
106515
|
+
let dir = dirname43(fileURLToPath10(import.meta.url));
|
|
106156
106516
|
for (let i2 = 0;i2 < 8; i2++) {
|
|
106157
|
-
const candidate =
|
|
106158
|
-
if (
|
|
106517
|
+
const candidate = join74(dir, "docs", "quickstart.md");
|
|
106518
|
+
if (existsSync47(candidate))
|
|
106159
106519
|
return candidate;
|
|
106160
|
-
const pkg =
|
|
106161
|
-
if (
|
|
106520
|
+
const pkg = join74(dir, "package.json");
|
|
106521
|
+
if (existsSync47(pkg))
|
|
106162
106522
|
return candidate;
|
|
106163
|
-
const parent =
|
|
106523
|
+
const parent = dirname43(dir);
|
|
106164
106524
|
if (parent === dir)
|
|
106165
106525
|
break;
|
|
106166
106526
|
dir = parent;
|
|
106167
106527
|
}
|
|
106168
106528
|
} catch {}
|
|
106169
|
-
return
|
|
106529
|
+
return join74(dirname43(fileURLToPath10(import.meta.url)), "docs", "quickstart.md");
|
|
106170
106530
|
}
|
|
106171
106531
|
var GREEN = "\x1B[32m";
|
|
106172
106532
|
var RESET = "\x1B[0m";
|
|
@@ -106251,94 +106611,12 @@ function createCliProgram() {
|
|
|
106251
106611
|
});
|
|
106252
106612
|
const baseHelpInformation = program2.helpInformation.bind(program2);
|
|
106253
106613
|
program2.helpInformation = () => `${headerHelpText()}${baseHelpInformation()}${quickstartHelpText()}`;
|
|
106254
|
-
program2
|
|
106255
|
-
|
|
106256
|
-
cwd: process.cwd(),
|
|
106257
|
-
...projectDir !== undefined ? { projectDir } : {},
|
|
106258
|
-
...typeof options.name === "string" ? { name: options.name } : {},
|
|
106259
|
-
...typeof options.language === "string" ? { language: projectLanguage(options.language) } : {},
|
|
106260
|
-
...options.dev === true ? { dev: true } : {},
|
|
106261
|
-
...options.debug === true ? { debug: true } : {},
|
|
106262
|
-
...options.allowNonempty === true ? { allowNonempty: true } : {}
|
|
106263
|
-
});
|
|
106264
|
-
process.stdout.write(formatProjectInitResult(result));
|
|
106265
|
-
});
|
|
106266
|
-
const plugin = program2.command("plugin").description("Install or inspect global Context agent plugins");
|
|
106614
|
+
registerProjectInitCommand(program2);
|
|
106615
|
+
registerPluginCommands(program2);
|
|
106267
106616
|
registerDebugCommands(program2);
|
|
106268
|
-
plugin.command("path").description("Print the bundled plugin marketplace root used by `context plugin install`").action(async () => {
|
|
106269
|
-
process.stdout.write(formatPluginPathResult(await runPluginPathCommand()));
|
|
106270
|
-
});
|
|
106271
|
-
plugin.command("status").description("Inspect the bundled plugin marketplace root and global agent availability").option("--agent <agent>", "agent target: claude | codex | all", "all").action(async (options) => {
|
|
106272
|
-
const agent = pluginAgentOption(options.agent);
|
|
106273
|
-
process.stdout.write(formatPluginStatusResult(await runPluginStatusCommand({ agent })));
|
|
106274
|
-
});
|
|
106275
|
-
plugin.command("install").description("Install the bundled Context plugin globally for Claude and/or Codex").option("--agent <agent>", "agent target: claude | codex | all", "all").option("--dry-run", "Print install commands without mutating global agent config").action(async (options) => {
|
|
106276
|
-
const agent = pluginAgentOption(options.agent);
|
|
106277
|
-
const result = await runPluginInstallCommand({
|
|
106278
|
-
agent,
|
|
106279
|
-
dryRun: options.dryRun === true
|
|
106280
|
-
});
|
|
106281
|
-
process.stdout.write(formatPluginInstallResult(result));
|
|
106282
|
-
});
|
|
106283
106617
|
registerContextWorkflowResourceCommands(program2);
|
|
106284
|
-
|
|
106285
|
-
|
|
106286
|
-
packageTemplate.command("accept [package-name]").description("Explicitly accept an unchanged generated starter template").option("--all", "accept all unchanged generated starter templates").option("--format <format>", "output format: text | json", "text").action(async (packageName, options) => {
|
|
106287
|
-
if (packageName === undefined === (options.all !== true)) {
|
|
106288
|
-
throw new ContextError(ExitCode.UserError, "provide one package name or --all", { category: ErrorCategory.UserInputInvalid });
|
|
106289
|
-
}
|
|
106290
|
-
if (options.format !== "text" && options.format !== "json") {
|
|
106291
|
-
throw new ContextError(ExitCode.UserError, "--format must be text or json", {
|
|
106292
|
-
category: ErrorCategory.UserInputInvalid
|
|
106293
|
-
});
|
|
106294
|
-
}
|
|
106295
|
-
const found = findContextProjectRoot(process.cwd());
|
|
106296
|
-
if (!found) {
|
|
106297
|
-
throw new ContextError(ExitCode.WorkspaceStateError, "package template acceptance requires a context project workspace", { category: ErrorCategory.WorkspaceNotFound });
|
|
106298
|
-
}
|
|
106299
|
-
const result = await acceptStarterPackageTemplates({
|
|
106300
|
-
projectRoot: found.projectRoot,
|
|
106301
|
-
...packageName === undefined ? {} : { packageNames: [packageName] }
|
|
106302
|
-
});
|
|
106303
|
-
if (options.format === "json") {
|
|
106304
|
-
process.stdout.write(`${JSON.stringify({
|
|
106305
|
-
action: "package-template-accepted",
|
|
106306
|
-
...result,
|
|
106307
|
-
next_action: {
|
|
106308
|
-
kind: "reevaluate-workspace",
|
|
106309
|
-
command: "context status --format json"
|
|
106310
|
-
}
|
|
106311
|
-
}, null, 2)}
|
|
106312
|
-
`);
|
|
106313
|
-
} else {
|
|
106314
|
-
process.stdout.write(formatFeedback({
|
|
106315
|
-
symbol: "✓",
|
|
106316
|
-
action: "accepted",
|
|
106317
|
-
subject: result.accepted.join(", ") || "package templates",
|
|
106318
|
-
headline: "starter package template",
|
|
106319
|
-
body: result.alreadyResolved.length === 0 ? [] : [`already resolved: ${result.alreadyResolved.join(", ")}`]
|
|
106320
|
-
}));
|
|
106321
|
-
}
|
|
106322
|
-
});
|
|
106323
|
-
program2.command("status").description("Print workspace overview and suggested next actions").option("--format <format>", "output format: table | json", "table").option("--view <view>", "with --format json, output view: summary | full", "summary").option("--managed", "use explicit current-conversation managed approval for this status loop").option("--resource-receipts <json-or-@file>", "current-conversation Agent Graph resource read receipts").addOption(new Option("--authority <authority>", "current-conversation scoped authority granted by the user; repeatable").argParser(collectWorkflowAuthorityOption).default([])).action(async (options) => {
|
|
106324
|
-
const rootOptions = program2.opts();
|
|
106325
|
-
const resourceReceiptsReference = typeof options.resourceReceipts === "string" ? options.resourceReceipts : typeof rootOptions.workflowResourceReceipts === "string" ? rootOptions.workflowResourceReceipts : undefined;
|
|
106326
|
-
const resourceReceipts = resourceReceiptsReference !== undefined ? await parseWorkflowResourceReceipts(resourceReceiptsReference, process.cwd()) : undefined;
|
|
106327
|
-
if (await runProjectStatusCommand({
|
|
106328
|
-
cwd: process.cwd(),
|
|
106329
|
-
format: options.format === "json" ? "json" : "table",
|
|
106330
|
-
view: options.view === "full" ? "full" : "summary",
|
|
106331
|
-
managed: options.managed === true,
|
|
106332
|
-
authorities: workflowAuthorities(options.authority),
|
|
106333
|
-
...resourceReceipts === undefined ? {} : { resourceReceipts },
|
|
106334
|
-
...resourceReceiptsReference === undefined ? {} : { resourceReceiptsReference }
|
|
106335
|
-
})) {
|
|
106336
|
-
return;
|
|
106337
|
-
}
|
|
106338
|
-
throw new ContextError(ExitCode.WorkspaceStateError, "status requires a context project workspace", {
|
|
106339
|
-
category: ErrorCategory.WorkspaceNotFound
|
|
106340
|
-
});
|
|
106341
|
-
});
|
|
106618
|
+
registerPackageCommands(program2);
|
|
106619
|
+
registerProjectStatusCommand(program2);
|
|
106342
106620
|
registerProjectRunCommand(program2, import.meta.url);
|
|
106343
106621
|
const review = program2.command("review").description("Review draft project candidates and apply approval decisions");
|
|
106344
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) => {
|
|
@@ -106486,70 +106764,9 @@ function createCliProgram() {
|
|
|
106486
106764
|
format: options.format === "json" ? "json" : "text"
|
|
106487
106765
|
});
|
|
106488
106766
|
});
|
|
106489
|
-
program2
|
|
106490
|
-
if (options.format !== "text" && options.format !== "json") {
|
|
106491
|
-
throw new ContextError(ExitCode.UserError, "--format must be text or json", {
|
|
106492
|
-
category: ErrorCategory.UserInputInvalid
|
|
106493
|
-
});
|
|
106494
|
-
}
|
|
106495
|
-
if (await runProjectCloseCommand({
|
|
106496
|
-
cwd: process.cwd(),
|
|
106497
|
-
format: options.format === "json" ? "json" : "text"
|
|
106498
|
-
})) {
|
|
106499
|
-
return;
|
|
106500
|
-
}
|
|
106501
|
-
throw new ContextError(ExitCode.WorkspaceStateError, "close requires a context project workspace", {
|
|
106502
|
-
category: ErrorCategory.WorkspaceNotFound
|
|
106503
|
-
});
|
|
106504
|
-
});
|
|
106505
|
-
program2.command("build").description("Build declared project packages").option("--format <format>", "output format: text | json", "text").option("--verbose", "include per-file build changes in JSON output").action(async (options) => {
|
|
106506
|
-
if (options.format !== "text" && options.format !== "json") {
|
|
106507
|
-
throw new ContextError(ExitCode.UserError, "--format must be text or json", {
|
|
106508
|
-
category: ErrorCategory.UserInputInvalid
|
|
106509
|
-
});
|
|
106510
|
-
}
|
|
106511
|
-
if (await runProjectBuildCommand({
|
|
106512
|
-
cwd: process.cwd(),
|
|
106513
|
-
format: options.format === "json" ? "json" : "text",
|
|
106514
|
-
verbose: options.verbose === true
|
|
106515
|
-
})) {
|
|
106516
|
-
return;
|
|
106517
|
-
}
|
|
106518
|
-
throw new ContextError(ExitCode.WorkspaceStateError, "build requires a context project workspace", {
|
|
106519
|
-
category: ErrorCategory.WorkspaceNotFound
|
|
106520
|
-
});
|
|
106521
|
-
});
|
|
106767
|
+
registerProjectCloseAndBuildCommands(program2);
|
|
106522
106768
|
registerProjectSourceCommands(program2);
|
|
106523
|
-
program2
|
|
106524
|
-
if (options.format !== "table" && options.format !== "json") {
|
|
106525
|
-
throw new ContextError(ExitCode.UserError, "--format must be table or json", {
|
|
106526
|
-
category: ErrorCategory.UserInputInvalid
|
|
106527
|
-
});
|
|
106528
|
-
}
|
|
106529
|
-
if (options.view !== undefined && options.view !== "diagnostics") {
|
|
106530
|
-
throw new ContextError(ExitCode.UserError, "--view must be diagnostics", {
|
|
106531
|
-
category: ErrorCategory.UserInputInvalid
|
|
106532
|
-
});
|
|
106533
|
-
}
|
|
106534
|
-
if (options.view === "diagnostics" && options.format !== "json") {
|
|
106535
|
-
throw new ContextError(ExitCode.UserError, "--view diagnostics requires --format json", {
|
|
106536
|
-
category: ErrorCategory.UserInputInvalid
|
|
106537
|
-
});
|
|
106538
|
-
}
|
|
106539
|
-
if (await runProjectVerifyCommand({
|
|
106540
|
-
cwd: process.cwd(),
|
|
106541
|
-
format: options.format === "json" ? "json" : "table",
|
|
106542
|
-
...options.compact === true ? { compact: true } : {},
|
|
106543
|
-
...options.view === "diagnostics" ? { view: "diagnostics" } : {},
|
|
106544
|
-
...typeof options.pageSize === "string" ? { pageSize: options.pageSize } : {},
|
|
106545
|
-
...typeof options.pageToken === "string" ? { pageToken: options.pageToken } : {}
|
|
106546
|
-
})) {
|
|
106547
|
-
return;
|
|
106548
|
-
}
|
|
106549
|
-
throw new ContextError(ExitCode.WorkspaceStateError, "verify requires a context project workspace", {
|
|
106550
|
-
category: ErrorCategory.WorkspaceNotFound
|
|
106551
|
-
});
|
|
106552
|
-
});
|
|
106769
|
+
registerProjectVerifyCommand(program2);
|
|
106553
106770
|
const cleanCacheAction = async (options) => {
|
|
106554
106771
|
const dryRun = options.dryRun === true;
|
|
106555
106772
|
await runDoctorCleanClaudePluginCache({ dryRun });
|
|
@@ -106581,10 +106798,12 @@ function createCliProgram() {
|
|
|
106581
106798
|
return program2;
|
|
106582
106799
|
}
|
|
106583
106800
|
async function cli_main(argv = process.argv) {
|
|
106584
|
-
await
|
|
106585
|
-
|
|
106586
|
-
|
|
106587
|
-
|
|
106801
|
+
await withContextRuntimeEventDelivery(async () => {
|
|
106802
|
+
await withDebugCliInvocation(argv, async () => {
|
|
106803
|
+
assertKnownTopLevelCommand(argv);
|
|
106804
|
+
const program2 = createCliProgram();
|
|
106805
|
+
await program2.parseAsync(argv);
|
|
106806
|
+
});
|
|
106588
106807
|
});
|
|
106589
106808
|
}
|
|
106590
106809
|
function isDirectCliInvocation(metaUrl, argv1) {
|