@c4a/context-cli 0.7.10 → 0.7.11
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/README.md +2 -2
- package/README.zh-CN.md +3 -3
- package/cli.js +1111 -402
- package/indexers/bundles/context-code-indexer/references/indexer.md +11 -1
- package/indexers/bundles/context-markdown-indexer/references/indexer.md +7 -2
- package/indexers/bundles/context-markdown-indexer/references/semantic-planning.md +9 -6
- package/indexers/contracts/profile-contract.json +245 -245
- package/indexers/release-manifest.json +6 -6
- package/package.json +12 -12
- package/parserEntryWorker.js +26 -2
- package/plugins/README.md +1 -1
- package/plugins/README_CN.md +1 -1
- 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/plugins/skills/context-code-indexer/references/indexer.md +11 -1
- package/plugins/skills/context-markdown-indexer/references/indexer.md +7 -2
- package/plugins/skills/context-markdown-indexer/references/semantic-planning.md +9 -6
- package/providers/context/graphs/workspace.yaml +1 -22
- package/providers/context/manifest.json +26 -62
- package/providers/context/provider.yaml +1 -1
- package/providers/context/resources/manuals/guides/knowledge-updates.md +80 -3
- package/providers/context/resources/manuals/guides/package-outputs.md +39 -1
- package/providers/context/resources/manuals/reference/project-api.md +21 -2
- package/providers/context/resources/procedures/knowledge-review.md +18 -2
- package/providers/context/resources/procedures/knowledge-updates.md +80 -3
- package/providers/context/resources/procedures/package-output.md +18 -0
- package/providers/context/resources/procedures/production-stage-files.md +21 -0
- package/providers/context/resources/procedures/repository-source-recovery.md +5 -3
- package/providers/context/resources/procedures/task-recovery.md +6 -0
- package/providers/context/resources/procedures/work-start-report.md +14 -7
- package/providers/context/resources/templates/work-start-report.md +11 -6
- package/providers/context/actions/inspect-repository-recovery.yaml +0 -6
- package/providers/context/actions/restore-repository-sources.yaml +0 -7
- package/providers/context/resources/dialogue/repository-source-recovery.md +0 -23
- package/providers/context/schemas/repository-source-recovery.schema.json +0 -40
package/cli.js
CHANGED
|
@@ -32029,7 +32029,17 @@ ${end.comment}` : end.comment;
|
|
|
32029
32029
|
});
|
|
32030
32030
|
|
|
32031
32031
|
// ../../node_modules/.bun/zod-to-json-schema@3.25.2+27912429049419a2/node_modules/zod-to-json-schema/dist/esm/Options.js
|
|
32032
|
-
var ignoreOverride,
|
|
32032
|
+
var ignoreOverride, jsonDescription = (jsonSchema, def) => {
|
|
32033
|
+
if (def.description) {
|
|
32034
|
+
try {
|
|
32035
|
+
return {
|
|
32036
|
+
...jsonSchema,
|
|
32037
|
+
...JSON.parse(def.description)
|
|
32038
|
+
};
|
|
32039
|
+
} catch {}
|
|
32040
|
+
}
|
|
32041
|
+
return jsonSchema;
|
|
32042
|
+
}, defaultOptions, getDefaultOptions = (options) => typeof options === "string" ? {
|
|
32033
32043
|
...defaultOptions,
|
|
32034
32044
|
name: options
|
|
32035
32045
|
} : {
|
|
@@ -33397,6 +33407,54 @@ var init_zodToJsonSchema = __esm(() => {
|
|
|
33397
33407
|
});
|
|
33398
33408
|
|
|
33399
33409
|
// ../../node_modules/.bun/zod-to-json-schema@3.25.2+27912429049419a2/node_modules/zod-to-json-schema/dist/esm/index.js
|
|
33410
|
+
var exports_esm = {};
|
|
33411
|
+
__export(exports_esm, {
|
|
33412
|
+
zodToJsonSchema: () => zodToJsonSchema,
|
|
33413
|
+
zodPatterns: () => zodPatterns,
|
|
33414
|
+
setResponseValueAndErrors: () => setResponseValueAndErrors,
|
|
33415
|
+
selectParser: () => selectParser,
|
|
33416
|
+
primitiveMappings: () => primitiveMappings,
|
|
33417
|
+
parseUnknownDef: () => parseUnknownDef,
|
|
33418
|
+
parseUnionDef: () => parseUnionDef,
|
|
33419
|
+
parseUndefinedDef: () => parseUndefinedDef,
|
|
33420
|
+
parseTupleDef: () => parseTupleDef,
|
|
33421
|
+
parseStringDef: () => parseStringDef,
|
|
33422
|
+
parseSetDef: () => parseSetDef,
|
|
33423
|
+
parseRecordDef: () => parseRecordDef,
|
|
33424
|
+
parseReadonlyDef: () => parseReadonlyDef,
|
|
33425
|
+
parsePromiseDef: () => parsePromiseDef,
|
|
33426
|
+
parsePipelineDef: () => parsePipelineDef,
|
|
33427
|
+
parseOptionalDef: () => parseOptionalDef,
|
|
33428
|
+
parseObjectDef: () => parseObjectDef,
|
|
33429
|
+
parseNumberDef: () => parseNumberDef,
|
|
33430
|
+
parseNullableDef: () => parseNullableDef,
|
|
33431
|
+
parseNullDef: () => parseNullDef,
|
|
33432
|
+
parseNeverDef: () => parseNeverDef,
|
|
33433
|
+
parseNativeEnumDef: () => parseNativeEnumDef,
|
|
33434
|
+
parseMapDef: () => parseMapDef,
|
|
33435
|
+
parseLiteralDef: () => parseLiteralDef,
|
|
33436
|
+
parseIntersectionDef: () => parseIntersectionDef,
|
|
33437
|
+
parseEnumDef: () => parseEnumDef,
|
|
33438
|
+
parseEffectsDef: () => parseEffectsDef,
|
|
33439
|
+
parseDefaultDef: () => parseDefaultDef,
|
|
33440
|
+
parseDef: () => parseDef,
|
|
33441
|
+
parseDateDef: () => parseDateDef,
|
|
33442
|
+
parseCatchDef: () => parseCatchDef,
|
|
33443
|
+
parseBrandedDef: () => parseBrandedDef,
|
|
33444
|
+
parseBooleanDef: () => parseBooleanDef,
|
|
33445
|
+
parseBigintDef: () => parseBigintDef,
|
|
33446
|
+
parseArrayDef: () => parseArrayDef,
|
|
33447
|
+
parseAnyDef: () => parseAnyDef,
|
|
33448
|
+
jsonDescription: () => jsonDescription,
|
|
33449
|
+
ignoreOverride: () => ignoreOverride,
|
|
33450
|
+
getRelativePath: () => getRelativePath,
|
|
33451
|
+
getRefs: () => getRefs,
|
|
33452
|
+
getDefaultOptions: () => getDefaultOptions,
|
|
33453
|
+
defaultOptions: () => defaultOptions,
|
|
33454
|
+
default: () => esm_default,
|
|
33455
|
+
addErrorMessage: () => addErrorMessage
|
|
33456
|
+
});
|
|
33457
|
+
var esm_default;
|
|
33400
33458
|
var init_esm = __esm(() => {
|
|
33401
33459
|
init_zodToJsonSchema();
|
|
33402
33460
|
init_Options();
|
|
@@ -33430,17 +33488,42 @@ var init_esm = __esm(() => {
|
|
|
33430
33488
|
init_unknown();
|
|
33431
33489
|
init_selectParser();
|
|
33432
33490
|
init_zodToJsonSchema();
|
|
33491
|
+
esm_default = zodToJsonSchema;
|
|
33433
33492
|
});
|
|
33434
33493
|
|
|
33435
33494
|
// ../context/src/packageSite.ts
|
|
33436
|
-
var packageSiteSchema;
|
|
33495
|
+
var siteHrefSchema, packageSiteHomeActionSchema, packageSiteHomeResourceSchema, packageSiteHomeSchema, packageSiteSchema;
|
|
33437
33496
|
var init_packageSite = __esm(() => {
|
|
33438
33497
|
init_zod();
|
|
33498
|
+
siteHrefSchema = exports_external.string().trim().min(1).refine((value) => /^(?:https?:\/\/|mailto:|\/(?!\/)|#)/u.test(value), "Use an https URL, mailto URL, root-relative path, or page anchor");
|
|
33499
|
+
packageSiteHomeActionSchema = exports_external.object({
|
|
33500
|
+
text: exports_external.string().trim().min(1),
|
|
33501
|
+
link: siteHrefSchema,
|
|
33502
|
+
theme: exports_external.enum(["brand", "alt"]).optional()
|
|
33503
|
+
}).strict();
|
|
33504
|
+
packageSiteHomeResourceSchema = exports_external.object({
|
|
33505
|
+
title: exports_external.string().trim().min(1),
|
|
33506
|
+
description: exports_external.string().trim().min(1).optional(),
|
|
33507
|
+
href: siteHrefSchema.optional(),
|
|
33508
|
+
action: exports_external.string().trim().min(1).optional(),
|
|
33509
|
+
command: exports_external.string().trim().min(1).optional(),
|
|
33510
|
+
featured: exports_external.boolean().optional()
|
|
33511
|
+
}).strict().refine((value) => value.href !== undefined || value.command !== undefined, {
|
|
33512
|
+
message: "A homepage resource requires href or command"
|
|
33513
|
+
});
|
|
33514
|
+
packageSiteHomeSchema = exports_external.object({
|
|
33515
|
+
title: exports_external.string().trim().min(1).optional(),
|
|
33516
|
+
slogan: exports_external.string().trim().min(1).optional(),
|
|
33517
|
+
description: exports_external.string().trim().min(1).optional(),
|
|
33518
|
+
actions: exports_external.array(packageSiteHomeActionSchema).optional(),
|
|
33519
|
+
resources: exports_external.array(packageSiteHomeResourceSchema).optional()
|
|
33520
|
+
}).strict();
|
|
33439
33521
|
packageSiteSchema = exports_external.object({
|
|
33440
33522
|
title: exports_external.string().trim().min(1).optional(),
|
|
33441
33523
|
description: exports_external.string().optional(),
|
|
33442
33524
|
lang: exports_external.string().min(1).default("en-US"),
|
|
33443
|
-
base: exports_external.string().regex(/^\/(?:[a-zA-Z0-9_-]+\/)*$/, "Use / or a slash-delimited deployment path, such as /docs/").default("/")
|
|
33525
|
+
base: exports_external.string().regex(/^\/(?:[a-zA-Z0-9_-]+\/)*$/, "Use / or a slash-delimited deployment path, such as /docs/").default("/"),
|
|
33526
|
+
home: packageSiteHomeSchema.optional()
|
|
33444
33527
|
}).strict();
|
|
33445
33528
|
});
|
|
33446
33529
|
|
|
@@ -55119,6 +55202,7 @@ async function withProjectWriteLock(projectRoot, name, action) {
|
|
|
55119
55202
|
owner: lockOwnerDetail(owner),
|
|
55120
55203
|
next_action: {
|
|
55121
55204
|
kind: processState === "running" ? "wait-for-active-context-command" : "inspect-project-write-lock",
|
|
55205
|
+
...processState === "not-running" ? { command: "context task recover --format json" } : {},
|
|
55122
55206
|
message: processState === "running" ? "Keep polling the existing Context command until it returns an exit code and receipt; do not start another write command." : "No active owner could be confirmed. Inspect the runtime lock and the previous Context process before retrying; do not delete a lock owned by a running process."
|
|
55123
55207
|
},
|
|
55124
55208
|
next: processState === "running" ? "Wait for the running context command to finish, then retry." : "Inspect the workspace runtime lock and previous Context process before retrying."
|
|
@@ -55673,6 +55757,40 @@ function inlineLinksFromTree(content3, tree) {
|
|
|
55673
55757
|
}
|
|
55674
55758
|
function replaceMarkdownInlineLinkTargets(content3, replacement) {
|
|
55675
55759
|
const links = markdownInlineLinks(content3);
|
|
55760
|
+
if (content3.includes("]:")) {
|
|
55761
|
+
const tree = unified().use(remarkParse).parse(content3);
|
|
55762
|
+
const visit2 = (node3) => {
|
|
55763
|
+
if (node3.type === "definition" && node3.url !== undefined) {
|
|
55764
|
+
const start = node3.position?.start?.offset;
|
|
55765
|
+
const end = node3.position?.end?.offset;
|
|
55766
|
+
if (start !== undefined && end !== undefined) {
|
|
55767
|
+
const raw = content3.slice(start, end);
|
|
55768
|
+
const prefix = /^\[[^\n]+\]:\s*/u.exec(raw);
|
|
55769
|
+
if (prefix) {
|
|
55770
|
+
const offset = prefix[0].length;
|
|
55771
|
+
const angle = raw[offset] === "<";
|
|
55772
|
+
const match = angle ? /^<([^>]*)>/u.exec(raw.slice(offset)) : /^((?:\\.|[^\s])+)/u.exec(raw.slice(offset));
|
|
55773
|
+
if (match) {
|
|
55774
|
+
const targetStart = start + offset + (angle ? 1 : 0);
|
|
55775
|
+
links.push({
|
|
55776
|
+
image: false,
|
|
55777
|
+
label: node3.identifier ?? "",
|
|
55778
|
+
target: match[1],
|
|
55779
|
+
start,
|
|
55780
|
+
end,
|
|
55781
|
+
targetStart,
|
|
55782
|
+
targetEnd: targetStart + match[1].length
|
|
55783
|
+
});
|
|
55784
|
+
}
|
|
55785
|
+
}
|
|
55786
|
+
}
|
|
55787
|
+
}
|
|
55788
|
+
for (const child of node3.children ?? [])
|
|
55789
|
+
visit2(child);
|
|
55790
|
+
};
|
|
55791
|
+
visit2(tree);
|
|
55792
|
+
links.sort((a, b) => a.targetStart - b.targetStart);
|
|
55793
|
+
}
|
|
55676
55794
|
let cursor = 0;
|
|
55677
55795
|
let output = "";
|
|
55678
55796
|
for (const link of links) {
|
|
@@ -63603,8 +63721,9 @@ function validateProductionStage(value) {
|
|
|
63603
63721
|
throw new TypeError("An unavailable source requires an explicit gap and pending investigation");
|
|
63604
63722
|
}
|
|
63605
63723
|
for (const usage of stage.indexer_usage) {
|
|
63606
|
-
|
|
63607
|
-
|
|
63724
|
+
const invalid = usage.scopes.filter((scope2) => !scopes.has(scope2));
|
|
63725
|
+
if (invalid.length)
|
|
63726
|
+
throw new TypeError(`indexer_usage.scopes contains unauthorized source refs: ${invalid.join(", ")}. Use stage.scopes source refs (${[...scopes.keys()].join(", ")}), not collection names. This is not an Indexer registration error.`);
|
|
63608
63727
|
}
|
|
63609
63728
|
const visited = new Set;
|
|
63610
63729
|
const visiting = new Set;
|
|
@@ -63624,7 +63743,9 @@ function validateProductionStage(value) {
|
|
|
63624
63743
|
visited.add(task.id);
|
|
63625
63744
|
}
|
|
63626
63745
|
for (const task of stage.tasks) {
|
|
63627
|
-
indexerKnowledgeCollectionSchema2.
|
|
63746
|
+
if (!indexerKnowledgeCollectionSchema2.safeParse(task.path.split("/")[0]).success) {
|
|
63747
|
+
throw new TypeError(`Article path "${task.path}" must be relative to knowledge/, e.g. business/example.md (without the knowledge/ prefix). Valid collections: ${TOP_LEVEL_NAMESPACES.join(", ")}. Correct the article path, not indexer_usage.scopes.`);
|
|
63748
|
+
}
|
|
63628
63749
|
if (!isSafeKnowledgeTargetPath(task.path.split("/")[0], task.path))
|
|
63629
63750
|
throw new TypeError(`Unsafe article target for ${task.id}`);
|
|
63630
63751
|
if (task.input !== productionTaskInput(task))
|
|
@@ -63712,7 +63833,7 @@ var init_productionStage = __esm(() => {
|
|
|
63712
63833
|
skills: exports_external.array(exports_external.object({ name, entry: name.optional() }).strict()).default([])
|
|
63713
63834
|
}).strict();
|
|
63714
63835
|
productionIndexerUsageSchema = exports_external.object({
|
|
63715
|
-
scopes: exports_external.array(name).min(1),
|
|
63836
|
+
scopes: exports_external.array(name).min(1).describe("Authorized source refs from stage.scopes, e.g. note:20260913/decision.md; not knowledge collection names"),
|
|
63716
63837
|
skills: exports_external.array(name).min(1),
|
|
63717
63838
|
purpose: name
|
|
63718
63839
|
}).strict();
|
|
@@ -64632,12 +64753,14 @@ Restore the authorized source and retry preparation.
|
|
|
64632
64753
|
"",
|
|
64633
64754
|
...scopes.map((scope2) => `- ${scope2.scope}: ${join25(directory, productionSourceFile(scope2.scope))}`),
|
|
64634
64755
|
"",
|
|
64635
|
-
"Use code skeletons and document outlines
|
|
64756
|
+
"Use code skeletons and document outlines to identify the authorized capability families and document tasks, then selectively read full material to decide reader topics. Navigation is not a complete feature inventory. Keep unchecked scope pending; do not parse all code or maintain per-symbol disposition just to plan.",
|
|
64636
64757
|
"Scale planning to the current request. For one or two documents or a clearly bounded module, decide which articles to add or revise and where they belong; do not redesign the whole knowledge base. Start with related existing topics, expand reading only when needed, and reuse applicable decisions. A large module may need several topics, but not investigation of unrelated modules.",
|
|
64637
|
-
"
|
|
64758
|
+
"Separate the whole requested outcome from the current writing batch. Use one batch unless actual dependencies or useful parallel work justify more; do not invent page counts or dependencies. A first useful delivery does not settle remaining authorized work.",
|
|
64759
|
+
"Use question and brief to describe the reader task and useful depth: a checked file/symbol or document section with a concrete next step for navigation, or the behavior, conditions and steps needed for explanation. Reuse or revise existing articles without replacing valid detail with generic summaries; split distinct tasks, not sources or symbols.",
|
|
64638
64760
|
...request.reassess.length ? [`Reassess earlier content exclusions: ${request.reassess.join(", ")}. Their source material changed or is unavailable. The stored decisions were preserved but no longer suppress investigation.`] : [],
|
|
64639
64761
|
"Keep user-confirmed long-term exclusions in the existing requirements file. For a content-based exclusion, retain source_baselines from the supplied stage scopes for the material actually read; changed material is investigated again. Do not turn a temporary failure or an unapproved suggestion into a permanent exclusion.",
|
|
64640
64762
|
"Declare available relevant skills and whether you can coordinate multiple Agents. Article sources may cross registered source and skill boundaries. Batch dependencies in after name article paths.",
|
|
64763
|
+
"Article path is relative to knowledge/ (for example business/example.md, not knowledge/business/example.md). indexer_usage.scopes names authorized source refs from the stage, not knowledge collections. Declare skills here; no separate Indexer registry is required.",
|
|
64641
64764
|
"List remaining investigation in pending_scopes when submitting a partial plan. This is source/module-level progress, not a per-file ledger. Omit it on a writing amendment to preserve the remaining scope; submit an explicit list to update it. Unresolved material gaps cannot be cleared by declaring their investigation complete.",
|
|
64642
64765
|
`Write the plan to ${productionAgentDirectory(stage.id)}/submissions/plan.yaml and use the current action command. This does not approve the work-start report.`,
|
|
64643
64766
|
""
|
|
@@ -64784,7 +64907,7 @@ var init_productionPlanning = __esm(() => {
|
|
|
64784
64907
|
stage: text5,
|
|
64785
64908
|
capabilities: productionCapabilitiesSchema,
|
|
64786
64909
|
articles: exports_external.array(exports_external.object({
|
|
64787
|
-
path: text5,
|
|
64910
|
+
path: text5.describe("Relative to knowledge/, e.g. business/example.md; do not prefix knowledge/"),
|
|
64788
64911
|
question: text5,
|
|
64789
64912
|
sources: exports_external.array(text5).min(1),
|
|
64790
64913
|
batch: text5,
|
|
@@ -66152,6 +66275,77 @@ var init_knowledgeAssetRepair = __esm(() => {
|
|
|
66152
66275
|
init_assetSourceRegistry();
|
|
66153
66276
|
});
|
|
66154
66277
|
|
|
66278
|
+
// src/project/reviewApplyIndexer.ts
|
|
66279
|
+
var exports_reviewApplyIndexer = {};
|
|
66280
|
+
__export(exports_reviewApplyIndexer, {
|
|
66281
|
+
renderApprovedIndexerMarkdown: () => renderApprovedIndexerMarkdown
|
|
66282
|
+
});
|
|
66283
|
+
function escapeHtmlAttribute(value) {
|
|
66284
|
+
return value.replace(/&/gu, "&").replace(/"/gu, """).replace(/</gu, "<").replace(/>/gu, ">");
|
|
66285
|
+
}
|
|
66286
|
+
function sectionMarkdown(section) {
|
|
66287
|
+
return [
|
|
66288
|
+
`<!-- context:section id="${escapeHtmlAttribute(section.section_key)}" -->`,
|
|
66289
|
+
"",
|
|
66290
|
+
section.markdown.trimEnd(),
|
|
66291
|
+
"",
|
|
66292
|
+
"<!-- /context:section -->"
|
|
66293
|
+
].join(`
|
|
66294
|
+
`);
|
|
66295
|
+
}
|
|
66296
|
+
function renderApprovedIndexerMarkdown(input) {
|
|
66297
|
+
if (input.record.approved_revision !== undefined) {
|
|
66298
|
+
const content3 = compactApprovedKnowledgeMarkdown(ensureApprovedKnowledgePresentation(input.record.body));
|
|
66299
|
+
return content3.replace(/^---\r?\n([\s\S]*?)\r?\n---/u, (_match, header) => {
|
|
66300
|
+
const metadata = import_yaml25.default.parse(header);
|
|
66301
|
+
const reclassified = input.record.approved_revision?.previous_path !== undefined && input.record.approved_revision.previous_path.split("/")[0] !== input.record.collection;
|
|
66302
|
+
return ["---", import_yaml25.default.stringify({
|
|
66303
|
+
...metadata,
|
|
66304
|
+
type: reclassified ? okfTypeForCollection(input.record.collection) : metadata.type ?? okfTypeForCollection(input.record.collection),
|
|
66305
|
+
timestamp: input.timestamp
|
|
66306
|
+
}).trimEnd(), "---"].join(`
|
|
66307
|
+
`);
|
|
66308
|
+
});
|
|
66309
|
+
}
|
|
66310
|
+
const binding = input.record.indexer_candidate;
|
|
66311
|
+
if (input.record.candidate_type !== "indexer-artifact" || binding === undefined) {
|
|
66312
|
+
throw new TypeError("Indexer approved renderer requires an indexer-artifact Candidate");
|
|
66313
|
+
}
|
|
66314
|
+
const title = input.record.review.title;
|
|
66315
|
+
const body = binding.sections.flatMap((section, index2) => [
|
|
66316
|
+
...index2 === 0 ? [] : [""],
|
|
66317
|
+
sectionMarkdown(section)
|
|
66318
|
+
]).join(`
|
|
66319
|
+
`);
|
|
66320
|
+
const description = readerKnowledgeDescription({
|
|
66321
|
+
description: input.record.review.summary,
|
|
66322
|
+
markdown: body,
|
|
66323
|
+
title
|
|
66324
|
+
});
|
|
66325
|
+
const frontmatter = import_yaml25.default.stringify({
|
|
66326
|
+
title,
|
|
66327
|
+
type: okfTypeForCollection(input.record.collection),
|
|
66328
|
+
description,
|
|
66329
|
+
timestamp: input.timestamp
|
|
66330
|
+
}).trimEnd();
|
|
66331
|
+
return [
|
|
66332
|
+
"---",
|
|
66333
|
+
frontmatter,
|
|
66334
|
+
"---",
|
|
66335
|
+
"",
|
|
66336
|
+
ensureMarkdownPageTitle(body, title),
|
|
66337
|
+
""
|
|
66338
|
+
].join(`
|
|
66339
|
+
`);
|
|
66340
|
+
}
|
|
66341
|
+
var import_yaml25;
|
|
66342
|
+
var init_reviewApplyIndexer = __esm(() => {
|
|
66343
|
+
init_okfTypes();
|
|
66344
|
+
init_packageKnowledgeProjection();
|
|
66345
|
+
init_approvedKnowledgeMetadata();
|
|
66346
|
+
import_yaml25 = __toESM(require_dist(), 1);
|
|
66347
|
+
});
|
|
66348
|
+
|
|
66155
66349
|
// src/project/approvedRevisionBatch.ts
|
|
66156
66350
|
var exports_approvedRevisionBatch = {};
|
|
66157
66351
|
__export(exports_approvedRevisionBatch, {
|
|
@@ -66208,7 +66402,8 @@ async function approvedRevisionCandidateApplied(root, candidate, applied, closed
|
|
|
66208
66402
|
return false;
|
|
66209
66403
|
if (!closed && applied === candidate.body)
|
|
66210
66404
|
return true;
|
|
66211
|
-
const
|
|
66405
|
+
const { renderApprovedIndexerMarkdown: renderApprovedIndexerMarkdown2 } = await Promise.resolve().then(() => (init_reviewApplyIndexer(), exports_reviewApplyIndexer));
|
|
66406
|
+
const expected = revisionComparableMarkdown(renderApprovedIndexerMarkdown2({ record: candidate, timestamp: candidate.updated }));
|
|
66212
66407
|
const approved = revisionComparableMarkdown(applied);
|
|
66213
66408
|
if (expected === approved)
|
|
66214
66409
|
return true;
|
|
@@ -66224,9 +66419,9 @@ async function approvedRevisionCandidateApplied(root, candidate, applied, closed
|
|
|
66224
66419
|
function revisionComparableMarkdown(markdown) {
|
|
66225
66420
|
const compact = compactApprovedKnowledgeMarkdown(ensureApprovedKnowledgePresentation(markdown));
|
|
66226
66421
|
return compact.replace(/^---\r?\n([\s\S]*?)\r?\n---/u, (_match, header) => {
|
|
66227
|
-
const metadata =
|
|
66422
|
+
const metadata = import_yaml26.default.parse(header);
|
|
66228
66423
|
const { timestamp: _timestamp, ...content3 } = metadata;
|
|
66229
|
-
return ["---",
|
|
66424
|
+
return ["---", import_yaml26.default.stringify(content3).trimEnd(), "---"].join(`
|
|
66230
66425
|
`);
|
|
66231
66426
|
});
|
|
66232
66427
|
}
|
|
@@ -66266,7 +66461,7 @@ async function observeApprovedRevisionBatch(root, request) {
|
|
|
66266
66461
|
...candidates.some((candidate) => candidate.status === "rejected") ? { revision_pending: true } : {}
|
|
66267
66462
|
};
|
|
66268
66463
|
}
|
|
66269
|
-
var
|
|
66464
|
+
var import_yaml26;
|
|
66270
66465
|
var init_approvedRevisionBatch = __esm(() => {
|
|
66271
66466
|
init_src2();
|
|
66272
66467
|
init_approvedRevision();
|
|
@@ -66275,7 +66470,7 @@ var init_approvedRevisionBatch = __esm(() => {
|
|
|
66275
66470
|
init_approvedKnowledgeMetadata();
|
|
66276
66471
|
init_durableSingleFileTransaction();
|
|
66277
66472
|
init_knowledgeAssetRepair();
|
|
66278
|
-
|
|
66473
|
+
import_yaml26 = __toESM(require_dist(), 1);
|
|
66279
66474
|
});
|
|
66280
66475
|
|
|
66281
66476
|
// src/project/verifyFrontmatter.ts
|
|
@@ -66291,7 +66486,7 @@ function isDeprecatedApprovedMarkdown(content3) {
|
|
|
66291
66486
|
if (end < 0)
|
|
66292
66487
|
return false;
|
|
66293
66488
|
try {
|
|
66294
|
-
const parsed =
|
|
66489
|
+
const parsed = import_yaml27.default.parse(content3.slice(4, end));
|
|
66295
66490
|
return isRecord7(parsed) && parsed.deprecated === true;
|
|
66296
66491
|
} catch {
|
|
66297
66492
|
return false;
|
|
@@ -66310,7 +66505,7 @@ function parseFrontmatter3(content3, path2, issues) {
|
|
|
66310
66505
|
return;
|
|
66311
66506
|
}
|
|
66312
66507
|
try {
|
|
66313
|
-
const parsed =
|
|
66508
|
+
const parsed = import_yaml27.default.parse(content3.slice(4, end));
|
|
66314
66509
|
if (!isRecord7(parsed)) {
|
|
66315
66510
|
issues.push({ severity: "error", code: "frontmatter-invalid", path: path2, line: 1, message: "frontmatter must be a YAML object" });
|
|
66316
66511
|
return;
|
|
@@ -66336,7 +66531,7 @@ function parseFrontmatterLoose(content3) {
|
|
|
66336
66531
|
if (end < 0)
|
|
66337
66532
|
return {};
|
|
66338
66533
|
try {
|
|
66339
|
-
const parsed =
|
|
66534
|
+
const parsed = import_yaml27.default.parse(content3.slice(4, end));
|
|
66340
66535
|
return isRecord7(parsed) ? parsed : {};
|
|
66341
66536
|
} catch {
|
|
66342
66537
|
return {};
|
|
@@ -66406,10 +66601,10 @@ async function validateApprovedMarkdown(input) {
|
|
|
66406
66601
|
});
|
|
66407
66602
|
}
|
|
66408
66603
|
}
|
|
66409
|
-
var
|
|
66604
|
+
var import_yaml27;
|
|
66410
66605
|
var init_verifyFrontmatter = __esm(() => {
|
|
66411
66606
|
init_okfTypes();
|
|
66412
|
-
|
|
66607
|
+
import_yaml27 = __toESM(require_dist(), 1);
|
|
66413
66608
|
});
|
|
66414
66609
|
|
|
66415
66610
|
// src/project/indexerTemplateSnapshots.ts
|
|
@@ -67297,7 +67492,7 @@ async function prepareApprovedKnowledgeSnapshotTarget(input) {
|
|
|
67297
67492
|
if (error.code !== "ENOENT")
|
|
67298
67493
|
throw error;
|
|
67299
67494
|
}
|
|
67300
|
-
const structure = before === undefined ? {} :
|
|
67495
|
+
const structure = before === undefined ? {} : import_yaml28.default.parse(before);
|
|
67301
67496
|
if (!structure || typeof structure !== "object" || Array.isArray(structure))
|
|
67302
67497
|
throw new TypeError("Invalid knowledge structure");
|
|
67303
67498
|
const articles = new Map(approvedKnowledgeSnapshotsFromStructure(structure).map((article) => [article.article_id, article]));
|
|
@@ -67321,7 +67516,7 @@ async function prepareApprovedKnowledgeSnapshotTarget(input) {
|
|
|
67321
67516
|
articles.set(article.article_id, article);
|
|
67322
67517
|
}
|
|
67323
67518
|
const entries2 = validateArticleStructureEntries([...articles.values()]);
|
|
67324
|
-
const content3 =
|
|
67519
|
+
const content3 = import_yaml28.default.stringify({
|
|
67325
67520
|
...structure,
|
|
67326
67521
|
articles: entries2.sort((a, b) => a.article_id.localeCompare(b.article_id))
|
|
67327
67522
|
});
|
|
@@ -67335,12 +67530,12 @@ async function prepareApprovedKnowledgeSnapshotTarget(input) {
|
|
|
67335
67530
|
content: content3
|
|
67336
67531
|
};
|
|
67337
67532
|
}
|
|
67338
|
-
var
|
|
67533
|
+
var import_yaml28, STRUCTURE_PATH2 = "knowledge/structure.yaml";
|
|
67339
67534
|
var init_approvedKnowledgeSnapshots = __esm(() => {
|
|
67340
67535
|
init_src2();
|
|
67341
67536
|
init_approvedKnowledgeMetadata();
|
|
67342
67537
|
init_durableSingleFileTransaction();
|
|
67343
|
-
|
|
67538
|
+
import_yaml28 = __toESM(require_dist(), 1);
|
|
67344
67539
|
});
|
|
67345
67540
|
|
|
67346
67541
|
// src/runtimeEventOutbox.ts
|
|
@@ -69378,7 +69573,7 @@ function parseFrontmatter4(content3) {
|
|
|
69378
69573
|
const match = /^---\r?\n([\s\S]*?)\r?\n---/u.exec(content3);
|
|
69379
69574
|
if (match?.[1] === undefined)
|
|
69380
69575
|
return {};
|
|
69381
|
-
const parsed =
|
|
69576
|
+
const parsed = import_yaml29.default.parse(match[1]);
|
|
69382
69577
|
return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
69383
69578
|
}
|
|
69384
69579
|
function isDeprecated(content3) {
|
|
@@ -69439,7 +69634,7 @@ async function writeApprovedStructureProjection(projectRoot) {
|
|
|
69439
69634
|
const { inputHash, structure, compactFiles } = await deriveApprovedStructure(projectRoot);
|
|
69440
69635
|
const outputPath = join48(projectRoot, STRUCTURE_PATH4);
|
|
69441
69636
|
await mkdir17(dirname21(outputPath), { recursive: true });
|
|
69442
|
-
await writeFile11(outputPath,
|
|
69637
|
+
await writeFile11(outputPath, import_yaml29.default.stringify(structure), "utf8");
|
|
69443
69638
|
await Promise.all(compactFiles.map((file) => writeFile11(file.absPath, file.content, "utf8")));
|
|
69444
69639
|
return { inputHash, articles: structure.articles.length, structure: STRUCTURE_PATH4 };
|
|
69445
69640
|
}
|
|
@@ -69507,7 +69702,7 @@ async function closeProjectWorkspace(projectRoot) {
|
|
|
69507
69702
|
}
|
|
69508
69703
|
const outputPath = join48(projectRoot, STRUCTURE_PATH4);
|
|
69509
69704
|
await mkdir17(dirname21(outputPath), { recursive: true });
|
|
69510
|
-
await writeFile11(outputPath, `${
|
|
69705
|
+
await writeFile11(outputPath, `${import_yaml29.default.stringify(structure)}`, "utf8");
|
|
69511
69706
|
await Promise.all(compactFiles.map((file) => writeFile11(file.absPath, file.content, "utf8")));
|
|
69512
69707
|
const { readTaskRollback } = await Promise.resolve().then(() => (init_taskRollback(), exports_taskRollback));
|
|
69513
69708
|
if (!production && !await readTaskRollback(projectRoot))
|
|
@@ -69558,7 +69753,7 @@ async function runProjectCloseCommand(input) {
|
|
|
69558
69753
|
}
|
|
69559
69754
|
return true;
|
|
69560
69755
|
}
|
|
69561
|
-
var
|
|
69756
|
+
var import_yaml29, KNOWLEDGE_ROOT = "knowledge", STRUCTURE_PATH4, STRUCTURE_SCHEMA_VERSION = "context.approved-structure.v1";
|
|
69562
69757
|
var init_close = __esm(() => {
|
|
69563
69758
|
init_indexerRequiredArticleReview();
|
|
69564
69759
|
init_approvedFileRead();
|
|
@@ -69579,7 +69774,7 @@ var init_close = __esm(() => {
|
|
|
69579
69774
|
init_candidateLedger();
|
|
69580
69775
|
init_knowledgeAssetRepair();
|
|
69581
69776
|
init_approvedKnowledgeMetadata();
|
|
69582
|
-
|
|
69777
|
+
import_yaml29 = __toESM(require_dist(), 1);
|
|
69583
69778
|
STRUCTURE_PATH4 = join48(KNOWLEDGE_ROOT, "structure.yaml");
|
|
69584
69779
|
});
|
|
69585
69780
|
|
|
@@ -69843,7 +70038,7 @@ async function optionalText(root, path2) {
|
|
|
69843
70038
|
}
|
|
69844
70039
|
async function readKnowledgeMap(root) {
|
|
69845
70040
|
const content3 = await optionalText(root, KNOWLEDGE_MAP_PATH);
|
|
69846
|
-
return content3 === undefined ? undefined : validateKnowledgeMap(
|
|
70041
|
+
return content3 === undefined ? undefined : validateKnowledgeMap(import_yaml30.parse(content3));
|
|
69847
70042
|
}
|
|
69848
70043
|
async function applyKnowledgeMapUpdate(projectRoot, update) {
|
|
69849
70044
|
return withProjectWriteLock(projectRoot, "adjust-knowledge-map", async () => {
|
|
@@ -69855,7 +70050,7 @@ async function applyKnowledgeMapUpdate(projectRoot, update) {
|
|
|
69855
70050
|
const preview = previewText === undefined ? undefined : JSON.parse(previewText);
|
|
69856
70051
|
const planned = preview?.topics?.flatMap((topic) => topic.article_targets ?? []) ?? [];
|
|
69857
70052
|
assertKnowledgeMapCoverage(next, approved, { known: [...approved, ...planned], current_revision: current?.revision ?? null });
|
|
69858
|
-
const content3 =
|
|
70053
|
+
const content3 = import_yaml30.stringify(next);
|
|
69859
70054
|
const previous2 = await optionalText(projectRoot, KNOWLEDGE_MAP_PATH);
|
|
69860
70055
|
await runDurableMultiFileTransaction({
|
|
69861
70056
|
projectRoot,
|
|
@@ -69876,14 +70071,14 @@ async function applyKnowledgeMapUpdate(projectRoot, update) {
|
|
|
69876
70071
|
};
|
|
69877
70072
|
});
|
|
69878
70073
|
}
|
|
69879
|
-
var
|
|
70074
|
+
var import_yaml30, KNOWLEDGE_MAP_PATH = "src/knowledge-map.yaml";
|
|
69880
70075
|
var init_knowledgeMap2 = __esm(() => {
|
|
69881
70076
|
init_knowledgeMapCoverage();
|
|
69882
70077
|
init_src2();
|
|
69883
70078
|
init_durableSingleFileTransaction();
|
|
69884
70079
|
init_durableMultiFileTransaction();
|
|
69885
70080
|
init_writeLock();
|
|
69886
|
-
|
|
70081
|
+
import_yaml30 = __toESM(require_dist(), 1);
|
|
69887
70082
|
});
|
|
69888
70083
|
|
|
69889
70084
|
// src/project/packageKnowledgeMap.ts
|
|
@@ -70157,7 +70352,7 @@ async function optionalWorkspaceText(root, path2) {
|
|
|
70157
70352
|
}
|
|
70158
70353
|
async function readWorkspaceChangelog(root) {
|
|
70159
70354
|
const value = await optionalWorkspaceText(root, "changelog.yaml");
|
|
70160
|
-
return value === undefined ? [] : ledgerSchema.parse(
|
|
70355
|
+
return value === undefined ? [] : ledgerSchema.parse(import_yaml31.parse(value)).entries;
|
|
70161
70356
|
}
|
|
70162
70357
|
async function workspaceVersion(root) {
|
|
70163
70358
|
const manifest = JSON.parse(await readFile45(join55(root, "package.json"), "utf8"));
|
|
@@ -70299,7 +70494,7 @@ async function recordWorkspaceVersion(root, value) {
|
|
|
70299
70494
|
const writes = {
|
|
70300
70495
|
"package.json": JSON.stringify(manifest, null, 2) + `
|
|
70301
70496
|
`,
|
|
70302
|
-
"changelog.yaml":
|
|
70497
|
+
"changelog.yaml": import_yaml31.stringify({ entries: entries2 }),
|
|
70303
70498
|
"CHANGELOG.md": renderChangelog(entries2),
|
|
70304
70499
|
".context-version.json": JSON.stringify({ version: entry.version, files: status.files }) + `
|
|
70305
70500
|
`
|
|
@@ -70313,13 +70508,13 @@ async function recordWorkspaceVersion(root, value) {
|
|
|
70313
70508
|
return { version: entry.version, next_action: { command: "context status --format json" } };
|
|
70314
70509
|
});
|
|
70315
70510
|
}
|
|
70316
|
-
var
|
|
70511
|
+
var import_yaml31, exec, semver, text6, changelogEntrySchema, changelogInputSchema, ledgerSchema, baselineSchema, hash2 = (value) => createHash15("sha256").update(JSON.stringify(value)).digest("hex");
|
|
70317
70512
|
var init_workspaceChangelog = __esm(() => {
|
|
70318
70513
|
init_zod();
|
|
70319
70514
|
init_writeLock();
|
|
70320
70515
|
init_durableSingleFileTransaction();
|
|
70321
70516
|
init_durableMultiFileTransaction();
|
|
70322
|
-
|
|
70517
|
+
import_yaml31 = __toESM(require_dist(), 1);
|
|
70323
70518
|
exec = promisify6(execFile6);
|
|
70324
70519
|
semver = exports_external.string().regex(/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/u);
|
|
70325
70520
|
text6 = exports_external.string().trim().min(1);
|
|
@@ -70452,17 +70647,22 @@ var siteMarkdownConfig, siteThemeScript, siteThemeCss = `
|
|
|
70452
70647
|
}
|
|
70453
70648
|
.VPNavBar .wrapper { padding: 0 24px !important; }
|
|
70454
70649
|
.VPNavBar .container { max-width: none !important; }
|
|
70650
|
+
.VPNav, .VPNavBar, .VPNavBar .wrapper { background: var(--vp-c-bg) !important; }
|
|
70455
70651
|
.VPNavBar .title { position: static !important; padding: 0 !important; width: var(--vp-sidebar-width) !important; flex-shrink: 0; }
|
|
70456
70652
|
.VPNavBarTitle .title { font-size: 15px; font-weight: 650; border: 0 !important; }
|
|
70457
70653
|
.VPNavBar .content { flex: 1; min-width: 0; padding-left: 0 !important; }
|
|
70458
70654
|
.VPNavBar .content-body { background: var(--vp-c-bg) !important; gap: 8px; }
|
|
70459
70655
|
.VPNavBarMenu { order: -1; flex: 1; min-width: 0; }
|
|
70460
|
-
.context-language { display: flex; align-items: center;
|
|
70461
|
-
|
|
70462
|
-
.context-language
|
|
70656
|
+
.context-language { display: inline-flex; align-items: center; padding: 5px 7px; border: 0; border-radius: 6px; color: var(--vp-c-text-2);
|
|
70657
|
+
background: transparent; white-space: nowrap; font-size: 12px; font-weight: 550; cursor: pointer; }
|
|
70658
|
+
.context-language:hover { color: var(--vp-c-brand-1); background: var(--vp-c-brand-soft); }
|
|
70463
70659
|
.VPNavBarMenuLink { font-size: 13px !important; font-weight: 550 !important; padding: 0 16px !important; }
|
|
70464
70660
|
.VPNavBarMenuLink.active { box-shadow: inset 0 -2px var(--vp-c-brand-1); }
|
|
70465
|
-
.VPNavBarSearch { flex
|
|
70661
|
+
.VPNavBarSearch { flex: 0 0 376px !important; width: 376px; padding: 0 12px !important; }
|
|
70662
|
+
.VPNavBarSearch #local-search, .VPNavBarSearch .DocSearch-Button { width: 352px; }
|
|
70663
|
+
.VPNavBarSearch .DocSearch-Button { display: flex; align-items: center; }
|
|
70664
|
+
.VPNavBarSearch .DocSearch-Button-Container { display: flex; flex: 1; min-width: 0; align-items: center; }
|
|
70665
|
+
.VPNavBarSearch .DocSearch-Button-Keys { margin-left: auto; }
|
|
70466
70666
|
.VPSidebar { border-top: 1px solid var(--vp-c-divider); border-right: 1px solid var(--vp-c-divider); scrollbar-width: thin; }
|
|
70467
70667
|
.VPSidebar .group + .group { border: 0; padding-top: 8px; }
|
|
70468
70668
|
.VPSidebarItem .link { min-width: 0; overflow: hidden; }
|
|
@@ -70508,16 +70708,84 @@ var siteMarkdownConfig, siteThemeScript, siteThemeCss = `
|
|
|
70508
70708
|
.vp-doc details { margin: 20px 0; border: 1px solid var(--vp-c-divider); border-radius: 6px; padding: 12px 16px; }
|
|
70509
70709
|
.vp-doc summary { cursor: pointer; font-size: 14px; font-weight: 550; }
|
|
70510
70710
|
.vp-doc img { max-width: 100%; height: auto; }
|
|
70711
|
+
.context-home { max-width: 100%; min-width: 0; overflow-x: clip; }
|
|
70712
|
+
.context-home .VPContent, .context-home .VPHome, .context-home .VPHero { max-width: 100%; min-width: 0; }
|
|
70713
|
+
.context-home .VPHome { padding-bottom: 0; }
|
|
70714
|
+
.context-home .VPHero { position: relative; padding: 132px 0 62px; }
|
|
70715
|
+
.context-home .VPHero::before { content: ''; position: absolute; top: -1px; right: 0; bottom: 0; left: calc(0px - var(--vp-sidebar-width)); pointer-events: none;
|
|
70716
|
+
background: linear-gradient(to bottom, transparent 58%, var(--vp-c-bg) 100%),
|
|
70717
|
+
radial-gradient(ellipse 58% 145% at 8% 18%, rgba(37,99,235,.16), transparent 72%),
|
|
70718
|
+
radial-gradient(ellipse 58% 150% at 68% 24%, rgba(0,190,200,.11), transparent 72%),
|
|
70719
|
+
linear-gradient(90deg, rgba(37,99,235,.045), rgba(0,190,200,.025) 68%, transparent); }
|
|
70720
|
+
.context-home .VPHero .container { position: relative; box-sizing: border-box; width: min(1180px, calc(100% - 104px)); max-width: none; min-width: 0; margin-left: 52px; margin-right: auto; }
|
|
70721
|
+
.context-home .VPHero .main { width: 100%; max-width: 980px; min-width: 0; }
|
|
70722
|
+
.context-home .VPHero .heading { display: block; width: 100%; min-width: 0; max-width: 100%; }
|
|
70723
|
+
.context-home .VPHero .name { display: block; width: 100%; max-width: 100%; overflow-wrap: anywhere; white-space: normal; color: transparent;
|
|
70724
|
+
background: linear-gradient(112deg, var(--vp-c-brand-1), var(--context-accent)); background-clip: text; -webkit-background-clip: text; }
|
|
70725
|
+
.context-home .VPHero .text { display: block; width: 100%; max-width: 100%; overflow-wrap: anywhere; word-break: break-word; white-space: normal;
|
|
70726
|
+
font-size: clamp(38px, 4.2vw, 60px); line-height: 1.08; letter-spacing: -.045em; }
|
|
70727
|
+
.context-home .VPHero .tagline { max-width: 820px; font-size: 18px; line-height: 1.75; }
|
|
70728
|
+
.context-home .VPHero .actions { width: 100%; min-width: 0; padding-top: 38px; flex-wrap: wrap; }
|
|
70729
|
+
.context-home .VPFeatures { display: none; }
|
|
70730
|
+
.context-home-section { width: min(1180px, calc(100% - 104px)); margin: 0 auto 0 52px; padding: 36px 0 44px; }
|
|
70731
|
+
.context-home-section + .context-home-section { border-top: 1px solid var(--vp-c-divider); }
|
|
70732
|
+
.context-home-map { padding-top: 0; }
|
|
70733
|
+
.context-home-resources { padding-top: 6px; border-top: 0 !important; }
|
|
70734
|
+
.context-home-section-heading { max-width: 700px; margin-bottom: 24px; }
|
|
70735
|
+
.context-home-section-heading h2 { margin: 2px 0 8px; border: 0; font-size: 28px; line-height: 1.3; letter-spacing: -.02em; }
|
|
70736
|
+
.context-home-section-heading > p:last-child { color: var(--vp-c-text-2); line-height: 1.7; }
|
|
70737
|
+
.context-home-kicker { margin: 0; color: var(--vp-c-brand-1); font-size: 11px; font-weight: 700; letter-spacing: .16em; }
|
|
70738
|
+
.context-home-map-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(290px, 100%), 1fr)); gap: 14px; }
|
|
70739
|
+
.context-home-map-card, .context-home-resource-card { border: 1px solid var(--vp-c-divider); background: color-mix(in srgb, var(--vp-c-bg) 88%, var(--vp-c-bg-soft));
|
|
70740
|
+
animation: context-home-rise .5s both; animation-delay: var(--context-home-delay); }
|
|
70741
|
+
.context-home-map-card { min-height: 224px; padding: 22px; border-radius: 14px; }
|
|
70742
|
+
.context-home-map-card:hover, .context-home-resource-card:hover { border-color: color-mix(in srgb, var(--vp-c-brand-1) 42%, var(--vp-c-divider));
|
|
70743
|
+
box-shadow: 0 14px 38px rgba(23,36,66,.08); transform: translateY(-2px); transition: border-color .18s, box-shadow .18s, transform .18s; }
|
|
70744
|
+
.context-home-map-card-heading { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; padding-bottom: 13px; border-bottom: 1px solid var(--vp-c-divider); }
|
|
70745
|
+
.context-home-map-card h3, .context-home-resource-card h3 { margin: 0; font-size: 17px; line-height: 1.45; }
|
|
70746
|
+
.context-home-map-card h3 a { color: var(--vp-c-text-1); }
|
|
70747
|
+
.context-home-map-card-heading span { flex: none; color: var(--vp-c-text-2); font-size: 11px; }
|
|
70748
|
+
.context-home-map-card ul { margin: 14px 0 0; padding: 0; list-style: none; }
|
|
70749
|
+
.context-home-map-card li { margin: 7px 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
70750
|
+
.context-home-map-card li a { color: var(--vp-c-text-2); font-size: 13px; }
|
|
70751
|
+
.context-home-map-card li a:hover, .context-home-map-more:hover { color: var(--vp-c-brand-1); }
|
|
70752
|
+
.context-home-map-more { display: inline-block; margin-top: 12px; color: var(--vp-c-brand-1); font-size: 12px; font-weight: 600; }
|
|
70753
|
+
.context-home-resource-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
|
|
70754
|
+
.context-home-resource-card { min-height: 118px; padding: 16px 18px; border-radius: 12px; }
|
|
70755
|
+
.context-home-resource-heading { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
|
|
70756
|
+
.context-home-resource-actions { display: flex; flex: none; align-items: center; gap: 6px; }
|
|
70757
|
+
.context-home-resource-action, .context-home-install-action { display: inline-flex; align-items: center; min-height: 28px; padding: 4px 8px; border: 1px solid var(--vp-c-divider); border-radius: 6px;
|
|
70758
|
+
color: var(--vp-c-text-2); background: var(--vp-c-bg); font-size: 11px; font-weight: 600; line-height: 1; white-space: nowrap; }
|
|
70759
|
+
.context-home-resource-action:hover, .context-home-install-action:hover { border-color: var(--vp-c-brand-1); color: var(--vp-c-brand-1); }
|
|
70760
|
+
.context-home-install-action { cursor: pointer; background: var(--vp-c-brand-soft); }
|
|
70761
|
+
.context-home-resource-card p { margin: 8px 0 0; color: var(--vp-c-text-2); font-size: 13px; line-height: 1.55; }
|
|
70762
|
+
.context-home-powered { width: min(1180px, calc(100% - 104px)); margin: 24px auto 0 52px; padding: 22px 0 30px; border-top: 1px solid var(--vp-c-divider);
|
|
70763
|
+
color: var(--vp-c-text-2); font-size: 11px; text-align: right; }
|
|
70764
|
+
.context-home-powered a { color: inherit; }
|
|
70765
|
+
@keyframes context-home-rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
|
|
70511
70766
|
@media (min-width: 960px) {
|
|
70512
70767
|
.VPSidebar { top: var(--vp-nav-height) !important; width: var(--vp-sidebar-width) !important; padding: 12px 0 48px !important; }
|
|
70513
70768
|
.VPSidebar .curtain { display: none; }
|
|
70514
70769
|
.VPContent.has-sidebar { padding-left: var(--vp-sidebar-width) !important; padding-right: 0 !important; }
|
|
70515
70770
|
.context-empty-sidebar .VPContent { padding-left: var(--vp-sidebar-width) !important; padding-right: 0 !important; }
|
|
70771
|
+
.context-home .VPContent { padding-left: var(--vp-sidebar-width) !important; padding-right: 0 !important; }
|
|
70516
70772
|
.VPNavBar .content { padding-right: 32px !important; }
|
|
70517
70773
|
.VPDoc { padding: 44px 36px 80px !important; }
|
|
70518
70774
|
.VPDoc > .container > .content { padding: 0 24px 80px 0 !important; }
|
|
70519
70775
|
}
|
|
70520
70776
|
@media (min-width: 1600px) { .VPDoc { padding-left: 52px !important; padding-right: 36px !important; } }
|
|
70777
|
+
@media (min-width: 960px) and (max-width: 1279px) {
|
|
70778
|
+
.VPNavBar .title { width: 220px !important; }
|
|
70779
|
+
.VPNavBarMenuLink { padding: 0 9px !important; }
|
|
70780
|
+
.VPNavBarSearch { flex-basis: 168px !important; width: 168px; }
|
|
70781
|
+
.VPNavBarSearch .DocSearch-Button { width: 144px; }
|
|
70782
|
+
.context-home .VPHero .main { max-width: 100%; }
|
|
70783
|
+
.context-home-resource-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
70784
|
+
}
|
|
70785
|
+
@media (min-width: 1280px) and (max-width: 1599px) {
|
|
70786
|
+
.VPNavBarSearch { flex-basis: 248px !important; width: 248px; }
|
|
70787
|
+
.VPNavBarSearch #local-search, .VPNavBarSearch .DocSearch-Button { width: 224px; }
|
|
70788
|
+
}
|
|
70521
70789
|
.context-mobile-directory { display: none; }
|
|
70522
70790
|
@media (max-width: 959px) {
|
|
70523
70791
|
.VPNavBar .wrapper { padding: 0 16px !important; }
|
|
@@ -70541,6 +70809,17 @@ var siteMarkdownConfig, siteThemeScript, siteThemeCss = `
|
|
|
70541
70809
|
.vp-doc h2 { font-size: 22px; }
|
|
70542
70810
|
.VPDoc { padding: 32px 36px 64px !important; }
|
|
70543
70811
|
.vp-doc a.header-anchor { margin-left: -0.8em; }
|
|
70812
|
+
.context-home .VPHero { padding-top: 104px; padding-bottom: 66px; }
|
|
70813
|
+
.context-home .VPHero::before { left: 0; }
|
|
70814
|
+
.context-home .VPHero .container { width: min(calc(100% - 36px), 680px); margin-left: auto; margin-right: auto; }
|
|
70815
|
+
.context-home .VPHero .text { font-size: 40px; }
|
|
70816
|
+
.context-home .VPHero .tagline { font-size: 16px; }
|
|
70817
|
+
.context-home-section, .context-home-powered { width: min(calc(100% - 36px), 680px); margin-left: auto; margin-right: auto; }
|
|
70818
|
+
.context-home-resource-grid { grid-template-columns: 1fr; }
|
|
70819
|
+
}
|
|
70820
|
+
@media (prefers-reduced-motion: reduce) {
|
|
70821
|
+
.context-home-map-card, .context-home-resource-card { animation: none; }
|
|
70822
|
+
.context-home-map-card:hover, .context-home-resource-card:hover { transform: none; }
|
|
70544
70823
|
}
|
|
70545
70824
|
.context-sources { margin-top: 0; margin-bottom: 24px; padding: 16px 20px; border: 1px solid var(--vp-c-divider); border-radius: 8px; background: var(--vp-sidebar-bg-color); color: var(--vp-c-text-2); font-size: 12px; line-height: 1.7; overflow-wrap: anywhere; }
|
|
70546
70825
|
.context-sources-header { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 4px 16px; margin-bottom: 8px; }
|
|
@@ -70626,9 +70905,12 @@ export default {
|
|
|
70626
70905
|
const data = useData();
|
|
70627
70906
|
const route = useRoute();
|
|
70628
70907
|
const sections = computed(() => data.theme.value.contextSections || []);
|
|
70908
|
+
const home = computed(() => data.theme.value.contextHome || {});
|
|
70629
70909
|
const selected = ref('');
|
|
70630
70910
|
const mounted = ref(false);
|
|
70631
70911
|
const language = ref('zh');
|
|
70912
|
+
const copiedCommand = ref('');
|
|
70913
|
+
let copyReset;
|
|
70632
70914
|
const chinese = computed(() => language.value === 'zh');
|
|
70633
70915
|
const languageKey = 'context-language:' + data.site.value.base;
|
|
70634
70916
|
onMounted(() => {
|
|
@@ -70641,6 +70923,76 @@ export default {
|
|
|
70641
70923
|
language.value = value;
|
|
70642
70924
|
try { localStorage.setItem(languageKey, value); } catch {}
|
|
70643
70925
|
};
|
|
70926
|
+
const href = value => value.startsWith('/') ? data.site.value.base + value.slice(1) : value;
|
|
70927
|
+
const external = value => /^https?:\/\//.test(value) || value.startsWith('mailto:');
|
|
70928
|
+
const copyCommand = async value => {
|
|
70929
|
+
try {
|
|
70930
|
+
await navigator.clipboard.writeText(value);
|
|
70931
|
+
copiedCommand.value = value;
|
|
70932
|
+
clearTimeout(copyReset);
|
|
70933
|
+
copyReset = setTimeout(() => { if (copiedCommand.value === value) copiedCommand.value = ''; }, 1600);
|
|
70934
|
+
} catch {}
|
|
70935
|
+
};
|
|
70936
|
+
const links = items => items.flatMap(item => [
|
|
70937
|
+
...(item.link ? [{ text: item.text, link: item.link }] : []),
|
|
70938
|
+
...links(item.items || []),
|
|
70939
|
+
]);
|
|
70940
|
+
const siteMap = () => h('section', { class: 'context-home-section context-home-map', 'aria-labelledby': 'context-home-map-title' }, [
|
|
70941
|
+
h('div', { class: 'context-home-section-heading' }, [
|
|
70942
|
+
h('p', { class: 'context-home-kicker' }, chinese.value ? 'KNOWLEDGE MAP' : 'KNOWLEDGE MAP'),
|
|
70943
|
+
h('h2', { id: 'context-home-map-title' }, chinese.value ? '网站地图' : 'Site map'),
|
|
70944
|
+
h('p', chinese.value ? '从主题进入知识,也可以继续查看栏目中的具体页面。' :
|
|
70945
|
+
'Start with a topic, then continue to the pages within each section.'),
|
|
70946
|
+
]),
|
|
70947
|
+
h('div', { class: 'context-home-map-grid' }, sections.value.map((section, index) => {
|
|
70948
|
+
const pages = links(section.items || []);
|
|
70949
|
+
return h('article', { class: 'context-home-map-card', style: { '--context-home-delay': (index * 35) + 'ms' } }, [
|
|
70950
|
+
h('div', { class: 'context-home-map-card-heading' }, [
|
|
70951
|
+
h('h3', h('a', { href: href(section.href) }, section.title)),
|
|
70952
|
+
h('span', chinese.value ? section.pages.length + ' 页' : section.pages.length + ' pages'),
|
|
70953
|
+
]),
|
|
70954
|
+
pages.length ? h('ul', pages.slice(0, 6).map(page => h('li',
|
|
70955
|
+
h('a', { href: href(page.link) }, page.text)))) : null,
|
|
70956
|
+
pages.length > 6 ? h('a', { class: 'context-home-map-more', href: href(section.href) },
|
|
70957
|
+
chinese.value ? '查看全部 ' + pages.length + ' 页 →' : 'View all ' + pages.length + ' pages →') : null,
|
|
70958
|
+
]);
|
|
70959
|
+
})),
|
|
70960
|
+
]);
|
|
70961
|
+
const resources = () => {
|
|
70962
|
+
const builtins = [
|
|
70963
|
+
{ title: 'LLM Docs', description: chinese.value ? '面向 Agent 和模型的结构化知识入口。' :
|
|
70964
|
+
'Structured knowledge entry points for agents and models.', href: '/llms/index.html', action: chinese.value ? '打开文档' : 'Open docs' },
|
|
70965
|
+
{ title: 'Changelog', description: chinese.value ? '查看知识内容的版本变化与更新时间。' :
|
|
70966
|
+
'Review knowledge versions and update history.', href: '/changelog.html', action: chinese.value ? '查看更新' : 'View updates' },
|
|
70967
|
+
];
|
|
70968
|
+
const items = [...(home.value.resources || []), ...builtins];
|
|
70969
|
+
return h('section', { class: 'context-home-section context-home-resources', 'aria-labelledby': 'context-home-resources-title' }, [
|
|
70970
|
+
h('div', { class: 'context-home-section-heading' }, [
|
|
70971
|
+
h('p', { class: 'context-home-kicker' }, chinese.value ? 'RESOURCES' : 'RESOURCES'),
|
|
70972
|
+
h('h2', { id: 'context-home-resources-title' }, chinese.value ? '工具与资源' : 'Tools and resources'),
|
|
70973
|
+
]),
|
|
70974
|
+
h('div', { class: 'context-home-resource-grid' }, items.map((item, index) => h('article', {
|
|
70975
|
+
class: 'context-home-resource-card', style: { '--context-home-delay': (index * 35) + 'ms' },
|
|
70976
|
+
}, [
|
|
70977
|
+
h('div', { class: 'context-home-resource-heading' }, [
|
|
70978
|
+
h('h3', item.title),
|
|
70979
|
+
h('div', { class: 'context-home-resource-actions' }, [
|
|
70980
|
+
item.command ? h('button', { class: 'context-home-install-action', type: 'button',
|
|
70981
|
+
title: (chinese.value ? '复制安装命令:' : 'Copy install command: ') + item.command,
|
|
70982
|
+
onClick: () => copyCommand(item.command) }, copiedCommand.value === item.command
|
|
70983
|
+
? (chinese.value ? '已复制' : 'Copied') : (chinese.value ? '安装' : 'Install')) : null,
|
|
70984
|
+
item.href ? h('a', { class: 'context-home-resource-action', href: href(item.href), ...(external(item.href)
|
|
70985
|
+
? { target: '_blank', rel: 'noopener noreferrer' } : {}) }, item.action || (chinese.value ? '访问' : 'Open')) : null,
|
|
70986
|
+
]),
|
|
70987
|
+
]),
|
|
70988
|
+
item.description ? h('p', item.description) : null,
|
|
70989
|
+
]))),
|
|
70990
|
+
]);
|
|
70991
|
+
};
|
|
70992
|
+
const poweredBy = () => home.value.branding ? h('footer', { class: 'context-home-powered' }, [
|
|
70993
|
+
home.value.branding.label + ' ',
|
|
70994
|
+
h('a', { href: home.value.branding.href, target: '_blank', rel: 'noopener noreferrer' }, home.value.branding.name),
|
|
70995
|
+
]) : null;
|
|
70644
70996
|
const history = computed(() => data.frontmatter.value.contextHistory
|
|
70645
70997
|
? JSON.parse(new TextDecoder().decode(Uint8Array.from(atob(data.frontmatter.value.contextHistory), char => char.charCodeAt(0)))) : null);
|
|
70646
70998
|
onMounted(() => { mounted.value = true; });
|
|
@@ -70667,6 +71019,7 @@ export default {
|
|
|
70667
71019
|
const active = computed(() => sections.value.find(section => section.key === selected.value));
|
|
70668
71020
|
const inLlms = computed(() => route.path.startsWith(data.site.value.base + 'llms/'));
|
|
70669
71021
|
const inHistory = computed(() => route.path === data.site.value.base + 'changelog.html');
|
|
71022
|
+
const inHome = computed(() => data.frontmatter.value.layout === 'home');
|
|
70670
71023
|
provide(dataSymbol, { ...data, theme: computed(() => ({ ...data.theme.value,
|
|
70671
71024
|
...data.theme.value.contextUiLabels?.[language.value],
|
|
70672
71025
|
sidebar: inLlms.value || inHistory.value ? [] : active.value?.items || [],
|
|
@@ -70678,9 +71031,12 @@ export default {
|
|
|
70678
71031
|
activeMatch: inLlms.value || inHistory.value ? '^' : '(?!)' }],
|
|
70679
71032
|
})) });
|
|
70680
71033
|
const slots = {
|
|
70681
|
-
'nav-bar-content-after': () => h('
|
|
70682
|
-
|
|
70683
|
-
|
|
71034
|
+
'nav-bar-content-after': () => h('button', { class: 'context-language', type: 'button',
|
|
71035
|
+
'aria-label': chinese.value ? 'Switch interface language to English' : '将界面语言切换为中文',
|
|
71036
|
+
title: chinese.value ? 'Switch to English' : '切换为中文',
|
|
71037
|
+
onClick: () => changeLanguage(chinese.value ? 'en' : 'zh') }, chinese.value ? 'EN' : '中文'),
|
|
71038
|
+
'home-features-before': () => [siteMap(), resources()],
|
|
71039
|
+
'home-features-after': poweredBy,
|
|
70684
71040
|
'doc-after': () => history.value ? h('section', { class: 'context-history-cards' },
|
|
70685
71041
|
history.value.length ? history.value.map((entry, index) =>
|
|
70686
71042
|
h('details', { class: 'context-history-card', open: index < 3, key: entry.version }, [
|
|
@@ -70729,7 +71085,8 @@ export default {
|
|
|
70729
71085
|
},
|
|
70730
71086
|
};
|
|
70731
71087
|
// History belongs between the page heading and footer metadata.
|
|
70732
|
-
return () => h(DefaultTheme.Layout, { class:
|
|
71088
|
+
return () => h(DefaultTheme.Layout, { class: inHome.value ? 'context-home' :
|
|
71089
|
+
inLlms.value || inHistory.value ? 'context-empty-sidebar' : undefined }, { ...slots, 'doc-after': undefined,
|
|
70733
71090
|
'doc-footer-before': () => [slots['doc-after'](), slots['doc-footer-before']()] });
|
|
70734
71091
|
}
|
|
70735
71092
|
},
|
|
@@ -70789,10 +71146,20 @@ export default {
|
|
|
70789
71146
|
`;
|
|
70790
71147
|
});
|
|
70791
71148
|
|
|
71149
|
+
// src/project/packageSiteBranding.ts
|
|
71150
|
+
var packageSiteBranding;
|
|
71151
|
+
var init_packageSiteBranding = __esm(() => {
|
|
71152
|
+
packageSiteBranding = {
|
|
71153
|
+
label: "Powered by",
|
|
71154
|
+
name: "context4ai/context",
|
|
71155
|
+
href: "https://github.com/context4ai/context"
|
|
71156
|
+
};
|
|
71157
|
+
});
|
|
71158
|
+
|
|
70792
71159
|
// src/project/packageSite.ts
|
|
70793
71160
|
import { createHash as createHash16 } from "node:crypto";
|
|
70794
71161
|
import { spawn as spawn3 } from "node:child_process";
|
|
70795
|
-
import { mkdir as mkdir19, mkdtemp, readFile as readFile46, writeFile as writeFile14, rm as rm11, symlink, cp, access as access5 } from "node:fs/promises";
|
|
71162
|
+
import { mkdir as mkdir19, mkdtemp, readFile as readFile46, writeFile as writeFile14, rm as rm11, symlink, cp, access as access5, stat as stat7 } from "node:fs/promises";
|
|
70796
71163
|
import { createRequire as createRequire5 } from "node:module";
|
|
70797
71164
|
import { dirname as dirname23, join as join56, posix as posix6 } from "node:path";
|
|
70798
71165
|
function sitePagePath(identity) {
|
|
@@ -70986,6 +71353,7 @@ async function writePackageSite(input) {
|
|
|
70986
71353
|
contextUpdated: historyDate,
|
|
70987
71354
|
contextUiLabels: { zh: siteThemeLabels("zh"), en: siteThemeLabels("en") },
|
|
70988
71355
|
contextSections: sections.map(({ key, title, href, pages, items }) => ({ key, title, href, pages, items })),
|
|
71356
|
+
contextHome: { resources: options.home?.resources ?? [], branding: packageSiteBranding },
|
|
70989
71357
|
sidebar: sections[0]?.items ?? [],
|
|
70990
71358
|
nav: [...sections.map((section) => ({ text: section.title, link: section.href })), { text: "更多", items: [{ text: "LLM Docs", link: "/llms/index.html" }, { text: "Changelog", link: "/changelog.html" }] }]
|
|
70991
71359
|
}
|
|
@@ -71022,11 +71390,24 @@ ${body}`);
|
|
|
71022
71390
|
`) + `
|
|
71023
71391
|
`);
|
|
71024
71392
|
}
|
|
71025
|
-
const
|
|
71026
|
-
|
|
71027
|
-
|
|
71028
|
-
|
|
71029
|
-
|
|
71393
|
+
const chinese = (options.lang ?? "en-US").startsWith("zh");
|
|
71394
|
+
const firstSection = sections[0]?.href ?? "/llms/index.html";
|
|
71395
|
+
const featuredResources = (options.home?.resources ?? []).filter((resource) => resource.featured && resource.href);
|
|
71396
|
+
const hero = {
|
|
71397
|
+
name: options.home?.title ?? options.title ?? pkg.name,
|
|
71398
|
+
text: options.home?.slogan ?? (chinese ? "从知识地图开始探索" : "Explore from the knowledge map"),
|
|
71399
|
+
tagline: options.home?.description ?? options.description ?? "",
|
|
71400
|
+
actions: options.home?.actions ?? [
|
|
71401
|
+
{ theme: "brand", text: chinese ? "浏览知识" : "Browse knowledge", link: firstSection },
|
|
71402
|
+
...featuredResources.map((resource) => ({ theme: "alt", text: resource.title, link: resource.href })),
|
|
71403
|
+
{ theme: "alt", text: "LLM Docs", link: "/llms/index.html" }
|
|
71404
|
+
]
|
|
71405
|
+
};
|
|
71406
|
+
await writeFile14(join56(temporary, "index.md"), `---
|
|
71407
|
+
layout: home
|
|
71408
|
+
title: ${JSON.stringify(options.home?.title ?? options.title ?? pkg.name)}
|
|
71409
|
+
hero: ${JSON.stringify(hero)}
|
|
71410
|
+
---
|
|
71030
71411
|
`);
|
|
71031
71412
|
await writeFile14(join56(temporary, "changelog.md"), `---
|
|
71032
71413
|
title: Changelog
|
|
@@ -71068,6 +71449,15 @@ title: LLM Docs
|
|
|
71068
71449
|
await cp(join56(root, path2), destination);
|
|
71069
71450
|
}
|
|
71070
71451
|
await compileSite(temporary, output);
|
|
71452
|
+
for (const file of await walkPackageFiles(output)) {
|
|
71453
|
+
const extension2 = posix6.extname(file.relPath).toLowerCase();
|
|
71454
|
+
const placeholder = [".css", ".js", ".mjs", ".cjs"].includes(extension2) ? `/* Intentionally empty. */
|
|
71455
|
+
` : [".html", ".htm"].includes(extension2) ? `<!-- Intentionally empty. -->
|
|
71456
|
+
` : null;
|
|
71457
|
+
if (placeholder !== null && (await stat7(file.absPath)).size === 0) {
|
|
71458
|
+
await writeFile14(file.absPath, placeholder);
|
|
71459
|
+
}
|
|
71460
|
+
}
|
|
71071
71461
|
await writeFile14(join56(output, "context-site-map.json"), JSON.stringify({
|
|
71072
71462
|
protocol: "context.site-output/v1",
|
|
71073
71463
|
knowledge_map_revision: structure?.revision ?? null,
|
|
@@ -71084,7 +71474,7 @@ title: LLM Docs
|
|
|
71084
71474
|
await rm11(temporary, { recursive: true, force: true });
|
|
71085
71475
|
}
|
|
71086
71476
|
}
|
|
71087
|
-
var PACKAGE_SITE_VERSION = "vitepress-site-
|
|
71477
|
+
var PACKAGE_SITE_VERSION = "vitepress-site-v41-home-safe-spacing", require2, encodePath = (path2) => path2.split("/").map(encodeURIComponent).join("/"), mdLabel = (value) => value.replace(/[\\[\]<>`*]/gu, "\\$&").replace(/[\r\n]/gu, " ");
|
|
71088
71478
|
var init_packageSite2 = __esm(() => {
|
|
71089
71479
|
init_packageOutputPaths();
|
|
71090
71480
|
init_workspaceChangelog();
|
|
@@ -71096,6 +71486,7 @@ var init_packageSite2 = __esm(() => {
|
|
|
71096
71486
|
init_packageKnowledgeMap();
|
|
71097
71487
|
init_markdownLinks();
|
|
71098
71488
|
init_packageSiteTheme();
|
|
71489
|
+
init_packageSiteBranding();
|
|
71099
71490
|
require2 = createRequire5(import.meta.url);
|
|
71100
71491
|
});
|
|
71101
71492
|
|
|
@@ -72274,7 +72665,7 @@ function validateRenderedSkillDefinition(input) {
|
|
|
72274
72665
|
}
|
|
72275
72666
|
let frontmatter;
|
|
72276
72667
|
try {
|
|
72277
|
-
frontmatter =
|
|
72668
|
+
frontmatter = import_yaml33.parse(frontmatterMatch[1]);
|
|
72278
72669
|
} catch {
|
|
72279
72670
|
frontmatter = null;
|
|
72280
72671
|
}
|
|
@@ -72301,7 +72692,7 @@ function validateRenderedSkillDefinition(input) {
|
|
|
72301
72692
|
});
|
|
72302
72693
|
}
|
|
72303
72694
|
}
|
|
72304
|
-
var
|
|
72695
|
+
var import_yaml33, OKF_OUTPUT_ROOTS2, SKILL_NAME_PATTERN;
|
|
72305
72696
|
var init_packageTemplateGuard = __esm(() => {
|
|
72306
72697
|
init_cliFeedback();
|
|
72307
72698
|
init_errors3();
|
|
@@ -72309,7 +72700,7 @@ var init_packageTemplateGuard = __esm(() => {
|
|
|
72309
72700
|
init_packageIndexes();
|
|
72310
72701
|
init_packageDistribution();
|
|
72311
72702
|
init_packageTemplateUtils();
|
|
72312
|
-
|
|
72703
|
+
import_yaml33 = __toESM(require_dist(), 1);
|
|
72313
72704
|
OKF_OUTPUT_ROOTS2 = new Set(["wikis", "guides", "rules", "feats"]);
|
|
72314
72705
|
SKILL_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/u;
|
|
72315
72706
|
});
|
|
@@ -72370,7 +72761,7 @@ function isDeprecatedKnowledge(content3) {
|
|
|
72370
72761
|
if (match?.[1] === undefined)
|
|
72371
72762
|
return false;
|
|
72372
72763
|
try {
|
|
72373
|
-
const frontmatter =
|
|
72764
|
+
const frontmatter = import_yaml35.parse(match[1]);
|
|
72374
72765
|
return frontmatter !== null && typeof frontmatter === "object" && !Array.isArray(frontmatter) && frontmatter.deprecated === true;
|
|
72375
72766
|
} catch {
|
|
72376
72767
|
return false;
|
|
@@ -72901,7 +73292,7 @@ async function runProjectBuildCommand(input) {
|
|
|
72901
73292
|
process.stdout.write(formatProjectBuildResult(result, input.format ?? "text", input.verbose === true));
|
|
72902
73293
|
return true;
|
|
72903
73294
|
}
|
|
72904
|
-
var
|
|
73295
|
+
var import_yaml35, PACKAGE_FINGERPRINT_ROOT, PACKAGE_BUILDER_PROTOCOL_VERSION = "v23-sibling-site-output";
|
|
72905
73296
|
var init_packageBuilder = __esm(() => {
|
|
72906
73297
|
init_knowledgeMap2();
|
|
72907
73298
|
init_approvedFileRead();
|
|
@@ -72938,7 +73329,7 @@ var init_packageBuilder = __esm(() => {
|
|
|
72938
73329
|
init_workspace();
|
|
72939
73330
|
init_packageTemplateReview();
|
|
72940
73331
|
init_approvedKnowledgeMetadata();
|
|
72941
|
-
|
|
73332
|
+
import_yaml35 = __toESM(require_dist(), 1);
|
|
72942
73333
|
PACKAGE_FINGERPRINT_ROOT = join62(".tmp", "context-runtime", "packages");
|
|
72943
73334
|
});
|
|
72944
73335
|
|
|
@@ -73709,7 +74100,7 @@ function parseApprovedRevision(value) {
|
|
|
73709
74100
|
if (!value || typeof value !== "object" || !("protocol" in value) || value.protocol !== "context.approved-revision/v1")
|
|
73710
74101
|
return;
|
|
73711
74102
|
const parsed = requestSchema2.parse(value);
|
|
73712
|
-
if (!isSafeKnowledgeTargetPath(parsed.target.collection, parsed.target.path) || parsed.revision !== requestDigest(parsed) || parsed.target.previous_path !== undefined && !isSafeKnowledgeTargetPath(parsed.target.
|
|
74103
|
+
if (!isSafeKnowledgeTargetPath(parsed.target.collection, parsed.target.path) || parsed.revision !== requestDigest(parsed) || parsed.target.previous_path !== undefined && (!indexerKnowledgeCollectionSchema2.safeParse(parsed.target.previous_path.split("/")[0]).success || !isSafeKnowledgeTargetPath(parsed.target.previous_path.split("/")[0], parsed.target.previous_path)))
|
|
73713
74104
|
throw new TypeError("Approved revision target or digest is invalid");
|
|
73714
74105
|
const { candidate: raw, batch_candidates: batch, ...rest } = parsed;
|
|
73715
74106
|
const request = { ...rest, ...batch === undefined ? {} : { batch_candidates: batch.map((item, index2) => parseCandidateRecord(item, index2 + 1)) } };
|
|
@@ -73902,12 +74293,15 @@ async function prepareApprovedRevision(input) {
|
|
|
73902
74293
|
};
|
|
73903
74294
|
}
|
|
73904
74295
|
if (input.move_to !== undefined) {
|
|
73905
|
-
|
|
73906
|
-
|
|
74296
|
+
const destinationCollection = indexerKnowledgeCollectionSchema2.safeParse(input.move_to.split("/")[0]);
|
|
74297
|
+
if (input.create || !destinationCollection.success || !isSafeKnowledgeTargetPath(destinationCollection.data, input.move_to) || input.move_to.includes("\\") || input.move_to === target.path) {
|
|
74298
|
+
throw new TypeError("Move requires a different safe path in a supported knowledge collection.");
|
|
73907
74299
|
}
|
|
73908
74300
|
const { moveKnowledgeLinkTargets: moveKnowledgeLinkTargets2 } = await Promise.resolve().then(() => (init_approvedPageMove(), exports_approvedPageMove));
|
|
73909
|
-
const movedMarkdown = moveKnowledgeLinkTargets2(target.markdown, input.move_to, target.path, new Map([[target.path, input.move_to]])).replace(/^resource:.*$/mu, `resource: knowledge:${input.move_to.replace(/\.md$/u, "")}`)
|
|
73910
|
-
|
|
74301
|
+
const movedMarkdown = moveKnowledgeLinkTargets2(target.markdown, input.move_to, target.path, new Map([[target.path, input.move_to]])).replace(/^resource:.*$/mu, `resource: knowledge:${input.move_to.replace(/\.md$/u, "")}`).replace(/^---\r?\n([\s\S]*?)\r?\n---/u, (header, fields) => target.collection === destinationCollection.data ? header : `---
|
|
74302
|
+
${import_yaml36.default.stringify({ ...import_yaml36.default.parse(fields), type: okfTypeForCollection(destinationCollection.data) }).trimEnd()}
|
|
74303
|
+
---`);
|
|
74304
|
+
target = { ...target, collection: destinationCollection.data, previous_path: target.path, path: input.move_to, markdown: movedMarkdown };
|
|
73911
74305
|
await assertApprovedRevisionBase(input.projectRoot, { target });
|
|
73912
74306
|
}
|
|
73913
74307
|
if (input.supporting_sources) {
|
|
@@ -73958,7 +74352,7 @@ async function prepareApprovedRevision(input) {
|
|
|
73958
74352
|
}
|
|
73959
74353
|
function frontmatter(markdown) {
|
|
73960
74354
|
const match = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/u.exec(markdown);
|
|
73961
|
-
const parsed = match ?
|
|
74355
|
+
const parsed = match ? import_yaml36.default.parse(match[1]) : undefined;
|
|
73962
74356
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
73963
74357
|
throw new TypeError("Revision must retain the approved page frontmatter");
|
|
73964
74358
|
return parsed;
|
|
@@ -74246,7 +74640,7 @@ async function reopenApprovedRevision(input) {
|
|
|
74246
74640
|
};
|
|
74247
74641
|
});
|
|
74248
74642
|
}
|
|
74249
|
-
var
|
|
74643
|
+
var import_yaml36, digest5, revisionTargetSchema, requestSchema2;
|
|
74250
74644
|
var init_approvedRevision = __esm(() => {
|
|
74251
74645
|
init_productionRequirements();
|
|
74252
74646
|
init_approvedRevisionEdits();
|
|
@@ -74263,8 +74657,9 @@ var init_approvedRevision = __esm(() => {
|
|
|
74263
74657
|
init_durableSingleFileTransaction();
|
|
74264
74658
|
init_durableMultiFileTransaction();
|
|
74265
74659
|
init_processedScopeStorage();
|
|
74660
|
+
init_okfTypes();
|
|
74266
74661
|
init_maintenanceStorage();
|
|
74267
|
-
|
|
74662
|
+
import_yaml36 = __toESM(require_dist(), 1);
|
|
74268
74663
|
digest5 = exports_external.string().regex(/^sha256:[a-f0-9]{64}$/u);
|
|
74269
74664
|
revisionTargetSchema = exports_external.object({
|
|
74270
74665
|
path: exports_external.string().min(1),
|
|
@@ -81718,7 +82113,7 @@ async function approveProductionReport(input) {
|
|
|
81718
82113
|
throw new TypeError("The report's plan changed. Read and present the current proposal before confirming it.");
|
|
81719
82114
|
}
|
|
81720
82115
|
const file = input.manifest ?? await readProductionFile(input);
|
|
81721
|
-
const decision = productionReportInputSchema.extend({ stage: exports_external.literal(stage.id) }).parse(
|
|
82116
|
+
const decision = productionReportInputSchema.extend({ stage: exports_external.literal(stage.id) }).parse(import_yaml39.default.parse(file.text));
|
|
81722
82117
|
if (!stage.report_approved)
|
|
81723
82118
|
await assertProductionPlanRequirementsCurrent(input.projectRoot, stage);
|
|
81724
82119
|
if (decision.decision === "approved")
|
|
@@ -81734,7 +82129,7 @@ async function approveProductionReport(input) {
|
|
|
81734
82129
|
}
|
|
81735
82130
|
}));
|
|
81736
82131
|
}
|
|
81737
|
-
var
|
|
82132
|
+
var import_yaml39, productionReportInputSchema;
|
|
81738
82133
|
var init_productionReport = __esm(() => {
|
|
81739
82134
|
init_zod();
|
|
81740
82135
|
init_src2();
|
|
@@ -81744,7 +82139,7 @@ var init_productionReport = __esm(() => {
|
|
|
81744
82139
|
init_productionStagePreparation();
|
|
81745
82140
|
init_productionPlanning();
|
|
81746
82141
|
init_productionFeedback();
|
|
81747
|
-
|
|
82142
|
+
import_yaml39 = __toESM(require_dist(), 1);
|
|
81748
82143
|
productionReportInputSchema = exports_external.object({ stage: exports_external.string().min(1), decision: exports_external.literal("approved") }).strict();
|
|
81749
82144
|
});
|
|
81750
82145
|
|
|
@@ -88328,6 +88723,355 @@ var init_actionInputWorkspace = __esm(() => {
|
|
|
88328
88723
|
init_workspace();
|
|
88329
88724
|
});
|
|
88330
88725
|
|
|
88726
|
+
// src/project/articleRetirement.ts
|
|
88727
|
+
var exports_articleRetirement = {};
|
|
88728
|
+
__export(exports_articleRetirement, {
|
|
88729
|
+
retireArticles: () => retireArticles,
|
|
88730
|
+
articleRetirementSchema: () => articleRetirementSchema
|
|
88731
|
+
});
|
|
88732
|
+
import { readFile as readFile74, readdir as readdir20 } from "node:fs/promises";
|
|
88733
|
+
import { posix as posix10 } from "node:path";
|
|
88734
|
+
function invalid(reason, message, details = {}) {
|
|
88735
|
+
throw new ContextError(ExitCode.UserError, message, {
|
|
88736
|
+
category: ErrorCategory.UserInputInvalid,
|
|
88737
|
+
reason_code: reason,
|
|
88738
|
+
...details,
|
|
88739
|
+
next_action: {
|
|
88740
|
+
command: next,
|
|
88741
|
+
message: "Keep the retirement input. Resolve the listed page/reference or finish the active revision, then preview it again; no retirement was applied."
|
|
88742
|
+
}
|
|
88743
|
+
});
|
|
88744
|
+
}
|
|
88745
|
+
async function text9(root2, path3) {
|
|
88746
|
+
try {
|
|
88747
|
+
return await readFile74(await safeProjectTarget(root2, path3), "utf8");
|
|
88748
|
+
} catch (error) {
|
|
88749
|
+
if (error.code === "ENOENT")
|
|
88750
|
+
return;
|
|
88751
|
+
throw error;
|
|
88752
|
+
}
|
|
88753
|
+
}
|
|
88754
|
+
async function retireArticles(input) {
|
|
88755
|
+
const parsed = articleRetirementSchema.safeParse(input.value);
|
|
88756
|
+
if (!parsed.success)
|
|
88757
|
+
invalid("article-retirement-input-invalid", "Provide reason and targets with exact approved paths and optional replacement paths.", { input_schema: { reason: "string", targets: [{ path: "collection/old.md", replacement: "collection/approved-successor.md (optional)" }] } });
|
|
88758
|
+
const value = parsed.data;
|
|
88759
|
+
return withProjectWriteLock(input.projectRoot, "retire-articles", async () => {
|
|
88760
|
+
if (input.apply)
|
|
88761
|
+
await recoverDurableMultiFileTransactions(input.projectRoot);
|
|
88762
|
+
if (input.apply && input.plan_digest && /^sha256:[a-f0-9]{64}$/u.test(input.plan_digest)) {
|
|
88763
|
+
const receipt3 = await text9(input.projectRoot, `.tmp/context-runtime/retirements/${input.plan_digest.slice(7)}/receipt.json`);
|
|
88764
|
+
if (receipt3) {
|
|
88765
|
+
const saved = JSON.parse(receipt3);
|
|
88766
|
+
if (saved.request !== indexerProtocolDigest(value))
|
|
88767
|
+
invalid("article-retirement-input-changed", "The retirement input differs from the applied request.");
|
|
88768
|
+
for (const file of saved.files) {
|
|
88769
|
+
const current2 = await text9(input.projectRoot, file.path);
|
|
88770
|
+
if ((current2 === undefined ? null : durableContentDigest(current2)) !== file.digest)
|
|
88771
|
+
invalid("article-retirement-result-changed", "Retirement was applied but a resulting file has since changed; inspect the current workspace.", { path: file.path });
|
|
88772
|
+
}
|
|
88773
|
+
return { action: "already-applied", revision: input.plan_digest, next_action: { command: next } };
|
|
88774
|
+
}
|
|
88775
|
+
}
|
|
88776
|
+
const maintenance = await readMaintenance(input.projectRoot);
|
|
88777
|
+
if ((await readCandidateRecords(input.projectRoot)).length || await readApprovedRevision(input.projectRoot) || await readKnowledgeUpdate(input.projectRoot) || await readTaskRollback(input.projectRoot) || maintenance.active) {
|
|
88778
|
+
invalid("article-retirement-active-review", "Finish the active candidate/revision delivery before retiring approved pages.");
|
|
88779
|
+
}
|
|
88780
|
+
const before = await text9(input.projectRoot, "knowledge/structure.yaml");
|
|
88781
|
+
const structure = before === undefined ? {} : import_yaml41.default.parse(before);
|
|
88782
|
+
const articles = validateArticleStructureEntries(structure.articles ?? []);
|
|
88783
|
+
const byPath = new Map(articles.map((article) => [article.path, article]));
|
|
88784
|
+
const selected = new Set(value.targets.map((target) => target.path));
|
|
88785
|
+
if (selected.size !== value.targets.length)
|
|
88786
|
+
invalid("article-retirement-duplicate", "Select each approved article once.");
|
|
88787
|
+
if (maintenance.pending.some((request) => request.targets.some((target) => selected.has(target.path)))) {
|
|
88788
|
+
invalid("article-retirement-pending-maintenance", "Cancel or finish queued maintenance for the selected pages before retirement.");
|
|
88789
|
+
}
|
|
88790
|
+
const stage = await readProductionStage(input.projectRoot);
|
|
88791
|
+
if (stage?.tasks.some((task) => selected.has(task.path) && !["accepted", "excluded", "replaced"].includes(task.status))) {
|
|
88792
|
+
invalid("article-retirement-pending-task", "A selected article still has unfinished production; finish or amend that task first.");
|
|
88793
|
+
}
|
|
88794
|
+
const replacements = new Map;
|
|
88795
|
+
for (const target of value.targets) {
|
|
88796
|
+
if (!byPath.has(target.path))
|
|
88797
|
+
invalid("article-retirement-target-missing", "Select an exact approved article path from knowledge/structure.yaml.", { path: target.path });
|
|
88798
|
+
if (target.replacement !== undefined && (!byPath.has(target.replacement) || selected.has(target.replacement))) {
|
|
88799
|
+
invalid("article-retirement-replacement-invalid", "Replacement must be an already-approved article outside the retirement set.", { path: target.path, replacement: target.replacement });
|
|
88800
|
+
}
|
|
88801
|
+
replacements.set(target.path, target.replacement);
|
|
88802
|
+
}
|
|
88803
|
+
const targets = [];
|
|
88804
|
+
const restore = [];
|
|
88805
|
+
function change(path3, old, content3) {
|
|
88806
|
+
if (old === content3)
|
|
88807
|
+
return;
|
|
88808
|
+
targets.push(content3 === undefined ? { path: path3, operation: "delete", base_digest: durableContentDigest(old), target_digest: null } : { path: path3, operation: "write", base_digest: old === undefined ? null : durableContentDigest(old), target_digest: durableContentDigest(content3), content: content3 });
|
|
88809
|
+
restore.push({ path: path3, base_digest: content3 === undefined ? null : durableContentDigest(content3), content: old ?? null });
|
|
88810
|
+
}
|
|
88811
|
+
const blockers = [];
|
|
88812
|
+
const readDigests = [];
|
|
88813
|
+
for (const article of articles) {
|
|
88814
|
+
const path3 = `knowledge/${article.path}`;
|
|
88815
|
+
const bytes = await text9(input.projectRoot, path3);
|
|
88816
|
+
if (bytes === undefined)
|
|
88817
|
+
invalid("article-retirement-article-missing", "Approved article bytes are missing; recover the workspace before retirement.", { path: path3 });
|
|
88818
|
+
readDigests.push({ path: path3, digest: durableContentDigest(bytes) });
|
|
88819
|
+
if (selected.has(article.path)) {
|
|
88820
|
+
change(path3, bytes);
|
|
88821
|
+
continue;
|
|
88822
|
+
}
|
|
88823
|
+
const content3 = replaceMarkdownInlineLinkTargets(bytes, (link2) => {
|
|
88824
|
+
if (link2.target.startsWith("#") || link2.target.startsWith("//"))
|
|
88825
|
+
return;
|
|
88826
|
+
const knowledge = link2.target.startsWith("knowledge:");
|
|
88827
|
+
if (!knowledge && /^[a-z][a-z0-9+.-]*:/iu.test(link2.target))
|
|
88828
|
+
return;
|
|
88829
|
+
const match = /^([^#?]*)(.*)$/u.exec(knowledge ? link2.target.slice(10) : link2.target);
|
|
88830
|
+
let target;
|
|
88831
|
+
try {
|
|
88832
|
+
target = decodeURI(match[1]);
|
|
88833
|
+
} catch {
|
|
88834
|
+
return;
|
|
88835
|
+
}
|
|
88836
|
+
const rooted = /^\/?knowledge\//u.test(target);
|
|
88837
|
+
if (target.startsWith("/") && !rooted)
|
|
88838
|
+
return;
|
|
88839
|
+
let resolved = knowledge ? target : rooted ? target.replace(/^\/?knowledge\//u, "") : posix10.normalize(posix10.join(posix10.dirname(article.path), target));
|
|
88840
|
+
if (knowledge && !resolved.endsWith(".md"))
|
|
88841
|
+
resolved += ".md";
|
|
88842
|
+
if (!selected.has(resolved))
|
|
88843
|
+
return;
|
|
88844
|
+
const replacement = replacements.get(resolved);
|
|
88845
|
+
if (!replacement || match[2].includes("#")) {
|
|
88846
|
+
blockers.push({ path: path3, target: link2.target, reason: replacement ? "Repair fragment links explicitly before retirement." : "Repair this incoming link or supply an approved replacement." });
|
|
88847
|
+
return;
|
|
88848
|
+
}
|
|
88849
|
+
return knowledge ? `knowledge:${target.endsWith(".md") ? replacement : replacement.replace(/\.md$/u, "")}${match[2]}` : `${encodeURI(rooted ? `${target.startsWith("/") ? "/" : ""}knowledge/${replacement}` : posix10.relative(posix10.dirname(article.path), replacement))}${match[2]}`;
|
|
88850
|
+
});
|
|
88851
|
+
change(path3, bytes, content3);
|
|
88852
|
+
}
|
|
88853
|
+
async function inspectTemplates(directory2) {
|
|
88854
|
+
const absolute = await safeProjectTarget(input.projectRoot, directory2);
|
|
88855
|
+
const entries2 = await readdir20(absolute, { withFileTypes: true }).catch((error) => {
|
|
88856
|
+
if (error.code === "ENOENT")
|
|
88857
|
+
return [];
|
|
88858
|
+
throw error;
|
|
88859
|
+
});
|
|
88860
|
+
for (const entry of entries2) {
|
|
88861
|
+
const path3 = `${directory2}/${entry.name}`;
|
|
88862
|
+
if (entry.isDirectory()) {
|
|
88863
|
+
await inspectTemplates(path3);
|
|
88864
|
+
continue;
|
|
88865
|
+
}
|
|
88866
|
+
if (!entry.isFile() || !entry.name.endsWith(".md"))
|
|
88867
|
+
continue;
|
|
88868
|
+
const bytes = await text9(input.projectRoot, path3);
|
|
88869
|
+
readDigests.push({ path: path3, digest: durableContentDigest(bytes) });
|
|
88870
|
+
replaceMarkdownInlineLinkTargets(bytes, (link2) => {
|
|
88871
|
+
if (/^(?!knowledge:)[a-z][a-z0-9+.-]*:/iu.test(link2.target))
|
|
88872
|
+
return;
|
|
88873
|
+
let destination;
|
|
88874
|
+
try {
|
|
88875
|
+
destination = decodeURI(link2.target.split(/[?#]/u)[0]);
|
|
88876
|
+
} catch {
|
|
88877
|
+
return;
|
|
88878
|
+
}
|
|
88879
|
+
if (destination.startsWith("knowledge:") && !destination.endsWith(".md"))
|
|
88880
|
+
destination += ".md";
|
|
88881
|
+
if ([...selected].some((old) => destination === old || destination.endsWith(`/${old}`) || destination === `knowledge:${old}`)) {
|
|
88882
|
+
blockers.push({ path: path3, target: link2.target, reason: "Update this custom package-template link before retirement." });
|
|
88883
|
+
}
|
|
88884
|
+
return;
|
|
88885
|
+
});
|
|
88886
|
+
}
|
|
88887
|
+
}
|
|
88888
|
+
await inspectTemplates("src/package-templates");
|
|
88889
|
+
const map4 = await readKnowledgeMap(input.projectRoot);
|
|
88890
|
+
if (map4) {
|
|
88891
|
+
const retiredIds = new Map(value.targets.map((target) => [byPath.get(target.path).article_id, target]));
|
|
88892
|
+
const upsert = map4.entries.flatMap((entry) => {
|
|
88893
|
+
const target = entry.target && retiredIds.get(entry.target.artifact_ref);
|
|
88894
|
+
if (!target)
|
|
88895
|
+
return [];
|
|
88896
|
+
if (target.replacement && entry.target?.section_key) {
|
|
88897
|
+
blockers.push({ path: KNOWLEDGE_MAP_PATH, target: entry.key, reason: "Rebind this fragment navigation entry explicitly before retirement." });
|
|
88898
|
+
return [];
|
|
88899
|
+
}
|
|
88900
|
+
const { target: _old, ...group } = entry;
|
|
88901
|
+
return [target.replacement ? { ...group, target: { artifact_ref: byPath.get(target.replacement).article_id } } : group];
|
|
88902
|
+
});
|
|
88903
|
+
const updated = updateKnowledgeMap(map4, { expected_revision: map4.revision, upsert, remove: [] });
|
|
88904
|
+
change(KNOWLEDGE_MAP_PATH, await text9(input.projectRoot, KNOWLEDGE_MAP_PATH), import_yaml41.default.stringify(updated));
|
|
88905
|
+
}
|
|
88906
|
+
change("knowledge/structure.yaml", before, import_yaml41.default.stringify({ ...structure, articles: articles.filter((article) => !selected.has(article.path)) }));
|
|
88907
|
+
targets.sort((a, b) => a.path.localeCompare(b.path));
|
|
88908
|
+
const revision = indexerProtocolDigest({ value, readDigests, targets });
|
|
88909
|
+
const preview = {
|
|
88910
|
+
action: "preview",
|
|
88911
|
+
revision,
|
|
88912
|
+
reason: value.reason,
|
|
88913
|
+
retired: value.targets,
|
|
88914
|
+
changed_files: targets.map((target) => ({ path: target.path, operation: target.operation })),
|
|
88915
|
+
blockers,
|
|
88916
|
+
next_action: { command: blockers.length ? next : `context task retire --input <same-file> --apply --plan-digest '${revision}' --format json` }
|
|
88917
|
+
};
|
|
88918
|
+
if (!input.apply)
|
|
88919
|
+
return preview;
|
|
88920
|
+
if (input.plan_digest !== revision)
|
|
88921
|
+
invalid("article-retirement-preview-stale", "Preview this retirement input again; the selected pages, links or navigation changed.");
|
|
88922
|
+
if (blockers.length)
|
|
88923
|
+
invalid("article-retirement-references-unresolved", "Resolve incoming fragment links before applying retirement.", { blockers });
|
|
88924
|
+
const directory = `.tmp/context-runtime/retirements/${revision.slice(7)}`;
|
|
88925
|
+
const recovery = `${directory}/restore.json`;
|
|
88926
|
+
const receipt2 = `${directory}/receipt.json`;
|
|
88927
|
+
change(recovery, await text9(input.projectRoot, recovery), JSON.stringify({ summary: `Restore retired articles: ${value.reason}`, discard_unfinished: true, files: [...restore] }));
|
|
88928
|
+
change(receipt2, await text9(input.projectRoot, receipt2), JSON.stringify({
|
|
88929
|
+
request: indexerProtocolDigest(value),
|
|
88930
|
+
files: targets.map((target) => ({ path: target.path, digest: target.target_digest }))
|
|
88931
|
+
}));
|
|
88932
|
+
await runDurableMultiFileTransaction({
|
|
88933
|
+
projectRoot: input.projectRoot,
|
|
88934
|
+
kind: "retire-articles",
|
|
88935
|
+
proposal_digest: revision,
|
|
88936
|
+
targets: targets.sort((a, b) => a.path.localeCompare(b.path)),
|
|
88937
|
+
...input.inject_failure ? { inject_failure: input.inject_failure } : {}
|
|
88938
|
+
});
|
|
88939
|
+
return {
|
|
88940
|
+
action: "applied",
|
|
88941
|
+
revision,
|
|
88942
|
+
retired: [...selected],
|
|
88943
|
+
recovery,
|
|
88944
|
+
next_action: { command: next, message: "Retired pages and references were updated together. Follow the current close/version/build Route before delivering outputs. The restore input is temporary; retain it or a Git baseline if later restoration is needed." }
|
|
88945
|
+
};
|
|
88946
|
+
});
|
|
88947
|
+
}
|
|
88948
|
+
var import_yaml41, articleRetirementSchema, next = "context status --format json";
|
|
88949
|
+
var init_articleRetirement = __esm(() => {
|
|
88950
|
+
init_zod();
|
|
88951
|
+
init_src2();
|
|
88952
|
+
init_errors3();
|
|
88953
|
+
init_cliFeedback();
|
|
88954
|
+
init_exitCode();
|
|
88955
|
+
init_candidateLedger();
|
|
88956
|
+
init_approvedRevision();
|
|
88957
|
+
init_knowledgeUpdate();
|
|
88958
|
+
init_taskRollback();
|
|
88959
|
+
init_maintenanceStorage();
|
|
88960
|
+
init_productionStageStore();
|
|
88961
|
+
init_knowledgeMap2();
|
|
88962
|
+
init_markdownLinks();
|
|
88963
|
+
init_durableSingleFileTransaction();
|
|
88964
|
+
init_durableMultiFileTransaction();
|
|
88965
|
+
init_writeLock();
|
|
88966
|
+
import_yaml41 = __toESM(require_dist(), 1);
|
|
88967
|
+
articleRetirementSchema = exports_external.object({
|
|
88968
|
+
reason: exports_external.string().trim().min(1),
|
|
88969
|
+
targets: exports_external.array(exports_external.object({ path: exports_external.string().min(1), replacement: exports_external.string().min(1).optional() }).strict()).min(1)
|
|
88970
|
+
}).strict();
|
|
88971
|
+
});
|
|
88972
|
+
|
|
88973
|
+
// src/lib/schemaOutput.ts
|
|
88974
|
+
var exports_schemaOutput = {};
|
|
88975
|
+
__export(exports_schemaOutput, {
|
|
88976
|
+
writeSchemaOutput: () => writeSchemaOutput,
|
|
88977
|
+
schemaOutputFormat: () => schemaOutputFormat
|
|
88978
|
+
});
|
|
88979
|
+
function schemaOutputFormat(value) {
|
|
88980
|
+
if (value === "text" || value === "yaml" || value === "json")
|
|
88981
|
+
return value;
|
|
88982
|
+
throw new ContextError(ExitCode.UserError, "Expected schema format text, json, or yaml", { category: ErrorCategory.UserInputInvalid });
|
|
88983
|
+
}
|
|
88984
|
+
function writeSchemaOutput(value, format2) {
|
|
88985
|
+
process.stdout.write(format2 === "json" ? `${JSON.stringify(value, null, 2)}
|
|
88986
|
+
` : import_yaml42.default.stringify(value));
|
|
88987
|
+
}
|
|
88988
|
+
var import_yaml42;
|
|
88989
|
+
var init_schemaOutput = __esm(() => {
|
|
88990
|
+
init_errors3();
|
|
88991
|
+
init_cliFeedback();
|
|
88992
|
+
init_exitCode();
|
|
88993
|
+
import_yaml42 = __toESM(require_dist(), 1);
|
|
88994
|
+
});
|
|
88995
|
+
|
|
88996
|
+
// src/project/writeLockRecovery.ts
|
|
88997
|
+
var exports_writeLockRecovery = {};
|
|
88998
|
+
__export(exports_writeLockRecovery, {
|
|
88999
|
+
recoverWriterLock: () => recoverWriterLock,
|
|
89000
|
+
inspectWriterLock: () => inspectWriterLock
|
|
89001
|
+
});
|
|
89002
|
+
import { lstat as lstat9, mkdir as mkdir32, readFile as readFile75, readdir as readdir21, rename as rename7, rmdir as rmdir2 } from "node:fs/promises";
|
|
89003
|
+
import { join as join94 } from "node:path";
|
|
89004
|
+
import { createHash as createHash28, randomUUID as randomUUID7 } from "node:crypto";
|
|
89005
|
+
async function inspectWriterLock(root2) {
|
|
89006
|
+
const path3 = await safeProjectTarget(root2, lockRelative);
|
|
89007
|
+
let stat11;
|
|
89008
|
+
try {
|
|
89009
|
+
stat11 = await lstat9(path3);
|
|
89010
|
+
} catch (error) {
|
|
89011
|
+
if (error.code === "ENOENT")
|
|
89012
|
+
return null;
|
|
89013
|
+
throw error;
|
|
89014
|
+
}
|
|
89015
|
+
if (!stat11.isDirectory() || stat11.isSymbolicLink())
|
|
89016
|
+
throw new Error("Writer lock must be a real directory.");
|
|
89017
|
+
const ownerPath = await safeProjectTarget(root2, `${lockRelative}/owner.json`);
|
|
89018
|
+
const bytes = await readFile75(ownerPath, "utf8");
|
|
89019
|
+
const owner = JSON.parse(bytes);
|
|
89020
|
+
if (owner.protocol !== "context.project-write-lock.v1" || !Number.isSafeInteger(owner.pid) || owner.pid <= 0) {
|
|
89021
|
+
throw new Error("Writer lock owner is invalid; preserve the lock for diagnosis.");
|
|
89022
|
+
}
|
|
89023
|
+
let processState = "running";
|
|
89024
|
+
try {
|
|
89025
|
+
process.kill(owner.pid, 0);
|
|
89026
|
+
} catch (error) {
|
|
89027
|
+
const code3 = error.code;
|
|
89028
|
+
processState = code3 === "ESRCH" ? "not-running" : code3 === "EPERM" ? "running" : "unknown";
|
|
89029
|
+
}
|
|
89030
|
+
const digest6 = `sha256:${createHash28("sha256").update(`${stat11.dev}:${stat11.ino}:${stat11.birthtimeMs}:${bytes}`).digest("hex")}`;
|
|
89031
|
+
return { ...owner, process_state: processState, digest: digest6, path: lockRelative };
|
|
89032
|
+
}
|
|
89033
|
+
async function recoverWriterLock(input) {
|
|
89034
|
+
const before = await inspectWriterLock(input.projectRoot);
|
|
89035
|
+
if (!before)
|
|
89036
|
+
return { action: "writer-lock-absent", next: "context task recover --format json" };
|
|
89037
|
+
if (before.process_state !== "not-running")
|
|
89038
|
+
throw new Error("Writer is running or cannot be identified as stopped; keep the lock.");
|
|
89039
|
+
if (!input.apply)
|
|
89040
|
+
return {
|
|
89041
|
+
action: "preview",
|
|
89042
|
+
operation: "writer-lock",
|
|
89043
|
+
revision: before.digest,
|
|
89044
|
+
owner: before,
|
|
89045
|
+
effect: "Archive only this orphan lock. Before applying, stop new workspace commands and confirm no surviving child writer or other host/container uses this workspace. This does not complete interrupted captures or transactions.",
|
|
89046
|
+
next: `${command2} --apply --plan-digest '${before.digest}'`
|
|
89047
|
+
};
|
|
89048
|
+
if (input.plan_digest !== before.digest)
|
|
89049
|
+
throw new Error("Writer lock changed; preview recovery again.");
|
|
89050
|
+
const path3 = join94(input.projectRoot, lockRelative);
|
|
89051
|
+
const guard = join94(path3, ".recovery");
|
|
89052
|
+
await mkdir32(guard);
|
|
89053
|
+
let archived = false;
|
|
89054
|
+
try {
|
|
89055
|
+
const current2 = await inspectWriterLock(input.projectRoot);
|
|
89056
|
+
if (current2?.digest !== before.digest || current2.process_state !== "not-running")
|
|
89057
|
+
throw new Error("Writer lock changed or owner resumed; keep the lock.");
|
|
89058
|
+
const names = await readdir21(path3);
|
|
89059
|
+
if (names.some((name3) => name3 !== "owner.json" && name3 !== ".recovery"))
|
|
89060
|
+
throw new Error("Unexpected lock contents; preserve for diagnosis.");
|
|
89061
|
+
const archive = `.tmp/context-runtime/locks/recovered-write-${randomUUID7()}.lock`;
|
|
89062
|
+
await rename7(path3, join94(input.projectRoot, archive));
|
|
89063
|
+
archived = true;
|
|
89064
|
+
return { action: "writer-lock-recovered", archived_lock: archive, next: "context task recover --format json" };
|
|
89065
|
+
} finally {
|
|
89066
|
+
if (!archived)
|
|
89067
|
+
await rmdir2(guard);
|
|
89068
|
+
}
|
|
89069
|
+
}
|
|
89070
|
+
var lockRelative = ".tmp/context-runtime/locks/project-write.lock", command2 = "context task recover --operation writer-lock --format json";
|
|
89071
|
+
var init_writeLockRecovery = __esm(() => {
|
|
89072
|
+
init_durableMultiFileTransaction();
|
|
89073
|
+
});
|
|
89074
|
+
|
|
88331
89075
|
// src/project/taskRecovery.ts
|
|
88332
89076
|
var exports_taskRecovery = {};
|
|
88333
89077
|
__export(exports_taskRecovery, {
|
|
@@ -88339,12 +89083,12 @@ __export(exports_taskRecovery, {
|
|
|
88339
89083
|
RECOVERY_COMMAND: () => RECOVERY_COMMAND
|
|
88340
89084
|
});
|
|
88341
89085
|
import { existsSync as existsSync26 } from "node:fs";
|
|
88342
|
-
import { dirname as dirname40, join as
|
|
88343
|
-
import { lstat as
|
|
89086
|
+
import { dirname as dirname40, join as join95 } from "node:path";
|
|
89087
|
+
import { lstat as lstat10, readdir as readdir22, readFile as readFile76 } from "node:fs/promises";
|
|
88344
89088
|
async function recoveryText(root2, path3) {
|
|
88345
89089
|
const target = await safeProjectTarget(root2, path3);
|
|
88346
89090
|
try {
|
|
88347
|
-
return await
|
|
89091
|
+
return await readFile76(target, "utf8");
|
|
88348
89092
|
} catch (error) {
|
|
88349
89093
|
if (error.code === "ENOENT")
|
|
88350
89094
|
return;
|
|
@@ -88355,22 +89099,22 @@ async function recoveryJournals(root2) {
|
|
|
88355
89099
|
const entries2 = [];
|
|
88356
89100
|
async function visit4(path3, depth) {
|
|
88357
89101
|
await safeProjectTarget(root2, path3);
|
|
88358
|
-
let
|
|
89102
|
+
let stat11;
|
|
88359
89103
|
try {
|
|
88360
|
-
|
|
89104
|
+
stat11 = await lstat10(join95(root2, path3));
|
|
88361
89105
|
} catch (error) {
|
|
88362
89106
|
if (error.code === "ENOENT")
|
|
88363
89107
|
return;
|
|
88364
89108
|
throw error;
|
|
88365
89109
|
}
|
|
88366
|
-
if (
|
|
89110
|
+
if (stat11.isSymbolicLink())
|
|
88367
89111
|
throw new TypeError("Recovery does not follow transaction symlinks.");
|
|
88368
|
-
if (
|
|
89112
|
+
if (stat11.isDirectory()) {
|
|
88369
89113
|
if (depth > 3)
|
|
88370
89114
|
throw new TypeError("Unexpected transaction directory depth; preserve it for diagnosis.");
|
|
88371
|
-
for (const name3 of (await
|
|
89115
|
+
for (const name3 of (await readdir22(join95(root2, path3))).sort())
|
|
88372
89116
|
await visit4(`${path3}/${name3}`, depth + 1);
|
|
88373
|
-
} else if (
|
|
89117
|
+
} else if (stat11.isFile())
|
|
88374
89118
|
entries2.push({ path: path3, digest: indexerProtocolDigest(await recoveryText(root2, path3)) });
|
|
88375
89119
|
}
|
|
88376
89120
|
await visit4(TRANSACTIONS_PATH, 0);
|
|
@@ -88380,8 +89124,8 @@ function recoveryResources() {
|
|
|
88380
89124
|
try {
|
|
88381
89125
|
const root2 = dirname40(contextWorkflowProviderPath());
|
|
88382
89126
|
const resources = {
|
|
88383
|
-
skill:
|
|
88384
|
-
issue_template:
|
|
89127
|
+
skill: join95(root2, "skills/recover-workspace/SKILL.md"),
|
|
89128
|
+
issue_template: join95(root2, "resources/templates/recovery-issue.md")
|
|
88385
89129
|
};
|
|
88386
89130
|
if (!Object.values(resources).every((path3) => existsSync26(path3)))
|
|
88387
89131
|
throw new Error("Recovery resources are absent from this Provider.");
|
|
@@ -88402,10 +89146,7 @@ async function inspectTaskRecovery(root2) {
|
|
|
88402
89146
|
}
|
|
88403
89147
|
const stage = await probe("production-stage", () => readProductionStage(root2));
|
|
88404
89148
|
const journals = await probe("transactions", () => recoveryJournals(root2));
|
|
88405
|
-
const lock = await probe("writer-lock",
|
|
88406
|
-
const text9 = await recoveryText(root2, ".tmp/context-runtime/locks/project-write.lock/owner.json");
|
|
88407
|
-
return text9 === undefined ? null : JSON.parse(text9);
|
|
88408
|
-
});
|
|
89149
|
+
const lock = await probe("writer-lock", () => inspectWriterLock(root2));
|
|
88409
89150
|
return {
|
|
88410
89151
|
action: "recovery-inspected",
|
|
88411
89152
|
resources: recoveryResources(),
|
|
@@ -88415,6 +89156,7 @@ async function inspectTaskRecovery(root2) {
|
|
|
88415
89156
|
transactions: journals,
|
|
88416
89157
|
writer_lock: lock,
|
|
88417
89158
|
actions: [
|
|
89159
|
+
...lock?.process_state === "not-running" ? [{ operation: "writer-lock", command: `${RECOVERY_COMMAND} --operation writer-lock` }] : [],
|
|
88418
89160
|
...journals?.length ? [{ operation: "transactions", command: `${RECOVERY_COMMAND} --operation transactions` }] : [],
|
|
88419
89161
|
...stage ? [{ operation: "continue", command: "context status --format json" }] : []
|
|
88420
89162
|
],
|
|
@@ -88460,6 +89202,7 @@ var init_taskRecovery = __esm(() => {
|
|
|
88460
89202
|
init_writeLock();
|
|
88461
89203
|
init_durableMultiFileTransaction();
|
|
88462
89204
|
init_workflowProvider();
|
|
89205
|
+
init_writeLockRecovery();
|
|
88463
89206
|
});
|
|
88464
89207
|
|
|
88465
89208
|
// src/project/taskLocalSourceAdjustment.ts
|
|
@@ -88467,8 +89210,8 @@ var exports_taskLocalSourceAdjustment = {};
|
|
|
88467
89210
|
__export(exports_taskLocalSourceAdjustment, {
|
|
88468
89211
|
adjustLocalRevisionSources: () => adjustLocalRevisionSources
|
|
88469
89212
|
});
|
|
88470
|
-
import { readFile as
|
|
88471
|
-
import { join as
|
|
89213
|
+
import { readFile as readFile77 } from "node:fs/promises";
|
|
89214
|
+
import { join as join96 } from "node:path";
|
|
88472
89215
|
async function adjustLocalRevisionSources(root2, input) {
|
|
88473
89216
|
const { readMaintenance: readMaintenance2 } = await Promise.resolve().then(() => (init_maintenanceStorage(), exports_maintenanceStorage));
|
|
88474
89217
|
if ((await readMaintenance2(root2)).active && await readProductionStage(root2))
|
|
@@ -88492,11 +89235,11 @@ async function adjustLocalRevisionSources(root2, input) {
|
|
|
88492
89235
|
if (input.refresh && (!current2.refresh_sources || indexerProtocolDigest([...current2.refresh_sources].sort()) !== indexerProtocolDigest([...selected].sort()))) {
|
|
88493
89236
|
throw new TypeError("No matching acquisition adjustment exists. Run task adjust without refresh first.");
|
|
88494
89237
|
}
|
|
88495
|
-
const raw = await
|
|
88496
|
-
let
|
|
89238
|
+
const raw = await readFile77(join96(root2, await revisionStoragePath(root2)), "utf8");
|
|
89239
|
+
let next2;
|
|
88497
89240
|
const discardIds = new Set;
|
|
88498
89241
|
if (!input.refresh) {
|
|
88499
|
-
|
|
89242
|
+
next2 = { ...current2, refresh_sources: selected };
|
|
88500
89243
|
} else {
|
|
88501
89244
|
const oldScopes = [
|
|
88502
89245
|
...revision?.processed_scopes ?? update?.scopes ?? [],
|
|
@@ -88570,7 +89313,7 @@ ${input.instruction}`,
|
|
|
88570
89313
|
|
|
88571
89314
|
${input.instruction}` : revision.instruction
|
|
88572
89315
|
};
|
|
88573
|
-
|
|
89316
|
+
next2 = { ...payload, revision: requestDigest(payload), ...!affected && candidate ? { candidate } : {} };
|
|
88574
89317
|
if (affected && candidate)
|
|
88575
89318
|
discardIds.add(candidate.candidate_id);
|
|
88576
89319
|
} else {
|
|
@@ -88578,14 +89321,14 @@ ${input.instruction}` : revision.instruction
|
|
|
88578
89321
|
const payload = { ...rest, scopes, requirements, changes: [rest.changes, input.instruction].filter(Boolean).join(`
|
|
88579
89322
|
|
|
88580
89323
|
`) };
|
|
88581
|
-
|
|
89324
|
+
next2 = { ...payload, revision: indexerProtocolDigest(payload) };
|
|
88582
89325
|
}
|
|
88583
89326
|
}
|
|
88584
89327
|
if (update && !input.refresh) {
|
|
88585
|
-
const { revision: _revision, ...payload } =
|
|
88586
|
-
|
|
89328
|
+
const { revision: _revision, ...payload } = next2;
|
|
89329
|
+
next2.revision = indexerProtocolDigest(payload);
|
|
88587
89330
|
}
|
|
88588
|
-
const content3 = `${JSON.stringify(
|
|
89331
|
+
const content3 = `${JSON.stringify(next2)}
|
|
88589
89332
|
`;
|
|
88590
89333
|
const targets = [{
|
|
88591
89334
|
path: await revisionStoragePath(root2),
|
|
@@ -88595,7 +89338,7 @@ ${input.instruction}` : revision.instruction
|
|
|
88595
89338
|
content: content3
|
|
88596
89339
|
}];
|
|
88597
89340
|
if (discardIds.size > 0) {
|
|
88598
|
-
const ledger = await
|
|
89341
|
+
const ledger = await readFile77(join96(root2, CANDIDATE_LEDGER_FILE), "utf8").catch((error) => {
|
|
88599
89342
|
if (error.code === "ENOENT")
|
|
88600
89343
|
return;
|
|
88601
89344
|
throw error;
|
|
@@ -88715,7 +89458,7 @@ var init_taskSourceAdjustment = __esm(() => {
|
|
|
88715
89458
|
});
|
|
88716
89459
|
|
|
88717
89460
|
// src/project/managedDocumentImport.ts
|
|
88718
|
-
import { readFile as
|
|
89461
|
+
import { readFile as readFile83 } from "node:fs/promises";
|
|
88719
89462
|
async function importManagedDocument(projectRoot, value) {
|
|
88720
89463
|
const input = inputSchema.parse(value);
|
|
88721
89464
|
if (input.type !== "sessions" && input.changes !== undefined)
|
|
@@ -88724,7 +89467,7 @@ async function importManagedDocument(projectRoot, value) {
|
|
|
88724
89467
|
const path3 = await assertManagedDocumentPath(projectRoot, input.type, input.name);
|
|
88725
89468
|
let previous3;
|
|
88726
89469
|
try {
|
|
88727
|
-
previous3 = await
|
|
89470
|
+
previous3 = await readFile83(path3, "utf8");
|
|
88728
89471
|
} catch (error) {
|
|
88729
89472
|
if (!(error && typeof error === "object" && ("code" in error) && error.code === "ENOENT"))
|
|
88730
89473
|
throw error;
|
|
@@ -88771,14 +89514,14 @@ var init_managedDocumentImport = __esm(() => {
|
|
|
88771
89514
|
});
|
|
88772
89515
|
|
|
88773
89516
|
// src/project/larkDocumentImport.ts
|
|
88774
|
-
import { readFile as
|
|
89517
|
+
import { readFile as readFile84 } from "node:fs/promises";
|
|
88775
89518
|
async function importLarkDocument(projectRoot, value) {
|
|
88776
89519
|
const input = schema3.parse(value);
|
|
88777
89520
|
const responsePages = [];
|
|
88778
89521
|
for (const path3 of input.response_files) {
|
|
88779
89522
|
assertActionInputWorkspace(projectRoot, path3);
|
|
88780
89523
|
const { resolve: resolve8 } = await import("node:path");
|
|
88781
|
-
responsePages.push(await
|
|
89524
|
+
responsePages.push(await readFile84(resolve8(projectRoot, path3), "utf8"));
|
|
88782
89525
|
}
|
|
88783
89526
|
const mediaFiles = {};
|
|
88784
89527
|
for (const [token, path3] of Object.entries(input.media_files ?? {})) {
|
|
@@ -88846,11 +89589,11 @@ var exports_managedDocumentRename = {};
|
|
|
88846
89589
|
__export(exports_managedDocumentRename, {
|
|
88847
89590
|
renameManagedDocument: () => renameManagedDocument
|
|
88848
89591
|
});
|
|
88849
|
-
import { readFile as
|
|
88850
|
-
import { join as
|
|
89592
|
+
import { readFile as readFile85 } from "node:fs/promises";
|
|
89593
|
+
import { join as join104, posix as posix11 } from "node:path";
|
|
88851
89594
|
async function optionalText2(path3) {
|
|
88852
89595
|
try {
|
|
88853
|
-
return await
|
|
89596
|
+
return await readFile85(path3, "utf8");
|
|
88854
89597
|
} catch (error) {
|
|
88855
89598
|
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT")
|
|
88856
89599
|
return;
|
|
@@ -88934,12 +89677,12 @@ async function renameManagedDocument(input) {
|
|
|
88934
89677
|
if (path3.split("/").includes("..") || path3.startsWith("/"))
|
|
88935
89678
|
throw new TypeError("Source references contain an unsafe knowledge path; repair it before renaming.");
|
|
88936
89679
|
await safeProjectTarget(input.projectRoot, path3);
|
|
88937
|
-
const before = await optionalText2(
|
|
89680
|
+
const before = await optionalText2(join104(input.projectRoot, path3));
|
|
88938
89681
|
if (before === undefined)
|
|
88939
89682
|
continue;
|
|
88940
89683
|
let after;
|
|
88941
89684
|
if (path3.endsWith(".yaml")) {
|
|
88942
|
-
const parsed =
|
|
89685
|
+
const parsed = import_yaml48.default.parse(before);
|
|
88943
89686
|
const updated = replace2(parsed);
|
|
88944
89687
|
if (path3 === "knowledge/structure.yaml") {
|
|
88945
89688
|
const rewritten = articles.map((article) => ({ ...article, sections: article.sections.map((section) => ({
|
|
@@ -88947,14 +89690,14 @@ async function renameManagedDocument(input) {
|
|
|
88947
89690
|
references: section.references.map((citation) => citation.source_ref !== input.source_ref ? citation : {
|
|
88948
89691
|
...citation,
|
|
88949
89692
|
source_ref: nextRef,
|
|
88950
|
-
locator: { ...citation.locator, path:
|
|
89693
|
+
locator: { ...citation.locator, path: posix11.basename(input.name) }
|
|
88951
89694
|
})
|
|
88952
89695
|
})) }));
|
|
88953
89696
|
updated.articles = rewritten;
|
|
88954
89697
|
}
|
|
88955
89698
|
if (JSON.stringify(parsed) === JSON.stringify(updated))
|
|
88956
89699
|
continue;
|
|
88957
|
-
after =
|
|
89700
|
+
after = import_yaml48.default.stringify(updated);
|
|
88958
89701
|
} else
|
|
88959
89702
|
after = before.replace(reference2, nextRef);
|
|
88960
89703
|
if (path3 === "src/index.ts")
|
|
@@ -88973,11 +89716,11 @@ async function renameManagedDocument(input) {
|
|
|
88973
89716
|
return;
|
|
88974
89717
|
}
|
|
88975
89718
|
const rooted = destination.startsWith("sources/") || destination.startsWith("/sources/");
|
|
88976
|
-
const resolved = rooted ? destination.replace(/^\//u, "") :
|
|
89719
|
+
const resolved = rooted ? destination.replace(/^\//u, "") : posix11.normalize(posix11.join(posix11.dirname(path3), destination));
|
|
88977
89720
|
if (resolved !== `sources/${type}/${oldName}`)
|
|
88978
89721
|
return;
|
|
88979
89722
|
const renamed = `sources/${type}/${input.name}`;
|
|
88980
|
-
return encodeURI(rooted ? `${destination.startsWith("/") ? "/" : ""}${renamed}` :
|
|
89723
|
+
return encodeURI(rooted ? `${destination.startsWith("/") ? "/" : ""}${renamed}` : posix11.relative(posix11.dirname(path3), renamed)) + match2[2];
|
|
88981
89724
|
});
|
|
88982
89725
|
if (before === after)
|
|
88983
89726
|
continue;
|
|
@@ -89006,7 +89749,7 @@ async function renameManagedDocument(input) {
|
|
|
89006
89749
|
};
|
|
89007
89750
|
});
|
|
89008
89751
|
}
|
|
89009
|
-
var
|
|
89752
|
+
var import_yaml48;
|
|
89010
89753
|
var init_managedDocumentRename = __esm(() => {
|
|
89011
89754
|
init_markdownLinks();
|
|
89012
89755
|
init_src2();
|
|
@@ -89018,12 +89761,12 @@ var init_managedDocumentRename = __esm(() => {
|
|
|
89018
89761
|
init_durableSingleFileTransaction();
|
|
89019
89762
|
init_durableMultiFileTransaction();
|
|
89020
89763
|
init_writeLock();
|
|
89021
|
-
|
|
89764
|
+
import_yaml48 = __toESM(require_dist(), 1);
|
|
89022
89765
|
});
|
|
89023
89766
|
|
|
89024
89767
|
// src/cli.ts
|
|
89025
89768
|
import { existsSync as existsSync36, realpathSync as realpathSync3 } from "node:fs";
|
|
89026
|
-
import { dirname as dirname47, join as
|
|
89769
|
+
import { dirname as dirname47, join as join108 } from "node:path";
|
|
89027
89770
|
import { fileURLToPath as fileURLToPath10, pathToFileURL as pathToFileURL3 } from "node:url";
|
|
89028
89771
|
|
|
89029
89772
|
// ../../node_modules/.bun/commander@11.1.0/node_modules/commander/esm.mjs
|
|
@@ -89103,7 +89846,7 @@ init_cliFeedback();
|
|
|
89103
89846
|
init_errors3();
|
|
89104
89847
|
init_exitCode();
|
|
89105
89848
|
import { createHash as createHash21 } from "node:crypto";
|
|
89106
|
-
import { mkdir as mkdir26, readdir as readdir16, readFile as readFile60, rm as rm16, stat as
|
|
89849
|
+
import { mkdir as mkdir26, readdir as readdir16, readFile as readFile60, rm as rm16, stat as stat10, writeFile as writeFile20 } from "node:fs/promises";
|
|
89107
89850
|
import { basename as basename8, dirname as dirname32, extname as extname12, join as join72, relative as relative22, resolve as resolve24 } from "node:path";
|
|
89108
89851
|
|
|
89109
89852
|
// src/project/documentCaptureAssets.ts
|
|
@@ -89113,7 +89856,7 @@ init_errors3();
|
|
|
89113
89856
|
init_exitCode();
|
|
89114
89857
|
init_markdownLinks();
|
|
89115
89858
|
import { readFileSync as readFileSync6 } from "node:fs";
|
|
89116
|
-
import { mkdir as mkdir24, readFile as readFile57, stat as
|
|
89859
|
+
import { mkdir as mkdir24, readFile as readFile57, stat as stat8, writeFile as writeFile18 } from "node:fs/promises";
|
|
89117
89860
|
import { dirname as dirname29, isAbsolute as isAbsolute13, join as join67, relative as relative20, resolve as resolve21 } from "node:path";
|
|
89118
89861
|
function runtimeError(message, detail) {
|
|
89119
89862
|
return new ContextError(ExitCode.UserError, message, {
|
|
@@ -89154,7 +89897,7 @@ async function writeCaptureAssetIfChanged(path2, content3) {
|
|
|
89154
89897
|
await writeFile18(path2, content3);
|
|
89155
89898
|
}
|
|
89156
89899
|
async function readLinkedCaptureAssets(input) {
|
|
89157
|
-
const rootStat = await
|
|
89900
|
+
const rootStat = await stat8(input.localRoot);
|
|
89158
89901
|
const boundaryRoot = rootStat.isFile() ? dirname29(input.localRoot) : input.localRoot;
|
|
89159
89902
|
const bySnapshotPath = new Map;
|
|
89160
89903
|
for (const file of input.files) {
|
|
@@ -89173,7 +89916,7 @@ async function readLinkedCaptureAssets(input) {
|
|
|
89173
89916
|
}
|
|
89174
89917
|
let bytes;
|
|
89175
89918
|
try {
|
|
89176
|
-
const assetStat = await
|
|
89919
|
+
const assetStat = await stat8(absolutePath);
|
|
89177
89920
|
if (!assetStat.isFile())
|
|
89178
89921
|
throw new TypeError("asset target is not a file");
|
|
89179
89922
|
bytes = await readFile57(absolutePath);
|
|
@@ -96967,7 +97710,7 @@ async function readRouteMetadataFiles(input) {
|
|
|
96967
97710
|
}
|
|
96968
97711
|
|
|
96969
97712
|
// src/project/documentSiteDetection.ts
|
|
96970
|
-
import { readdir as readdir15, stat as
|
|
97713
|
+
import { readdir as readdir15, stat as stat9 } from "node:fs/promises";
|
|
96971
97714
|
import { basename as basename7, extname as extname11, join as join68, relative as relative21, resolve as resolve22 } from "node:path";
|
|
96972
97715
|
var SKIPPED_DIRS = new Set([
|
|
96973
97716
|
".cache",
|
|
@@ -97018,7 +97761,7 @@ async function detectDocumentSiteFiles(input) {
|
|
|
97018
97761
|
const result = emptyDetection();
|
|
97019
97762
|
let rootStats;
|
|
97020
97763
|
try {
|
|
97021
|
-
rootStats = await
|
|
97764
|
+
rootStats = await stat9(localRoot);
|
|
97022
97765
|
} catch {
|
|
97023
97766
|
return result;
|
|
97024
97767
|
}
|
|
@@ -97222,7 +97965,7 @@ function assignFlatSnapshotPaths(files, module) {
|
|
|
97222
97965
|
});
|
|
97223
97966
|
}
|
|
97224
97967
|
async function walkMarkdownFiles(input) {
|
|
97225
|
-
const rootStat = await
|
|
97968
|
+
const rootStat = await stat10(input.localRoot);
|
|
97226
97969
|
if (rootStat.isFile()) {
|
|
97227
97970
|
const sourcePath = normalizeSnapshotRelativePath(basename8(input.localRoot));
|
|
97228
97971
|
return {
|
|
@@ -97839,7 +98582,7 @@ init_cliFeedback();
|
|
|
97839
98582
|
init_errors3();
|
|
97840
98583
|
init_exitCode();
|
|
97841
98584
|
init_atomicWrite();
|
|
97842
|
-
var
|
|
98585
|
+
var import_yaml37 = __toESM(require_dist(), 1);
|
|
97843
98586
|
import { existsSync as existsSync20 } from "node:fs";
|
|
97844
98587
|
import { join as join75 } from "node:path";
|
|
97845
98588
|
var SOURCE_NAME_PATTERN2 = /^[a-z0-9][a-z0-9._-]*$/u;
|
|
@@ -97916,7 +98659,7 @@ async function writeRepoRegistry(projectRoot, registry2) {
|
|
|
97916
98659
|
modules.push(registryRecordToYaml(record4));
|
|
97917
98660
|
namespaces.set(record4.namespace, modules);
|
|
97918
98661
|
}
|
|
97919
|
-
await atomicWriteFile(path2,
|
|
98662
|
+
await atomicWriteFile(path2, import_yaml37.default.stringify({
|
|
97920
98663
|
sources: [...namespaces].map(([name3, modules]) => ({ name: name3, modules }))
|
|
97921
98664
|
}));
|
|
97922
98665
|
}
|
|
@@ -98479,7 +99222,7 @@ init_errors3();
|
|
|
98479
99222
|
init_exitCode();
|
|
98480
99223
|
init_approvedKnowledgeMetadata();
|
|
98481
99224
|
init_knowledgeAssets();
|
|
98482
|
-
var
|
|
99225
|
+
var import_yaml38 = __toESM(require_dist(), 1);
|
|
98483
99226
|
import { createHash as createHash22 } from "node:crypto";
|
|
98484
99227
|
import { mkdir as mkdir28, writeFile as writeFile21 } from "node:fs/promises";
|
|
98485
99228
|
import { dirname as dirname34, join as join77 } from "node:path";
|
|
@@ -98553,7 +99296,7 @@ async function buildApprovedArticleIndex(projectRoot) {
|
|
|
98553
99296
|
const block = frontmatterBlock(content3);
|
|
98554
99297
|
if (block === null)
|
|
98555
99298
|
continue;
|
|
98556
|
-
const parsed =
|
|
99299
|
+
const parsed = import_yaml38.default.parse(block.yaml);
|
|
98557
99300
|
if (!isRecord14(parsed))
|
|
98558
99301
|
continue;
|
|
98559
99302
|
const frontmatter2 = hydrateApprovedFrontmatter({
|
|
@@ -98600,13 +99343,13 @@ function updateFrontmatter(content3, mutate) {
|
|
|
98600
99343
|
next: "Fix approved Markdown frontmatter before running this review maintenance command."
|
|
98601
99344
|
});
|
|
98602
99345
|
}
|
|
98603
|
-
const parsed =
|
|
99346
|
+
const parsed = import_yaml38.default.parse(block.yaml);
|
|
98604
99347
|
if (!isRecord14(parsed)) {
|
|
98605
99348
|
throw new ContextError(ExitCode.WorkspaceStateError, "approved page frontmatter must be a YAML object", {
|
|
98606
99349
|
category: ErrorCategory.SchemaInvalid
|
|
98607
99350
|
});
|
|
98608
99351
|
}
|
|
98609
|
-
const yaml3 =
|
|
99352
|
+
const yaml3 = import_yaml38.default.stringify(mutate(parsed)).trimEnd();
|
|
98610
99353
|
return `---
|
|
98611
99354
|
${yaml3}
|
|
98612
99355
|
---${content3.slice(block.end)}`;
|
|
@@ -105437,76 +106180,12 @@ init_errors3();
|
|
|
105437
106180
|
init_exitCode();
|
|
105438
106181
|
init_candidateLedger();
|
|
105439
106182
|
init_writeLock();
|
|
106183
|
+
init_reviewApplyIndexer();
|
|
106184
|
+
init_approvedKnowledgeSnapshots();
|
|
105440
106185
|
import { existsSync as existsSync25 } from "node:fs";
|
|
105441
106186
|
import { readFile as readFile69 } from "node:fs/promises";
|
|
105442
106187
|
import { join as join91 } from "node:path";
|
|
105443
106188
|
|
|
105444
|
-
// src/project/reviewApplyIndexer.ts
|
|
105445
|
-
init_okfTypes();
|
|
105446
|
-
init_packageKnowledgeProjection();
|
|
105447
|
-
init_approvedKnowledgeMetadata();
|
|
105448
|
-
var import_yaml39 = __toESM(require_dist(), 1);
|
|
105449
|
-
function escapeHtmlAttribute(value) {
|
|
105450
|
-
return value.replace(/&/gu, "&").replace(/"/gu, """).replace(/</gu, "<").replace(/>/gu, ">");
|
|
105451
|
-
}
|
|
105452
|
-
function sectionMarkdown(section) {
|
|
105453
|
-
return [
|
|
105454
|
-
`<!-- context:section id="${escapeHtmlAttribute(section.section_key)}" -->`,
|
|
105455
|
-
"",
|
|
105456
|
-
section.markdown.trimEnd(),
|
|
105457
|
-
"",
|
|
105458
|
-
"<!-- /context:section -->"
|
|
105459
|
-
].join(`
|
|
105460
|
-
`);
|
|
105461
|
-
}
|
|
105462
|
-
function renderApprovedIndexerMarkdown(input) {
|
|
105463
|
-
if (input.record.approved_revision !== undefined) {
|
|
105464
|
-
const content3 = compactApprovedKnowledgeMarkdown(ensureApprovedKnowledgePresentation(input.record.body));
|
|
105465
|
-
return content3.replace(/^---\r?\n([\s\S]*?)\r?\n---/u, (_match, header) => {
|
|
105466
|
-
const metadata = import_yaml39.default.parse(header);
|
|
105467
|
-
return ["---", import_yaml39.default.stringify({
|
|
105468
|
-
...metadata,
|
|
105469
|
-
type: metadata.type ?? okfTypeForCollection(input.record.collection),
|
|
105470
|
-
timestamp: input.timestamp
|
|
105471
|
-
}).trimEnd(), "---"].join(`
|
|
105472
|
-
`);
|
|
105473
|
-
});
|
|
105474
|
-
}
|
|
105475
|
-
const binding = input.record.indexer_candidate;
|
|
105476
|
-
if (input.record.candidate_type !== "indexer-artifact" || binding === undefined) {
|
|
105477
|
-
throw new TypeError("Indexer approved renderer requires an indexer-artifact Candidate");
|
|
105478
|
-
}
|
|
105479
|
-
const title = input.record.review.title;
|
|
105480
|
-
const body = binding.sections.flatMap((section, index2) => [
|
|
105481
|
-
...index2 === 0 ? [] : [""],
|
|
105482
|
-
sectionMarkdown(section)
|
|
105483
|
-
]).join(`
|
|
105484
|
-
`);
|
|
105485
|
-
const description = readerKnowledgeDescription({
|
|
105486
|
-
description: input.record.review.summary,
|
|
105487
|
-
markdown: body,
|
|
105488
|
-
title
|
|
105489
|
-
});
|
|
105490
|
-
const frontmatter2 = import_yaml39.default.stringify({
|
|
105491
|
-
title,
|
|
105492
|
-
type: okfTypeForCollection(input.record.collection),
|
|
105493
|
-
description,
|
|
105494
|
-
timestamp: input.timestamp
|
|
105495
|
-
}).trimEnd();
|
|
105496
|
-
return [
|
|
105497
|
-
"---",
|
|
105498
|
-
frontmatter2,
|
|
105499
|
-
"---",
|
|
105500
|
-
"",
|
|
105501
|
-
ensureMarkdownPageTitle(body, title),
|
|
105502
|
-
""
|
|
105503
|
-
].join(`
|
|
105504
|
-
`);
|
|
105505
|
-
}
|
|
105506
|
-
|
|
105507
|
-
// src/project/reviewApply.ts
|
|
105508
|
-
init_approvedKnowledgeSnapshots();
|
|
105509
|
-
|
|
105510
106189
|
// src/project/reviewCandidateAuthority.ts
|
|
105511
106190
|
init_src2();
|
|
105512
106191
|
init_approvedRevision();
|
|
@@ -105604,7 +106283,7 @@ async function prepareApprovedPage(input) {
|
|
|
105604
106283
|
const relPath = join91("knowledge", input.record.path);
|
|
105605
106284
|
const existingView = findApprovedPageForArticleId(input.record.indexer_candidate.artifact_ref, input.approvedPageIndex);
|
|
105606
106285
|
const previousPath = input.record.approved_revision?.previous_path;
|
|
105607
|
-
if (previousPath !== undefined && !isSafeKnowledgeTargetPath(
|
|
106286
|
+
if (previousPath !== undefined && (!isSafeKnowledgeTargetPath(previousPath.split("/")[0], previousPath) || previousPath.includes("\\")))
|
|
105608
106287
|
throw new TypeError("Unsafe original page path in a move");
|
|
105609
106288
|
if (existingView !== undefined && existingView.relPath !== relPath && existingView.relPath !== (previousPath === undefined ? undefined : `knowledge/${previousPath}`)) {
|
|
105610
106289
|
throw new ContextError(ExitCode.WorkspaceStateError, `approved page already exists for view_ref at a different path: ${input.record.article_id}`, {
|
|
@@ -107326,22 +108005,52 @@ function requireProjectRoot2() {
|
|
|
107326
108005
|
}
|
|
107327
108006
|
function registerDocumentRevisionCommand(program2) {
|
|
107328
108007
|
const task = program2.command("task").description("Explicit current-task recovery");
|
|
107329
|
-
task.command("
|
|
108008
|
+
task.command("retire").description("Preview or apply explicit approved-article retirement and reference cleanup").option("--input <file>", "YAML/JSON reason and targets with optional approved replacement; - for stdin").option("--schema", "show the retirement input schema").option("--apply", "apply the reviewed retirement within existing user authorization").option("--plan-digest <digest>", "exact current retirement preview").option("--format <format>", "output format: json", "json").action(async (options) => {
|
|
108009
|
+
const { retireArticles: retireArticles2, articleRetirementSchema: articleRetirementSchema2 } = await Promise.resolve().then(() => (init_articleRetirement(), exports_articleRetirement));
|
|
108010
|
+
if (options.schema) {
|
|
108011
|
+
const { zodToJsonSchema: zodToJsonSchema3 } = await Promise.resolve().then(() => (init_esm(), exports_esm));
|
|
108012
|
+
const { writeSchemaOutput: writeSchemaOutput2, schemaOutputFormat: schemaOutputFormat2 } = await Promise.resolve().then(() => (init_schemaOutput(), exports_schemaOutput));
|
|
108013
|
+
writeSchemaOutput2(zodToJsonSchema3(articleRetirementSchema2), schemaOutputFormat2(options.format));
|
|
108014
|
+
return;
|
|
108015
|
+
}
|
|
108016
|
+
if (options.format !== "json" || !options.input)
|
|
108017
|
+
throw new ContextError(ExitCode.UserError, "Use --input <file> --format json, or --schema.", { category: ErrorCategory.UserInputInvalid });
|
|
108018
|
+
assertActionInputWorkspace(process.cwd(), options.input);
|
|
108019
|
+
const value = await readYamlOrJsonInput({
|
|
108020
|
+
path: options.input,
|
|
108021
|
+
label: "article retirement",
|
|
108022
|
+
missingNext: "Provide reason and targets with exact approved paths and optional replacement paths.",
|
|
108023
|
+
readFailureNext: "Use an input file in this workspace.",
|
|
108024
|
+
parseFailureNext: "Provide valid YAML or JSON."
|
|
108025
|
+
});
|
|
108026
|
+
const result = await retireArticles2({
|
|
108027
|
+
projectRoot: requireProjectRoot2(),
|
|
108028
|
+
value,
|
|
108029
|
+
...options.apply ? { apply: true } : {},
|
|
108030
|
+
...options.planDigest ? { plan_digest: options.planDigest } : {}
|
|
108031
|
+
});
|
|
108032
|
+
if (result.action === "preview" && result.blockers.length === 0)
|
|
108033
|
+
result.next_action.command = `context task retire --input '${options.input.replace(/'/gu, "'\\''")}' --apply --plan-digest '${result.revision}' --format json`;
|
|
108034
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}
|
|
108035
|
+
`);
|
|
108036
|
+
});
|
|
108037
|
+
task.command("recover").description("Inspect or preview scoped recovery independently of the normal workflow Route").option("--operation <operation>", "inspect, writer-lock or transactions; use ordinary file submission/revise for article repair", "inspect").option("--apply", "apply the reviewed recovery scope within existing user authorization").option("--plan-digest <digest>", "exact current recovery preview").option("--format <format>", "output format: json", "json").action(async (options) => {
|
|
107330
108038
|
if (options.format !== "json")
|
|
107331
108039
|
throw new TypeError("--format must be json");
|
|
107332
|
-
if (!["inspect", "transactions"].includes(options.operation))
|
|
107333
|
-
throw new TypeError("Use inspect or transactions. Repair current task files or use context revise for an accepted article; old workset/plan recovery is not supported.");
|
|
108040
|
+
if (!["inspect", "writer-lock", "transactions"].includes(options.operation))
|
|
108041
|
+
throw new TypeError("Use inspect, writer-lock or transactions. Repair current task files or use context revise for an accepted article; old workset/plan recovery is not supported.");
|
|
107334
108042
|
if (options.operation === "inspect" && options.apply)
|
|
107335
108043
|
throw new TypeError("Inspection is read-only; select a recovery operation to apply.");
|
|
107336
108044
|
const projectRoot = requireProjectRoot2();
|
|
107337
108045
|
const { inspectTaskRecovery: inspectTaskRecovery2, recoverTaskTransactions: recoverTaskTransactions2 } = await Promise.resolve().then(() => (init_taskRecovery(), exports_taskRecovery));
|
|
108046
|
+
const { recoverWriterLock: recoverWriterLock2 } = await Promise.resolve().then(() => (init_writeLockRecovery(), exports_writeLockRecovery));
|
|
107338
108047
|
const base = {
|
|
107339
108048
|
projectRoot,
|
|
107340
108049
|
...options.apply ? { apply: true } : {},
|
|
107341
108050
|
...options.planDigest ? { plan_digest: options.planDigest } : {}
|
|
107342
108051
|
};
|
|
107343
108052
|
try {
|
|
107344
|
-
const result = options.operation === "inspect" ? await inspectTaskRecovery2(projectRoot) : await recoverTaskTransactions2(base);
|
|
108053
|
+
const result = options.operation === "inspect" ? await inspectTaskRecovery2(projectRoot) : options.operation === "writer-lock" ? await recoverWriterLock2(base) : await recoverTaskTransactions2(base);
|
|
107345
108054
|
process.stdout.write(`${JSON.stringify(result, null, 2)}
|
|
107346
108055
|
`);
|
|
107347
108056
|
} catch (error) {
|
|
@@ -107465,7 +108174,7 @@ function registerDocumentRevisionCommand(program2) {
|
|
|
107465
108174
|
process.stdout.write(`${JSON.stringify(await beginKnowledgeUpdate(requireProjectRoot2(), value), null, 2)}
|
|
107466
108175
|
`);
|
|
107467
108176
|
});
|
|
107468
|
-
program2.command("revise <target>").description("Repair one current Candidate or approved knowledge page through the Indexer lifecycle").requiredOption("--instruction <feedback>", "reader-facing correction request").option("--regenerate", "regenerate program blocks for an approved page, even at the same source version").option("--timing <timing>", "after-batch or priority for approved pages; current Candidates are repaired in place", "after-batch").option("--move-to <path>", "explicit new approved path in
|
|
108177
|
+
program2.command("revise <target>").description("Repair one current Candidate or approved knowledge page through the Indexer lifecycle").requiredOption("--instruction <feedback>", "reader-facing correction request").option("--regenerate", "regenerate program blocks for an approved page, even at the same source version").option("--timing <timing>", "after-batch or priority for approved pages; current Candidates are repaired in place", "after-batch").option("--move-to <path>", "explicit new approved path in any supported collection; preserves page identity").option("--format <format>", "output format: json", "json").action(async (target, options) => {
|
|
107469
108178
|
if (options.format !== "json") {
|
|
107470
108179
|
throw new ContextError(ExitCode.UserError, "--format must be json", {
|
|
107471
108180
|
category: ErrorCategory.UserInputInvalid
|
|
@@ -107494,8 +108203,8 @@ function registerDocumentRevisionCommand(program2) {
|
|
|
107494
108203
|
init_workspace();
|
|
107495
108204
|
init_workspaceChangelog();
|
|
107496
108205
|
function registerVersionCommands(program2) {
|
|
107497
|
-
const
|
|
107498
|
-
|
|
108206
|
+
const command3 = program2.command("version").description("Inspect formal changes and record a knowledge workspace SemVer and changelog");
|
|
108207
|
+
command3.command("inspect").option("--publish", "include same-version dist changes before publishing").option("--format <format>", "json", "json").action(async (options) => {
|
|
107499
108208
|
const root2 = findContextProjectRoot(process.cwd())?.projectRoot;
|
|
107500
108209
|
if (!root2)
|
|
107501
108210
|
throw new TypeError("Run inside a Context workspace");
|
|
@@ -107507,7 +108216,7 @@ function registerVersionCommands(program2) {
|
|
|
107507
108216
|
}, null, 2) + `
|
|
107508
108217
|
`);
|
|
107509
108218
|
});
|
|
107510
|
-
|
|
108219
|
+
command3.command("publish-check").option("--format <format>", "json", "json").action(async () => {
|
|
107511
108220
|
const root2 = findContextProjectRoot(process.cwd())?.projectRoot;
|
|
107512
108221
|
if (!root2)
|
|
107513
108222
|
throw new TypeError("Run inside a Context workspace");
|
|
@@ -107515,7 +108224,7 @@ function registerVersionCommands(program2) {
|
|
|
107515
108224
|
process.stdout.write(JSON.stringify(await inspectWorkspacePublish2(root2), null, 2) + `
|
|
107516
108225
|
`);
|
|
107517
108226
|
});
|
|
107518
|
-
|
|
108227
|
+
command3.command("published").requiredOption("--hash <hash>", "publish-check hash of uploaded artifacts").requiredOption("--receipt <receipt>", "successful external publication receipt").option("--format <format>", "json", "json").action(async (options) => {
|
|
107519
108228
|
const root2 = findContextProjectRoot(process.cwd())?.projectRoot;
|
|
107520
108229
|
if (!root2)
|
|
107521
108230
|
throw new TypeError("Run inside a Context workspace");
|
|
@@ -107523,7 +108232,7 @@ function registerVersionCommands(program2) {
|
|
|
107523
108232
|
process.stdout.write(JSON.stringify(await markWorkspacePublished2(root2, options.hash, options.receipt)) + `
|
|
107524
108233
|
`);
|
|
107525
108234
|
});
|
|
107526
|
-
|
|
108235
|
+
command3.command("record").requiredOption("--input <file>", "YAML/JSON file or -").option("--format <format>", "json", "json").action(async (options) => {
|
|
107527
108236
|
const root2 = findContextProjectRoot(process.cwd())?.projectRoot;
|
|
107528
108237
|
if (!root2)
|
|
107529
108238
|
throw new TypeError("Run inside a Context workspace");
|
|
@@ -107641,10 +108350,10 @@ init_actionInputWorkspace();
|
|
|
107641
108350
|
|
|
107642
108351
|
// src/project/actionCompletionOutput.ts
|
|
107643
108352
|
init_atomicWrite();
|
|
107644
|
-
var
|
|
108353
|
+
var import_yaml43 = __toESM(require_dist(), 1);
|
|
107645
108354
|
import { Buffer as Buffer4 } from "node:buffer";
|
|
107646
|
-
import { createHash as
|
|
107647
|
-
import { join as
|
|
108355
|
+
import { createHash as createHash29 } from "node:crypto";
|
|
108356
|
+
import { join as join97 } from "node:path";
|
|
107648
108357
|
var INLINE_LIMIT = 16 * 1024;
|
|
107649
108358
|
function record4(value) {
|
|
107650
108359
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : undefined;
|
|
@@ -107657,7 +108366,7 @@ function shortText(value, limit = 400) {
|
|
|
107657
108366
|
}
|
|
107658
108367
|
function serializeActionCompletion(value, format2) {
|
|
107659
108368
|
return format2 === "json" ? `${JSON.stringify(value, null, 2)}
|
|
107660
|
-
` :
|
|
108369
|
+
` : import_yaml43.default.stringify(value);
|
|
107661
108370
|
}
|
|
107662
108371
|
async function prepareActionCompletionOutput(input) {
|
|
107663
108372
|
if (input.verbose)
|
|
@@ -107669,9 +108378,9 @@ async function prepareActionCompletionOutput(input) {
|
|
|
107669
108378
|
const production = typeof result.stage_state === "string";
|
|
107670
108379
|
if (production && Buffer4.byteLength(full) <= INLINE_LIMIT)
|
|
107671
108380
|
return input.result;
|
|
107672
|
-
const digest6 =
|
|
107673
|
-
const root2 =
|
|
107674
|
-
const resultFile =
|
|
108381
|
+
const digest6 = createHash29("sha256").update(full).digest("hex");
|
|
108382
|
+
const root2 = join97(input.projectRoot, ".tmp/context-runtime/action-results");
|
|
108383
|
+
const resultFile = join97(root2, `${digest6}.json`);
|
|
107675
108384
|
await atomicWriteFile(resultFile, full);
|
|
107676
108385
|
if (production)
|
|
107677
108386
|
return {
|
|
@@ -107681,10 +108390,10 @@ async function prepareActionCompletionOutput(input) {
|
|
|
107681
108390
|
details: resultFile,
|
|
107682
108391
|
...pick(result, ["next", "next_preparation"])
|
|
107683
108392
|
};
|
|
107684
|
-
const
|
|
107685
|
-
const nextFile =
|
|
108393
|
+
const next2 = record4(result.next) ?? record4(record4(result.workflow)?.current) ?? record4(record4(result.continuation)?.next);
|
|
108394
|
+
const nextFile = next2 === undefined ? undefined : join97(root2, `${digest6}.next.json`);
|
|
107686
108395
|
if (nextFile !== undefined)
|
|
107687
|
-
await atomicWriteFile(nextFile, serializeActionCompletion(
|
|
108396
|
+
await atomicWriteFile(nextFile, serializeActionCompletion(next2, "json"));
|
|
107688
108397
|
const outcomes = (Array.isArray(result.outcomes) ? result.outcomes : []).map(record4).filter((item) => item !== undefined);
|
|
107689
108398
|
const counts2 = {};
|
|
107690
108399
|
for (const item of outcomes) {
|
|
@@ -107721,12 +108430,12 @@ async function prepareActionCompletionOutput(input) {
|
|
|
107721
108430
|
"task_completion",
|
|
107722
108431
|
"pages"
|
|
107723
108432
|
]),
|
|
107724
|
-
next_route:
|
|
108433
|
+
next_route: next2 === undefined ? null : {
|
|
107725
108434
|
file: nextFile,
|
|
107726
|
-
digest: `sha256:${
|
|
107727
|
-
...pick(
|
|
107728
|
-
commands:
|
|
107729
|
-
gate:
|
|
108435
|
+
digest: `sha256:${createHash29("sha256").update(serializeActionCompletion(next2, "json")).digest("hex")}`,
|
|
108436
|
+
...pick(next2, ["revision", "node", "availability"]),
|
|
108437
|
+
commands: next2.commands,
|
|
108438
|
+
gate: next2.gate === undefined ? undefined : pick(record4(next2.gate), ["id", "resolution", "delegatable"])
|
|
107730
108439
|
},
|
|
107731
108440
|
...failure2 === undefined ? {} : { next_preparation: {
|
|
107732
108441
|
outcome: failure2.outcome,
|
|
@@ -107740,7 +108449,7 @@ async function prepareActionCompletionOutput(input) {
|
|
|
107740
108449
|
summary.outcomes.pop();
|
|
107741
108450
|
summary.outcomes_omitted++;
|
|
107742
108451
|
}
|
|
107743
|
-
summary.details_required = summary.outcomes_omitted > 0 || failure2?.outcome === "failed" || outcomes.some((item) => !["accepted", "material-expanded"].includes(String(item.outcome))) || outcomes.length === 0 && result.outcome === undefined && result.workflow_summary === undefined ||
|
|
108452
|
+
summary.details_required = summary.outcomes_omitted > 0 || failure2?.outcome === "failed" || outcomes.some((item) => !["accepted", "material-expanded"].includes(String(item.outcome))) || outcomes.length === 0 && result.outcome === undefined && result.workflow_summary === undefined || next2 === undefined && result.workflow_summary === undefined;
|
|
107744
108453
|
return summary;
|
|
107745
108454
|
}
|
|
107746
108455
|
|
|
@@ -107770,34 +108479,34 @@ init_errors3();
|
|
|
107770
108479
|
init_cliFeedback();
|
|
107771
108480
|
init_exitCode();
|
|
107772
108481
|
init_productionFeedback();
|
|
107773
|
-
var
|
|
108482
|
+
var import_yaml44 = __toESM(require_dist(), 1);
|
|
107774
108483
|
import { relative as relative24, resolve as resolve32 } from "node:path";
|
|
107775
108484
|
async function completeCurrentProductionAction(input) {
|
|
107776
108485
|
return withProductionFeedback({ operation: "action", file: input.submissionPath }, () => withProjectWriteLock(input.projectRoot, "production-action", async () => {
|
|
107777
108486
|
await recoverDurableMultiFileTransactions(input.projectRoot);
|
|
107778
108487
|
const stage = await readProductionStage(input.projectRoot);
|
|
107779
|
-
const
|
|
108488
|
+
const invalid2 = (message) => new ContextError(ExitCode.UserError, message, {
|
|
107780
108489
|
category: ErrorCategory.UserInputInvalid,
|
|
107781
108490
|
reason_code: "invalid-production-submission",
|
|
107782
108491
|
next_action: { command: "context status --format json" }
|
|
107783
108492
|
});
|
|
107784
108493
|
if (!stage)
|
|
107785
|
-
throw
|
|
108494
|
+
throw invalid2("The production stage expired. Read the current route; do not restore a previous process.");
|
|
107786
108495
|
if (input.preview)
|
|
107787
|
-
throw
|
|
108496
|
+
throw invalid2("Stage files do not use the retired Author preview. Submit the current task files.");
|
|
107788
108497
|
if (!input.submissionPath || input.submissionPath === "-")
|
|
107789
|
-
throw
|
|
108498
|
+
throw invalid2("Production requires a stage-local manifest file, not stdin.");
|
|
107790
108499
|
const path3 = relative24(resolve32(input.projectRoot, productionAgentDirectory(stage.id)), resolve32(input.cwd, input.submissionPath));
|
|
107791
108500
|
const manifest = await readProductionFile({ projectRoot: input.projectRoot, stage: stage.id, path: path3 });
|
|
107792
|
-
const value =
|
|
108501
|
+
const value = import_yaml44.default.parse(manifest.text, { uniqueKeys: true });
|
|
107793
108502
|
if (!value || typeof value !== "object" || !("stage" in value) || value.stage !== stage.id) {
|
|
107794
|
-
throw
|
|
108503
|
+
throw invalid2("The manifest must identify the current production stage. No tasks were saved.");
|
|
107795
108504
|
}
|
|
107796
108505
|
const submission = { projectRoot: input.projectRoot, stage: stage.id, path: path3, manifest, multiAgent: input.multiAgent === true };
|
|
107797
108506
|
if ("decision" in value)
|
|
107798
108507
|
return approveProductionReport({ ...submission, revision: input.revision });
|
|
107799
108508
|
if (input.revision !== stage.id)
|
|
107800
|
-
throw
|
|
108509
|
+
throw invalid2("Use the current stage revision; task input handles protect independent submissions.");
|
|
107801
108510
|
if (!stage.planning_complete || "articles" in value)
|
|
107802
108511
|
return submitProductionPlan(submission);
|
|
107803
108512
|
return completeProductionSubmission(submission);
|
|
@@ -107936,7 +108645,7 @@ init_errors3();
|
|
|
107936
108645
|
init_cliFeedback();
|
|
107937
108646
|
init_exitCode();
|
|
107938
108647
|
init_productionFeedback();
|
|
107939
|
-
var
|
|
108648
|
+
var import_yaml45 = __toESM(require_dist(), 1);
|
|
107940
108649
|
import { relative as relative25, resolve as resolve33 } from "node:path";
|
|
107941
108650
|
var productionKnownTasksSchema = productionPlanInputSchema.omit({ stage: true });
|
|
107942
108651
|
async function prepareKnownProductionTasks(input) {
|
|
@@ -107944,29 +108653,29 @@ async function prepareKnownProductionTasks(input) {
|
|
|
107944
108653
|
await recoverDurableMultiFileTransactions(input.projectRoot);
|
|
107945
108654
|
const path3 = relative25(resolve33(input.projectRoot, ".tmp/agent-work"), resolve33(input.cwd, input.path));
|
|
107946
108655
|
const fixed2 = await readProductionPlanningFile({ projectRoot: input.projectRoot, path: path3 });
|
|
107947
|
-
const
|
|
108656
|
+
const invalid2 = (message) => new ContextError(ExitCode.UserError, message, {
|
|
107948
108657
|
category: ErrorCategory.UserInputInvalid,
|
|
107949
108658
|
reason_code: "invalid-known-production-tasks",
|
|
107950
108659
|
file: input.path,
|
|
107951
108660
|
input_schema: zodToJsonSchema(productionKnownTasksSchema, { $refStrategy: "none" }),
|
|
107952
108661
|
next_action: { command: "context status --format json" }
|
|
107953
108662
|
});
|
|
107954
|
-
const plan = productionKnownTasksSchema.parse(
|
|
108663
|
+
const plan = productionKnownTasksSchema.parse(import_yaml45.default.parse(fixed2.text, { uniqueKeys: true }));
|
|
107955
108664
|
const request = await productionPlanningRequest(input.projectRoot);
|
|
107956
108665
|
let stage = await readProductionStage(input.projectRoot);
|
|
107957
108666
|
if (!request || stage?.report_approved || (stage ? ![stage.id, request.revision].includes(input.revision) : request.revision !== input.revision)) {
|
|
107958
|
-
throw
|
|
108667
|
+
throw invalid2("Use known tasks before report approval, with the current preparation revision. Approved stages use ordinary task amendments.");
|
|
107959
108668
|
}
|
|
107960
108669
|
if (!stage) {
|
|
107961
108670
|
await prepareCurrentProductionStage({ projectRoot: input.projectRoot, revision: input.revision });
|
|
107962
108671
|
stage = await readProductionStage(input.projectRoot);
|
|
107963
108672
|
}
|
|
107964
|
-
const
|
|
108673
|
+
const text10 = import_yaml45.default.stringify({ ...plan, stage: stage.id });
|
|
107965
108674
|
const result = await submitProductionPlan({
|
|
107966
108675
|
projectRoot: input.projectRoot,
|
|
107967
108676
|
stage: stage.id,
|
|
107968
108677
|
path: fixed2.path,
|
|
107969
|
-
manifest: { path: fixed2.path, text:
|
|
108678
|
+
manifest: { path: fixed2.path, text: text10, bytes: Buffer.byteLength(text10), digest: durableContentDigest(text10) }
|
|
107970
108679
|
});
|
|
107971
108680
|
return { ...result, next_action: { command: "context status --format json" } };
|
|
107972
108681
|
}));
|
|
@@ -108083,9 +108792,9 @@ function registerProjectActionCommands(program2) {
|
|
|
108083
108792
|
// src/commands/cleanClaudePluginCache.ts
|
|
108084
108793
|
init_cliFeedback();
|
|
108085
108794
|
import { existsSync as existsSync27 } from "node:fs";
|
|
108086
|
-
import { readdir as
|
|
108795
|
+
import { readdir as readdir23, rm as rm19 } from "node:fs/promises";
|
|
108087
108796
|
import { homedir } from "node:os";
|
|
108088
|
-
import { join as
|
|
108797
|
+
import { join as join98 } from "node:path";
|
|
108089
108798
|
var ORPHAN_MARKER = ".orphaned_at";
|
|
108090
108799
|
var CLAUDE_PLUGIN_CACHE_ROOT_ENV = "C4A_CLAUDE_PLUGIN_CACHE_ROOT";
|
|
108091
108800
|
var CLAUDE_PLUGIN_CACHE_HOME_ENV = "C4A_CLAUDE_PLUGIN_CACHE_HOME";
|
|
@@ -108098,23 +108807,23 @@ async function cleanClaudePluginCache(opts = {}) {
|
|
|
108098
108807
|
lines.push("· claude plugin cache: missing — nothing to clean");
|
|
108099
108808
|
return { lines, removed, scanned };
|
|
108100
108809
|
}
|
|
108101
|
-
const marketplaces = await
|
|
108810
|
+
const marketplaces = await readdir23(cacheRoot, { withFileTypes: true });
|
|
108102
108811
|
for (const mp of marketplaces) {
|
|
108103
108812
|
if (!mp.isDirectory())
|
|
108104
108813
|
continue;
|
|
108105
|
-
const mpDir =
|
|
108106
|
-
const plugins = await
|
|
108814
|
+
const mpDir = join98(cacheRoot, mp.name);
|
|
108815
|
+
const plugins = await readdir23(mpDir, { withFileTypes: true });
|
|
108107
108816
|
for (const pl of plugins) {
|
|
108108
108817
|
if (!pl.isDirectory())
|
|
108109
108818
|
continue;
|
|
108110
|
-
const plDir =
|
|
108111
|
-
const versions = await
|
|
108819
|
+
const plDir = join98(mpDir, pl.name);
|
|
108820
|
+
const versions = await readdir23(plDir, { withFileTypes: true });
|
|
108112
108821
|
for (const ver of versions) {
|
|
108113
108822
|
if (!ver.isDirectory())
|
|
108114
108823
|
continue;
|
|
108115
108824
|
scanned += 1;
|
|
108116
|
-
const verDir =
|
|
108117
|
-
const markerPath =
|
|
108825
|
+
const verDir = join98(plDir, ver.name);
|
|
108826
|
+
const markerPath = join98(verDir, ORPHAN_MARKER);
|
|
108118
108827
|
if (!existsSync27(markerPath))
|
|
108119
108828
|
continue;
|
|
108120
108829
|
const label2 = `${mp.name}/${pl.name}/${ver.name}`;
|
|
@@ -108146,11 +108855,11 @@ function resolveClaudePluginCacheRoot(opts) {
|
|
|
108146
108855
|
if (explicitRoot)
|
|
108147
108856
|
return explicitRoot;
|
|
108148
108857
|
const home = opts.home ?? process.env[CLAUDE_PLUGIN_CACHE_HOME_ENV] ?? homedir();
|
|
108149
|
-
return
|
|
108858
|
+
return join98(home, ".claude", "plugins", "cache");
|
|
108150
108859
|
}
|
|
108151
108860
|
async function isEmptyDir(dir) {
|
|
108152
108861
|
try {
|
|
108153
|
-
const entries2 = await
|
|
108862
|
+
const entries2 = await readdir23(dir);
|
|
108154
108863
|
return entries2.length === 0;
|
|
108155
108864
|
} catch {
|
|
108156
108865
|
return false;
|
|
@@ -108178,13 +108887,13 @@ init_exitCode();
|
|
|
108178
108887
|
|
|
108179
108888
|
// src/lib/packageVersion.ts
|
|
108180
108889
|
import { existsSync as existsSync28, readFileSync as readFileSync9 } from "node:fs";
|
|
108181
|
-
import { dirname as dirname41, join as
|
|
108890
|
+
import { dirname as dirname41, join as join99 } from "node:path";
|
|
108182
108891
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
108183
108892
|
function readPackageVersion() {
|
|
108184
108893
|
try {
|
|
108185
108894
|
let dir = dirname41(fileURLToPath7(import.meta.url));
|
|
108186
108895
|
for (let depth = 0;depth < 8; depth += 1) {
|
|
108187
|
-
const packagePath =
|
|
108896
|
+
const packagePath = join99(dir, "package.json");
|
|
108188
108897
|
if (existsSync28(packagePath)) {
|
|
108189
108898
|
const parsed = JSON.parse(readFileSync9(packagePath, "utf8"));
|
|
108190
108899
|
if (typeof parsed.version === "string" && parsed.version.length > 0) {
|
|
@@ -108207,12 +108916,12 @@ function readPackageVersion() {
|
|
|
108207
108916
|
|
|
108208
108917
|
// src/project/sourceCommands.ts
|
|
108209
108918
|
init_src2();
|
|
108210
|
-
import { readFile as
|
|
108919
|
+
import { readFile as readFile86 } from "node:fs/promises";
|
|
108211
108920
|
import { isAbsolute as isAbsolute22, resolve as resolve37 } from "node:path";
|
|
108212
108921
|
init_cliFeedback();
|
|
108213
108922
|
init_errors3();
|
|
108214
108923
|
init_exitCode();
|
|
108215
|
-
var
|
|
108924
|
+
var import_yaml49 = __toESM(require_dist(), 1);
|
|
108216
108925
|
|
|
108217
108926
|
// src/project/repoSourceRecovery.ts
|
|
108218
108927
|
init_cliFeedback();
|
|
@@ -108220,7 +108929,7 @@ init_errors3();
|
|
|
108220
108929
|
init_exitCode();
|
|
108221
108930
|
import { execFile as execFile10 } from "node:child_process";
|
|
108222
108931
|
import { existsSync as existsSync29 } from "node:fs";
|
|
108223
|
-
import { lstat as
|
|
108932
|
+
import { lstat as lstat11, mkdir as mkdir33, readlink as readlink2, realpath as realpath8, rm as rm20, symlink as symlink3 } from "node:fs/promises";
|
|
108224
108933
|
import { basename as basename11, dirname as dirname42, isAbsolute as isAbsolute19, relative as relative26, resolve as resolve34 } from "node:path";
|
|
108225
108934
|
import { promisify as promisify10 } from "node:util";
|
|
108226
108935
|
init_writeLock();
|
|
@@ -108404,7 +109113,7 @@ async function cloneCheckout(input) {
|
|
|
108404
109113
|
next: `Use local mode with path ${JSON.stringify(target)} after inspecting the existing checkout.`
|
|
108405
109114
|
});
|
|
108406
109115
|
}
|
|
108407
|
-
await
|
|
109116
|
+
await mkdir33(dirname42(target), { recursive: true });
|
|
108408
109117
|
const cloneArgs = ["clone", "--no-checkout", "--depth=1", "--filter=blob:none", input.remote, target];
|
|
108409
109118
|
try {
|
|
108410
109119
|
await execFileAsync6("git", cloneArgs, { encoding: "utf8", maxBuffer: 4 * 1024 * 1024 });
|
|
@@ -108450,7 +109159,7 @@ async function bindLocalAlias(input) {
|
|
|
108450
109159
|
return;
|
|
108451
109160
|
const projectRoot = await realpath8(input.projectRoot);
|
|
108452
109161
|
const alias = resolve34(projectRoot, input.declaredLocal);
|
|
108453
|
-
const stats = await
|
|
109162
|
+
const stats = await lstat11(alias).catch(() => null);
|
|
108454
109163
|
if (stats !== null) {
|
|
108455
109164
|
if (stats.isSymbolicLink()) {
|
|
108456
109165
|
const actual = resolve34(dirname42(alias), await readlink2(alias));
|
|
@@ -108469,7 +109178,7 @@ async function bindLocalAlias(input) {
|
|
|
108469
109178
|
});
|
|
108470
109179
|
}
|
|
108471
109180
|
}
|
|
108472
|
-
await
|
|
109181
|
+
await mkdir33(dirname42(alias), { recursive: true });
|
|
108473
109182
|
await symlink3(relative26(dirname42(alias), input.checkout) || ".", alias);
|
|
108474
109183
|
}
|
|
108475
109184
|
function selectPhysicalGroup(sources, selector) {
|
|
@@ -108559,11 +109268,11 @@ async function restoreRepositorySources(input) {
|
|
|
108559
109268
|
// src/project/sourceDocumentStatus.ts
|
|
108560
109269
|
init_src2();
|
|
108561
109270
|
import { existsSync as existsSync30 } from "node:fs";
|
|
108562
|
-
import { readFile as
|
|
108563
|
-
import { join as
|
|
109271
|
+
import { readFile as readFile79 } from "node:fs/promises";
|
|
109272
|
+
import { join as join101 } from "node:path";
|
|
108564
109273
|
// src/project/sourceCommandViews.ts
|
|
108565
|
-
import { readFile as
|
|
108566
|
-
import { join as
|
|
109274
|
+
import { readFile as readFile78 } from "node:fs/promises";
|
|
109275
|
+
import { join as join100 } from "node:path";
|
|
108567
109276
|
init_workspace();
|
|
108568
109277
|
init_documentBatchManifest();
|
|
108569
109278
|
function repoSourceAgentView(source2) {
|
|
@@ -108626,7 +109335,7 @@ async function fileSourceAgentViewWithNextAction(input) {
|
|
|
108626
109335
|
};
|
|
108627
109336
|
}
|
|
108628
109337
|
function documentSourceManifestPath(source2) {
|
|
108629
|
-
return source2.snapshot?.manifest ??
|
|
109338
|
+
return source2.snapshot?.manifest ?? join100(source2.materializedAt, "manifest.json");
|
|
108630
109339
|
}
|
|
108631
109340
|
async function fileSourceDocumentSiteHint(input) {
|
|
108632
109341
|
const detection = await detectDocumentSiteFiles({
|
|
@@ -108636,7 +109345,7 @@ async function fileSourceDocumentSiteHint(input) {
|
|
|
108636
109345
|
let snapshotConfigured = false;
|
|
108637
109346
|
const manifest = documentSourceManifestPath(input.source);
|
|
108638
109347
|
try {
|
|
108639
|
-
const parsed = parseDocumentSnapshotForSource(JSON.parse(await
|
|
109348
|
+
const parsed = parseDocumentSnapshotForSource(JSON.parse(await readFile78(join100(input.projectRoot, manifest), "utf8")), input.source.name);
|
|
108640
109349
|
snapshotConfigured = manifestUsesMdxJsonDocs(parsed);
|
|
108641
109350
|
} catch {
|
|
108642
109351
|
snapshotConfigured = false;
|
|
@@ -108668,11 +109377,11 @@ async function larkSourceAgentViewWithNextAction(input) {
|
|
|
108668
109377
|
// src/project/sourceDocumentStatus.ts
|
|
108669
109378
|
init_documentBatchManifest();
|
|
108670
109379
|
function documentSourceManifestPath2(source2) {
|
|
108671
|
-
return source2.snapshot?.manifest ??
|
|
109380
|
+
return source2.snapshot?.manifest ?? join101(source2.materializedAt, "manifest.json");
|
|
108672
109381
|
}
|
|
108673
109382
|
async function documentSnapshotState(input) {
|
|
108674
109383
|
const manifest = documentSourceManifestPath2(input.source);
|
|
108675
|
-
const manifestPath =
|
|
109384
|
+
const manifestPath = join101(input.projectRoot, manifest);
|
|
108676
109385
|
if (!existsSync30(manifestPath)) {
|
|
108677
109386
|
return {
|
|
108678
109387
|
snapshotReady: false,
|
|
@@ -108683,7 +109392,7 @@ async function documentSnapshotState(input) {
|
|
|
108683
109392
|
};
|
|
108684
109393
|
}
|
|
108685
109394
|
try {
|
|
108686
|
-
const parsed = findDocumentSnapshotForSource(JSON.parse(await
|
|
109395
|
+
const parsed = findDocumentSnapshotForSource(JSON.parse(await readFile79(manifestPath, "utf8")), input.source.name);
|
|
108687
109396
|
if (parsed === null) {
|
|
108688
109397
|
return {
|
|
108689
109398
|
snapshotReady: false,
|
|
@@ -108751,7 +109460,7 @@ async function documentSnapshotState(input) {
|
|
|
108751
109460
|
const missing = [
|
|
108752
109461
|
...parsed.files.map((file) => file.path),
|
|
108753
109462
|
...(parsed.assets ?? []).filter((asset) => asset.content_hash !== undefined).map((asset) => asset.path)
|
|
108754
|
-
].find((path3) => !existsSync30(
|
|
109463
|
+
].find((path3) => !existsSync30(join101(input.projectRoot, input.source.materializedAt, path3)));
|
|
108755
109464
|
if (missing !== undefined) {
|
|
108756
109465
|
return {
|
|
108757
109466
|
snapshotReady: false,
|
|
@@ -108850,10 +109559,10 @@ init_atomicWrite();
|
|
|
108850
109559
|
init_cliFeedback();
|
|
108851
109560
|
init_errors3();
|
|
108852
109561
|
init_exitCode();
|
|
108853
|
-
var
|
|
108854
|
-
import { createHash as
|
|
108855
|
-
import { readFile as
|
|
108856
|
-
import { basename as basename12, extname as extname15, isAbsolute as isAbsolute20, join as
|
|
109562
|
+
var import_yaml46 = __toESM(require_dist(), 1);
|
|
109563
|
+
import { createHash as createHash30 } from "node:crypto";
|
|
109564
|
+
import { readFile as readFile80, realpath as realpath9 } from "node:fs/promises";
|
|
109565
|
+
import { basename as basename12, extname as extname15, isAbsolute as isAbsolute20, join as join102, relative as relative27, resolve as resolve35 } from "node:path";
|
|
108857
109566
|
init_writeLock();
|
|
108858
109567
|
var SOURCE_NAME_PATTERN3 = /^[a-z0-9][a-z0-9._-]*$/u;
|
|
108859
109568
|
function isDateSourceNamespace(value) {
|
|
@@ -108882,7 +109591,7 @@ function defaultLarkModule(input) {
|
|
|
108882
109591
|
if (titleSlug.length > 0)
|
|
108883
109592
|
return titleSlug;
|
|
108884
109593
|
}
|
|
108885
|
-
const opaqueSlug = (kind, identity) => `${kind}-${
|
|
109594
|
+
const opaqueSlug = (kind, identity) => `${kind}-${createHash30("sha256").update(identity).digest("hex").slice(0, 12)}`;
|
|
108886
109595
|
if (input.url !== undefined) {
|
|
108887
109596
|
try {
|
|
108888
109597
|
const parsed = new URL(input.url);
|
|
@@ -108949,8 +109658,8 @@ function assertSafeFileInclude(value) {
|
|
|
108949
109658
|
}
|
|
108950
109659
|
async function readRegistryDocument(projectRoot, registryPath2) {
|
|
108951
109660
|
try {
|
|
108952
|
-
const content3 = await
|
|
108953
|
-
return content3.trim().length === 0 ? { sources: [] } :
|
|
109661
|
+
const content3 = await readFile80(join102(projectRoot, registryPath2), "utf8");
|
|
109662
|
+
return content3.trim().length === 0 ? { sources: [] } : import_yaml46.default.parse(content3);
|
|
108954
109663
|
} catch (error) {
|
|
108955
109664
|
if (error instanceof Error && "code" in error && error.code === "ENOENT")
|
|
108956
109665
|
return { sources: [] };
|
|
@@ -109067,7 +109776,7 @@ async function addFileSourceUnlocked(input) {
|
|
|
109067
109776
|
const record6 = entry2;
|
|
109068
109777
|
return record6.name !== input.name && record6.id !== input.name;
|
|
109069
109778
|
}), nextEntry];
|
|
109070
|
-
await atomicWriteFile(
|
|
109779
|
+
await atomicWriteFile(join102(input.projectRoot, DEFAULT_FILE_SOURCES_REGISTRY_PATH), import_yaml46.default.stringify({ sources: nextSources }));
|
|
109071
109780
|
const updated = await loadSourcesRegistry({ rootDir: input.projectRoot });
|
|
109072
109781
|
const entry = updated.files.find((source2) => source2.name === input.name || source2.id === input.name);
|
|
109073
109782
|
if (entry === undefined) {
|
|
@@ -109123,7 +109832,7 @@ async function addLarkSourceUnlocked(input) {
|
|
|
109123
109832
|
const record6 = entry2;
|
|
109124
109833
|
return record6.name !== input.name && record6.id !== input.name;
|
|
109125
109834
|
}), nextEntry];
|
|
109126
|
-
await atomicWriteFile(
|
|
109835
|
+
await atomicWriteFile(join102(input.projectRoot, DEFAULT_LARK_SOURCES_REGISTRY_PATH), import_yaml46.default.stringify({ sources: nextSources }));
|
|
109127
109836
|
const updated = await loadSourcesRegistry({ rootDir: input.projectRoot });
|
|
109128
109837
|
const entry = updated.larks.find((source2) => source2.name === input.name || source2.id === input.name);
|
|
109129
109838
|
if (entry === undefined) {
|
|
@@ -109323,11 +110032,11 @@ init_candidateLedger();
|
|
|
109323
110032
|
init_documentBatchManifest();
|
|
109324
110033
|
init_workspace();
|
|
109325
110034
|
init_writeLock();
|
|
109326
|
-
var
|
|
110035
|
+
var import_yaml47 = __toESM(require_dist(), 1);
|
|
109327
110036
|
import { existsSync as existsSync31 } from "node:fs";
|
|
109328
|
-
import { createHash as
|
|
109329
|
-
import { readFile as
|
|
109330
|
-
import { isAbsolute as isAbsolute21, join as
|
|
110037
|
+
import { createHash as createHash31 } from "node:crypto";
|
|
110038
|
+
import { readFile as readFile81, readdir as readdir24, rm as rm21 } from "node:fs/promises";
|
|
110039
|
+
import { isAbsolute as isAbsolute21, join as join103, relative as relative28, resolve as resolve36, sep as sep8 } from "node:path";
|
|
109331
110040
|
function sourceIdentity(source2) {
|
|
109332
110041
|
if (source2.kind === "source.collection")
|
|
109333
110042
|
return;
|
|
@@ -109359,10 +110068,10 @@ function collectStrings(value, output) {
|
|
|
109359
110068
|
}
|
|
109360
110069
|
}
|
|
109361
110070
|
async function yamlReferences(input) {
|
|
109362
|
-
const absolutePath =
|
|
110071
|
+
const absolutePath = join103(input.projectRoot, input.path);
|
|
109363
110072
|
if (!existsSync31(absolutePath))
|
|
109364
110073
|
return false;
|
|
109365
|
-
const parsed =
|
|
110074
|
+
const parsed = import_yaml47.default.parse(await readFile81(absolutePath, "utf8"));
|
|
109366
110075
|
const strings = [];
|
|
109367
110076
|
collectStrings(parsed, strings);
|
|
109368
110077
|
return strings.some((value) => stringReferencesSource(value, input.source));
|
|
@@ -109488,11 +110197,11 @@ async function registryRemovalWrite(projectRoot, source2) {
|
|
|
109488
110197
|
const path3 = registryPath2(source2.type);
|
|
109489
110198
|
if (path3 === null)
|
|
109490
110199
|
return;
|
|
109491
|
-
const absolutePath =
|
|
109492
|
-
const document4 = existsSync31(absolutePath) ?
|
|
110200
|
+
const absolutePath = join103(projectRoot, path3);
|
|
110201
|
+
const document4 = existsSync31(absolutePath) ? import_yaml47.default.parse(await readFile81(absolutePath, "utf8")) : { sources: [] };
|
|
109493
110202
|
return {
|
|
109494
110203
|
path: absolutePath,
|
|
109495
|
-
bytes:
|
|
110204
|
+
bytes: import_yaml47.default.stringify(removeDocumentEntry(document4, source2))
|
|
109496
110205
|
};
|
|
109497
110206
|
}
|
|
109498
110207
|
function safeManagedMaterializedPath(projectRoot, source2) {
|
|
@@ -109507,7 +110216,7 @@ function safeManagedMaterializedPath(projectRoot, source2) {
|
|
|
109507
110216
|
return absolute;
|
|
109508
110217
|
}
|
|
109509
110218
|
function safeManagedManifestPath(projectRoot, source2) {
|
|
109510
|
-
const manifest = source2.manifest ??
|
|
110219
|
+
const manifest = source2.manifest ?? join103(source2.materializedAt, "manifest.json");
|
|
109511
110220
|
if (isAbsolute21(manifest))
|
|
109512
110221
|
throw unsafeOwnership(source2, manifest);
|
|
109513
110222
|
const absolute = resolve36(projectRoot, manifest);
|
|
@@ -109542,7 +110251,7 @@ function projectRelative(projectRoot, path3) {
|
|
|
109542
110251
|
return relative28(projectRoot, path3).split(sep8).join("/");
|
|
109543
110252
|
}
|
|
109544
110253
|
function digest6(value) {
|
|
109545
|
-
return `sha256:${
|
|
110254
|
+
return `sha256:${createHash31("sha256").update(JSON.stringify(value)).digest("hex")}`;
|
|
109546
110255
|
}
|
|
109547
110256
|
async function sharedMaterializedOwners(projectRoot, source2) {
|
|
109548
110257
|
const target = safeManagedMaterializedPath(projectRoot, source2);
|
|
@@ -109636,12 +110345,12 @@ async function createRemovalPlan(projectRoot, selector) {
|
|
|
109636
110345
|
source: source2,
|
|
109637
110346
|
registry: registryPath2(source2.type),
|
|
109638
110347
|
registryBytes: registryWrite?.bytes ?? null,
|
|
109639
|
-
managedBytes: source2.type === "note" || source2.type === "sessions" ? await
|
|
110348
|
+
managedBytes: source2.type === "note" || source2.type === "sessions" ? await readFile81(absoluteRemovals[0], "utf8") : null,
|
|
109640
110349
|
references,
|
|
109641
110350
|
cleanup,
|
|
109642
110351
|
manifestBytes: manifestWrite?.bytes ?? null
|
|
109643
110352
|
});
|
|
109644
|
-
const
|
|
110353
|
+
const next2 = references.length > 0 ? `Remove all listed references, then preview context source remove '${source2.id}' --format json again.` : `context source remove '${source2.id}' --yes --plan-digest '${planDigest}' --format json`;
|
|
109645
110354
|
return {
|
|
109646
110355
|
action: "preview",
|
|
109647
110356
|
source: source2,
|
|
@@ -109650,7 +110359,7 @@ async function createRemovalPlan(projectRoot, selector) {
|
|
|
109650
110359
|
references,
|
|
109651
110360
|
plan_digest: planDigest,
|
|
109652
110361
|
cleanup,
|
|
109653
|
-
next,
|
|
110362
|
+
next: next2,
|
|
109654
110363
|
...registryWrite === undefined ? {} : { registryWrite },
|
|
109655
110364
|
...manifestWrite !== undefined ? { manifestWrite } : {},
|
|
109656
110365
|
absoluteRemovals: [...new Set(absoluteRemovals)].sort()
|
|
@@ -109669,12 +110378,12 @@ function publicRemovalResult(plan, action) {
|
|
|
109669
110378
|
};
|
|
109670
110379
|
}
|
|
109671
110380
|
async function pruneExtractRuntime(projectRoot, source2) {
|
|
109672
|
-
const fingerprintPath =
|
|
110381
|
+
const fingerprintPath = join103(projectRoot, ".tmp/context-runtime/extract/source-fingerprints.json");
|
|
109673
110382
|
const removedPhaseIds = new Set;
|
|
109674
110383
|
if (existsSync31(fingerprintPath)) {
|
|
109675
|
-
const parsed = JSON.parse(await
|
|
110384
|
+
const parsed = JSON.parse(await readFile81(fingerprintPath, "utf8"));
|
|
109676
110385
|
const phases = parsed.phases ?? {};
|
|
109677
|
-
const
|
|
110386
|
+
const next2 = Object.fromEntries(Object.entries(phases).filter(([phaseId, raw]) => {
|
|
109678
110387
|
if (raw === null || typeof raw !== "object" || Array.isArray(raw))
|
|
109679
110388
|
return true;
|
|
109680
110389
|
const sources = raw.sources;
|
|
@@ -109683,30 +110392,30 @@ async function pruneExtractRuntime(projectRoot, source2) {
|
|
|
109683
110392
|
removedPhaseIds.add(phaseId);
|
|
109684
110393
|
return keep;
|
|
109685
110394
|
}));
|
|
109686
|
-
await atomicWriteFile(fingerprintPath, `${JSON.stringify({ ...parsed, phases:
|
|
110395
|
+
await atomicWriteFile(fingerprintPath, `${JSON.stringify({ ...parsed, phases: next2 }, null, 2)}
|
|
109687
110396
|
`);
|
|
109688
110397
|
}
|
|
109689
|
-
const phaseOwnershipPath =
|
|
110398
|
+
const phaseOwnershipPath = join103(projectRoot, ".tmp/context-runtime/extract/custom-phase-candidates.json");
|
|
109690
110399
|
if (existsSync31(phaseOwnershipPath) && removedPhaseIds.size > 0) {
|
|
109691
|
-
const parsed = JSON.parse(await
|
|
110400
|
+
const parsed = JSON.parse(await readFile81(phaseOwnershipPath, "utf8"));
|
|
109692
110401
|
const phases = Object.fromEntries(Object.entries(parsed.phases ?? {}).filter(([phaseId]) => !removedPhaseIds.has(phaseId)));
|
|
109693
110402
|
await atomicWriteFile(phaseOwnershipPath, `${JSON.stringify({ ...parsed, phases }, null, 2)}
|
|
109694
110403
|
`);
|
|
109695
110404
|
}
|
|
109696
|
-
const symbolPath =
|
|
110405
|
+
const symbolPath = join103(projectRoot, ".tmp/context-runtime/extract/source-symbols.json");
|
|
109697
110406
|
if (existsSync31(symbolPath)) {
|
|
109698
|
-
const parsed = JSON.parse(await
|
|
110407
|
+
const parsed = JSON.parse(await readFile81(symbolPath, "utf8"));
|
|
109699
110408
|
const symbols = Array.isArray(parsed.symbols) ? parsed.symbols.filter((entry) => entry === null || typeof entry !== "object" || Array.isArray(entry) || entry.source !== source2.name) : [];
|
|
109700
110409
|
const phaseFingerprints = Object.fromEntries(Object.entries(parsed.phaseFingerprints ?? {}).filter(([phaseId]) => !removedPhaseIds.has(phaseId)));
|
|
109701
110410
|
await atomicWriteFile(symbolPath, `${JSON.stringify({ ...parsed, phaseFingerprints, symbols }, null, 2)}
|
|
109702
110411
|
`);
|
|
109703
110412
|
}
|
|
109704
|
-
const snapshotRoot =
|
|
110413
|
+
const snapshotRoot = join103(projectRoot, ".tmp/context-runtime/extract/candidates");
|
|
109705
110414
|
const visit4 = async (directory) => {
|
|
109706
110415
|
if (!existsSync31(directory))
|
|
109707
110416
|
return;
|
|
109708
|
-
for (const entry of await
|
|
109709
|
-
const path3 =
|
|
110417
|
+
for (const entry of await readdir24(directory, { withFileTypes: true })) {
|
|
110418
|
+
const path3 = join103(directory, entry.name);
|
|
109710
110419
|
if (entry.isDirectory()) {
|
|
109711
110420
|
await visit4(path3);
|
|
109712
110421
|
continue;
|
|
@@ -109714,7 +110423,7 @@ async function pruneExtractRuntime(projectRoot, source2) {
|
|
|
109714
110423
|
if (!entry.isFile() || !entry.name.endsWith(".json"))
|
|
109715
110424
|
continue;
|
|
109716
110425
|
try {
|
|
109717
|
-
const parsed = JSON.parse(await
|
|
110426
|
+
const parsed = JSON.parse(await readFile81(path3, "utf8"));
|
|
109718
110427
|
const refs = Array.isArray(parsed.source_refs) ? parsed.source_refs : [];
|
|
109719
110428
|
if (parsed.source === source2.name || refs.some((ref2) => typeof ref2 === "string" && stringReferencesSource(ref2, source2))) {
|
|
109720
110429
|
await rm21(path3, { force: true });
|
|
@@ -109756,7 +110465,7 @@ async function removeProjectSource(input) {
|
|
|
109756
110465
|
});
|
|
109757
110466
|
}
|
|
109758
110467
|
await applyAtomicFileBatch({
|
|
109759
|
-
transactionRoot:
|
|
110468
|
+
transactionRoot: join103(input.projectRoot, ".tmp", "context-runtime", "source-remove-transactions"),
|
|
109760
110469
|
writes: [...plan.registryWrite === undefined ? [] : [plan.registryWrite], ...plan.manifestWrite !== undefined ? [plan.manifestWrite] : []],
|
|
109761
110470
|
removals: plan.absoluteRemovals
|
|
109762
110471
|
});
|
|
@@ -109772,11 +110481,11 @@ init_workspace();
|
|
|
109772
110481
|
init_writeLock();
|
|
109773
110482
|
init_durableMultiFileTransaction();
|
|
109774
110483
|
init_durableSingleFileTransaction();
|
|
109775
|
-
import { readFile as
|
|
110484
|
+
import { readFile as readFile82 } from "node:fs/promises";
|
|
109776
110485
|
import ts from "typescript";
|
|
109777
|
-
function generateSourceConfiguration(
|
|
109778
|
-
const file = ts.createSourceFile("index.ts",
|
|
109779
|
-
if (ts.transpileModule(
|
|
110486
|
+
function generateSourceConfiguration(text10, selected) {
|
|
110487
|
+
const file = ts.createSourceFile("index.ts", text10, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
110488
|
+
if (ts.transpileModule(text10, { reportDiagnostics: true }).diagnostics?.some((item) => item.category === ts.DiagnosticCategory.Error))
|
|
109780
110489
|
return;
|
|
109781
110490
|
const imports = file.statements.filter(ts.isImportDeclaration).filter((node3) => ts.isStringLiteral(node3.moduleSpecifier) && node3.moduleSpecifier.text === "@c4a/context");
|
|
109782
110491
|
if (imports.length !== 1)
|
|
@@ -109887,7 +110596,7 @@ function generateSourceConfiguration(text9, selected) {
|
|
|
109887
110596
|
}
|
|
109888
110597
|
}
|
|
109889
110598
|
if (!additions.length && !captures.length)
|
|
109890
|
-
return
|
|
110599
|
+
return text10;
|
|
109891
110600
|
const identifiers = new Set;
|
|
109892
110601
|
const visit4 = (node3) => {
|
|
109893
110602
|
if (ts.isIdentifier(node3))
|
|
@@ -109907,12 +110616,12 @@ function generateSourceConfiguration(text9, selected) {
|
|
|
109907
110616
|
}
|
|
109908
110617
|
if (needed.size)
|
|
109909
110618
|
edits.push({ start: bindings.getStart(file) + 1, end: bindings.getStart(file) + 1, value: ` ${[...needed].join(", ")},` });
|
|
109910
|
-
return edits.sort((a, b) => b.start - a.start).reduce((result, edit) => result.slice(0, edit.start) + edit.value + result.slice(edit.end),
|
|
110619
|
+
return edits.sort((a, b) => b.start - a.start).reduce((result, edit) => result.slice(0, edit.start) + edit.value + result.slice(edit.end), text10);
|
|
109911
110620
|
}
|
|
109912
110621
|
async function configureRegisteredSources(projectRoot, selected) {
|
|
109913
110622
|
return withProjectWriteLock(projectRoot, "source-project-configuration", async () => {
|
|
109914
110623
|
const path3 = "src/index.ts";
|
|
109915
|
-
const config = JSON.parse(await
|
|
110624
|
+
const config = JSON.parse(await readFile82(await safeProjectTarget(projectRoot, "package.json"), "utf8"));
|
|
109916
110625
|
if (config.context?.entry !== path3)
|
|
109917
110626
|
return {
|
|
109918
110627
|
status: "manual",
|
|
@@ -109921,8 +110630,8 @@ async function configureRegisteredSources(projectRoot, selected) {
|
|
|
109921
110630
|
sources: selected
|
|
109922
110631
|
};
|
|
109923
110632
|
const target = await safeProjectTarget(projectRoot, path3);
|
|
109924
|
-
const
|
|
109925
|
-
const updated = generateSourceConfiguration(
|
|
110633
|
+
const text10 = await readFile82(target, "utf8");
|
|
110634
|
+
const updated = generateSourceConfiguration(text10, selected);
|
|
109926
110635
|
if (updated === undefined)
|
|
109927
110636
|
return {
|
|
109928
110637
|
status: "manual",
|
|
@@ -109930,15 +110639,15 @@ async function configureRegisteredSources(projectRoot, selected) {
|
|
|
109930
110639
|
message: "Registration is saved. Preserve the custom project entry and configure only these sources manually.",
|
|
109931
110640
|
sources: selected
|
|
109932
110641
|
};
|
|
109933
|
-
if (updated !==
|
|
110642
|
+
if (updated !== text10)
|
|
109934
110643
|
await runDurableSingleFileTransaction({
|
|
109935
110644
|
projectRoot,
|
|
109936
110645
|
kind: "source-project-configuration",
|
|
109937
110646
|
target_path: path3,
|
|
109938
|
-
expected_base_digest: durableContentDigest(
|
|
110647
|
+
expected_base_digest: durableContentDigest(text10),
|
|
109939
110648
|
target_content: updated
|
|
109940
110649
|
});
|
|
109941
|
-
return { status: updated ===
|
|
110650
|
+
return { status: updated === text10 ? "unchanged" : "configured", file: path3 };
|
|
109942
110651
|
});
|
|
109943
110652
|
}
|
|
109944
110653
|
|
|
@@ -110001,7 +110710,7 @@ async function readIncludeList(projectRoot, path3) {
|
|
|
110001
110710
|
}
|
|
110002
110711
|
let content3;
|
|
110003
110712
|
try {
|
|
110004
|
-
content3 = await
|
|
110713
|
+
content3 = await readFile86(isAbsolute22(trimmed) ? resolve37(trimmed) : resolve37(projectRoot, trimmed), "utf8");
|
|
110005
110714
|
} catch (error) {
|
|
110006
110715
|
throw new ContextError(ExitCode.UserError, `cannot read include list: ${trimmed}`, {
|
|
110007
110716
|
category: ErrorCategory.UserInputInvalid,
|
|
@@ -110042,7 +110751,7 @@ function rowsFromValue(value) {
|
|
|
110042
110751
|
return value.map((item) => item && typeof item === "object" && !Array.isArray(item) ? item : { value: item });
|
|
110043
110752
|
}
|
|
110044
110753
|
if (value && typeof value === "object") {
|
|
110045
|
-
return Object.entries(value).map(([key,
|
|
110754
|
+
return Object.entries(value).map(([key, next2]) => ({ key, value: next2 }));
|
|
110046
110755
|
}
|
|
110047
110756
|
return [{ value }];
|
|
110048
110757
|
}
|
|
@@ -110069,7 +110778,7 @@ function writeFormatted(value, format2) {
|
|
|
110069
110778
|
return;
|
|
110070
110779
|
}
|
|
110071
110780
|
if (format2 === "yaml") {
|
|
110072
|
-
process.stdout.write(
|
|
110781
|
+
process.stdout.write(import_yaml49.default.stringify(value));
|
|
110073
110782
|
return;
|
|
110074
110783
|
}
|
|
110075
110784
|
process.stdout.write(renderTable2(value));
|
|
@@ -110390,16 +111099,16 @@ report shown above. A direct maintenance call outside that Route may omit it.
|
|
|
110390
111099
|
init_cliFeedback();
|
|
110391
111100
|
init_errors3();
|
|
110392
111101
|
init_exitCode();
|
|
110393
|
-
var
|
|
111102
|
+
var import_yaml51 = __toESM(require_dist(), 1);
|
|
110394
111103
|
|
|
110395
111104
|
// src/project/productionSkillCatalog.ts
|
|
110396
111105
|
init_errors3();
|
|
110397
111106
|
init_cliFeedback();
|
|
110398
111107
|
init_exitCode();
|
|
110399
|
-
var
|
|
111108
|
+
var import_yaml50 = __toESM(require_dist(), 1);
|
|
110400
111109
|
import { constants as constants6, existsSync as existsSync32 } from "node:fs";
|
|
110401
|
-
import { lstat as
|
|
110402
|
-
import { dirname as dirname43, join as
|
|
111110
|
+
import { lstat as lstat12, open as open5, readdir as readdir25 } from "node:fs/promises";
|
|
111111
|
+
import { dirname as dirname43, join as join105, resolve as resolve38 } from "node:path";
|
|
110403
111112
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
110404
111113
|
function bundledSkillRoot() {
|
|
110405
111114
|
const directory = dirname43(fileURLToPath8(import.meta.url));
|
|
@@ -110426,11 +111135,11 @@ async function listProductionSkills(root2) {
|
|
|
110426
111135
|
}
|
|
110427
111136
|
}
|
|
110428
111137
|
async function readProductionSkills(root2) {
|
|
110429
|
-
const entries2 = (await
|
|
111138
|
+
const entries2 = (await readdir25(root2, { withFileTypes: true })).filter((entry) => entry.isDirectory()).sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
110430
111139
|
const skills = [];
|
|
110431
111140
|
for (const directory of entries2) {
|
|
110432
|
-
const entry =
|
|
110433
|
-
if (!(await
|
|
111141
|
+
const entry = join105(root2, directory.name, "SKILL.md");
|
|
111142
|
+
if (!(await lstat12(entry)).isFile())
|
|
110434
111143
|
throw new TypeError(`Skill entry must be a regular file: ${entry}`);
|
|
110435
111144
|
const handle2 = await open5(entry, constants6.O_RDONLY | constants6.O_NOFOLLOW | constants6.O_NONBLOCK);
|
|
110436
111145
|
let header;
|
|
@@ -110446,7 +111155,7 @@ async function readProductionSkills(root2) {
|
|
|
110446
111155
|
const frontmatter2 = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/u.exec(header);
|
|
110447
111156
|
if (!frontmatter2)
|
|
110448
111157
|
throw new TypeError(`Skill entry needs complete frontmatter within 64 KiB: ${entry}`);
|
|
110449
|
-
const value =
|
|
111158
|
+
const value = import_yaml50.default.parse(frontmatter2[1], { uniqueKeys: true });
|
|
110450
111159
|
if (!value || typeof value !== "object" || !("name" in value) || typeof value.name !== "string" || !value.name.trim() || !("description" in value) || typeof value.description !== "string" || !value.description.trim()) {
|
|
110451
111160
|
throw new TypeError(`Skill entry needs a name and description: ${entry}`);
|
|
110452
111161
|
}
|
|
@@ -110509,7 +111218,7 @@ function outputFormat2(options) {
|
|
|
110509
111218
|
}
|
|
110510
111219
|
function writeOutput(value, format2) {
|
|
110511
111220
|
process.stdout.write(format2 === "json" ? `${JSON.stringify(value, null, 2)}
|
|
110512
|
-
` :
|
|
111221
|
+
` : import_yaml51.default.stringify(value));
|
|
110513
111222
|
}
|
|
110514
111223
|
function registerProjectIndexerCommands(program2) {
|
|
110515
111224
|
const indexer = program2.command("indexer").description("Discover bundled skills or inspect a benchmark result");
|
|
@@ -110593,7 +111302,7 @@ function initCommand2(input, projectDir) {
|
|
|
110593
111302
|
return args.map(shellQuote7).join(" ");
|
|
110594
111303
|
}
|
|
110595
111304
|
function readyResult(input, projectRoot, relocation) {
|
|
110596
|
-
const
|
|
111305
|
+
const command3 = workflowCommand(input);
|
|
110597
111306
|
return {
|
|
110598
111307
|
schema: "context.entry.v1",
|
|
110599
111308
|
guidance: {
|
|
@@ -110610,7 +111319,7 @@ function readyResult(input, projectRoot, relocation) {
|
|
|
110610
111319
|
},
|
|
110611
111320
|
next_action: {
|
|
110612
111321
|
kind: relocation ? "enter-workspace" : "evaluate-workflow",
|
|
110613
|
-
command: relocation ? `cd ${shellQuote7(projectRoot)} && ${
|
|
111322
|
+
command: relocation ? `cd ${shellQuote7(projectRoot)} && ${command3}` : command3,
|
|
110614
111323
|
effect: "read",
|
|
110615
111324
|
confirmation: "not-required"
|
|
110616
111325
|
}
|
|
@@ -110837,7 +111546,7 @@ init_cliFeedback();
|
|
|
110837
111546
|
init_errors3();
|
|
110838
111547
|
init_exitCode();
|
|
110839
111548
|
import { existsSync as existsSync35 } from "node:fs";
|
|
110840
|
-
import { dirname as dirname46, join as
|
|
111549
|
+
import { dirname as dirname46, join as join107, resolve as resolve40 } from "node:path";
|
|
110841
111550
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
110842
111551
|
|
|
110843
111552
|
// src/project/pluginInstallTargets.ts
|
|
@@ -110846,9 +111555,9 @@ init_errors3();
|
|
|
110846
111555
|
init_exitCode();
|
|
110847
111556
|
import { execFile as execFile11 } from "node:child_process";
|
|
110848
111557
|
import { existsSync as existsSync34 } from "node:fs";
|
|
110849
|
-
import { cp as cp2, mkdir as
|
|
111558
|
+
import { cp as cp2, mkdir as mkdir34, readdir as readdir26, readFile as readFile87, rename as rename8, rm as rm22, writeFile as writeFile25 } from "node:fs/promises";
|
|
110850
111559
|
import { homedir as homedir2 } from "node:os";
|
|
110851
|
-
import { dirname as dirname45, join as
|
|
111560
|
+
import { dirname as dirname45, join as join106 } from "node:path";
|
|
110852
111561
|
import { promisify as promisify11 } from "node:util";
|
|
110853
111562
|
var execFileAsync7 = promisify11(execFile11);
|
|
110854
111563
|
var MARKETPLACE_NAME = "c4a";
|
|
@@ -110864,31 +111573,31 @@ var CURSOR_PLUGIN_ROOT_ENV = "CONTEXT_CURSOR_PLUGIN_ROOT";
|
|
|
110864
111573
|
function shellQuote8(value) {
|
|
110865
111574
|
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
110866
111575
|
}
|
|
110867
|
-
function commandLine(
|
|
110868
|
-
return [
|
|
111576
|
+
function commandLine(command3, args) {
|
|
111577
|
+
return [command3, ...args.map((arg) => shellQuote8(arg))].join(" ");
|
|
110869
111578
|
}
|
|
110870
|
-
async function runExternal(
|
|
111579
|
+
async function runExternal(command3, args) {
|
|
110871
111580
|
try {
|
|
110872
|
-
await execFileAsync7(
|
|
111581
|
+
await execFileAsync7(command3, args, {
|
|
110873
111582
|
maxBuffer: 1024 * 1024
|
|
110874
111583
|
});
|
|
110875
111584
|
} catch (error) {
|
|
110876
111585
|
const message = error instanceof Error ? error.message : String(error);
|
|
110877
|
-
throw new ContextError(ExitCode.ExternalToolError, `${commandLine(
|
|
111586
|
+
throw new ContextError(ExitCode.ExternalToolError, `${commandLine(command3, args)} failed: ${message}`, {
|
|
110878
111587
|
category: ErrorCategory.ExternalToolFailed
|
|
110879
111588
|
});
|
|
110880
111589
|
}
|
|
110881
111590
|
}
|
|
110882
|
-
async function runExternalOptional(
|
|
111591
|
+
async function runExternalOptional(command3, args) {
|
|
110883
111592
|
try {
|
|
110884
|
-
await runExternal(
|
|
111593
|
+
await runExternal(command3, args);
|
|
110885
111594
|
return true;
|
|
110886
111595
|
} catch {
|
|
110887
111596
|
return false;
|
|
110888
111597
|
}
|
|
110889
111598
|
}
|
|
110890
|
-
async function commandAvailable(
|
|
110891
|
-
return runExternalOptional("sh", ["-lc", `command -v ${
|
|
111599
|
+
async function commandAvailable(command3) {
|
|
111600
|
+
return runExternalOptional("sh", ["-lc", `command -v ${command3} >/dev/null 2>&1`]);
|
|
110892
111601
|
}
|
|
110893
111602
|
async function claudePluginInstalled(pluginId) {
|
|
110894
111603
|
try {
|
|
@@ -110902,23 +111611,23 @@ async function claudePluginInstalled(pluginId) {
|
|
|
110902
111611
|
}
|
|
110903
111612
|
}
|
|
110904
111613
|
function codexHome() {
|
|
110905
|
-
return process.env.CODEX_HOME?.trim() ||
|
|
111614
|
+
return process.env.CODEX_HOME?.trim() || join106(homedir2(), ".codex");
|
|
110906
111615
|
}
|
|
110907
111616
|
function claudePluginCacheRoot() {
|
|
110908
111617
|
const explicitRoot = process.env[CLAUDE_PLUGIN_CACHE_ROOT_ENV2]?.trim();
|
|
110909
111618
|
if (explicitRoot)
|
|
110910
111619
|
return explicitRoot;
|
|
110911
111620
|
const home = process.env[CLAUDE_PLUGIN_CACHE_HOME_ENV2]?.trim() || homedir2();
|
|
110912
|
-
return
|
|
111621
|
+
return join106(home, ".claude", "plugins", "cache");
|
|
110913
111622
|
}
|
|
110914
111623
|
function sharedSkillsRoot() {
|
|
110915
|
-
return process.env[SHARED_SKILLS_ROOT_ENV]?.trim() ||
|
|
111624
|
+
return process.env[SHARED_SKILLS_ROOT_ENV]?.trim() || join106(homedir2(), ".agents", "skills");
|
|
110916
111625
|
}
|
|
110917
111626
|
function claudeSkillsRoot() {
|
|
110918
|
-
return process.env[CLAUDE_SKILLS_ROOT_ENV]?.trim() ||
|
|
111627
|
+
return process.env[CLAUDE_SKILLS_ROOT_ENV]?.trim() || join106(homedir2(), ".claude", "skills");
|
|
110919
111628
|
}
|
|
110920
111629
|
function cursorPluginRoot() {
|
|
110921
|
-
return process.env[CURSOR_PLUGIN_ROOT_ENV]?.trim() ||
|
|
111630
|
+
return process.env[CURSOR_PLUGIN_ROOT_ENV]?.trim() || join106(homedir2(), ".cursor", "plugins", "local", PLUGIN_NAME);
|
|
110922
111631
|
}
|
|
110923
111632
|
function blockHeader(line) {
|
|
110924
111633
|
const match = line.match(/^\s*\[([^\]]+)\]\s*$/u);
|
|
@@ -110929,9 +111638,9 @@ function isStaleMarketplaceBlock(header, block) {
|
|
|
110929
111638
|
return true;
|
|
110930
111639
|
if (header !== `marketplaces.${MARKETPLACE_NAME}`)
|
|
110931
111640
|
return false;
|
|
110932
|
-
const
|
|
111641
|
+
const text10 = block.join(`
|
|
110933
111642
|
`);
|
|
110934
|
-
return
|
|
111643
|
+
return text10.includes('source_type = "local"') || text10.includes("/c4a-plugins") || text10.includes("context4ai/context");
|
|
110935
111644
|
}
|
|
110936
111645
|
function isStalePluginBlock(header) {
|
|
110937
111646
|
return header === `plugins."context@context"` || header === `plugins."context@c4a"` || header === "plugins.context";
|
|
@@ -110969,27 +111678,27 @@ function pruneLegacyCodexConfigContent(content3) {
|
|
|
110969
111678
|
`), removed };
|
|
110970
111679
|
}
|
|
110971
111680
|
async function pruneLegacyCodexConfig(dryRun, steps) {
|
|
110972
|
-
const configPath =
|
|
110973
|
-
const current2 = await
|
|
111681
|
+
const configPath = join106(codexHome(), "config.toml");
|
|
111682
|
+
const current2 = await readFile87(configPath, "utf8").catch(() => "");
|
|
110974
111683
|
if (!current2)
|
|
110975
111684
|
return;
|
|
110976
|
-
const
|
|
110977
|
-
if (
|
|
111685
|
+
const next2 = pruneLegacyCodexConfigContent(current2);
|
|
111686
|
+
if (next2.removed.length === 0)
|
|
110978
111687
|
return;
|
|
110979
111688
|
steps.push({
|
|
110980
111689
|
agent: "codex",
|
|
110981
|
-
command: `prune stale Codex config blocks: ${
|
|
111690
|
+
command: `prune stale Codex config blocks: ${next2.removed.join(", ")}`,
|
|
110982
111691
|
status: dryRun ? "planned" : "ran"
|
|
110983
111692
|
});
|
|
110984
111693
|
if (!dryRun) {
|
|
110985
|
-
await writeFile25(configPath,
|
|
111694
|
+
await writeFile25(configPath, next2.content, "utf8");
|
|
110986
111695
|
}
|
|
110987
111696
|
}
|
|
110988
111697
|
async function pruneCodexPluginCacheForName(pluginName, keepVersion, dryRun, steps) {
|
|
110989
|
-
const cacheRoot =
|
|
111698
|
+
const cacheRoot = join106(codexHome(), "plugins", "cache", MARKETPLACE_NAME, pluginName);
|
|
110990
111699
|
if (!existsSync34(cacheRoot))
|
|
110991
111700
|
return;
|
|
110992
|
-
const versions = (await
|
|
111701
|
+
const versions = (await readdir26(cacheRoot, { withFileTypes: true }).catch(() => [])).filter((entry) => entry.isDirectory() && entry.name !== keepVersion).map((entry) => entry.name).sort();
|
|
110993
111702
|
if (versions.length === 0)
|
|
110994
111703
|
return;
|
|
110995
111704
|
steps.push({
|
|
@@ -110998,7 +111707,7 @@ async function pruneCodexPluginCacheForName(pluginName, keepVersion, dryRun, ste
|
|
|
110998
111707
|
status: dryRun ? "planned" : "ran"
|
|
110999
111708
|
});
|
|
111000
111709
|
if (!dryRun)
|
|
111001
|
-
await Promise.all(versions.map((version3) => rm22(
|
|
111710
|
+
await Promise.all(versions.map((version3) => rm22(join106(cacheRoot, version3), { recursive: true, force: true })));
|
|
111002
111711
|
}
|
|
111003
111712
|
async function pruneCodexPluginCache(currentVersion, dryRun, steps) {
|
|
111004
111713
|
await pruneCodexPluginCacheForName(PLUGIN_NAME, currentVersion, dryRun, steps);
|
|
@@ -111008,7 +111717,7 @@ async function pruneCodexPluginCache(currentVersion, dryRun, steps) {
|
|
|
111008
111717
|
}
|
|
111009
111718
|
async function isEmptyDir2(dir) {
|
|
111010
111719
|
try {
|
|
111011
|
-
return (await
|
|
111720
|
+
return (await readdir26(dir)).length === 0;
|
|
111012
111721
|
} catch {
|
|
111013
111722
|
return false;
|
|
111014
111723
|
}
|
|
@@ -111018,19 +111727,19 @@ async function pruneClaudeOrphanContextCache(dryRun, steps) {
|
|
|
111018
111727
|
if (!existsSync34(cacheRoot))
|
|
111019
111728
|
return;
|
|
111020
111729
|
const removed = [];
|
|
111021
|
-
const marketplaces = await
|
|
111730
|
+
const marketplaces = await readdir26(cacheRoot, { withFileTypes: true }).catch(() => []);
|
|
111022
111731
|
for (const marketplace of marketplaces) {
|
|
111023
111732
|
if (!marketplace.isDirectory())
|
|
111024
111733
|
continue;
|
|
111025
|
-
const pluginDir =
|
|
111734
|
+
const pluginDir = join106(cacheRoot, marketplace.name, PLUGIN_NAME);
|
|
111026
111735
|
if (!existsSync34(pluginDir))
|
|
111027
111736
|
continue;
|
|
111028
|
-
const versions = await
|
|
111737
|
+
const versions = await readdir26(pluginDir, { withFileTypes: true }).catch(() => []);
|
|
111029
111738
|
for (const version3 of versions) {
|
|
111030
111739
|
if (!version3.isDirectory())
|
|
111031
111740
|
continue;
|
|
111032
|
-
const versionDir =
|
|
111033
|
-
if (!existsSync34(
|
|
111741
|
+
const versionDir = join106(pluginDir, version3.name);
|
|
111742
|
+
if (!existsSync34(join106(versionDir, ORPHAN_MARKER2)))
|
|
111034
111743
|
continue;
|
|
111035
111744
|
removed.push(`${marketplace.name}/${PLUGIN_NAME}/${version3.name}`);
|
|
111036
111745
|
if (!dryRun) {
|
|
@@ -111040,7 +111749,7 @@ async function pruneClaudeOrphanContextCache(dryRun, steps) {
|
|
|
111040
111749
|
if (!dryRun && await isEmptyDir2(pluginDir)) {
|
|
111041
111750
|
await rm22(pluginDir, { recursive: true, force: true });
|
|
111042
111751
|
}
|
|
111043
|
-
const marketplaceDir =
|
|
111752
|
+
const marketplaceDir = join106(cacheRoot, marketplace.name);
|
|
111044
111753
|
if (!dryRun && await isEmptyDir2(marketplaceDir)) {
|
|
111045
111754
|
await rm22(marketplaceDir, { recursive: true, force: true });
|
|
111046
111755
|
}
|
|
@@ -111061,7 +111770,7 @@ async function pruneClaudeLegacyPluginCache(dryRun, steps) {
|
|
|
111061
111770
|
return;
|
|
111062
111771
|
const removed = [];
|
|
111063
111772
|
for (const pluginName of LEGACY_PLUGIN_NAMES) {
|
|
111064
|
-
const pluginDir =
|
|
111773
|
+
const pluginDir = join106(cacheRoot, MARKETPLACE_NAME, pluginName);
|
|
111065
111774
|
if (!existsSync34(pluginDir))
|
|
111066
111775
|
continue;
|
|
111067
111776
|
removed.push(`${MARKETPLACE_NAME}/${pluginName}`);
|
|
@@ -111078,12 +111787,12 @@ async function pruneClaudeLegacyPluginCache(dryRun, steps) {
|
|
|
111078
111787
|
}
|
|
111079
111788
|
}
|
|
111080
111789
|
async function pruneClaudeSupersededContextCache(root2, dryRun, steps) {
|
|
111081
|
-
const manifest = await
|
|
111790
|
+
const manifest = await readFile87(join106(root2, "claude", ".claude-plugin", "plugin.json"), "utf8").then((content3) => JSON.parse(content3)).catch(() => null);
|
|
111082
111791
|
const currentVersion = typeof manifest?.version === "string" ? manifest.version : null;
|
|
111083
111792
|
if (!currentVersion)
|
|
111084
111793
|
return;
|
|
111085
|
-
const pluginDir =
|
|
111086
|
-
const staleVersions = (await
|
|
111794
|
+
const pluginDir = join106(claudePluginCacheRoot(), MARKETPLACE_NAME, PLUGIN_NAME);
|
|
111795
|
+
const staleVersions = (await readdir26(pluginDir, { withFileTypes: true }).catch(() => [])).filter((entry) => entry.isDirectory() && entry.name !== currentVersion).map((entry) => entry.name);
|
|
111087
111796
|
if (staleVersions.length === 0)
|
|
111088
111797
|
return;
|
|
111089
111798
|
steps.push({
|
|
@@ -111092,7 +111801,7 @@ async function pruneClaudeSupersededContextCache(root2, dryRun, steps) {
|
|
|
111092
111801
|
status: dryRun ? "planned" : "ran"
|
|
111093
111802
|
});
|
|
111094
111803
|
if (!dryRun) {
|
|
111095
|
-
await Promise.all(staleVersions.map((version3) => rm22(
|
|
111804
|
+
await Promise.all(staleVersions.map((version3) => rm22(join106(pluginDir, version3), { recursive: true, force: true })));
|
|
111096
111805
|
}
|
|
111097
111806
|
}
|
|
111098
111807
|
function enableCodexPluginConfig(content3) {
|
|
@@ -111156,36 +111865,36 @@ source = ${JSON.stringify(root2)}
|
|
|
111156
111865
|
`;
|
|
111157
111866
|
}
|
|
111158
111867
|
async function ensureCodexPluginEnabled() {
|
|
111159
|
-
const configPath =
|
|
111160
|
-
await
|
|
111161
|
-
const current2 = await
|
|
111162
|
-
const
|
|
111163
|
-
if (
|
|
111164
|
-
await writeFile25(configPath,
|
|
111868
|
+
const configPath = join106(codexHome(), "config.toml");
|
|
111869
|
+
await mkdir34(dirname45(configPath), { recursive: true });
|
|
111870
|
+
const current2 = await readFile87(configPath, "utf8").catch(() => "");
|
|
111871
|
+
const next2 = enableCodexPluginConfig(current2);
|
|
111872
|
+
if (next2 !== current2) {
|
|
111873
|
+
await writeFile25(configPath, next2, "utf8");
|
|
111165
111874
|
}
|
|
111166
111875
|
}
|
|
111167
111876
|
async function ensureCodexLocalMarketplace(root2) {
|
|
111168
|
-
const configPath =
|
|
111169
|
-
await
|
|
111170
|
-
const current2 = await
|
|
111171
|
-
const
|
|
111172
|
-
if (
|
|
111173
|
-
await writeFile25(configPath,
|
|
111877
|
+
const configPath = join106(codexHome(), "config.toml");
|
|
111878
|
+
await mkdir34(dirname45(configPath), { recursive: true });
|
|
111879
|
+
const current2 = await readFile87(configPath, "utf8").catch(() => "");
|
|
111880
|
+
const next2 = upsertCodexLocalMarketplaceConfig(current2, root2);
|
|
111881
|
+
if (next2 !== current2) {
|
|
111882
|
+
await writeFile25(configPath, next2, "utf8");
|
|
111174
111883
|
}
|
|
111175
111884
|
}
|
|
111176
111885
|
async function codexPluginVersion(root2) {
|
|
111177
|
-
const manifestPath =
|
|
111178
|
-
const manifest = JSON.parse(await
|
|
111886
|
+
const manifestPath = join106(root2, "codex", ".codex-plugin", "plugin.json");
|
|
111887
|
+
const manifest = JSON.parse(await readFile87(manifestPath, "utf8"));
|
|
111179
111888
|
if (typeof manifest.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/u.test(manifest.version)) {
|
|
111180
111889
|
throw new Error(`Codex plugin manifest has an invalid version: ${manifestPath}`);
|
|
111181
111890
|
}
|
|
111182
111891
|
return manifest.version;
|
|
111183
111892
|
}
|
|
111184
111893
|
function codexPluginCacheDir(version3) {
|
|
111185
|
-
return
|
|
111894
|
+
return join106(codexHome(), "plugins", "cache", MARKETPLACE_NAME, PLUGIN_NAME, version3);
|
|
111186
111895
|
}
|
|
111187
111896
|
async function replaceDirectoryFromSource(source2, target) {
|
|
111188
|
-
await
|
|
111897
|
+
await mkdir34(dirname45(target), { recursive: true });
|
|
111189
111898
|
const temporary = `${target}.tmp-${process.pid}-${Date.now()}`;
|
|
111190
111899
|
const previous3 = `${target}.previous-${process.pid}-${Date.now()}`;
|
|
111191
111900
|
await rm22(temporary, { recursive: true, force: true });
|
|
@@ -111193,19 +111902,19 @@ async function replaceDirectoryFromSource(source2, target) {
|
|
|
111193
111902
|
const hadPrevious = existsSync34(target);
|
|
111194
111903
|
try {
|
|
111195
111904
|
if (hadPrevious)
|
|
111196
|
-
await
|
|
111197
|
-
await
|
|
111905
|
+
await rename8(target, previous3);
|
|
111906
|
+
await rename8(temporary, target);
|
|
111198
111907
|
if (hadPrevious)
|
|
111199
111908
|
await rm22(previous3, { recursive: true, force: true });
|
|
111200
111909
|
} catch (error) {
|
|
111201
111910
|
await rm22(temporary, { recursive: true, force: true });
|
|
111202
111911
|
if (hadPrevious && !existsSync34(target) && existsSync34(previous3))
|
|
111203
|
-
await
|
|
111912
|
+
await rename8(previous3, target);
|
|
111204
111913
|
throw error;
|
|
111205
111914
|
}
|
|
111206
111915
|
}
|
|
111207
111916
|
async function materializeCodexPluginCache(root2, version3, dryRun, steps) {
|
|
111208
|
-
const source2 =
|
|
111917
|
+
const source2 = join106(root2, "codex");
|
|
111209
111918
|
const target = codexPluginCacheDir(version3);
|
|
111210
111919
|
steps.push({
|
|
111211
111920
|
agent: "codex",
|
|
@@ -111217,16 +111926,16 @@ async function materializeCodexPluginCache(root2, version3, dryRun, steps) {
|
|
|
111217
111926
|
await replaceDirectoryFromSource(source2, target);
|
|
111218
111927
|
}
|
|
111219
111928
|
async function bundledProviderSkillNames(root2) {
|
|
111220
|
-
const skillsRoot =
|
|
111221
|
-
const entries2 = await
|
|
111929
|
+
const skillsRoot = join106(root2, "skills");
|
|
111930
|
+
const entries2 = await readdir26(skillsRoot, { withFileTypes: true });
|
|
111222
111931
|
const names = [];
|
|
111223
111932
|
for (const entry of entries2) {
|
|
111224
111933
|
if (!entry.isDirectory() || entry.name === "context")
|
|
111225
111934
|
continue;
|
|
111226
|
-
const skillPath =
|
|
111935
|
+
const skillPath = join106(skillsRoot, entry.name, "SKILL.md");
|
|
111227
111936
|
if (!existsSync34(skillPath))
|
|
111228
111937
|
continue;
|
|
111229
|
-
const skill = await
|
|
111938
|
+
const skill = await readFile87(skillPath, "utf8");
|
|
111230
111939
|
if (!/^\s*context-role:\s*["']?indexer-provider["']?\s*$/mu.test(skill))
|
|
111231
111940
|
continue;
|
|
111232
111941
|
names.push(entry.name);
|
|
@@ -111238,10 +111947,10 @@ async function bundledProviderSkillNames(root2) {
|
|
|
111238
111947
|
return names;
|
|
111239
111948
|
}
|
|
111240
111949
|
async function materializeProviderSkills(root2, targetRoot, agent, dryRun, steps) {
|
|
111241
|
-
const sourceRoot2 =
|
|
111950
|
+
const sourceRoot2 = join106(root2, "skills");
|
|
111242
111951
|
for (const name3 of await bundledProviderSkillNames(root2)) {
|
|
111243
|
-
const source2 =
|
|
111244
|
-
const target =
|
|
111952
|
+
const source2 = join106(sourceRoot2, name3);
|
|
111953
|
+
const target = join106(targetRoot, name3);
|
|
111245
111954
|
steps.push({
|
|
111246
111955
|
agent,
|
|
111247
111956
|
command: `materialize lifecycle Provider skill: ${shellQuote8(source2)} -> ${shellQuote8(target)}`,
|
|
@@ -111252,7 +111961,7 @@ async function materializeProviderSkills(root2, targetRoot, agent, dryRun, steps
|
|
|
111252
111961
|
}
|
|
111253
111962
|
}
|
|
111254
111963
|
async function installCursor(root2, dryRun, steps) {
|
|
111255
|
-
const source2 =
|
|
111964
|
+
const source2 = join106(root2, "cursor");
|
|
111256
111965
|
const target = cursorPluginRoot();
|
|
111257
111966
|
steps.push({
|
|
111258
111967
|
agent: "cursor",
|
|
@@ -111307,12 +112016,12 @@ async function installCodex(root2, dryRun, steps) {
|
|
|
111307
112016
|
steps.push({ agent: "codex", command: commandLine("codex", addArgs), status: dryRun ? "planned" : "ran" });
|
|
111308
112017
|
steps.push({
|
|
111309
112018
|
agent: "codex",
|
|
111310
|
-
command: `ensure ${shellQuote8(
|
|
112019
|
+
command: `ensure ${shellQuote8(join106(codexHome(), "config.toml"))} registers local marketplace ${shellQuote8(MARKETPLACE_NAME)}`,
|
|
111311
112020
|
status: dryRun ? "planned" : "ran"
|
|
111312
112021
|
});
|
|
111313
112022
|
steps.push({
|
|
111314
112023
|
agent: "codex",
|
|
111315
|
-
command: `ensure ${shellQuote8(
|
|
112024
|
+
command: `ensure ${shellQuote8(join106(codexHome(), "config.toml"))} enables ${shellQuote8(PLUGIN_ID)}`,
|
|
111316
112025
|
status: dryRun ? "planned" : "ran"
|
|
111317
112026
|
});
|
|
111318
112027
|
if (dryRun) {
|
|
@@ -111367,13 +112076,13 @@ function pluginRootCandidates() {
|
|
|
111367
112076
|
return [resolve40(envRoot)];
|
|
111368
112077
|
const candidates = [];
|
|
111369
112078
|
for (const dir of packageCandidateDirs()) {
|
|
111370
|
-
candidates.push(
|
|
111371
|
-
candidates.push(
|
|
112079
|
+
candidates.push(join107(dir, "plugins"));
|
|
112080
|
+
candidates.push(join107(dir, "dist", "plugins"));
|
|
111372
112081
|
}
|
|
111373
112082
|
return [...new Set(candidates)];
|
|
111374
112083
|
}
|
|
111375
112084
|
function isInstallablePluginRoot(root2) {
|
|
111376
|
-
return existsSync35(
|
|
112085
|
+
return existsSync35(join107(root2, ".claude-plugin", "marketplace.json")) && existsSync35(join107(root2, ".agents", "plugins", "marketplace.json")) && existsSync35(join107(root2, "claude", ".claude-plugin", "plugin.json")) && existsSync35(join107(root2, "codex", ".codex-plugin", "plugin.json")) && existsSync35(join107(root2, "cursor", ".cursor-plugin", "plugin.json")) && existsSync35(join107(root2, "skills"));
|
|
111377
112086
|
}
|
|
111378
112087
|
function resolveBundledPluginsRoot() {
|
|
111379
112088
|
const candidates = pluginRootCandidates();
|
|
@@ -111603,10 +112312,10 @@ function readQuickstartPath() {
|
|
|
111603
112312
|
try {
|
|
111604
112313
|
let dir = dirname47(fileURLToPath10(import.meta.url));
|
|
111605
112314
|
for (let i2 = 0;i2 < 8; i2++) {
|
|
111606
|
-
const candidate =
|
|
112315
|
+
const candidate = join108(dir, "docs", "quickstart.md");
|
|
111607
112316
|
if (existsSync36(candidate))
|
|
111608
112317
|
return candidate;
|
|
111609
|
-
const pkg =
|
|
112318
|
+
const pkg = join108(dir, "package.json");
|
|
111610
112319
|
if (existsSync36(pkg))
|
|
111611
112320
|
return candidate;
|
|
111612
112321
|
const parent = dirname47(dir);
|
|
@@ -111615,7 +112324,7 @@ function readQuickstartPath() {
|
|
|
111615
112324
|
dir = parent;
|
|
111616
112325
|
}
|
|
111617
112326
|
} catch {}
|
|
111618
|
-
return
|
|
112327
|
+
return join108(dirname47(fileURLToPath10(import.meta.url)), "docs", "quickstart.md");
|
|
111619
112328
|
}
|
|
111620
112329
|
var GREEN = "\x1B[32m";
|
|
111621
112330
|
var RESET = "\x1B[0m";
|
|
@@ -111641,7 +112350,7 @@ ${greenBox([
|
|
|
111641
112350
|
`;
|
|
111642
112351
|
}
|
|
111643
112352
|
function assertKnownTopLevelCommand(argv, program2) {
|
|
111644
|
-
const commands = new Set(["help", ...program2.commands.flatMap((
|
|
112353
|
+
const commands = new Set(["help", ...program2.commands.flatMap((command3) => [command3.name(), ...command3.aliases()])]);
|
|
111645
112354
|
for (const token of argv.slice(2)) {
|
|
111646
112355
|
if (token === "-h" || token === "--help" || token === "-V" || token === "--version")
|
|
111647
112356
|
return;
|
|
@@ -111867,9 +112576,9 @@ async function cli_main(argv = process.argv) {
|
|
|
111867
112576
|
await withContextRuntimeEventDelivery(async () => {
|
|
111868
112577
|
const program2 = createCliProgram();
|
|
111869
112578
|
assertKnownTopLevelCommand(argv, program2);
|
|
111870
|
-
const overrideExit = (
|
|
111871
|
-
|
|
111872
|
-
|
|
112579
|
+
const overrideExit = (command3) => {
|
|
112580
|
+
command3.exitOverride();
|
|
112581
|
+
command3.commands.forEach(overrideExit);
|
|
111873
112582
|
};
|
|
111874
112583
|
overrideExit(program2);
|
|
111875
112584
|
try {
|