@c4a/context-cli 0.7.10 → 0.7.12
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 +1216 -450
- 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 +29 -65
- package/providers/context/provider.yaml +1 -1
- package/providers/context/resources/manuals/guides/knowledge-updates.md +87 -3
- package/providers/context/resources/manuals/guides/package-outputs.md +39 -1
- package/providers/context/resources/manuals/guides/workspace-prepare.md +3 -0
- 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 +87 -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/procedures/workspace-prepare.md +3 -0
- 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) {
|
|
@@ -56101,7 +56219,9 @@ function projectPackageKnowledgeMarkdown(content3) {
|
|
|
56101
56219
|
return content3;
|
|
56102
56220
|
const body = content3.slice(match[0].length).replace(CONTEXT_METADATA_BLOCK_RE, "").replace(CONTEXT_SECTION_OPEN_RE, (opening) => {
|
|
56103
56221
|
const key = /\bid="([a-zA-Z0-9_-]+)"/u.exec(opening)?.[1];
|
|
56104
|
-
return key === undefined ? "" :
|
|
56222
|
+
return key === undefined ? "" : `
|
|
56223
|
+
|
|
56224
|
+
<a id="section-${encodeURIComponent(key)}"></a>
|
|
56105
56225
|
|
|
56106
56226
|
`;
|
|
56107
56227
|
}).replace(CONTEXT_SECTION_CLOSE_RE, `
|
|
@@ -63603,8 +63723,9 @@ function validateProductionStage(value) {
|
|
|
63603
63723
|
throw new TypeError("An unavailable source requires an explicit gap and pending investigation");
|
|
63604
63724
|
}
|
|
63605
63725
|
for (const usage of stage.indexer_usage) {
|
|
63606
|
-
|
|
63607
|
-
|
|
63726
|
+
const invalid = usage.scopes.filter((scope2) => !scopes.has(scope2));
|
|
63727
|
+
if (invalid.length)
|
|
63728
|
+
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
63729
|
}
|
|
63609
63730
|
const visited = new Set;
|
|
63610
63731
|
const visiting = new Set;
|
|
@@ -63624,7 +63745,9 @@ function validateProductionStage(value) {
|
|
|
63624
63745
|
visited.add(task.id);
|
|
63625
63746
|
}
|
|
63626
63747
|
for (const task of stage.tasks) {
|
|
63627
|
-
indexerKnowledgeCollectionSchema2.
|
|
63748
|
+
if (!indexerKnowledgeCollectionSchema2.safeParse(task.path.split("/")[0]).success) {
|
|
63749
|
+
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.`);
|
|
63750
|
+
}
|
|
63628
63751
|
if (!isSafeKnowledgeTargetPath(task.path.split("/")[0], task.path))
|
|
63629
63752
|
throw new TypeError(`Unsafe article target for ${task.id}`);
|
|
63630
63753
|
if (task.input !== productionTaskInput(task))
|
|
@@ -63712,7 +63835,7 @@ var init_productionStage = __esm(() => {
|
|
|
63712
63835
|
skills: exports_external.array(exports_external.object({ name, entry: name.optional() }).strict()).default([])
|
|
63713
63836
|
}).strict();
|
|
63714
63837
|
productionIndexerUsageSchema = exports_external.object({
|
|
63715
|
-
scopes: exports_external.array(name).min(1),
|
|
63838
|
+
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
63839
|
skills: exports_external.array(name).min(1),
|
|
63717
63840
|
purpose: name
|
|
63718
63841
|
}).strict();
|
|
@@ -63748,6 +63871,20 @@ var init_productionStage = __esm(() => {
|
|
|
63748
63871
|
});
|
|
63749
63872
|
|
|
63750
63873
|
// src/project/productionStageStore.ts
|
|
63874
|
+
var exports_productionStageStore = {};
|
|
63875
|
+
__export(exports_productionStageStore, {
|
|
63876
|
+
writeProductionProjection: () => writeProductionProjection,
|
|
63877
|
+
saveProductionStage: () => saveProductionStage,
|
|
63878
|
+
readProductionStageSnapshot: () => readProductionStageSnapshot,
|
|
63879
|
+
readProductionStage: () => readProductionStage,
|
|
63880
|
+
readProductionCapabilities: () => readProductionCapabilities,
|
|
63881
|
+
productionStageDirectory: () => productionStageDirectory,
|
|
63882
|
+
productionSourceFile: () => productionSourceFile,
|
|
63883
|
+
productionPlanMarkdown: () => productionPlanMarkdown,
|
|
63884
|
+
prepareNextProductionStage: () => prepareNextProductionStage,
|
|
63885
|
+
materializeProductionStage: () => materializeProductionStage,
|
|
63886
|
+
PRODUCTION_STAGES_ROOT: () => PRODUCTION_STAGES_ROOT
|
|
63887
|
+
});
|
|
63751
63888
|
import { constants as constants4 } from "node:fs";
|
|
63752
63889
|
import { readFile as readFile21, access as access2, stat as stat5 } from "node:fs/promises";
|
|
63753
63890
|
import { join as join20 } from "node:path";
|
|
@@ -64632,12 +64769,14 @@ Restore the authorized source and retry preparation.
|
|
|
64632
64769
|
"",
|
|
64633
64770
|
...scopes.map((scope2) => `- ${scope2.scope}: ${join25(directory, productionSourceFile(scope2.scope))}`),
|
|
64634
64771
|
"",
|
|
64635
|
-
"Use code skeletons and document outlines
|
|
64772
|
+
"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
64773
|
"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
|
-
"
|
|
64774
|
+
"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.",
|
|
64775
|
+
"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
64776
|
...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
64777
|
"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
64778
|
"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.",
|
|
64779
|
+
"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
64780
|
"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
64781
|
`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
64782
|
""
|
|
@@ -64677,9 +64816,9 @@ async function submitProductionPlan(input) {
|
|
|
64677
64816
|
throw new TypeError("Pending investigation must name unique authorized stage scopes");
|
|
64678
64817
|
}
|
|
64679
64818
|
if (stage.gaps.some((gap) => !pendingScopes.includes(gap.scope)))
|
|
64680
|
-
throw
|
|
64819
|
+
throw refreshRequired(stage.id, "Keep unresolved material gaps in pending_scopes; restore the source if unavailable, then prepare the current stage to refresh its material snapshot");
|
|
64681
64820
|
if (plan.articles.some((article) => article.sources.some((scope2) => stage.gaps.some((gap) => gap.scope === scope2)))) {
|
|
64682
|
-
throw
|
|
64821
|
+
throw refreshRequired(stage.id, "An article requires unavailable material in the captured stage. Restore the source if needed, then prepare the current stage; independent source plans may proceed");
|
|
64683
64822
|
}
|
|
64684
64823
|
for (const source2 of stage.scopes)
|
|
64685
64824
|
if (!stage.gaps.some((gap) => gap.scope === source2.scope) && await productionSourceBaseline(input.projectRoot, source2.scope) !== source2.baseline) {
|
|
@@ -64784,7 +64923,7 @@ var init_productionPlanning = __esm(() => {
|
|
|
64784
64923
|
stage: text5,
|
|
64785
64924
|
capabilities: productionCapabilitiesSchema,
|
|
64786
64925
|
articles: exports_external.array(exports_external.object({
|
|
64787
|
-
path: text5,
|
|
64926
|
+
path: text5.describe("Relative to knowledge/, e.g. business/example.md; do not prefix knowledge/"),
|
|
64788
64927
|
question: text5,
|
|
64789
64928
|
sources: exports_external.array(text5).min(1),
|
|
64790
64929
|
batch: text5,
|
|
@@ -64793,7 +64932,7 @@ var init_productionPlanning = __esm(() => {
|
|
|
64793
64932
|
}).strict()),
|
|
64794
64933
|
indexer_usage: exports_external.array(productionIndexerUsageSchema).default([]),
|
|
64795
64934
|
replaces: exports_external.array(text5).default([]),
|
|
64796
|
-
pending_scopes: exports_external.array(text5).optional()
|
|
64935
|
+
pending_scopes: exports_external.array(text5).describe("Exact authorized source refs from the current stage scopes; no prose or module descriptions. Omit on amendments to preserve remaining investigation.").optional()
|
|
64797
64936
|
}).strict();
|
|
64798
64937
|
});
|
|
64799
64938
|
|
|
@@ -66152,6 +66291,77 @@ var init_knowledgeAssetRepair = __esm(() => {
|
|
|
66152
66291
|
init_assetSourceRegistry();
|
|
66153
66292
|
});
|
|
66154
66293
|
|
|
66294
|
+
// src/project/reviewApplyIndexer.ts
|
|
66295
|
+
var exports_reviewApplyIndexer = {};
|
|
66296
|
+
__export(exports_reviewApplyIndexer, {
|
|
66297
|
+
renderApprovedIndexerMarkdown: () => renderApprovedIndexerMarkdown
|
|
66298
|
+
});
|
|
66299
|
+
function escapeHtmlAttribute(value) {
|
|
66300
|
+
return value.replace(/&/gu, "&").replace(/"/gu, """).replace(/</gu, "<").replace(/>/gu, ">");
|
|
66301
|
+
}
|
|
66302
|
+
function sectionMarkdown(section) {
|
|
66303
|
+
return [
|
|
66304
|
+
`<!-- context:section id="${escapeHtmlAttribute(section.section_key)}" -->`,
|
|
66305
|
+
"",
|
|
66306
|
+
section.markdown.trimEnd(),
|
|
66307
|
+
"",
|
|
66308
|
+
"<!-- /context:section -->"
|
|
66309
|
+
].join(`
|
|
66310
|
+
`);
|
|
66311
|
+
}
|
|
66312
|
+
function renderApprovedIndexerMarkdown(input) {
|
|
66313
|
+
if (input.record.approved_revision !== undefined) {
|
|
66314
|
+
const content3 = compactApprovedKnowledgeMarkdown(ensureApprovedKnowledgePresentation(input.record.body));
|
|
66315
|
+
return content3.replace(/^---\r?\n([\s\S]*?)\r?\n---/u, (_match, header) => {
|
|
66316
|
+
const metadata = import_yaml25.default.parse(header);
|
|
66317
|
+
const reclassified = input.record.approved_revision?.previous_path !== undefined && input.record.approved_revision.previous_path.split("/")[0] !== input.record.collection;
|
|
66318
|
+
return ["---", import_yaml25.default.stringify({
|
|
66319
|
+
...metadata,
|
|
66320
|
+
type: reclassified ? okfTypeForCollection(input.record.collection) : metadata.type ?? okfTypeForCollection(input.record.collection),
|
|
66321
|
+
timestamp: input.timestamp
|
|
66322
|
+
}).trimEnd(), "---"].join(`
|
|
66323
|
+
`);
|
|
66324
|
+
});
|
|
66325
|
+
}
|
|
66326
|
+
const binding = input.record.indexer_candidate;
|
|
66327
|
+
if (input.record.candidate_type !== "indexer-artifact" || binding === undefined) {
|
|
66328
|
+
throw new TypeError("Indexer approved renderer requires an indexer-artifact Candidate");
|
|
66329
|
+
}
|
|
66330
|
+
const title = input.record.review.title;
|
|
66331
|
+
const body = binding.sections.flatMap((section, index2) => [
|
|
66332
|
+
...index2 === 0 ? [] : [""],
|
|
66333
|
+
sectionMarkdown(section)
|
|
66334
|
+
]).join(`
|
|
66335
|
+
`);
|
|
66336
|
+
const description = readerKnowledgeDescription({
|
|
66337
|
+
description: input.record.review.summary,
|
|
66338
|
+
markdown: body,
|
|
66339
|
+
title
|
|
66340
|
+
});
|
|
66341
|
+
const frontmatter = import_yaml25.default.stringify({
|
|
66342
|
+
title,
|
|
66343
|
+
type: okfTypeForCollection(input.record.collection),
|
|
66344
|
+
description,
|
|
66345
|
+
timestamp: input.timestamp
|
|
66346
|
+
}).trimEnd();
|
|
66347
|
+
return [
|
|
66348
|
+
"---",
|
|
66349
|
+
frontmatter,
|
|
66350
|
+
"---",
|
|
66351
|
+
"",
|
|
66352
|
+
ensureMarkdownPageTitle(body, title),
|
|
66353
|
+
""
|
|
66354
|
+
].join(`
|
|
66355
|
+
`);
|
|
66356
|
+
}
|
|
66357
|
+
var import_yaml25;
|
|
66358
|
+
var init_reviewApplyIndexer = __esm(() => {
|
|
66359
|
+
init_okfTypes();
|
|
66360
|
+
init_packageKnowledgeProjection();
|
|
66361
|
+
init_approvedKnowledgeMetadata();
|
|
66362
|
+
import_yaml25 = __toESM(require_dist(), 1);
|
|
66363
|
+
});
|
|
66364
|
+
|
|
66155
66365
|
// src/project/approvedRevisionBatch.ts
|
|
66156
66366
|
var exports_approvedRevisionBatch = {};
|
|
66157
66367
|
__export(exports_approvedRevisionBatch, {
|
|
@@ -66208,7 +66418,8 @@ async function approvedRevisionCandidateApplied(root, candidate, applied, closed
|
|
|
66208
66418
|
return false;
|
|
66209
66419
|
if (!closed && applied === candidate.body)
|
|
66210
66420
|
return true;
|
|
66211
|
-
const
|
|
66421
|
+
const { renderApprovedIndexerMarkdown: renderApprovedIndexerMarkdown2 } = await Promise.resolve().then(() => (init_reviewApplyIndexer(), exports_reviewApplyIndexer));
|
|
66422
|
+
const expected = revisionComparableMarkdown(renderApprovedIndexerMarkdown2({ record: candidate, timestamp: candidate.updated }));
|
|
66212
66423
|
const approved = revisionComparableMarkdown(applied);
|
|
66213
66424
|
if (expected === approved)
|
|
66214
66425
|
return true;
|
|
@@ -66224,9 +66435,9 @@ async function approvedRevisionCandidateApplied(root, candidate, applied, closed
|
|
|
66224
66435
|
function revisionComparableMarkdown(markdown) {
|
|
66225
66436
|
const compact = compactApprovedKnowledgeMarkdown(ensureApprovedKnowledgePresentation(markdown));
|
|
66226
66437
|
return compact.replace(/^---\r?\n([\s\S]*?)\r?\n---/u, (_match, header) => {
|
|
66227
|
-
const metadata =
|
|
66438
|
+
const metadata = import_yaml26.default.parse(header);
|
|
66228
66439
|
const { timestamp: _timestamp, ...content3 } = metadata;
|
|
66229
|
-
return ["---",
|
|
66440
|
+
return ["---", import_yaml26.default.stringify(content3).trimEnd(), "---"].join(`
|
|
66230
66441
|
`);
|
|
66231
66442
|
});
|
|
66232
66443
|
}
|
|
@@ -66266,7 +66477,7 @@ async function observeApprovedRevisionBatch(root, request) {
|
|
|
66266
66477
|
...candidates.some((candidate) => candidate.status === "rejected") ? { revision_pending: true } : {}
|
|
66267
66478
|
};
|
|
66268
66479
|
}
|
|
66269
|
-
var
|
|
66480
|
+
var import_yaml26;
|
|
66270
66481
|
var init_approvedRevisionBatch = __esm(() => {
|
|
66271
66482
|
init_src2();
|
|
66272
66483
|
init_approvedRevision();
|
|
@@ -66275,7 +66486,7 @@ var init_approvedRevisionBatch = __esm(() => {
|
|
|
66275
66486
|
init_approvedKnowledgeMetadata();
|
|
66276
66487
|
init_durableSingleFileTransaction();
|
|
66277
66488
|
init_knowledgeAssetRepair();
|
|
66278
|
-
|
|
66489
|
+
import_yaml26 = __toESM(require_dist(), 1);
|
|
66279
66490
|
});
|
|
66280
66491
|
|
|
66281
66492
|
// src/project/verifyFrontmatter.ts
|
|
@@ -66291,7 +66502,7 @@ function isDeprecatedApprovedMarkdown(content3) {
|
|
|
66291
66502
|
if (end < 0)
|
|
66292
66503
|
return false;
|
|
66293
66504
|
try {
|
|
66294
|
-
const parsed =
|
|
66505
|
+
const parsed = import_yaml27.default.parse(content3.slice(4, end));
|
|
66295
66506
|
return isRecord7(parsed) && parsed.deprecated === true;
|
|
66296
66507
|
} catch {
|
|
66297
66508
|
return false;
|
|
@@ -66310,7 +66521,7 @@ function parseFrontmatter3(content3, path2, issues) {
|
|
|
66310
66521
|
return;
|
|
66311
66522
|
}
|
|
66312
66523
|
try {
|
|
66313
|
-
const parsed =
|
|
66524
|
+
const parsed = import_yaml27.default.parse(content3.slice(4, end));
|
|
66314
66525
|
if (!isRecord7(parsed)) {
|
|
66315
66526
|
issues.push({ severity: "error", code: "frontmatter-invalid", path: path2, line: 1, message: "frontmatter must be a YAML object" });
|
|
66316
66527
|
return;
|
|
@@ -66336,7 +66547,7 @@ function parseFrontmatterLoose(content3) {
|
|
|
66336
66547
|
if (end < 0)
|
|
66337
66548
|
return {};
|
|
66338
66549
|
try {
|
|
66339
|
-
const parsed =
|
|
66550
|
+
const parsed = import_yaml27.default.parse(content3.slice(4, end));
|
|
66340
66551
|
return isRecord7(parsed) ? parsed : {};
|
|
66341
66552
|
} catch {
|
|
66342
66553
|
return {};
|
|
@@ -66406,10 +66617,10 @@ async function validateApprovedMarkdown(input) {
|
|
|
66406
66617
|
});
|
|
66407
66618
|
}
|
|
66408
66619
|
}
|
|
66409
|
-
var
|
|
66620
|
+
var import_yaml27;
|
|
66410
66621
|
var init_verifyFrontmatter = __esm(() => {
|
|
66411
66622
|
init_okfTypes();
|
|
66412
|
-
|
|
66623
|
+
import_yaml27 = __toESM(require_dist(), 1);
|
|
66413
66624
|
});
|
|
66414
66625
|
|
|
66415
66626
|
// src/project/indexerTemplateSnapshots.ts
|
|
@@ -66827,7 +67038,7 @@ var init_indexerMainRunStore = __esm(() => {
|
|
|
66827
67038
|
// src/project/productionDeliveryScope.ts
|
|
66828
67039
|
import { readFile as readFile34 } from "node:fs/promises";
|
|
66829
67040
|
import { join as join36, posix as posix2 } from "node:path";
|
|
66830
|
-
async function productionDeliverableArticles(root) {
|
|
67041
|
+
async function productionDeliverableArticles(root, phase = "delivery") {
|
|
66831
67042
|
return withProductionFeedback({ operation: "delivery-scope" }, async () => {
|
|
66832
67043
|
const stage = await readProductionStage(root);
|
|
66833
67044
|
if (!stage)
|
|
@@ -66850,6 +67061,8 @@ async function productionDeliverableArticles(root) {
|
|
|
66850
67061
|
continue;
|
|
66851
67062
|
selected.set(article.article_id, { path: article.path, article_id: article.article_id });
|
|
66852
67063
|
}
|
|
67064
|
+
if (phase === "review")
|
|
67065
|
+
return [...selected.values()];
|
|
66853
67066
|
for (const article of selected.values()) {
|
|
66854
67067
|
const markdown = await readFile34(await safeProjectTarget(root, join36("knowledge", article.path)), "utf8");
|
|
66855
67068
|
for (const link of markdownReaderLinks(markdown)) {
|
|
@@ -66948,6 +67161,9 @@ async function clearCompletedLifecycle(projectRoot) {
|
|
|
66948
67161
|
if (production) {
|
|
66949
67162
|
if (production.delivery)
|
|
66950
67163
|
throw new TypeError("Partial delivery must retain the production stage and its unfinished tasks; finish the build or explicitly resume writing.");
|
|
67164
|
+
if (dispatchProductionStage(production, productionCapabilitiesSchema.parse({})).state !== "ended") {
|
|
67165
|
+
throw new TypeError("Production still has unfinished work; keep its files and follow context status --format json.");
|
|
67166
|
+
}
|
|
66951
67167
|
const candidates = await readCandidateRecords(projectRoot);
|
|
66952
67168
|
await assertRequiredArticlesReviewed(projectRoot, candidates);
|
|
66953
67169
|
if (candidates.some((candidate) => candidate.status === "draft") || (await readProjectCloseStatus(projectRoot)).state !== "ready") {
|
|
@@ -66987,6 +67203,7 @@ async function clearCompletedLifecycle(projectRoot) {
|
|
|
66987
67203
|
var COMPLETED_RUNTIME_PATHS;
|
|
66988
67204
|
var init_lifecycleCleanup = __esm(() => {
|
|
66989
67205
|
init_productionStageStore();
|
|
67206
|
+
init_productionStage();
|
|
66990
67207
|
init_indexerRequiredArticleReview();
|
|
66991
67208
|
init_candidateLedger();
|
|
66992
67209
|
init_close();
|
|
@@ -67022,7 +67239,7 @@ async function requestProductionDelivery(root) {
|
|
|
67022
67239
|
if (stage.delivery)
|
|
67023
67240
|
return true;
|
|
67024
67241
|
const candidates = await readCandidateRecords(root);
|
|
67025
|
-
const formal = await productionDeliverableArticles(root);
|
|
67242
|
+
const formal = await productionDeliverableArticles(root, "review");
|
|
67026
67243
|
const selected = stage.tasks.filter((task) => task.status === "accepted" && (candidates.some((candidate) => candidate.candidate_id === task.accepted?.receipt) || formal.some((article) => article.article_id === task.article_id && article.path === task.path)));
|
|
67027
67244
|
if (!selected.length)
|
|
67028
67245
|
throw new TypeError("No completed articles are available. Continue the current writing task before requesting delivery.");
|
|
@@ -67076,7 +67293,7 @@ var init_productionDelivery = __esm(() => {
|
|
|
67076
67293
|
|
|
67077
67294
|
// src/project/indexerRequiredArticleReview.ts
|
|
67078
67295
|
async function assertRequiredArticlesReviewed(root, candidates) {
|
|
67079
|
-
if ((await readMaintenance(root)).active)
|
|
67296
|
+
if ((await readMaintenance(root)).active || await readApprovedRevision(root))
|
|
67080
67297
|
return;
|
|
67081
67298
|
const rejected = candidates.filter((candidate) => candidate.status === "rejected" && candidate.indexer_candidate);
|
|
67082
67299
|
const production = await readProductionStage(root);
|
|
@@ -67147,6 +67364,7 @@ var init_indexerRequiredArticleReview = __esm(() => {
|
|
|
67147
67364
|
init_productionSubmissionFiles();
|
|
67148
67365
|
init_productionPlanning();
|
|
67149
67366
|
init_maintenanceStorage();
|
|
67367
|
+
init_approvedRevision();
|
|
67150
67368
|
});
|
|
67151
67369
|
|
|
67152
67370
|
// src/project/partialDelivery.ts
|
|
@@ -67297,7 +67515,7 @@ async function prepareApprovedKnowledgeSnapshotTarget(input) {
|
|
|
67297
67515
|
if (error.code !== "ENOENT")
|
|
67298
67516
|
throw error;
|
|
67299
67517
|
}
|
|
67300
|
-
const structure = before === undefined ? {} :
|
|
67518
|
+
const structure = before === undefined ? {} : import_yaml28.default.parse(before);
|
|
67301
67519
|
if (!structure || typeof structure !== "object" || Array.isArray(structure))
|
|
67302
67520
|
throw new TypeError("Invalid knowledge structure");
|
|
67303
67521
|
const articles = new Map(approvedKnowledgeSnapshotsFromStructure(structure).map((article) => [article.article_id, article]));
|
|
@@ -67321,7 +67539,7 @@ async function prepareApprovedKnowledgeSnapshotTarget(input) {
|
|
|
67321
67539
|
articles.set(article.article_id, article);
|
|
67322
67540
|
}
|
|
67323
67541
|
const entries2 = validateArticleStructureEntries([...articles.values()]);
|
|
67324
|
-
const content3 =
|
|
67542
|
+
const content3 = import_yaml28.default.stringify({
|
|
67325
67543
|
...structure,
|
|
67326
67544
|
articles: entries2.sort((a, b) => a.article_id.localeCompare(b.article_id))
|
|
67327
67545
|
});
|
|
@@ -67335,12 +67553,12 @@ async function prepareApprovedKnowledgeSnapshotTarget(input) {
|
|
|
67335
67553
|
content: content3
|
|
67336
67554
|
};
|
|
67337
67555
|
}
|
|
67338
|
-
var
|
|
67556
|
+
var import_yaml28, STRUCTURE_PATH2 = "knowledge/structure.yaml";
|
|
67339
67557
|
var init_approvedKnowledgeSnapshots = __esm(() => {
|
|
67340
67558
|
init_src2();
|
|
67341
67559
|
init_approvedKnowledgeMetadata();
|
|
67342
67560
|
init_durableSingleFileTransaction();
|
|
67343
|
-
|
|
67561
|
+
import_yaml28 = __toESM(require_dist(), 1);
|
|
67344
67562
|
});
|
|
67345
67563
|
|
|
67346
67564
|
// src/runtimeEventOutbox.ts
|
|
@@ -69378,7 +69596,7 @@ function parseFrontmatter4(content3) {
|
|
|
69378
69596
|
const match = /^---\r?\n([\s\S]*?)\r?\n---/u.exec(content3);
|
|
69379
69597
|
if (match?.[1] === undefined)
|
|
69380
69598
|
return {};
|
|
69381
|
-
const parsed =
|
|
69599
|
+
const parsed = import_yaml29.default.parse(match[1]);
|
|
69382
69600
|
return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
69383
69601
|
}
|
|
69384
69602
|
function isDeprecated(content3) {
|
|
@@ -69439,7 +69657,7 @@ async function writeApprovedStructureProjection(projectRoot) {
|
|
|
69439
69657
|
const { inputHash, structure, compactFiles } = await deriveApprovedStructure(projectRoot);
|
|
69440
69658
|
const outputPath = join48(projectRoot, STRUCTURE_PATH4);
|
|
69441
69659
|
await mkdir17(dirname21(outputPath), { recursive: true });
|
|
69442
|
-
await writeFile11(outputPath,
|
|
69660
|
+
await writeFile11(outputPath, import_yaml29.default.stringify(structure), "utf8");
|
|
69443
69661
|
await Promise.all(compactFiles.map((file) => writeFile11(file.absPath, file.content, "utf8")));
|
|
69444
69662
|
return { inputHash, articles: structure.articles.length, structure: STRUCTURE_PATH4 };
|
|
69445
69663
|
}
|
|
@@ -69507,7 +69725,7 @@ async function closeProjectWorkspace(projectRoot) {
|
|
|
69507
69725
|
}
|
|
69508
69726
|
const outputPath = join48(projectRoot, STRUCTURE_PATH4);
|
|
69509
69727
|
await mkdir17(dirname21(outputPath), { recursive: true });
|
|
69510
|
-
await writeFile11(outputPath, `${
|
|
69728
|
+
await writeFile11(outputPath, `${import_yaml29.default.stringify(structure)}`, "utf8");
|
|
69511
69729
|
await Promise.all(compactFiles.map((file) => writeFile11(file.absPath, file.content, "utf8")));
|
|
69512
69730
|
const { readTaskRollback } = await Promise.resolve().then(() => (init_taskRollback(), exports_taskRollback));
|
|
69513
69731
|
if (!production && !await readTaskRollback(projectRoot))
|
|
@@ -69558,7 +69776,7 @@ async function runProjectCloseCommand(input) {
|
|
|
69558
69776
|
}
|
|
69559
69777
|
return true;
|
|
69560
69778
|
}
|
|
69561
|
-
var
|
|
69779
|
+
var import_yaml29, KNOWLEDGE_ROOT = "knowledge", STRUCTURE_PATH4, STRUCTURE_SCHEMA_VERSION = "context.approved-structure.v1";
|
|
69562
69780
|
var init_close = __esm(() => {
|
|
69563
69781
|
init_indexerRequiredArticleReview();
|
|
69564
69782
|
init_approvedFileRead();
|
|
@@ -69579,7 +69797,7 @@ var init_close = __esm(() => {
|
|
|
69579
69797
|
init_candidateLedger();
|
|
69580
69798
|
init_knowledgeAssetRepair();
|
|
69581
69799
|
init_approvedKnowledgeMetadata();
|
|
69582
|
-
|
|
69800
|
+
import_yaml29 = __toESM(require_dist(), 1);
|
|
69583
69801
|
STRUCTURE_PATH4 = join48(KNOWLEDGE_ROOT, "structure.yaml");
|
|
69584
69802
|
});
|
|
69585
69803
|
|
|
@@ -69843,7 +70061,7 @@ async function optionalText(root, path2) {
|
|
|
69843
70061
|
}
|
|
69844
70062
|
async function readKnowledgeMap(root) {
|
|
69845
70063
|
const content3 = await optionalText(root, KNOWLEDGE_MAP_PATH);
|
|
69846
|
-
return content3 === undefined ? undefined : validateKnowledgeMap(
|
|
70064
|
+
return content3 === undefined ? undefined : validateKnowledgeMap(import_yaml30.parse(content3));
|
|
69847
70065
|
}
|
|
69848
70066
|
async function applyKnowledgeMapUpdate(projectRoot, update) {
|
|
69849
70067
|
return withProjectWriteLock(projectRoot, "adjust-knowledge-map", async () => {
|
|
@@ -69855,7 +70073,7 @@ async function applyKnowledgeMapUpdate(projectRoot, update) {
|
|
|
69855
70073
|
const preview = previewText === undefined ? undefined : JSON.parse(previewText);
|
|
69856
70074
|
const planned = preview?.topics?.flatMap((topic) => topic.article_targets ?? []) ?? [];
|
|
69857
70075
|
assertKnowledgeMapCoverage(next, approved, { known: [...approved, ...planned], current_revision: current?.revision ?? null });
|
|
69858
|
-
const content3 =
|
|
70076
|
+
const content3 = import_yaml30.stringify(next);
|
|
69859
70077
|
const previous2 = await optionalText(projectRoot, KNOWLEDGE_MAP_PATH);
|
|
69860
70078
|
await runDurableMultiFileTransaction({
|
|
69861
70079
|
projectRoot,
|
|
@@ -69876,14 +70094,14 @@ async function applyKnowledgeMapUpdate(projectRoot, update) {
|
|
|
69876
70094
|
};
|
|
69877
70095
|
});
|
|
69878
70096
|
}
|
|
69879
|
-
var
|
|
70097
|
+
var import_yaml30, KNOWLEDGE_MAP_PATH = "src/knowledge-map.yaml";
|
|
69880
70098
|
var init_knowledgeMap2 = __esm(() => {
|
|
69881
70099
|
init_knowledgeMapCoverage();
|
|
69882
70100
|
init_src2();
|
|
69883
70101
|
init_durableSingleFileTransaction();
|
|
69884
70102
|
init_durableMultiFileTransaction();
|
|
69885
70103
|
init_writeLock();
|
|
69886
|
-
|
|
70104
|
+
import_yaml30 = __toESM(require_dist(), 1);
|
|
69887
70105
|
});
|
|
69888
70106
|
|
|
69889
70107
|
// src/project/packageKnowledgeMap.ts
|
|
@@ -70157,7 +70375,7 @@ async function optionalWorkspaceText(root, path2) {
|
|
|
70157
70375
|
}
|
|
70158
70376
|
async function readWorkspaceChangelog(root) {
|
|
70159
70377
|
const value = await optionalWorkspaceText(root, "changelog.yaml");
|
|
70160
|
-
return value === undefined ? [] : ledgerSchema.parse(
|
|
70378
|
+
return value === undefined ? [] : ledgerSchema.parse(import_yaml31.parse(value)).entries;
|
|
70161
70379
|
}
|
|
70162
70380
|
async function workspaceVersion(root) {
|
|
70163
70381
|
const manifest = JSON.parse(await readFile45(join55(root, "package.json"), "utf8"));
|
|
@@ -70299,7 +70517,7 @@ async function recordWorkspaceVersion(root, value) {
|
|
|
70299
70517
|
const writes = {
|
|
70300
70518
|
"package.json": JSON.stringify(manifest, null, 2) + `
|
|
70301
70519
|
`,
|
|
70302
|
-
"changelog.yaml":
|
|
70520
|
+
"changelog.yaml": import_yaml31.stringify({ entries: entries2 }),
|
|
70303
70521
|
"CHANGELOG.md": renderChangelog(entries2),
|
|
70304
70522
|
".context-version.json": JSON.stringify({ version: entry.version, files: status.files }) + `
|
|
70305
70523
|
`
|
|
@@ -70313,13 +70531,13 @@ async function recordWorkspaceVersion(root, value) {
|
|
|
70313
70531
|
return { version: entry.version, next_action: { command: "context status --format json" } };
|
|
70314
70532
|
});
|
|
70315
70533
|
}
|
|
70316
|
-
var
|
|
70534
|
+
var import_yaml31, exec, semver, text6, changelogEntrySchema, changelogInputSchema, ledgerSchema, baselineSchema, hash2 = (value) => createHash15("sha256").update(JSON.stringify(value)).digest("hex");
|
|
70317
70535
|
var init_workspaceChangelog = __esm(() => {
|
|
70318
70536
|
init_zod();
|
|
70319
70537
|
init_writeLock();
|
|
70320
70538
|
init_durableSingleFileTransaction();
|
|
70321
70539
|
init_durableMultiFileTransaction();
|
|
70322
|
-
|
|
70540
|
+
import_yaml31 = __toESM(require_dist(), 1);
|
|
70323
70541
|
exec = promisify6(execFile6);
|
|
70324
70542
|
semver = exports_external.string().regex(/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/u);
|
|
70325
70543
|
text6 = exports_external.string().trim().min(1);
|
|
@@ -70452,17 +70670,22 @@ var siteMarkdownConfig, siteThemeScript, siteThemeCss = `
|
|
|
70452
70670
|
}
|
|
70453
70671
|
.VPNavBar .wrapper { padding: 0 24px !important; }
|
|
70454
70672
|
.VPNavBar .container { max-width: none !important; }
|
|
70673
|
+
.VPNav, .VPNavBar, .VPNavBar .wrapper { background: var(--vp-c-bg) !important; }
|
|
70455
70674
|
.VPNavBar .title { position: static !important; padding: 0 !important; width: var(--vp-sidebar-width) !important; flex-shrink: 0; }
|
|
70456
70675
|
.VPNavBarTitle .title { font-size: 15px; font-weight: 650; border: 0 !important; }
|
|
70457
70676
|
.VPNavBar .content { flex: 1; min-width: 0; padding-left: 0 !important; }
|
|
70458
70677
|
.VPNavBar .content-body { background: var(--vp-c-bg) !important; gap: 8px; }
|
|
70459
70678
|
.VPNavBarMenu { order: -1; flex: 1; min-width: 0; }
|
|
70460
|
-
.context-language { display: flex; align-items: center;
|
|
70461
|
-
|
|
70462
|
-
.context-language
|
|
70679
|
+
.context-language { display: inline-flex; align-items: center; padding: 5px 7px; border: 0; border-radius: 6px; color: var(--vp-c-text-2);
|
|
70680
|
+
background: transparent; white-space: nowrap; font-size: 12px; font-weight: 550; cursor: pointer; }
|
|
70681
|
+
.context-language:hover { color: var(--vp-c-brand-1); background: var(--vp-c-brand-soft); }
|
|
70463
70682
|
.VPNavBarMenuLink { font-size: 13px !important; font-weight: 550 !important; padding: 0 16px !important; }
|
|
70464
70683
|
.VPNavBarMenuLink.active { box-shadow: inset 0 -2px var(--vp-c-brand-1); }
|
|
70465
|
-
.VPNavBarSearch { flex
|
|
70684
|
+
.VPNavBarSearch { flex: 0 0 376px !important; width: 376px; padding: 0 12px !important; }
|
|
70685
|
+
.VPNavBarSearch #local-search, .VPNavBarSearch .DocSearch-Button { width: 352px; }
|
|
70686
|
+
.VPNavBarSearch .DocSearch-Button { display: flex; align-items: center; }
|
|
70687
|
+
.VPNavBarSearch .DocSearch-Button-Container { display: flex; flex: 1; min-width: 0; align-items: center; }
|
|
70688
|
+
.VPNavBarSearch .DocSearch-Button-Keys { margin-left: auto; }
|
|
70466
70689
|
.VPSidebar { border-top: 1px solid var(--vp-c-divider); border-right: 1px solid var(--vp-c-divider); scrollbar-width: thin; }
|
|
70467
70690
|
.VPSidebar .group + .group { border: 0; padding-top: 8px; }
|
|
70468
70691
|
.VPSidebarItem .link { min-width: 0; overflow: hidden; }
|
|
@@ -70508,16 +70731,84 @@ var siteMarkdownConfig, siteThemeScript, siteThemeCss = `
|
|
|
70508
70731
|
.vp-doc details { margin: 20px 0; border: 1px solid var(--vp-c-divider); border-radius: 6px; padding: 12px 16px; }
|
|
70509
70732
|
.vp-doc summary { cursor: pointer; font-size: 14px; font-weight: 550; }
|
|
70510
70733
|
.vp-doc img { max-width: 100%; height: auto; }
|
|
70734
|
+
.context-home { max-width: 100%; min-width: 0; overflow-x: clip; }
|
|
70735
|
+
.context-home .VPContent, .context-home .VPHome, .context-home .VPHero { max-width: 100%; min-width: 0; }
|
|
70736
|
+
.context-home .VPHome { padding-bottom: 0; }
|
|
70737
|
+
.context-home .VPHero { position: relative; padding: 132px 0 62px; }
|
|
70738
|
+
.context-home .VPHero::before { content: ''; position: absolute; top: -1px; right: 0; bottom: 0; left: calc(0px - var(--vp-sidebar-width)); pointer-events: none;
|
|
70739
|
+
background: linear-gradient(to bottom, transparent 58%, var(--vp-c-bg) 100%),
|
|
70740
|
+
radial-gradient(ellipse 58% 145% at 8% 18%, rgba(37,99,235,.16), transparent 72%),
|
|
70741
|
+
radial-gradient(ellipse 58% 150% at 68% 24%, rgba(0,190,200,.11), transparent 72%),
|
|
70742
|
+
linear-gradient(90deg, rgba(37,99,235,.045), rgba(0,190,200,.025) 68%, transparent); }
|
|
70743
|
+
.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; }
|
|
70744
|
+
.context-home .VPHero .main { width: 100%; max-width: 980px; min-width: 0; }
|
|
70745
|
+
.context-home .VPHero .heading { display: block; width: 100%; min-width: 0; max-width: 100%; }
|
|
70746
|
+
.context-home .VPHero .name { display: block; width: 100%; max-width: 100%; overflow-wrap: anywhere; white-space: normal; color: transparent;
|
|
70747
|
+
background: linear-gradient(112deg, var(--vp-c-brand-1), var(--context-accent)); background-clip: text; -webkit-background-clip: text; }
|
|
70748
|
+
.context-home .VPHero .text { display: block; width: 100%; max-width: 100%; overflow-wrap: anywhere; word-break: break-word; white-space: normal;
|
|
70749
|
+
font-size: clamp(38px, 4.2vw, 60px); line-height: 1.08; letter-spacing: -.045em; }
|
|
70750
|
+
.context-home .VPHero .tagline { max-width: 820px; font-size: 18px; line-height: 1.75; }
|
|
70751
|
+
.context-home .VPHero .actions { width: 100%; min-width: 0; padding-top: 38px; flex-wrap: wrap; }
|
|
70752
|
+
.context-home .VPFeatures { display: none; }
|
|
70753
|
+
.context-home-section { width: min(1180px, calc(100% - 104px)); margin: 0 auto 0 52px; padding: 36px 0 44px; }
|
|
70754
|
+
.context-home-section + .context-home-section { border-top: 1px solid var(--vp-c-divider); }
|
|
70755
|
+
.context-home-map { padding-top: 0; }
|
|
70756
|
+
.context-home-resources { padding-top: 6px; border-top: 0 !important; }
|
|
70757
|
+
.context-home-section-heading { max-width: 700px; margin-bottom: 24px; }
|
|
70758
|
+
.context-home-section-heading h2 { margin: 2px 0 8px; border: 0; font-size: 28px; line-height: 1.3; letter-spacing: -.02em; }
|
|
70759
|
+
.context-home-section-heading > p:last-child { color: var(--vp-c-text-2); line-height: 1.7; }
|
|
70760
|
+
.context-home-kicker { margin: 0; color: var(--vp-c-brand-1); font-size: 11px; font-weight: 700; letter-spacing: .16em; }
|
|
70761
|
+
.context-home-map-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(290px, 100%), 1fr)); gap: 14px; }
|
|
70762
|
+
.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));
|
|
70763
|
+
animation: context-home-rise .5s both; animation-delay: var(--context-home-delay); }
|
|
70764
|
+
.context-home-map-card { min-height: 224px; padding: 22px; border-radius: 14px; }
|
|
70765
|
+
.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));
|
|
70766
|
+
box-shadow: 0 14px 38px rgba(23,36,66,.08); transform: translateY(-2px); transition: border-color .18s, box-shadow .18s, transform .18s; }
|
|
70767
|
+
.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); }
|
|
70768
|
+
.context-home-map-card h3, .context-home-resource-card h3 { margin: 0; font-size: 17px; line-height: 1.45; }
|
|
70769
|
+
.context-home-map-card h3 a { color: var(--vp-c-text-1); }
|
|
70770
|
+
.context-home-map-card-heading span { flex: none; color: var(--vp-c-text-2); font-size: 11px; }
|
|
70771
|
+
.context-home-map-card ul { margin: 14px 0 0; padding: 0; list-style: none; }
|
|
70772
|
+
.context-home-map-card li { margin: 7px 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
70773
|
+
.context-home-map-card li a { color: var(--vp-c-text-2); font-size: 13px; }
|
|
70774
|
+
.context-home-map-card li a:hover, .context-home-map-more:hover { color: var(--vp-c-brand-1); }
|
|
70775
|
+
.context-home-map-more { display: inline-block; margin-top: 12px; color: var(--vp-c-brand-1); font-size: 12px; font-weight: 600; }
|
|
70776
|
+
.context-home-resource-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
|
|
70777
|
+
.context-home-resource-card { min-height: 118px; padding: 16px 18px; border-radius: 12px; }
|
|
70778
|
+
.context-home-resource-heading { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
|
|
70779
|
+
.context-home-resource-actions { display: flex; flex: none; align-items: center; gap: 6px; }
|
|
70780
|
+
.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;
|
|
70781
|
+
color: var(--vp-c-text-2); background: var(--vp-c-bg); font-size: 11px; font-weight: 600; line-height: 1; white-space: nowrap; }
|
|
70782
|
+
.context-home-resource-action:hover, .context-home-install-action:hover { border-color: var(--vp-c-brand-1); color: var(--vp-c-brand-1); }
|
|
70783
|
+
.context-home-install-action { cursor: pointer; background: var(--vp-c-brand-soft); }
|
|
70784
|
+
.context-home-resource-card p { margin: 8px 0 0; color: var(--vp-c-text-2); font-size: 13px; line-height: 1.55; }
|
|
70785
|
+
.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);
|
|
70786
|
+
color: var(--vp-c-text-2); font-size: 11px; text-align: right; }
|
|
70787
|
+
.context-home-powered a { color: inherit; }
|
|
70788
|
+
@keyframes context-home-rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
|
|
70511
70789
|
@media (min-width: 960px) {
|
|
70512
70790
|
.VPSidebar { top: var(--vp-nav-height) !important; width: var(--vp-sidebar-width) !important; padding: 12px 0 48px !important; }
|
|
70513
70791
|
.VPSidebar .curtain { display: none; }
|
|
70514
70792
|
.VPContent.has-sidebar { padding-left: var(--vp-sidebar-width) !important; padding-right: 0 !important; }
|
|
70515
70793
|
.context-empty-sidebar .VPContent { padding-left: var(--vp-sidebar-width) !important; padding-right: 0 !important; }
|
|
70794
|
+
.context-home .VPContent { padding-left: var(--vp-sidebar-width) !important; padding-right: 0 !important; }
|
|
70516
70795
|
.VPNavBar .content { padding-right: 32px !important; }
|
|
70517
70796
|
.VPDoc { padding: 44px 36px 80px !important; }
|
|
70518
70797
|
.VPDoc > .container > .content { padding: 0 24px 80px 0 !important; }
|
|
70519
70798
|
}
|
|
70520
70799
|
@media (min-width: 1600px) { .VPDoc { padding-left: 52px !important; padding-right: 36px !important; } }
|
|
70800
|
+
@media (min-width: 960px) and (max-width: 1279px) {
|
|
70801
|
+
.VPNavBar .title { width: 220px !important; }
|
|
70802
|
+
.VPNavBarMenuLink { padding: 0 9px !important; }
|
|
70803
|
+
.VPNavBarSearch { flex-basis: 168px !important; width: 168px; }
|
|
70804
|
+
.VPNavBarSearch .DocSearch-Button { width: 144px; }
|
|
70805
|
+
.context-home .VPHero .main { max-width: 100%; }
|
|
70806
|
+
.context-home-resource-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
70807
|
+
}
|
|
70808
|
+
@media (min-width: 1280px) and (max-width: 1599px) {
|
|
70809
|
+
.VPNavBarSearch { flex-basis: 248px !important; width: 248px; }
|
|
70810
|
+
.VPNavBarSearch #local-search, .VPNavBarSearch .DocSearch-Button { width: 224px; }
|
|
70811
|
+
}
|
|
70521
70812
|
.context-mobile-directory { display: none; }
|
|
70522
70813
|
@media (max-width: 959px) {
|
|
70523
70814
|
.VPNavBar .wrapper { padding: 0 16px !important; }
|
|
@@ -70541,6 +70832,25 @@ var siteMarkdownConfig, siteThemeScript, siteThemeCss = `
|
|
|
70541
70832
|
.vp-doc h2 { font-size: 22px; }
|
|
70542
70833
|
.VPDoc { padding: 32px 36px 64px !important; }
|
|
70543
70834
|
.vp-doc a.header-anchor { margin-left: -0.8em; }
|
|
70835
|
+
.context-home .VPHero { padding-top: 104px; padding-bottom: 66px; }
|
|
70836
|
+
.context-home .VPHero::before { left: 0; }
|
|
70837
|
+
.context-home .VPHero .container { width: min(calc(100% - 36px), 680px); margin-left: auto; margin-right: auto; }
|
|
70838
|
+
.context-home .VPHero .text { font-size: 40px; }
|
|
70839
|
+
.context-home .VPHero .tagline { font-size: 16px; }
|
|
70840
|
+
.context-home-section, .context-home-powered { width: min(calc(100% - 36px), 680px); margin-left: auto; margin-right: auto; }
|
|
70841
|
+
.context-home-resource-grid { grid-template-columns: 1fr; }
|
|
70842
|
+
}
|
|
70843
|
+
@media (max-width: 959px) {
|
|
70844
|
+
.VPNavBarMenu { display: none !important; }
|
|
70845
|
+
.VPNavBarHamburger { display: flex !important; }
|
|
70846
|
+
.VPNavScreen { display: block !important; }
|
|
70847
|
+
.VPNavBarSearch { flex: 0 0 48px !important; width: 48px; padding: 0 4px !important; }
|
|
70848
|
+
.VPNavBarSearch #local-search, .VPNavBarSearch .DocSearch-Button { width: 40px; }
|
|
70849
|
+
.VPNavBarSearch .DocSearch-Button-Placeholder, .VPNavBarSearch .DocSearch-Button-Keys { display: none !important; }
|
|
70850
|
+
}
|
|
70851
|
+
@media (prefers-reduced-motion: reduce) {
|
|
70852
|
+
.context-home-map-card, .context-home-resource-card { animation: none; }
|
|
70853
|
+
.context-home-map-card:hover, .context-home-resource-card:hover { transform: none; }
|
|
70544
70854
|
}
|
|
70545
70855
|
.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
70856
|
.context-sources-header { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 4px 16px; margin-bottom: 8px; }
|
|
@@ -70553,7 +70863,7 @@ var siteMarkdownConfig, siteThemeScript, siteThemeCss = `
|
|
|
70553
70863
|
.context-sources a { color: inherit; text-decoration: none; border-bottom: 1px solid transparent; }
|
|
70554
70864
|
.context-sources a:hover { color: var(--vp-c-brand-1); border-color: currentColor; }
|
|
70555
70865
|
.context-diagram { overflow: auto; padding: 20px; background: var(--vp-c-bg); }
|
|
70556
|
-
.context-diagram svg {
|
|
70866
|
+
.context-diagram svg { height: auto; }
|
|
70557
70867
|
.context-diagram .node rect, .context-diagram .node polygon, .context-diagram .node circle,
|
|
70558
70868
|
.context-diagram .flowchart-link { stroke-width: 1px !important; }
|
|
70559
70869
|
.context-rendered:not(.context-show-source) pre, .context-rendered:not(.context-show-source) > .copy,
|
|
@@ -70610,7 +70920,7 @@ var init_packageSiteTheme = __esm(() => {
|
|
|
70610
70920
|
if (!silent) { const token = state.push('context_anchor', '', 0); token.content = match[1]; }
|
|
70611
70921
|
state.line = line + 1;
|
|
70612
70922
|
return true;
|
|
70613
|
-
});
|
|
70923
|
+
}, { alt: ['paragraph'] });
|
|
70614
70924
|
md.renderer.rules.context_anchor = (tokens, index) => '<a id="' + md.utils.escapeHtml(tokens[index].content) + '"></a>\n';
|
|
70615
70925
|
}
|
|
70616
70926
|
`;
|
|
@@ -70626,9 +70936,12 @@ export default {
|
|
|
70626
70936
|
const data = useData();
|
|
70627
70937
|
const route = useRoute();
|
|
70628
70938
|
const sections = computed(() => data.theme.value.contextSections || []);
|
|
70939
|
+
const home = computed(() => data.theme.value.contextHome || {});
|
|
70629
70940
|
const selected = ref('');
|
|
70630
70941
|
const mounted = ref(false);
|
|
70631
70942
|
const language = ref('zh');
|
|
70943
|
+
const copiedCommand = ref('');
|
|
70944
|
+
let copyReset;
|
|
70632
70945
|
const chinese = computed(() => language.value === 'zh');
|
|
70633
70946
|
const languageKey = 'context-language:' + data.site.value.base;
|
|
70634
70947
|
onMounted(() => {
|
|
@@ -70641,6 +70954,76 @@ export default {
|
|
|
70641
70954
|
language.value = value;
|
|
70642
70955
|
try { localStorage.setItem(languageKey, value); } catch {}
|
|
70643
70956
|
};
|
|
70957
|
+
const href = value => value.startsWith('/') ? data.site.value.base + value.slice(1) : value;
|
|
70958
|
+
const external = value => /^https?:\/\//.test(value) || value.startsWith('mailto:');
|
|
70959
|
+
const copyCommand = async value => {
|
|
70960
|
+
try {
|
|
70961
|
+
await navigator.clipboard.writeText(value);
|
|
70962
|
+
copiedCommand.value = value;
|
|
70963
|
+
clearTimeout(copyReset);
|
|
70964
|
+
copyReset = setTimeout(() => { if (copiedCommand.value === value) copiedCommand.value = ''; }, 1600);
|
|
70965
|
+
} catch {}
|
|
70966
|
+
};
|
|
70967
|
+
const links = items => items.flatMap(item => [
|
|
70968
|
+
...(item.link ? [{ text: item.text, link: item.link }] : []),
|
|
70969
|
+
...links(item.items || []),
|
|
70970
|
+
]);
|
|
70971
|
+
const siteMap = () => h('section', { class: 'context-home-section context-home-map', 'aria-labelledby': 'context-home-map-title' }, [
|
|
70972
|
+
h('div', { class: 'context-home-section-heading' }, [
|
|
70973
|
+
h('p', { class: 'context-home-kicker' }, chinese.value ? 'KNOWLEDGE MAP' : 'KNOWLEDGE MAP'),
|
|
70974
|
+
h('h2', { id: 'context-home-map-title' }, chinese.value ? '网站地图' : 'Site map'),
|
|
70975
|
+
h('p', chinese.value ? '从主题进入知识,也可以继续查看栏目中的具体页面。' :
|
|
70976
|
+
'Start with a topic, then continue to the pages within each section.'),
|
|
70977
|
+
]),
|
|
70978
|
+
h('div', { class: 'context-home-map-grid' }, sections.value.map((section, index) => {
|
|
70979
|
+
const pages = links(section.items || []);
|
|
70980
|
+
return h('article', { class: 'context-home-map-card', style: { '--context-home-delay': (index * 35) + 'ms' } }, [
|
|
70981
|
+
h('div', { class: 'context-home-map-card-heading' }, [
|
|
70982
|
+
h('h3', h('a', { href: href(section.href) }, section.title)),
|
|
70983
|
+
h('span', chinese.value ? section.pages.length + ' 页' : section.pages.length + ' pages'),
|
|
70984
|
+
]),
|
|
70985
|
+
pages.length ? h('ul', pages.slice(0, 6).map(page => h('li',
|
|
70986
|
+
h('a', { href: href(page.link) }, page.text)))) : null,
|
|
70987
|
+
pages.length > 6 ? h('a', { class: 'context-home-map-more', href: href(section.href) },
|
|
70988
|
+
chinese.value ? '查看全部 ' + pages.length + ' 页 →' : 'View all ' + pages.length + ' pages →') : null,
|
|
70989
|
+
]);
|
|
70990
|
+
})),
|
|
70991
|
+
]);
|
|
70992
|
+
const resources = () => {
|
|
70993
|
+
const builtins = [
|
|
70994
|
+
{ title: 'LLM Docs', description: chinese.value ? '面向 Agent 和模型的结构化知识入口。' :
|
|
70995
|
+
'Structured knowledge entry points for agents and models.', href: '/llms/index.html', action: chinese.value ? '打开文档' : 'Open docs' },
|
|
70996
|
+
{ title: 'Changelog', description: chinese.value ? '查看知识内容的版本变化与更新时间。' :
|
|
70997
|
+
'Review knowledge versions and update history.', href: '/changelog.html', action: chinese.value ? '查看更新' : 'View updates' },
|
|
70998
|
+
];
|
|
70999
|
+
const items = [...(home.value.resources || []), ...builtins];
|
|
71000
|
+
return h('section', { class: 'context-home-section context-home-resources', 'aria-labelledby': 'context-home-resources-title' }, [
|
|
71001
|
+
h('div', { class: 'context-home-section-heading' }, [
|
|
71002
|
+
h('p', { class: 'context-home-kicker' }, chinese.value ? 'RESOURCES' : 'RESOURCES'),
|
|
71003
|
+
h('h2', { id: 'context-home-resources-title' }, chinese.value ? '工具与资源' : 'Tools and resources'),
|
|
71004
|
+
]),
|
|
71005
|
+
h('div', { class: 'context-home-resource-grid' }, items.map((item, index) => h('article', {
|
|
71006
|
+
class: 'context-home-resource-card', style: { '--context-home-delay': (index * 35) + 'ms' },
|
|
71007
|
+
}, [
|
|
71008
|
+
h('div', { class: 'context-home-resource-heading' }, [
|
|
71009
|
+
h('h3', item.title),
|
|
71010
|
+
h('div', { class: 'context-home-resource-actions' }, [
|
|
71011
|
+
item.command ? h('button', { class: 'context-home-install-action', type: 'button',
|
|
71012
|
+
title: (chinese.value ? '复制安装命令:' : 'Copy install command: ') + item.command,
|
|
71013
|
+
onClick: () => copyCommand(item.command) }, copiedCommand.value === item.command
|
|
71014
|
+
? (chinese.value ? '已复制' : 'Copied') : (chinese.value ? '安装' : 'Install')) : null,
|
|
71015
|
+
item.href ? h('a', { class: 'context-home-resource-action', href: href(item.href), ...(external(item.href)
|
|
71016
|
+
? { target: '_blank', rel: 'noopener noreferrer' } : {}) }, item.action || (chinese.value ? '访问' : 'Open')) : null,
|
|
71017
|
+
]),
|
|
71018
|
+
]),
|
|
71019
|
+
item.description ? h('p', item.description) : null,
|
|
71020
|
+
]))),
|
|
71021
|
+
]);
|
|
71022
|
+
};
|
|
71023
|
+
const poweredBy = () => home.value.branding ? h('footer', { class: 'context-home-powered' }, [
|
|
71024
|
+
home.value.branding.label + ' ',
|
|
71025
|
+
h('a', { href: home.value.branding.href, target: '_blank', rel: 'noopener noreferrer' }, home.value.branding.name),
|
|
71026
|
+
]) : null;
|
|
70644
71027
|
const history = computed(() => data.frontmatter.value.contextHistory
|
|
70645
71028
|
? JSON.parse(new TextDecoder().decode(Uint8Array.from(atob(data.frontmatter.value.contextHistory), char => char.charCodeAt(0)))) : null);
|
|
70646
71029
|
onMounted(() => { mounted.value = true; });
|
|
@@ -70667,6 +71050,7 @@ export default {
|
|
|
70667
71050
|
const active = computed(() => sections.value.find(section => section.key === selected.value));
|
|
70668
71051
|
const inLlms = computed(() => route.path.startsWith(data.site.value.base + 'llms/'));
|
|
70669
71052
|
const inHistory = computed(() => route.path === data.site.value.base + 'changelog.html');
|
|
71053
|
+
const inHome = computed(() => data.frontmatter.value.layout === 'home');
|
|
70670
71054
|
provide(dataSymbol, { ...data, theme: computed(() => ({ ...data.theme.value,
|
|
70671
71055
|
...data.theme.value.contextUiLabels?.[language.value],
|
|
70672
71056
|
sidebar: inLlms.value || inHistory.value ? [] : active.value?.items || [],
|
|
@@ -70678,9 +71062,12 @@ export default {
|
|
|
70678
71062
|
activeMatch: inLlms.value || inHistory.value ? '^' : '(?!)' }],
|
|
70679
71063
|
})) });
|
|
70680
71064
|
const slots = {
|
|
70681
|
-
'nav-bar-content-after': () => h('
|
|
70682
|
-
|
|
70683
|
-
|
|
71065
|
+
'nav-bar-content-after': () => h('button', { class: 'context-language', type: 'button',
|
|
71066
|
+
'aria-label': chinese.value ? 'Switch interface language to English' : '将界面语言切换为中文',
|
|
71067
|
+
title: chinese.value ? 'Switch to English' : '切换为中文',
|
|
71068
|
+
onClick: () => changeLanguage(chinese.value ? 'en' : 'zh') }, chinese.value ? 'EN' : '中文'),
|
|
71069
|
+
'home-features-before': () => [siteMap(), resources()],
|
|
71070
|
+
'home-features-after': poweredBy,
|
|
70684
71071
|
'doc-after': () => history.value ? h('section', { class: 'context-history-cards' },
|
|
70685
71072
|
history.value.length ? history.value.map((entry, index) =>
|
|
70686
71073
|
h('details', { class: 'context-history-card', open: index < 3, key: entry.version }, [
|
|
@@ -70729,7 +71116,8 @@ export default {
|
|
|
70729
71116
|
},
|
|
70730
71117
|
};
|
|
70731
71118
|
// History belongs between the page heading and footer metadata.
|
|
70732
|
-
return () => h(DefaultTheme.Layout, { class:
|
|
71119
|
+
return () => h(DefaultTheme.Layout, { class: inHome.value ? 'context-home' :
|
|
71120
|
+
inLlms.value || inHistory.value ? 'context-empty-sidebar' : undefined }, { ...slots, 'doc-after': undefined,
|
|
70733
71121
|
'doc-footer-before': () => [slots['doc-after'](), slots['doc-footer-before']()] });
|
|
70734
71122
|
}
|
|
70735
71123
|
},
|
|
@@ -70789,10 +71177,20 @@ export default {
|
|
|
70789
71177
|
`;
|
|
70790
71178
|
});
|
|
70791
71179
|
|
|
71180
|
+
// src/project/packageSiteBranding.ts
|
|
71181
|
+
var packageSiteBranding;
|
|
71182
|
+
var init_packageSiteBranding = __esm(() => {
|
|
71183
|
+
packageSiteBranding = {
|
|
71184
|
+
label: "Powered by",
|
|
71185
|
+
name: "context4ai/context",
|
|
71186
|
+
href: "https://github.com/context4ai/context"
|
|
71187
|
+
};
|
|
71188
|
+
});
|
|
71189
|
+
|
|
70792
71190
|
// src/project/packageSite.ts
|
|
70793
71191
|
import { createHash as createHash16 } from "node:crypto";
|
|
70794
71192
|
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";
|
|
71193
|
+
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
71194
|
import { createRequire as createRequire5 } from "node:module";
|
|
70797
71195
|
import { dirname as dirname23, join as join56, posix as posix6 } from "node:path";
|
|
70798
71196
|
function sitePagePath(identity) {
|
|
@@ -70986,6 +71384,7 @@ async function writePackageSite(input) {
|
|
|
70986
71384
|
contextUpdated: historyDate,
|
|
70987
71385
|
contextUiLabels: { zh: siteThemeLabels("zh"), en: siteThemeLabels("en") },
|
|
70988
71386
|
contextSections: sections.map(({ key, title, href, pages, items }) => ({ key, title, href, pages, items })),
|
|
71387
|
+
contextHome: { resources: options.home?.resources ?? [], branding: packageSiteBranding },
|
|
70989
71388
|
sidebar: sections[0]?.items ?? [],
|
|
70990
71389
|
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
71390
|
}
|
|
@@ -71022,11 +71421,24 @@ ${body}`);
|
|
|
71022
71421
|
`) + `
|
|
71023
71422
|
`);
|
|
71024
71423
|
}
|
|
71025
|
-
const
|
|
71026
|
-
|
|
71027
|
-
|
|
71028
|
-
|
|
71029
|
-
|
|
71424
|
+
const chinese = (options.lang ?? "en-US").startsWith("zh");
|
|
71425
|
+
const firstSection = sections[0]?.href ?? "/llms/index.html";
|
|
71426
|
+
const featuredResources = (options.home?.resources ?? []).filter((resource) => resource.featured && resource.href);
|
|
71427
|
+
const hero = {
|
|
71428
|
+
name: options.home?.title ?? options.title ?? pkg.name,
|
|
71429
|
+
text: options.home?.slogan ?? (chinese ? "从知识地图开始探索" : "Explore from the knowledge map"),
|
|
71430
|
+
tagline: options.home?.description ?? options.description ?? "",
|
|
71431
|
+
actions: options.home?.actions ?? [
|
|
71432
|
+
{ theme: "brand", text: chinese ? "浏览知识" : "Browse knowledge", link: firstSection },
|
|
71433
|
+
...featuredResources.map((resource) => ({ theme: "alt", text: resource.title, link: resource.href })),
|
|
71434
|
+
{ theme: "alt", text: "LLM Docs", link: "/llms/index.html" }
|
|
71435
|
+
]
|
|
71436
|
+
};
|
|
71437
|
+
await writeFile14(join56(temporary, "index.md"), `---
|
|
71438
|
+
layout: home
|
|
71439
|
+
title: ${JSON.stringify(options.home?.title ?? options.title ?? pkg.name)}
|
|
71440
|
+
hero: ${JSON.stringify(hero)}
|
|
71441
|
+
---
|
|
71030
71442
|
`);
|
|
71031
71443
|
await writeFile14(join56(temporary, "changelog.md"), `---
|
|
71032
71444
|
title: Changelog
|
|
@@ -71068,6 +71480,15 @@ title: LLM Docs
|
|
|
71068
71480
|
await cp(join56(root, path2), destination);
|
|
71069
71481
|
}
|
|
71070
71482
|
await compileSite(temporary, output);
|
|
71483
|
+
for (const file of await walkPackageFiles(output)) {
|
|
71484
|
+
const extension2 = posix6.extname(file.relPath).toLowerCase();
|
|
71485
|
+
const placeholder = [".css", ".js", ".mjs", ".cjs"].includes(extension2) ? `/* Intentionally empty. */
|
|
71486
|
+
` : [".html", ".htm"].includes(extension2) ? `<!-- Intentionally empty. -->
|
|
71487
|
+
` : null;
|
|
71488
|
+
if (placeholder !== null && (await stat7(file.absPath)).size === 0) {
|
|
71489
|
+
await writeFile14(file.absPath, placeholder);
|
|
71490
|
+
}
|
|
71491
|
+
}
|
|
71071
71492
|
await writeFile14(join56(output, "context-site-map.json"), JSON.stringify({
|
|
71072
71493
|
protocol: "context.site-output/v1",
|
|
71073
71494
|
knowledge_map_revision: structure?.revision ?? null,
|
|
@@ -71084,7 +71505,7 @@ title: LLM Docs
|
|
|
71084
71505
|
await rm11(temporary, { recursive: true, force: true });
|
|
71085
71506
|
}
|
|
71086
71507
|
}
|
|
71087
|
-
var PACKAGE_SITE_VERSION = "vitepress-site-
|
|
71508
|
+
var PACKAGE_SITE_VERSION = "vitepress-site-v42-section-anchor-blocks", require2, encodePath = (path2) => path2.split("/").map(encodeURIComponent).join("/"), mdLabel = (value) => value.replace(/[\\[\]<>`*]/gu, "\\$&").replace(/[\r\n]/gu, " ");
|
|
71088
71509
|
var init_packageSite2 = __esm(() => {
|
|
71089
71510
|
init_packageOutputPaths();
|
|
71090
71511
|
init_workspaceChangelog();
|
|
@@ -71096,6 +71517,7 @@ var init_packageSite2 = __esm(() => {
|
|
|
71096
71517
|
init_packageKnowledgeMap();
|
|
71097
71518
|
init_markdownLinks();
|
|
71098
71519
|
init_packageSiteTheme();
|
|
71520
|
+
init_packageSiteBranding();
|
|
71099
71521
|
require2 = createRequire5(import.meta.url);
|
|
71100
71522
|
});
|
|
71101
71523
|
|
|
@@ -72274,7 +72696,7 @@ function validateRenderedSkillDefinition(input) {
|
|
|
72274
72696
|
}
|
|
72275
72697
|
let frontmatter;
|
|
72276
72698
|
try {
|
|
72277
|
-
frontmatter =
|
|
72699
|
+
frontmatter = import_yaml33.parse(frontmatterMatch[1]);
|
|
72278
72700
|
} catch {
|
|
72279
72701
|
frontmatter = null;
|
|
72280
72702
|
}
|
|
@@ -72301,7 +72723,7 @@ function validateRenderedSkillDefinition(input) {
|
|
|
72301
72723
|
});
|
|
72302
72724
|
}
|
|
72303
72725
|
}
|
|
72304
|
-
var
|
|
72726
|
+
var import_yaml33, OKF_OUTPUT_ROOTS2, SKILL_NAME_PATTERN;
|
|
72305
72727
|
var init_packageTemplateGuard = __esm(() => {
|
|
72306
72728
|
init_cliFeedback();
|
|
72307
72729
|
init_errors3();
|
|
@@ -72309,7 +72731,7 @@ var init_packageTemplateGuard = __esm(() => {
|
|
|
72309
72731
|
init_packageIndexes();
|
|
72310
72732
|
init_packageDistribution();
|
|
72311
72733
|
init_packageTemplateUtils();
|
|
72312
|
-
|
|
72734
|
+
import_yaml33 = __toESM(require_dist(), 1);
|
|
72313
72735
|
OKF_OUTPUT_ROOTS2 = new Set(["wikis", "guides", "rules", "feats"]);
|
|
72314
72736
|
SKILL_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/u;
|
|
72315
72737
|
});
|
|
@@ -72370,7 +72792,7 @@ function isDeprecatedKnowledge(content3) {
|
|
|
72370
72792
|
if (match?.[1] === undefined)
|
|
72371
72793
|
return false;
|
|
72372
72794
|
try {
|
|
72373
|
-
const frontmatter =
|
|
72795
|
+
const frontmatter = import_yaml35.parse(match[1]);
|
|
72374
72796
|
return frontmatter !== null && typeof frontmatter === "object" && !Array.isArray(frontmatter) && frontmatter.deprecated === true;
|
|
72375
72797
|
} catch {
|
|
72376
72798
|
return false;
|
|
@@ -72797,10 +73219,11 @@ async function buildProjectPackagesInternal(projectRoot, options) {
|
|
|
72797
73219
|
if (!production && (!maintenanceActive || (await readRevisionDelivery(projectRoot))?.partial) && !await readTaskRollback(projectRoot))
|
|
72798
73220
|
await completeRevisionDelivery(projectRoot);
|
|
72799
73221
|
const { finishApprovedRevision } = await Promise.resolve().then(() => (init_approvedRevision(), exports_approvedRevision));
|
|
72800
|
-
await finishApprovedRevision(projectRoot);
|
|
72801
73222
|
const { readApprovedRevision: readApprovedRevision2 } = await Promise.resolve().then(() => (init_approvedRevision(), exports_approvedRevision));
|
|
73223
|
+
const revisionInterruptedProduction = !!production && !!await readApprovedRevision2(projectRoot);
|
|
73224
|
+
await finishApprovedRevision(projectRoot);
|
|
72802
73225
|
const { readKnowledgeUpdate } = await Promise.resolve().then(() => (init_knowledgeUpdate(), exports_knowledgeUpdate));
|
|
72803
|
-
if (!production?.delivery && !maintenanceActive && !await readTaskRollback(projectRoot) && !await readApprovedRevision2(projectRoot) && !await readKnowledgeUpdate(projectRoot) && (await readProjectCloseStatus(projectRoot)).state === "ready") {
|
|
73226
|
+
if (!revisionInterruptedProduction && !production?.delivery && !maintenanceActive && !await readTaskRollback(projectRoot) && !await readApprovedRevision2(projectRoot) && !await readKnowledgeUpdate(projectRoot) && (await readProjectCloseStatus(projectRoot)).state === "ready") {
|
|
72804
73227
|
const { clearCompletedLifecycle: clearCompletedLifecycle2 } = await Promise.resolve().then(() => (init_lifecycleCleanup(), exports_lifecycleCleanup));
|
|
72805
73228
|
await clearCompletedLifecycle2(projectRoot);
|
|
72806
73229
|
}
|
|
@@ -72901,7 +73324,7 @@ async function runProjectBuildCommand(input) {
|
|
|
72901
73324
|
process.stdout.write(formatProjectBuildResult(result, input.format ?? "text", input.verbose === true));
|
|
72902
73325
|
return true;
|
|
72903
73326
|
}
|
|
72904
|
-
var
|
|
73327
|
+
var import_yaml35, PACKAGE_FINGERPRINT_ROOT, PACKAGE_BUILDER_PROTOCOL_VERSION = "v23-sibling-site-output";
|
|
72905
73328
|
var init_packageBuilder = __esm(() => {
|
|
72906
73329
|
init_knowledgeMap2();
|
|
72907
73330
|
init_approvedFileRead();
|
|
@@ -72938,7 +73361,7 @@ var init_packageBuilder = __esm(() => {
|
|
|
72938
73361
|
init_workspace();
|
|
72939
73362
|
init_packageTemplateReview();
|
|
72940
73363
|
init_approvedKnowledgeMetadata();
|
|
72941
|
-
|
|
73364
|
+
import_yaml35 = __toESM(require_dist(), 1);
|
|
72942
73365
|
PACKAGE_FINGERPRINT_ROOT = join62(".tmp", "context-runtime", "packages");
|
|
72943
73366
|
});
|
|
72944
73367
|
|
|
@@ -73691,7 +74114,7 @@ __export(exports_approvedRevision, {
|
|
|
73691
74114
|
assertApprovedRevisionBase: () => assertApprovedRevisionBase,
|
|
73692
74115
|
APPROVED_REVISION_PATH: () => APPROVED_REVISION_PATH
|
|
73693
74116
|
});
|
|
73694
|
-
import { readFile as readFile56, realpath as realpath6 } from "node:fs/promises";
|
|
74117
|
+
import { readFile as readFile56, realpath as realpath6, rm as rm15 } from "node:fs/promises";
|
|
73695
74118
|
import { join as join66, relative as relative19, isAbsolute as isAbsolute12 } from "node:path";
|
|
73696
74119
|
function requestDigest(input) {
|
|
73697
74120
|
const scopes = input.processed_scopes?.filter((scope2) => input.target.source_refs.some((ref) => ref === scope2.source_ref || ref.startsWith(`${scope2.source_ref}#`) || ref.startsWith(`${scope2.source_ref}/`)));
|
|
@@ -73709,7 +74132,7 @@ function parseApprovedRevision(value) {
|
|
|
73709
74132
|
if (!value || typeof value !== "object" || !("protocol" in value) || value.protocol !== "context.approved-revision/v1")
|
|
73710
74133
|
return;
|
|
73711
74134
|
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.
|
|
74135
|
+
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
74136
|
throw new TypeError("Approved revision target or digest is invalid");
|
|
73714
74137
|
const { candidate: raw, batch_candidates: batch, ...rest } = parsed;
|
|
73715
74138
|
const request = { ...rest, ...batch === undefined ? {} : { batch_candidates: batch.map((item, index2) => parseCandidateRecord(item, index2 + 1)) } };
|
|
@@ -73902,12 +74325,15 @@ async function prepareApprovedRevision(input) {
|
|
|
73902
74325
|
};
|
|
73903
74326
|
}
|
|
73904
74327
|
if (input.move_to !== undefined) {
|
|
73905
|
-
|
|
73906
|
-
|
|
74328
|
+
const destinationCollection = indexerKnowledgeCollectionSchema2.safeParse(input.move_to.split("/")[0]);
|
|
74329
|
+
if (input.create || !destinationCollection.success || !isSafeKnowledgeTargetPath(destinationCollection.data, input.move_to) || input.move_to.includes("\\") || input.move_to === target.path) {
|
|
74330
|
+
throw new TypeError("Move requires a different safe path in a supported knowledge collection.");
|
|
73907
74331
|
}
|
|
73908
74332
|
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
|
-
|
|
74333
|
+
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 : `---
|
|
74334
|
+
${import_yaml36.default.stringify({ ...import_yaml36.default.parse(fields), type: okfTypeForCollection(destinationCollection.data) }).trimEnd()}
|
|
74335
|
+
---`);
|
|
74336
|
+
target = { ...target, collection: destinationCollection.data, previous_path: target.path, path: input.move_to, markdown: movedMarkdown };
|
|
73911
74337
|
await assertApprovedRevisionBase(input.projectRoot, { target });
|
|
73912
74338
|
}
|
|
73913
74339
|
if (input.supporting_sources) {
|
|
@@ -73958,7 +74384,7 @@ async function prepareApprovedRevision(input) {
|
|
|
73958
74384
|
}
|
|
73959
74385
|
function frontmatter(markdown) {
|
|
73960
74386
|
const match = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/u.exec(markdown);
|
|
73961
|
-
const parsed = match ?
|
|
74387
|
+
const parsed = match ? import_yaml36.default.parse(match[1]) : undefined;
|
|
73962
74388
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
73963
74389
|
throw new TypeError("Revision must retain the approved page frontmatter");
|
|
73964
74390
|
return parsed;
|
|
@@ -74143,6 +74569,11 @@ async function advanceApprovedRevision(projectRoot, request) {
|
|
|
74143
74569
|
const { finishMaintenanceRevision: finishMaintenanceRevision2 } = await Promise.resolve().then(() => (init_knowledgeMaintenance(), exports_knowledgeMaintenance));
|
|
74144
74570
|
if (await finishMaintenanceRevision2(projectRoot))
|
|
74145
74571
|
return;
|
|
74572
|
+
const { readProductionStage: readProductionStage2 } = await Promise.resolve().then(() => (init_productionStageStore(), exports_productionStageStore));
|
|
74573
|
+
if (await readProductionStage2(projectRoot)) {
|
|
74574
|
+
await rm15(join66(projectRoot, await revisionStoragePath(projectRoot)), { force: true });
|
|
74575
|
+
return;
|
|
74576
|
+
}
|
|
74146
74577
|
const { clearCompletedLifecycle: clearCompletedLifecycle2 } = await Promise.resolve().then(() => (init_lifecycleCleanup(), exports_lifecycleCleanup));
|
|
74147
74578
|
await clearCompletedLifecycle2(projectRoot);
|
|
74148
74579
|
}
|
|
@@ -74246,7 +74677,7 @@ async function reopenApprovedRevision(input) {
|
|
|
74246
74677
|
};
|
|
74247
74678
|
});
|
|
74248
74679
|
}
|
|
74249
|
-
var
|
|
74680
|
+
var import_yaml36, digest5, revisionTargetSchema, requestSchema2;
|
|
74250
74681
|
var init_approvedRevision = __esm(() => {
|
|
74251
74682
|
init_productionRequirements();
|
|
74252
74683
|
init_approvedRevisionEdits();
|
|
@@ -74263,8 +74694,9 @@ var init_approvedRevision = __esm(() => {
|
|
|
74263
74694
|
init_durableSingleFileTransaction();
|
|
74264
74695
|
init_durableMultiFileTransaction();
|
|
74265
74696
|
init_processedScopeStorage();
|
|
74697
|
+
init_okfTypes();
|
|
74266
74698
|
init_maintenanceStorage();
|
|
74267
|
-
|
|
74699
|
+
import_yaml36 = __toESM(require_dist(), 1);
|
|
74268
74700
|
digest5 = exports_external.string().regex(/^sha256:[a-f0-9]{64}$/u);
|
|
74269
74701
|
revisionTargetSchema = exports_external.object({
|
|
74270
74702
|
path: exports_external.string().min(1),
|
|
@@ -80458,7 +80890,7 @@ var init_documentRun = __esm(() => {
|
|
|
80458
80890
|
});
|
|
80459
80891
|
|
|
80460
80892
|
// src/lib/atomicFileBatch.ts
|
|
80461
|
-
import { lstat as lstat7, mkdir as mkdir25, mkdtemp as mkdtemp3, rename as rename6, rm as
|
|
80893
|
+
import { lstat as lstat7, mkdir as mkdir25, mkdtemp as mkdtemp3, rename as rename6, rm as rm16, writeFile as writeFile19 } from "node:fs/promises";
|
|
80462
80894
|
import { dirname as dirname31, join as join70, resolve as resolve23 } from "node:path";
|
|
80463
80895
|
async function existingFileKind(path2) {
|
|
80464
80896
|
try {
|
|
@@ -80521,7 +80953,7 @@ async function applyAtomicFileBatch(input) {
|
|
|
80521
80953
|
} catch (error) {
|
|
80522
80954
|
const rollbackFailures = [];
|
|
80523
80955
|
for (const path2 of installed.reverse()) {
|
|
80524
|
-
await
|
|
80956
|
+
await rm16(path2, { force: true }).catch((rollbackError) => {
|
|
80525
80957
|
rollbackFailures.push(`remove ${path2}: ${String(rollbackError)}`);
|
|
80526
80958
|
});
|
|
80527
80959
|
}
|
|
@@ -80538,7 +80970,7 @@ async function applyAtomicFileBatch(input) {
|
|
|
80538
80970
|
throw error;
|
|
80539
80971
|
} finally {
|
|
80540
80972
|
if (!preserveTransaction)
|
|
80541
|
-
await
|
|
80973
|
+
await rm16(transactionDir, { recursive: true, force: true });
|
|
80542
80974
|
}
|
|
80543
80975
|
}
|
|
80544
80976
|
var init_atomicFileBatch = () => {};
|
|
@@ -81718,7 +82150,7 @@ async function approveProductionReport(input) {
|
|
|
81718
82150
|
throw new TypeError("The report's plan changed. Read and present the current proposal before confirming it.");
|
|
81719
82151
|
}
|
|
81720
82152
|
const file = input.manifest ?? await readProductionFile(input);
|
|
81721
|
-
const decision = productionReportInputSchema.extend({ stage: exports_external.literal(stage.id) }).parse(
|
|
82153
|
+
const decision = productionReportInputSchema.extend({ stage: exports_external.literal(stage.id) }).parse(import_yaml39.default.parse(file.text));
|
|
81722
82154
|
if (!stage.report_approved)
|
|
81723
82155
|
await assertProductionPlanRequirementsCurrent(input.projectRoot, stage);
|
|
81724
82156
|
if (decision.decision === "approved")
|
|
@@ -81734,7 +82166,7 @@ async function approveProductionReport(input) {
|
|
|
81734
82166
|
}
|
|
81735
82167
|
}));
|
|
81736
82168
|
}
|
|
81737
|
-
var
|
|
82169
|
+
var import_yaml39, productionReportInputSchema;
|
|
81738
82170
|
var init_productionReport = __esm(() => {
|
|
81739
82171
|
init_zod();
|
|
81740
82172
|
init_src2();
|
|
@@ -81744,7 +82176,7 @@ var init_productionReport = __esm(() => {
|
|
|
81744
82176
|
init_productionStagePreparation();
|
|
81745
82177
|
init_productionPlanning();
|
|
81746
82178
|
init_productionFeedback();
|
|
81747
|
-
|
|
82179
|
+
import_yaml39 = __toESM(require_dist(), 1);
|
|
81748
82180
|
productionReportInputSchema = exports_external.object({ stage: exports_external.string().min(1), decision: exports_external.literal("approved") }).strict();
|
|
81749
82181
|
});
|
|
81750
82182
|
|
|
@@ -86644,7 +87076,7 @@ var init_larkResourceCommand = __esm(() => {
|
|
|
86644
87076
|
|
|
86645
87077
|
// src/lib/larkResourceMaterialization.ts
|
|
86646
87078
|
import { createHash as createHash26 } from "node:crypto";
|
|
86647
|
-
import { mkdtemp as mkdtemp4, readFile as readFile67, readdir as readdir18, rm as
|
|
87079
|
+
import { mkdtemp as mkdtemp4, readFile as readFile67, readdir as readdir18, rm as rm19 } from "node:fs/promises";
|
|
86648
87080
|
import { extname as extname13, join as join88 } from "node:path";
|
|
86649
87081
|
import { tmpdir } from "node:os";
|
|
86650
87082
|
function countByKind(items, status) {
|
|
@@ -86777,7 +87209,7 @@ async function downloadedFile(input) {
|
|
|
86777
87209
|
const bytes = await readFile67(join88(tempRoot, path3));
|
|
86778
87210
|
return { path: path3, bytes, mediaType: mediaTypeFor(path3, bytes) };
|
|
86779
87211
|
} finally {
|
|
86780
|
-
await
|
|
87212
|
+
await rm19(tempRoot, { recursive: true, force: true });
|
|
86781
87213
|
}
|
|
86782
87214
|
}
|
|
86783
87215
|
function parseCsv(value) {
|
|
@@ -86909,7 +87341,7 @@ ${markdownTable2(parseCsv(csv))}
|
|
|
86909
87341
|
[CSV snapshot](${sourceAssetTarget(path3)}) <!-- ${resource.locator} -->`
|
|
86910
87342
|
};
|
|
86911
87343
|
} finally {
|
|
86912
|
-
await
|
|
87344
|
+
await rm19(tempRoot, { recursive: true, force: true });
|
|
86913
87345
|
}
|
|
86914
87346
|
}
|
|
86915
87347
|
function basePageRecords(value) {
|
|
@@ -87043,7 +87475,7 @@ async function whiteboardMaterialization(resource, runner2, identity) {
|
|
|
87043
87475
|
], { cwd: tempRoot });
|
|
87044
87476
|
rawPayload = JSON.parse(await readFile67(join88(tempRoot, "raw.json"), "utf8"));
|
|
87045
87477
|
} finally {
|
|
87046
|
-
await
|
|
87478
|
+
await rm19(tempRoot, { recursive: true, force: true });
|
|
87047
87479
|
}
|
|
87048
87480
|
const digest6 = resourceDigest(resource);
|
|
87049
87481
|
const previewPath = `materialized/${resource.kind}/${digest6}${extensionFor2(preview.mediaType, preview.path)}`;
|
|
@@ -88328,6 +88760,355 @@ var init_actionInputWorkspace = __esm(() => {
|
|
|
88328
88760
|
init_workspace();
|
|
88329
88761
|
});
|
|
88330
88762
|
|
|
88763
|
+
// src/project/articleRetirement.ts
|
|
88764
|
+
var exports_articleRetirement = {};
|
|
88765
|
+
__export(exports_articleRetirement, {
|
|
88766
|
+
retireArticles: () => retireArticles,
|
|
88767
|
+
articleRetirementSchema: () => articleRetirementSchema
|
|
88768
|
+
});
|
|
88769
|
+
import { readFile as readFile74, readdir as readdir20 } from "node:fs/promises";
|
|
88770
|
+
import { posix as posix10 } from "node:path";
|
|
88771
|
+
function invalid(reason, message, details = {}) {
|
|
88772
|
+
throw new ContextError(ExitCode.UserError, message, {
|
|
88773
|
+
category: ErrorCategory.UserInputInvalid,
|
|
88774
|
+
reason_code: reason,
|
|
88775
|
+
...details,
|
|
88776
|
+
next_action: {
|
|
88777
|
+
command: next,
|
|
88778
|
+
message: "Keep the retirement input. Resolve the listed page/reference or finish the active revision, then preview it again; no retirement was applied."
|
|
88779
|
+
}
|
|
88780
|
+
});
|
|
88781
|
+
}
|
|
88782
|
+
async function text9(root2, path3) {
|
|
88783
|
+
try {
|
|
88784
|
+
return await readFile74(await safeProjectTarget(root2, path3), "utf8");
|
|
88785
|
+
} catch (error) {
|
|
88786
|
+
if (error.code === "ENOENT")
|
|
88787
|
+
return;
|
|
88788
|
+
throw error;
|
|
88789
|
+
}
|
|
88790
|
+
}
|
|
88791
|
+
async function retireArticles(input) {
|
|
88792
|
+
const parsed = articleRetirementSchema.safeParse(input.value);
|
|
88793
|
+
if (!parsed.success)
|
|
88794
|
+
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)" }] } });
|
|
88795
|
+
const value = parsed.data;
|
|
88796
|
+
return withProjectWriteLock(input.projectRoot, "retire-articles", async () => {
|
|
88797
|
+
if (input.apply)
|
|
88798
|
+
await recoverDurableMultiFileTransactions(input.projectRoot);
|
|
88799
|
+
if (input.apply && input.plan_digest && /^sha256:[a-f0-9]{64}$/u.test(input.plan_digest)) {
|
|
88800
|
+
const receipt3 = await text9(input.projectRoot, `.tmp/context-runtime/retirements/${input.plan_digest.slice(7)}/receipt.json`);
|
|
88801
|
+
if (receipt3) {
|
|
88802
|
+
const saved = JSON.parse(receipt3);
|
|
88803
|
+
if (saved.request !== indexerProtocolDigest(value))
|
|
88804
|
+
invalid("article-retirement-input-changed", "The retirement input differs from the applied request.");
|
|
88805
|
+
for (const file of saved.files) {
|
|
88806
|
+
const current2 = await text9(input.projectRoot, file.path);
|
|
88807
|
+
if ((current2 === undefined ? null : durableContentDigest(current2)) !== file.digest)
|
|
88808
|
+
invalid("article-retirement-result-changed", "Retirement was applied but a resulting file has since changed; inspect the current workspace.", { path: file.path });
|
|
88809
|
+
}
|
|
88810
|
+
return { action: "already-applied", revision: input.plan_digest, next_action: { command: next } };
|
|
88811
|
+
}
|
|
88812
|
+
}
|
|
88813
|
+
const maintenance = await readMaintenance(input.projectRoot);
|
|
88814
|
+
if ((await readCandidateRecords(input.projectRoot)).length || await readApprovedRevision(input.projectRoot) || await readKnowledgeUpdate(input.projectRoot) || await readTaskRollback(input.projectRoot) || maintenance.active) {
|
|
88815
|
+
invalid("article-retirement-active-review", "Finish the active candidate/revision delivery before retiring approved pages.");
|
|
88816
|
+
}
|
|
88817
|
+
const before = await text9(input.projectRoot, "knowledge/structure.yaml");
|
|
88818
|
+
const structure = before === undefined ? {} : import_yaml41.default.parse(before);
|
|
88819
|
+
const articles = validateArticleStructureEntries(structure.articles ?? []);
|
|
88820
|
+
const byPath = new Map(articles.map((article) => [article.path, article]));
|
|
88821
|
+
const selected = new Set(value.targets.map((target) => target.path));
|
|
88822
|
+
if (selected.size !== value.targets.length)
|
|
88823
|
+
invalid("article-retirement-duplicate", "Select each approved article once.");
|
|
88824
|
+
if (maintenance.pending.some((request) => request.targets.some((target) => selected.has(target.path)))) {
|
|
88825
|
+
invalid("article-retirement-pending-maintenance", "Cancel or finish queued maintenance for the selected pages before retirement.");
|
|
88826
|
+
}
|
|
88827
|
+
const stage = await readProductionStage(input.projectRoot);
|
|
88828
|
+
if (stage?.tasks.some((task) => selected.has(task.path) && !["accepted", "excluded", "replaced"].includes(task.status))) {
|
|
88829
|
+
invalid("article-retirement-pending-task", "A selected article still has unfinished production; finish or amend that task first.");
|
|
88830
|
+
}
|
|
88831
|
+
const replacements = new Map;
|
|
88832
|
+
for (const target of value.targets) {
|
|
88833
|
+
if (!byPath.has(target.path))
|
|
88834
|
+
invalid("article-retirement-target-missing", "Select an exact approved article path from knowledge/structure.yaml.", { path: target.path });
|
|
88835
|
+
if (target.replacement !== undefined && (!byPath.has(target.replacement) || selected.has(target.replacement))) {
|
|
88836
|
+
invalid("article-retirement-replacement-invalid", "Replacement must be an already-approved article outside the retirement set.", { path: target.path, replacement: target.replacement });
|
|
88837
|
+
}
|
|
88838
|
+
replacements.set(target.path, target.replacement);
|
|
88839
|
+
}
|
|
88840
|
+
const targets = [];
|
|
88841
|
+
const restore = [];
|
|
88842
|
+
function change(path3, old, content3) {
|
|
88843
|
+
if (old === content3)
|
|
88844
|
+
return;
|
|
88845
|
+
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 });
|
|
88846
|
+
restore.push({ path: path3, base_digest: content3 === undefined ? null : durableContentDigest(content3), content: old ?? null });
|
|
88847
|
+
}
|
|
88848
|
+
const blockers = [];
|
|
88849
|
+
const readDigests = [];
|
|
88850
|
+
for (const article of articles) {
|
|
88851
|
+
const path3 = `knowledge/${article.path}`;
|
|
88852
|
+
const bytes = await text9(input.projectRoot, path3);
|
|
88853
|
+
if (bytes === undefined)
|
|
88854
|
+
invalid("article-retirement-article-missing", "Approved article bytes are missing; recover the workspace before retirement.", { path: path3 });
|
|
88855
|
+
readDigests.push({ path: path3, digest: durableContentDigest(bytes) });
|
|
88856
|
+
if (selected.has(article.path)) {
|
|
88857
|
+
change(path3, bytes);
|
|
88858
|
+
continue;
|
|
88859
|
+
}
|
|
88860
|
+
const content3 = replaceMarkdownInlineLinkTargets(bytes, (link2) => {
|
|
88861
|
+
if (link2.target.startsWith("#") || link2.target.startsWith("//"))
|
|
88862
|
+
return;
|
|
88863
|
+
const knowledge = link2.target.startsWith("knowledge:");
|
|
88864
|
+
if (!knowledge && /^[a-z][a-z0-9+.-]*:/iu.test(link2.target))
|
|
88865
|
+
return;
|
|
88866
|
+
const match = /^([^#?]*)(.*)$/u.exec(knowledge ? link2.target.slice(10) : link2.target);
|
|
88867
|
+
let target;
|
|
88868
|
+
try {
|
|
88869
|
+
target = decodeURI(match[1]);
|
|
88870
|
+
} catch {
|
|
88871
|
+
return;
|
|
88872
|
+
}
|
|
88873
|
+
const rooted = /^\/?knowledge\//u.test(target);
|
|
88874
|
+
if (target.startsWith("/") && !rooted)
|
|
88875
|
+
return;
|
|
88876
|
+
let resolved = knowledge ? target : rooted ? target.replace(/^\/?knowledge\//u, "") : posix10.normalize(posix10.join(posix10.dirname(article.path), target));
|
|
88877
|
+
if (knowledge && !resolved.endsWith(".md"))
|
|
88878
|
+
resolved += ".md";
|
|
88879
|
+
if (!selected.has(resolved))
|
|
88880
|
+
return;
|
|
88881
|
+
const replacement = replacements.get(resolved);
|
|
88882
|
+
if (!replacement || match[2].includes("#")) {
|
|
88883
|
+
blockers.push({ path: path3, target: link2.target, reason: replacement ? "Repair fragment links explicitly before retirement." : "Repair this incoming link or supply an approved replacement." });
|
|
88884
|
+
return;
|
|
88885
|
+
}
|
|
88886
|
+
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]}`;
|
|
88887
|
+
});
|
|
88888
|
+
change(path3, bytes, content3);
|
|
88889
|
+
}
|
|
88890
|
+
async function inspectTemplates(directory2) {
|
|
88891
|
+
const absolute = await safeProjectTarget(input.projectRoot, directory2);
|
|
88892
|
+
const entries2 = await readdir20(absolute, { withFileTypes: true }).catch((error) => {
|
|
88893
|
+
if (error.code === "ENOENT")
|
|
88894
|
+
return [];
|
|
88895
|
+
throw error;
|
|
88896
|
+
});
|
|
88897
|
+
for (const entry of entries2) {
|
|
88898
|
+
const path3 = `${directory2}/${entry.name}`;
|
|
88899
|
+
if (entry.isDirectory()) {
|
|
88900
|
+
await inspectTemplates(path3);
|
|
88901
|
+
continue;
|
|
88902
|
+
}
|
|
88903
|
+
if (!entry.isFile() || !entry.name.endsWith(".md"))
|
|
88904
|
+
continue;
|
|
88905
|
+
const bytes = await text9(input.projectRoot, path3);
|
|
88906
|
+
readDigests.push({ path: path3, digest: durableContentDigest(bytes) });
|
|
88907
|
+
replaceMarkdownInlineLinkTargets(bytes, (link2) => {
|
|
88908
|
+
if (/^(?!knowledge:)[a-z][a-z0-9+.-]*:/iu.test(link2.target))
|
|
88909
|
+
return;
|
|
88910
|
+
let destination;
|
|
88911
|
+
try {
|
|
88912
|
+
destination = decodeURI(link2.target.split(/[?#]/u)[0]);
|
|
88913
|
+
} catch {
|
|
88914
|
+
return;
|
|
88915
|
+
}
|
|
88916
|
+
if (destination.startsWith("knowledge:") && !destination.endsWith(".md"))
|
|
88917
|
+
destination += ".md";
|
|
88918
|
+
if ([...selected].some((old) => destination === old || destination.endsWith(`/${old}`) || destination === `knowledge:${old}`)) {
|
|
88919
|
+
blockers.push({ path: path3, target: link2.target, reason: "Update this custom package-template link before retirement." });
|
|
88920
|
+
}
|
|
88921
|
+
return;
|
|
88922
|
+
});
|
|
88923
|
+
}
|
|
88924
|
+
}
|
|
88925
|
+
await inspectTemplates("src/package-templates");
|
|
88926
|
+
const map4 = await readKnowledgeMap(input.projectRoot);
|
|
88927
|
+
if (map4) {
|
|
88928
|
+
const retiredIds = new Map(value.targets.map((target) => [byPath.get(target.path).article_id, target]));
|
|
88929
|
+
const upsert = map4.entries.flatMap((entry) => {
|
|
88930
|
+
const target = entry.target && retiredIds.get(entry.target.artifact_ref);
|
|
88931
|
+
if (!target)
|
|
88932
|
+
return [];
|
|
88933
|
+
if (target.replacement && entry.target?.section_key) {
|
|
88934
|
+
blockers.push({ path: KNOWLEDGE_MAP_PATH, target: entry.key, reason: "Rebind this fragment navigation entry explicitly before retirement." });
|
|
88935
|
+
return [];
|
|
88936
|
+
}
|
|
88937
|
+
const { target: _old, ...group } = entry;
|
|
88938
|
+
return [target.replacement ? { ...group, target: { artifact_ref: byPath.get(target.replacement).article_id } } : group];
|
|
88939
|
+
});
|
|
88940
|
+
const updated = updateKnowledgeMap(map4, { expected_revision: map4.revision, upsert, remove: [] });
|
|
88941
|
+
change(KNOWLEDGE_MAP_PATH, await text9(input.projectRoot, KNOWLEDGE_MAP_PATH), import_yaml41.default.stringify(updated));
|
|
88942
|
+
}
|
|
88943
|
+
change("knowledge/structure.yaml", before, import_yaml41.default.stringify({ ...structure, articles: articles.filter((article) => !selected.has(article.path)) }));
|
|
88944
|
+
targets.sort((a, b) => a.path.localeCompare(b.path));
|
|
88945
|
+
const revision = indexerProtocolDigest({ value, readDigests, targets });
|
|
88946
|
+
const preview = {
|
|
88947
|
+
action: "preview",
|
|
88948
|
+
revision,
|
|
88949
|
+
reason: value.reason,
|
|
88950
|
+
retired: value.targets,
|
|
88951
|
+
changed_files: targets.map((target) => ({ path: target.path, operation: target.operation })),
|
|
88952
|
+
blockers,
|
|
88953
|
+
next_action: { command: blockers.length ? next : `context task retire --input <same-file> --apply --plan-digest '${revision}' --format json` }
|
|
88954
|
+
};
|
|
88955
|
+
if (!input.apply)
|
|
88956
|
+
return preview;
|
|
88957
|
+
if (input.plan_digest !== revision)
|
|
88958
|
+
invalid("article-retirement-preview-stale", "Preview this retirement input again; the selected pages, links or navigation changed.");
|
|
88959
|
+
if (blockers.length)
|
|
88960
|
+
invalid("article-retirement-references-unresolved", "Resolve incoming fragment links before applying retirement.", { blockers });
|
|
88961
|
+
const directory = `.tmp/context-runtime/retirements/${revision.slice(7)}`;
|
|
88962
|
+
const recovery = `${directory}/restore.json`;
|
|
88963
|
+
const receipt2 = `${directory}/receipt.json`;
|
|
88964
|
+
change(recovery, await text9(input.projectRoot, recovery), JSON.stringify({ summary: `Restore retired articles: ${value.reason}`, discard_unfinished: true, files: [...restore] }));
|
|
88965
|
+
change(receipt2, await text9(input.projectRoot, receipt2), JSON.stringify({
|
|
88966
|
+
request: indexerProtocolDigest(value),
|
|
88967
|
+
files: targets.map((target) => ({ path: target.path, digest: target.target_digest }))
|
|
88968
|
+
}));
|
|
88969
|
+
await runDurableMultiFileTransaction({
|
|
88970
|
+
projectRoot: input.projectRoot,
|
|
88971
|
+
kind: "retire-articles",
|
|
88972
|
+
proposal_digest: revision,
|
|
88973
|
+
targets: targets.sort((a, b) => a.path.localeCompare(b.path)),
|
|
88974
|
+
...input.inject_failure ? { inject_failure: input.inject_failure } : {}
|
|
88975
|
+
});
|
|
88976
|
+
return {
|
|
88977
|
+
action: "applied",
|
|
88978
|
+
revision,
|
|
88979
|
+
retired: [...selected],
|
|
88980
|
+
recovery,
|
|
88981
|
+
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." }
|
|
88982
|
+
};
|
|
88983
|
+
});
|
|
88984
|
+
}
|
|
88985
|
+
var import_yaml41, articleRetirementSchema, next = "context status --format json";
|
|
88986
|
+
var init_articleRetirement = __esm(() => {
|
|
88987
|
+
init_zod();
|
|
88988
|
+
init_src2();
|
|
88989
|
+
init_errors3();
|
|
88990
|
+
init_cliFeedback();
|
|
88991
|
+
init_exitCode();
|
|
88992
|
+
init_candidateLedger();
|
|
88993
|
+
init_approvedRevision();
|
|
88994
|
+
init_knowledgeUpdate();
|
|
88995
|
+
init_taskRollback();
|
|
88996
|
+
init_maintenanceStorage();
|
|
88997
|
+
init_productionStageStore();
|
|
88998
|
+
init_knowledgeMap2();
|
|
88999
|
+
init_markdownLinks();
|
|
89000
|
+
init_durableSingleFileTransaction();
|
|
89001
|
+
init_durableMultiFileTransaction();
|
|
89002
|
+
init_writeLock();
|
|
89003
|
+
import_yaml41 = __toESM(require_dist(), 1);
|
|
89004
|
+
articleRetirementSchema = exports_external.object({
|
|
89005
|
+
reason: exports_external.string().trim().min(1),
|
|
89006
|
+
targets: exports_external.array(exports_external.object({ path: exports_external.string().min(1), replacement: exports_external.string().min(1).optional() }).strict()).min(1)
|
|
89007
|
+
}).strict();
|
|
89008
|
+
});
|
|
89009
|
+
|
|
89010
|
+
// src/lib/schemaOutput.ts
|
|
89011
|
+
var exports_schemaOutput = {};
|
|
89012
|
+
__export(exports_schemaOutput, {
|
|
89013
|
+
writeSchemaOutput: () => writeSchemaOutput,
|
|
89014
|
+
schemaOutputFormat: () => schemaOutputFormat
|
|
89015
|
+
});
|
|
89016
|
+
function schemaOutputFormat(value) {
|
|
89017
|
+
if (value === "text" || value === "yaml" || value === "json")
|
|
89018
|
+
return value;
|
|
89019
|
+
throw new ContextError(ExitCode.UserError, "Expected schema format text, json, or yaml", { category: ErrorCategory.UserInputInvalid });
|
|
89020
|
+
}
|
|
89021
|
+
function writeSchemaOutput(value, format2) {
|
|
89022
|
+
process.stdout.write(format2 === "json" ? `${JSON.stringify(value, null, 2)}
|
|
89023
|
+
` : import_yaml42.default.stringify(value));
|
|
89024
|
+
}
|
|
89025
|
+
var import_yaml42;
|
|
89026
|
+
var init_schemaOutput = __esm(() => {
|
|
89027
|
+
init_errors3();
|
|
89028
|
+
init_cliFeedback();
|
|
89029
|
+
init_exitCode();
|
|
89030
|
+
import_yaml42 = __toESM(require_dist(), 1);
|
|
89031
|
+
});
|
|
89032
|
+
|
|
89033
|
+
// src/project/writeLockRecovery.ts
|
|
89034
|
+
var exports_writeLockRecovery = {};
|
|
89035
|
+
__export(exports_writeLockRecovery, {
|
|
89036
|
+
recoverWriterLock: () => recoverWriterLock,
|
|
89037
|
+
inspectWriterLock: () => inspectWriterLock
|
|
89038
|
+
});
|
|
89039
|
+
import { lstat as lstat9, mkdir as mkdir32, readFile as readFile75, readdir as readdir21, rename as rename7, rmdir as rmdir2 } from "node:fs/promises";
|
|
89040
|
+
import { join as join94 } from "node:path";
|
|
89041
|
+
import { createHash as createHash28, randomUUID as randomUUID7 } from "node:crypto";
|
|
89042
|
+
async function inspectWriterLock(root2) {
|
|
89043
|
+
const path3 = await safeProjectTarget(root2, lockRelative);
|
|
89044
|
+
let stat11;
|
|
89045
|
+
try {
|
|
89046
|
+
stat11 = await lstat9(path3);
|
|
89047
|
+
} catch (error) {
|
|
89048
|
+
if (error.code === "ENOENT")
|
|
89049
|
+
return null;
|
|
89050
|
+
throw error;
|
|
89051
|
+
}
|
|
89052
|
+
if (!stat11.isDirectory() || stat11.isSymbolicLink())
|
|
89053
|
+
throw new Error("Writer lock must be a real directory.");
|
|
89054
|
+
const ownerPath = await safeProjectTarget(root2, `${lockRelative}/owner.json`);
|
|
89055
|
+
const bytes = await readFile75(ownerPath, "utf8");
|
|
89056
|
+
const owner = JSON.parse(bytes);
|
|
89057
|
+
if (owner.protocol !== "context.project-write-lock.v1" || !Number.isSafeInteger(owner.pid) || owner.pid <= 0) {
|
|
89058
|
+
throw new Error("Writer lock owner is invalid; preserve the lock for diagnosis.");
|
|
89059
|
+
}
|
|
89060
|
+
let processState = "running";
|
|
89061
|
+
try {
|
|
89062
|
+
process.kill(owner.pid, 0);
|
|
89063
|
+
} catch (error) {
|
|
89064
|
+
const code3 = error.code;
|
|
89065
|
+
processState = code3 === "ESRCH" ? "not-running" : code3 === "EPERM" ? "running" : "unknown";
|
|
89066
|
+
}
|
|
89067
|
+
const digest6 = `sha256:${createHash28("sha256").update(`${stat11.dev}:${stat11.ino}:${stat11.birthtimeMs}:${bytes}`).digest("hex")}`;
|
|
89068
|
+
return { ...owner, process_state: processState, digest: digest6, path: lockRelative };
|
|
89069
|
+
}
|
|
89070
|
+
async function recoverWriterLock(input) {
|
|
89071
|
+
const before = await inspectWriterLock(input.projectRoot);
|
|
89072
|
+
if (!before)
|
|
89073
|
+
return { action: "writer-lock-absent", next: "context task recover --format json" };
|
|
89074
|
+
if (before.process_state !== "not-running")
|
|
89075
|
+
throw new Error("Writer is running or cannot be identified as stopped; keep the lock.");
|
|
89076
|
+
if (!input.apply)
|
|
89077
|
+
return {
|
|
89078
|
+
action: "preview",
|
|
89079
|
+
operation: "writer-lock",
|
|
89080
|
+
revision: before.digest,
|
|
89081
|
+
owner: before,
|
|
89082
|
+
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.",
|
|
89083
|
+
next: `${command2} --apply --plan-digest '${before.digest}'`
|
|
89084
|
+
};
|
|
89085
|
+
if (input.plan_digest !== before.digest)
|
|
89086
|
+
throw new Error("Writer lock changed; preview recovery again.");
|
|
89087
|
+
const path3 = join94(input.projectRoot, lockRelative);
|
|
89088
|
+
const guard = join94(path3, ".recovery");
|
|
89089
|
+
await mkdir32(guard);
|
|
89090
|
+
let archived = false;
|
|
89091
|
+
try {
|
|
89092
|
+
const current2 = await inspectWriterLock(input.projectRoot);
|
|
89093
|
+
if (current2?.digest !== before.digest || current2.process_state !== "not-running")
|
|
89094
|
+
throw new Error("Writer lock changed or owner resumed; keep the lock.");
|
|
89095
|
+
const names = await readdir21(path3);
|
|
89096
|
+
if (names.some((name3) => name3 !== "owner.json" && name3 !== ".recovery"))
|
|
89097
|
+
throw new Error("Unexpected lock contents; preserve for diagnosis.");
|
|
89098
|
+
const archive = `.tmp/context-runtime/locks/recovered-write-${randomUUID7()}.lock`;
|
|
89099
|
+
await rename7(path3, join94(input.projectRoot, archive));
|
|
89100
|
+
archived = true;
|
|
89101
|
+
return { action: "writer-lock-recovered", archived_lock: archive, next: "context task recover --format json" };
|
|
89102
|
+
} finally {
|
|
89103
|
+
if (!archived)
|
|
89104
|
+
await rmdir2(guard);
|
|
89105
|
+
}
|
|
89106
|
+
}
|
|
89107
|
+
var lockRelative = ".tmp/context-runtime/locks/project-write.lock", command2 = "context task recover --operation writer-lock --format json";
|
|
89108
|
+
var init_writeLockRecovery = __esm(() => {
|
|
89109
|
+
init_durableMultiFileTransaction();
|
|
89110
|
+
});
|
|
89111
|
+
|
|
88331
89112
|
// src/project/taskRecovery.ts
|
|
88332
89113
|
var exports_taskRecovery = {};
|
|
88333
89114
|
__export(exports_taskRecovery, {
|
|
@@ -88339,12 +89120,12 @@ __export(exports_taskRecovery, {
|
|
|
88339
89120
|
RECOVERY_COMMAND: () => RECOVERY_COMMAND
|
|
88340
89121
|
});
|
|
88341
89122
|
import { existsSync as existsSync26 } from "node:fs";
|
|
88342
|
-
import { dirname as dirname40, join as
|
|
88343
|
-
import { lstat as
|
|
89123
|
+
import { dirname as dirname40, join as join95 } from "node:path";
|
|
89124
|
+
import { lstat as lstat10, readdir as readdir22, readFile as readFile76 } from "node:fs/promises";
|
|
88344
89125
|
async function recoveryText(root2, path3) {
|
|
88345
89126
|
const target = await safeProjectTarget(root2, path3);
|
|
88346
89127
|
try {
|
|
88347
|
-
return await
|
|
89128
|
+
return await readFile76(target, "utf8");
|
|
88348
89129
|
} catch (error) {
|
|
88349
89130
|
if (error.code === "ENOENT")
|
|
88350
89131
|
return;
|
|
@@ -88355,22 +89136,22 @@ async function recoveryJournals(root2) {
|
|
|
88355
89136
|
const entries2 = [];
|
|
88356
89137
|
async function visit4(path3, depth) {
|
|
88357
89138
|
await safeProjectTarget(root2, path3);
|
|
88358
|
-
let
|
|
89139
|
+
let stat11;
|
|
88359
89140
|
try {
|
|
88360
|
-
|
|
89141
|
+
stat11 = await lstat10(join95(root2, path3));
|
|
88361
89142
|
} catch (error) {
|
|
88362
89143
|
if (error.code === "ENOENT")
|
|
88363
89144
|
return;
|
|
88364
89145
|
throw error;
|
|
88365
89146
|
}
|
|
88366
|
-
if (
|
|
89147
|
+
if (stat11.isSymbolicLink())
|
|
88367
89148
|
throw new TypeError("Recovery does not follow transaction symlinks.");
|
|
88368
|
-
if (
|
|
89149
|
+
if (stat11.isDirectory()) {
|
|
88369
89150
|
if (depth > 3)
|
|
88370
89151
|
throw new TypeError("Unexpected transaction directory depth; preserve it for diagnosis.");
|
|
88371
|
-
for (const name3 of (await
|
|
89152
|
+
for (const name3 of (await readdir22(join95(root2, path3))).sort())
|
|
88372
89153
|
await visit4(`${path3}/${name3}`, depth + 1);
|
|
88373
|
-
} else if (
|
|
89154
|
+
} else if (stat11.isFile())
|
|
88374
89155
|
entries2.push({ path: path3, digest: indexerProtocolDigest(await recoveryText(root2, path3)) });
|
|
88375
89156
|
}
|
|
88376
89157
|
await visit4(TRANSACTIONS_PATH, 0);
|
|
@@ -88380,8 +89161,8 @@ function recoveryResources() {
|
|
|
88380
89161
|
try {
|
|
88381
89162
|
const root2 = dirname40(contextWorkflowProviderPath());
|
|
88382
89163
|
const resources = {
|
|
88383
|
-
skill:
|
|
88384
|
-
issue_template:
|
|
89164
|
+
skill: join95(root2, "skills/recover-workspace/SKILL.md"),
|
|
89165
|
+
issue_template: join95(root2, "resources/templates/recovery-issue.md")
|
|
88385
89166
|
};
|
|
88386
89167
|
if (!Object.values(resources).every((path3) => existsSync26(path3)))
|
|
88387
89168
|
throw new Error("Recovery resources are absent from this Provider.");
|
|
@@ -88402,10 +89183,7 @@ async function inspectTaskRecovery(root2) {
|
|
|
88402
89183
|
}
|
|
88403
89184
|
const stage = await probe("production-stage", () => readProductionStage(root2));
|
|
88404
89185
|
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
|
-
});
|
|
89186
|
+
const lock = await probe("writer-lock", () => inspectWriterLock(root2));
|
|
88409
89187
|
return {
|
|
88410
89188
|
action: "recovery-inspected",
|
|
88411
89189
|
resources: recoveryResources(),
|
|
@@ -88415,6 +89193,7 @@ async function inspectTaskRecovery(root2) {
|
|
|
88415
89193
|
transactions: journals,
|
|
88416
89194
|
writer_lock: lock,
|
|
88417
89195
|
actions: [
|
|
89196
|
+
...lock?.process_state === "not-running" ? [{ operation: "writer-lock", command: `${RECOVERY_COMMAND} --operation writer-lock` }] : [],
|
|
88418
89197
|
...journals?.length ? [{ operation: "transactions", command: `${RECOVERY_COMMAND} --operation transactions` }] : [],
|
|
88419
89198
|
...stage ? [{ operation: "continue", command: "context status --format json" }] : []
|
|
88420
89199
|
],
|
|
@@ -88460,6 +89239,7 @@ var init_taskRecovery = __esm(() => {
|
|
|
88460
89239
|
init_writeLock();
|
|
88461
89240
|
init_durableMultiFileTransaction();
|
|
88462
89241
|
init_workflowProvider();
|
|
89242
|
+
init_writeLockRecovery();
|
|
88463
89243
|
});
|
|
88464
89244
|
|
|
88465
89245
|
// src/project/taskLocalSourceAdjustment.ts
|
|
@@ -88467,8 +89247,8 @@ var exports_taskLocalSourceAdjustment = {};
|
|
|
88467
89247
|
__export(exports_taskLocalSourceAdjustment, {
|
|
88468
89248
|
adjustLocalRevisionSources: () => adjustLocalRevisionSources
|
|
88469
89249
|
});
|
|
88470
|
-
import { readFile as
|
|
88471
|
-
import { join as
|
|
89250
|
+
import { readFile as readFile77 } from "node:fs/promises";
|
|
89251
|
+
import { join as join96 } from "node:path";
|
|
88472
89252
|
async function adjustLocalRevisionSources(root2, input) {
|
|
88473
89253
|
const { readMaintenance: readMaintenance2 } = await Promise.resolve().then(() => (init_maintenanceStorage(), exports_maintenanceStorage));
|
|
88474
89254
|
if ((await readMaintenance2(root2)).active && await readProductionStage(root2))
|
|
@@ -88492,11 +89272,11 @@ async function adjustLocalRevisionSources(root2, input) {
|
|
|
88492
89272
|
if (input.refresh && (!current2.refresh_sources || indexerProtocolDigest([...current2.refresh_sources].sort()) !== indexerProtocolDigest([...selected].sort()))) {
|
|
88493
89273
|
throw new TypeError("No matching acquisition adjustment exists. Run task adjust without refresh first.");
|
|
88494
89274
|
}
|
|
88495
|
-
const raw = await
|
|
88496
|
-
let
|
|
89275
|
+
const raw = await readFile77(join96(root2, await revisionStoragePath(root2)), "utf8");
|
|
89276
|
+
let next2;
|
|
88497
89277
|
const discardIds = new Set;
|
|
88498
89278
|
if (!input.refresh) {
|
|
88499
|
-
|
|
89279
|
+
next2 = { ...current2, refresh_sources: selected };
|
|
88500
89280
|
} else {
|
|
88501
89281
|
const oldScopes = [
|
|
88502
89282
|
...revision?.processed_scopes ?? update?.scopes ?? [],
|
|
@@ -88570,7 +89350,7 @@ ${input.instruction}`,
|
|
|
88570
89350
|
|
|
88571
89351
|
${input.instruction}` : revision.instruction
|
|
88572
89352
|
};
|
|
88573
|
-
|
|
89353
|
+
next2 = { ...payload, revision: requestDigest(payload), ...!affected && candidate ? { candidate } : {} };
|
|
88574
89354
|
if (affected && candidate)
|
|
88575
89355
|
discardIds.add(candidate.candidate_id);
|
|
88576
89356
|
} else {
|
|
@@ -88578,14 +89358,14 @@ ${input.instruction}` : revision.instruction
|
|
|
88578
89358
|
const payload = { ...rest, scopes, requirements, changes: [rest.changes, input.instruction].filter(Boolean).join(`
|
|
88579
89359
|
|
|
88580
89360
|
`) };
|
|
88581
|
-
|
|
89361
|
+
next2 = { ...payload, revision: indexerProtocolDigest(payload) };
|
|
88582
89362
|
}
|
|
88583
89363
|
}
|
|
88584
89364
|
if (update && !input.refresh) {
|
|
88585
|
-
const { revision: _revision, ...payload } =
|
|
88586
|
-
|
|
89365
|
+
const { revision: _revision, ...payload } = next2;
|
|
89366
|
+
next2.revision = indexerProtocolDigest(payload);
|
|
88587
89367
|
}
|
|
88588
|
-
const content3 = `${JSON.stringify(
|
|
89368
|
+
const content3 = `${JSON.stringify(next2)}
|
|
88589
89369
|
`;
|
|
88590
89370
|
const targets = [{
|
|
88591
89371
|
path: await revisionStoragePath(root2),
|
|
@@ -88595,7 +89375,7 @@ ${input.instruction}` : revision.instruction
|
|
|
88595
89375
|
content: content3
|
|
88596
89376
|
}];
|
|
88597
89377
|
if (discardIds.size > 0) {
|
|
88598
|
-
const ledger = await
|
|
89378
|
+
const ledger = await readFile77(join96(root2, CANDIDATE_LEDGER_FILE), "utf8").catch((error) => {
|
|
88599
89379
|
if (error.code === "ENOENT")
|
|
88600
89380
|
return;
|
|
88601
89381
|
throw error;
|
|
@@ -88631,6 +89411,7 @@ var init_taskLocalSourceAdjustment = __esm(() => {
|
|
|
88631
89411
|
// src/project/taskSourceAdjustment.ts
|
|
88632
89412
|
var exports_taskSourceAdjustment = {};
|
|
88633
89413
|
__export(exports_taskSourceAdjustment, {
|
|
89414
|
+
taskSourceAdjustmentSchema: () => taskSourceAdjustmentSchema,
|
|
88634
89415
|
adjustCurrentTaskSources: () => adjustCurrentTaskSources
|
|
88635
89416
|
});
|
|
88636
89417
|
async function adjustCurrentTaskSources(projectRoot, value) {
|
|
@@ -88685,7 +89466,7 @@ async function adjustCurrentTaskSources(projectRoot, value) {
|
|
|
88685
89466
|
});
|
|
88686
89467
|
});
|
|
88687
89468
|
}
|
|
88688
|
-
var schema2;
|
|
89469
|
+
var schema2, taskSourceAdjustmentSchema;
|
|
88689
89470
|
var init_taskSourceAdjustment = __esm(() => {
|
|
88690
89471
|
init_src2();
|
|
88691
89472
|
init_knowledgeMap2();
|
|
@@ -88712,10 +89493,11 @@ var init_taskSourceAdjustment = __esm(() => {
|
|
|
88712
89493
|
instruction: exports_external.string().trim().min(1),
|
|
88713
89494
|
refresh: exports_external.boolean().optional()
|
|
88714
89495
|
}).strict();
|
|
89496
|
+
taskSourceAdjustmentSchema = exports_external.union([schema2, exports_external.object({ knowledge_map: knowledgeMapUpdateSchema }).strict()]);
|
|
88715
89497
|
});
|
|
88716
89498
|
|
|
88717
89499
|
// src/project/managedDocumentImport.ts
|
|
88718
|
-
import { readFile as
|
|
89500
|
+
import { readFile as readFile83 } from "node:fs/promises";
|
|
88719
89501
|
async function importManagedDocument(projectRoot, value) {
|
|
88720
89502
|
const input = inputSchema.parse(value);
|
|
88721
89503
|
if (input.type !== "sessions" && input.changes !== undefined)
|
|
@@ -88724,7 +89506,7 @@ async function importManagedDocument(projectRoot, value) {
|
|
|
88724
89506
|
const path3 = await assertManagedDocumentPath(projectRoot, input.type, input.name);
|
|
88725
89507
|
let previous3;
|
|
88726
89508
|
try {
|
|
88727
|
-
previous3 = await
|
|
89509
|
+
previous3 = await readFile83(path3, "utf8");
|
|
88728
89510
|
} catch (error) {
|
|
88729
89511
|
if (!(error && typeof error === "object" && ("code" in error) && error.code === "ENOENT"))
|
|
88730
89512
|
throw error;
|
|
@@ -88771,14 +89553,14 @@ var init_managedDocumentImport = __esm(() => {
|
|
|
88771
89553
|
});
|
|
88772
89554
|
|
|
88773
89555
|
// src/project/larkDocumentImport.ts
|
|
88774
|
-
import { readFile as
|
|
89556
|
+
import { readFile as readFile84 } from "node:fs/promises";
|
|
88775
89557
|
async function importLarkDocument(projectRoot, value) {
|
|
88776
89558
|
const input = schema3.parse(value);
|
|
88777
89559
|
const responsePages = [];
|
|
88778
89560
|
for (const path3 of input.response_files) {
|
|
88779
89561
|
assertActionInputWorkspace(projectRoot, path3);
|
|
88780
89562
|
const { resolve: resolve8 } = await import("node:path");
|
|
88781
|
-
responsePages.push(await
|
|
89563
|
+
responsePages.push(await readFile84(resolve8(projectRoot, path3), "utf8"));
|
|
88782
89564
|
}
|
|
88783
89565
|
const mediaFiles = {};
|
|
88784
89566
|
for (const [token, path3] of Object.entries(input.media_files ?? {})) {
|
|
@@ -88846,11 +89628,11 @@ var exports_managedDocumentRename = {};
|
|
|
88846
89628
|
__export(exports_managedDocumentRename, {
|
|
88847
89629
|
renameManagedDocument: () => renameManagedDocument
|
|
88848
89630
|
});
|
|
88849
|
-
import { readFile as
|
|
88850
|
-
import { join as
|
|
89631
|
+
import { readFile as readFile85 } from "node:fs/promises";
|
|
89632
|
+
import { join as join104, posix as posix11 } from "node:path";
|
|
88851
89633
|
async function optionalText2(path3) {
|
|
88852
89634
|
try {
|
|
88853
|
-
return await
|
|
89635
|
+
return await readFile85(path3, "utf8");
|
|
88854
89636
|
} catch (error) {
|
|
88855
89637
|
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT")
|
|
88856
89638
|
return;
|
|
@@ -88934,12 +89716,12 @@ async function renameManagedDocument(input) {
|
|
|
88934
89716
|
if (path3.split("/").includes("..") || path3.startsWith("/"))
|
|
88935
89717
|
throw new TypeError("Source references contain an unsafe knowledge path; repair it before renaming.");
|
|
88936
89718
|
await safeProjectTarget(input.projectRoot, path3);
|
|
88937
|
-
const before = await optionalText2(
|
|
89719
|
+
const before = await optionalText2(join104(input.projectRoot, path3));
|
|
88938
89720
|
if (before === undefined)
|
|
88939
89721
|
continue;
|
|
88940
89722
|
let after;
|
|
88941
89723
|
if (path3.endsWith(".yaml")) {
|
|
88942
|
-
const parsed =
|
|
89724
|
+
const parsed = import_yaml48.default.parse(before);
|
|
88943
89725
|
const updated = replace2(parsed);
|
|
88944
89726
|
if (path3 === "knowledge/structure.yaml") {
|
|
88945
89727
|
const rewritten = articles.map((article) => ({ ...article, sections: article.sections.map((section) => ({
|
|
@@ -88947,14 +89729,14 @@ async function renameManagedDocument(input) {
|
|
|
88947
89729
|
references: section.references.map((citation) => citation.source_ref !== input.source_ref ? citation : {
|
|
88948
89730
|
...citation,
|
|
88949
89731
|
source_ref: nextRef,
|
|
88950
|
-
locator: { ...citation.locator, path:
|
|
89732
|
+
locator: { ...citation.locator, path: posix11.basename(input.name) }
|
|
88951
89733
|
})
|
|
88952
89734
|
})) }));
|
|
88953
89735
|
updated.articles = rewritten;
|
|
88954
89736
|
}
|
|
88955
89737
|
if (JSON.stringify(parsed) === JSON.stringify(updated))
|
|
88956
89738
|
continue;
|
|
88957
|
-
after =
|
|
89739
|
+
after = import_yaml48.default.stringify(updated);
|
|
88958
89740
|
} else
|
|
88959
89741
|
after = before.replace(reference2, nextRef);
|
|
88960
89742
|
if (path3 === "src/index.ts")
|
|
@@ -88973,11 +89755,11 @@ async function renameManagedDocument(input) {
|
|
|
88973
89755
|
return;
|
|
88974
89756
|
}
|
|
88975
89757
|
const rooted = destination.startsWith("sources/") || destination.startsWith("/sources/");
|
|
88976
|
-
const resolved = rooted ? destination.replace(/^\//u, "") :
|
|
89758
|
+
const resolved = rooted ? destination.replace(/^\//u, "") : posix11.normalize(posix11.join(posix11.dirname(path3), destination));
|
|
88977
89759
|
if (resolved !== `sources/${type}/${oldName}`)
|
|
88978
89760
|
return;
|
|
88979
89761
|
const renamed = `sources/${type}/${input.name}`;
|
|
88980
|
-
return encodeURI(rooted ? `${destination.startsWith("/") ? "/" : ""}${renamed}` :
|
|
89762
|
+
return encodeURI(rooted ? `${destination.startsWith("/") ? "/" : ""}${renamed}` : posix11.relative(posix11.dirname(path3), renamed)) + match2[2];
|
|
88981
89763
|
});
|
|
88982
89764
|
if (before === after)
|
|
88983
89765
|
continue;
|
|
@@ -89006,7 +89788,7 @@ async function renameManagedDocument(input) {
|
|
|
89006
89788
|
};
|
|
89007
89789
|
});
|
|
89008
89790
|
}
|
|
89009
|
-
var
|
|
89791
|
+
var import_yaml48;
|
|
89010
89792
|
var init_managedDocumentRename = __esm(() => {
|
|
89011
89793
|
init_markdownLinks();
|
|
89012
89794
|
init_src2();
|
|
@@ -89018,12 +89800,12 @@ var init_managedDocumentRename = __esm(() => {
|
|
|
89018
89800
|
init_durableSingleFileTransaction();
|
|
89019
89801
|
init_durableMultiFileTransaction();
|
|
89020
89802
|
init_writeLock();
|
|
89021
|
-
|
|
89803
|
+
import_yaml48 = __toESM(require_dist(), 1);
|
|
89022
89804
|
});
|
|
89023
89805
|
|
|
89024
89806
|
// src/cli.ts
|
|
89025
89807
|
import { existsSync as existsSync36, realpathSync as realpathSync3 } from "node:fs";
|
|
89026
|
-
import { dirname as dirname47, join as
|
|
89808
|
+
import { dirname as dirname47, join as join108 } from "node:path";
|
|
89027
89809
|
import { fileURLToPath as fileURLToPath10, pathToFileURL as pathToFileURL3 } from "node:url";
|
|
89028
89810
|
|
|
89029
89811
|
// ../../node_modules/.bun/commander@11.1.0/node_modules/commander/esm.mjs
|
|
@@ -89103,7 +89885,7 @@ init_cliFeedback();
|
|
|
89103
89885
|
init_errors3();
|
|
89104
89886
|
init_exitCode();
|
|
89105
89887
|
import { createHash as createHash21 } from "node:crypto";
|
|
89106
|
-
import { mkdir as mkdir26, readdir as readdir16, readFile as readFile60, rm as
|
|
89888
|
+
import { mkdir as mkdir26, readdir as readdir16, readFile as readFile60, rm as rm17, stat as stat10, writeFile as writeFile20 } from "node:fs/promises";
|
|
89107
89889
|
import { basename as basename8, dirname as dirname32, extname as extname12, join as join72, relative as relative22, resolve as resolve24 } from "node:path";
|
|
89108
89890
|
|
|
89109
89891
|
// src/project/documentCaptureAssets.ts
|
|
@@ -89113,7 +89895,7 @@ init_errors3();
|
|
|
89113
89895
|
init_exitCode();
|
|
89114
89896
|
init_markdownLinks();
|
|
89115
89897
|
import { readFileSync as readFileSync6 } from "node:fs";
|
|
89116
|
-
import { mkdir as mkdir24, readFile as readFile57, stat as
|
|
89898
|
+
import { mkdir as mkdir24, readFile as readFile57, stat as stat8, writeFile as writeFile18 } from "node:fs/promises";
|
|
89117
89899
|
import { dirname as dirname29, isAbsolute as isAbsolute13, join as join67, relative as relative20, resolve as resolve21 } from "node:path";
|
|
89118
89900
|
function runtimeError(message, detail) {
|
|
89119
89901
|
return new ContextError(ExitCode.UserError, message, {
|
|
@@ -89154,7 +89936,7 @@ async function writeCaptureAssetIfChanged(path2, content3) {
|
|
|
89154
89936
|
await writeFile18(path2, content3);
|
|
89155
89937
|
}
|
|
89156
89938
|
async function readLinkedCaptureAssets(input) {
|
|
89157
|
-
const rootStat = await
|
|
89939
|
+
const rootStat = await stat8(input.localRoot);
|
|
89158
89940
|
const boundaryRoot = rootStat.isFile() ? dirname29(input.localRoot) : input.localRoot;
|
|
89159
89941
|
const bySnapshotPath = new Map;
|
|
89160
89942
|
for (const file of input.files) {
|
|
@@ -89173,7 +89955,7 @@ async function readLinkedCaptureAssets(input) {
|
|
|
89173
89955
|
}
|
|
89174
89956
|
let bytes;
|
|
89175
89957
|
try {
|
|
89176
|
-
const assetStat = await
|
|
89958
|
+
const assetStat = await stat8(absolutePath);
|
|
89177
89959
|
if (!assetStat.isFile())
|
|
89178
89960
|
throw new TypeError("asset target is not a file");
|
|
89179
89961
|
bytes = await readFile57(absolutePath);
|
|
@@ -96967,7 +97749,7 @@ async function readRouteMetadataFiles(input) {
|
|
|
96967
97749
|
}
|
|
96968
97750
|
|
|
96969
97751
|
// src/project/documentSiteDetection.ts
|
|
96970
|
-
import { readdir as readdir15, stat as
|
|
97752
|
+
import { readdir as readdir15, stat as stat9 } from "node:fs/promises";
|
|
96971
97753
|
import { basename as basename7, extname as extname11, join as join68, relative as relative21, resolve as resolve22 } from "node:path";
|
|
96972
97754
|
var SKIPPED_DIRS = new Set([
|
|
96973
97755
|
".cache",
|
|
@@ -97018,7 +97800,7 @@ async function detectDocumentSiteFiles(input) {
|
|
|
97018
97800
|
const result = emptyDetection();
|
|
97019
97801
|
let rootStats;
|
|
97020
97802
|
try {
|
|
97021
|
-
rootStats = await
|
|
97803
|
+
rootStats = await stat9(localRoot);
|
|
97022
97804
|
} catch {
|
|
97023
97805
|
return result;
|
|
97024
97806
|
}
|
|
@@ -97222,7 +98004,7 @@ function assignFlatSnapshotPaths(files, module) {
|
|
|
97222
98004
|
});
|
|
97223
98005
|
}
|
|
97224
98006
|
async function walkMarkdownFiles(input) {
|
|
97225
|
-
const rootStat = await
|
|
98007
|
+
const rootStat = await stat10(input.localRoot);
|
|
97226
98008
|
if (rootStat.isFile()) {
|
|
97227
98009
|
const sourcePath = normalizeSnapshotRelativePath(basename8(input.localRoot));
|
|
97228
98010
|
return {
|
|
@@ -97349,13 +98131,13 @@ async function removeEmptySnapshotDirs(root, dir = root) {
|
|
|
97349
98131
|
return;
|
|
97350
98132
|
const remaining = await readdir16(dir);
|
|
97351
98133
|
if (remaining.length === 0) {
|
|
97352
|
-
await
|
|
98134
|
+
await rm17(dir, { recursive: true, force: true });
|
|
97353
98135
|
}
|
|
97354
98136
|
}
|
|
97355
98137
|
async function cleanupStaleSnapshotFiles(input) {
|
|
97356
98138
|
for (const path2 of input.previousPaths) {
|
|
97357
98139
|
if (!input.currentPaths.has(path2)) {
|
|
97358
|
-
await
|
|
98140
|
+
await rm17(join72(input.materializedAtAbsPath, path2), { force: true });
|
|
97359
98141
|
}
|
|
97360
98142
|
}
|
|
97361
98143
|
await removeEmptySnapshotDirs(input.materializedAtAbsPath);
|
|
@@ -97728,7 +98510,7 @@ init_cliFeedback();
|
|
|
97728
98510
|
init_errors3();
|
|
97729
98511
|
init_exitCode();
|
|
97730
98512
|
import { existsSync as existsSync21 } from "node:fs";
|
|
97731
|
-
import { lstat as lstat8, mkdir as mkdir27, readFile as readFile62, readlink, realpath as realpath7, rm as
|
|
98513
|
+
import { lstat as lstat8, mkdir as mkdir27, readFile as readFile62, readlink, realpath as realpath7, rm as rm18, symlink as symlink2 } from "node:fs/promises";
|
|
97732
98514
|
import { execFile as execFile8 } from "node:child_process";
|
|
97733
98515
|
import { promisify as promisify8 } from "node:util";
|
|
97734
98516
|
import { dirname as dirname33, isAbsolute as isAbsolute14, join as join76, relative as relative23, resolve as resolve26 } from "node:path";
|
|
@@ -97839,7 +98621,7 @@ init_cliFeedback();
|
|
|
97839
98621
|
init_errors3();
|
|
97840
98622
|
init_exitCode();
|
|
97841
98623
|
init_atomicWrite();
|
|
97842
|
-
var
|
|
98624
|
+
var import_yaml37 = __toESM(require_dist(), 1);
|
|
97843
98625
|
import { existsSync as existsSync20 } from "node:fs";
|
|
97844
98626
|
import { join as join75 } from "node:path";
|
|
97845
98627
|
var SOURCE_NAME_PATTERN2 = /^[a-z0-9][a-z0-9._-]*$/u;
|
|
@@ -97916,7 +98698,7 @@ async function writeRepoRegistry(projectRoot, registry2) {
|
|
|
97916
98698
|
modules.push(registryRecordToYaml(record4));
|
|
97917
98699
|
namespaces.set(record4.namespace, modules);
|
|
97918
98700
|
}
|
|
97919
|
-
await atomicWriteFile(path2,
|
|
98701
|
+
await atomicWriteFile(path2, import_yaml37.default.stringify({
|
|
97920
98702
|
sources: [...namespaces].map(([name3, modules]) => ({ name: name3, modules }))
|
|
97921
98703
|
}));
|
|
97922
98704
|
}
|
|
@@ -98082,7 +98864,7 @@ async function ensureMaterializedSymlink(input) {
|
|
|
98082
98864
|
const currentAbs = resolve26(dirname33(linkPath), current2);
|
|
98083
98865
|
if (currentAbs === input.localAbs)
|
|
98084
98866
|
return true;
|
|
98085
|
-
await
|
|
98867
|
+
await rm18(linkPath);
|
|
98086
98868
|
}
|
|
98087
98869
|
const relTarget = relative23(dirname33(linkPath), input.localAbs) || ".";
|
|
98088
98870
|
await symlink2(relTarget, linkPath);
|
|
@@ -98479,7 +99261,7 @@ init_errors3();
|
|
|
98479
99261
|
init_exitCode();
|
|
98480
99262
|
init_approvedKnowledgeMetadata();
|
|
98481
99263
|
init_knowledgeAssets();
|
|
98482
|
-
var
|
|
99264
|
+
var import_yaml38 = __toESM(require_dist(), 1);
|
|
98483
99265
|
import { createHash as createHash22 } from "node:crypto";
|
|
98484
99266
|
import { mkdir as mkdir28, writeFile as writeFile21 } from "node:fs/promises";
|
|
98485
99267
|
import { dirname as dirname34, join as join77 } from "node:path";
|
|
@@ -98553,7 +99335,7 @@ async function buildApprovedArticleIndex(projectRoot) {
|
|
|
98553
99335
|
const block = frontmatterBlock(content3);
|
|
98554
99336
|
if (block === null)
|
|
98555
99337
|
continue;
|
|
98556
|
-
const parsed =
|
|
99338
|
+
const parsed = import_yaml38.default.parse(block.yaml);
|
|
98557
99339
|
if (!isRecord14(parsed))
|
|
98558
99340
|
continue;
|
|
98559
99341
|
const frontmatter2 = hydrateApprovedFrontmatter({
|
|
@@ -98600,13 +99382,13 @@ function updateFrontmatter(content3, mutate) {
|
|
|
98600
99382
|
next: "Fix approved Markdown frontmatter before running this review maintenance command."
|
|
98601
99383
|
});
|
|
98602
99384
|
}
|
|
98603
|
-
const parsed =
|
|
99385
|
+
const parsed = import_yaml38.default.parse(block.yaml);
|
|
98604
99386
|
if (!isRecord14(parsed)) {
|
|
98605
99387
|
throw new ContextError(ExitCode.WorkspaceStateError, "approved page frontmatter must be a YAML object", {
|
|
98606
99388
|
category: ErrorCategory.SchemaInvalid
|
|
98607
99389
|
});
|
|
98608
99390
|
}
|
|
98609
|
-
const yaml3 =
|
|
99391
|
+
const yaml3 = import_yaml38.default.stringify(mutate(parsed)).trimEnd();
|
|
98610
99392
|
return `---
|
|
98611
99393
|
${yaml3}
|
|
98612
99394
|
---${content3.slice(block.end)}`;
|
|
@@ -105437,76 +106219,12 @@ init_errors3();
|
|
|
105437
106219
|
init_exitCode();
|
|
105438
106220
|
init_candidateLedger();
|
|
105439
106221
|
init_writeLock();
|
|
106222
|
+
init_reviewApplyIndexer();
|
|
106223
|
+
init_approvedKnowledgeSnapshots();
|
|
105440
106224
|
import { existsSync as existsSync25 } from "node:fs";
|
|
105441
106225
|
import { readFile as readFile69 } from "node:fs/promises";
|
|
105442
106226
|
import { join as join91 } from "node:path";
|
|
105443
106227
|
|
|
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
106228
|
// src/project/reviewCandidateAuthority.ts
|
|
105511
106229
|
init_src2();
|
|
105512
106230
|
init_approvedRevision();
|
|
@@ -105550,12 +106268,13 @@ async function readProductionReviewCandidates(projectRoot) {
|
|
|
105550
106268
|
init_productionFeedback();
|
|
105551
106269
|
async function loadReviewCandidateAuthority(projectRoot) {
|
|
105552
106270
|
return withProductionFeedback({ operation: "review" }, async () => {
|
|
105553
|
-
const production = await readProductionReviewCandidates(projectRoot);
|
|
105554
|
-
if (production)
|
|
105555
|
-
return new Map(production.candidates.map((candidate) => [candidate.candidate_id, candidate]));
|
|
105556
106271
|
const revision = await readApprovedRevision(projectRoot);
|
|
105557
|
-
if (!revision)
|
|
106272
|
+
if (!revision) {
|
|
106273
|
+
const production = await readProductionReviewCandidates(projectRoot);
|
|
106274
|
+
if (production)
|
|
106275
|
+
return new Map(production.candidates.map((candidate) => [candidate.candidate_id, candidate]));
|
|
105558
106276
|
throw new TypeError("No current production or article revision is available for Review");
|
|
106277
|
+
}
|
|
105559
106278
|
if (!revision.review_ready && !revision.candidate)
|
|
105560
106279
|
throw new TypeError("Complete the current article revision before Review");
|
|
105561
106280
|
const observed = await observeApprovedRevisionBatch(projectRoot, revision);
|
|
@@ -105604,7 +106323,7 @@ async function prepareApprovedPage(input) {
|
|
|
105604
106323
|
const relPath = join91("knowledge", input.record.path);
|
|
105605
106324
|
const existingView = findApprovedPageForArticleId(input.record.indexer_candidate.artifact_ref, input.approvedPageIndex);
|
|
105606
106325
|
const previousPath = input.record.approved_revision?.previous_path;
|
|
105607
|
-
if (previousPath !== undefined && !isSafeKnowledgeTargetPath(
|
|
106326
|
+
if (previousPath !== undefined && (!isSafeKnowledgeTargetPath(previousPath.split("/")[0], previousPath) || previousPath.includes("\\")))
|
|
105608
106327
|
throw new TypeError("Unsafe original page path in a move");
|
|
105609
106328
|
if (existingView !== undefined && existingView.relPath !== relPath && existingView.relPath !== (previousPath === undefined ? undefined : `knowledge/${previousPath}`)) {
|
|
105610
106329
|
throw new ContextError(ExitCode.WorkspaceStateError, `approved page already exists for view_ref at a different path: ${input.record.article_id}`, {
|
|
@@ -107326,22 +108045,52 @@ function requireProjectRoot2() {
|
|
|
107326
108045
|
}
|
|
107327
108046
|
function registerDocumentRevisionCommand(program2) {
|
|
107328
108047
|
const task = program2.command("task").description("Explicit current-task recovery");
|
|
107329
|
-
task.command("
|
|
108048
|
+
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) => {
|
|
108049
|
+
const { retireArticles: retireArticles2, articleRetirementSchema: articleRetirementSchema2 } = await Promise.resolve().then(() => (init_articleRetirement(), exports_articleRetirement));
|
|
108050
|
+
if (options.schema) {
|
|
108051
|
+
const { zodToJsonSchema: zodToJsonSchema3 } = await Promise.resolve().then(() => (init_esm(), exports_esm));
|
|
108052
|
+
const { writeSchemaOutput: writeSchemaOutput2, schemaOutputFormat: schemaOutputFormat2 } = await Promise.resolve().then(() => (init_schemaOutput(), exports_schemaOutput));
|
|
108053
|
+
writeSchemaOutput2(zodToJsonSchema3(articleRetirementSchema2), schemaOutputFormat2(options.format));
|
|
108054
|
+
return;
|
|
108055
|
+
}
|
|
108056
|
+
if (options.format !== "json" || !options.input)
|
|
108057
|
+
throw new ContextError(ExitCode.UserError, "Use --input <file> --format json, or --schema.", { category: ErrorCategory.UserInputInvalid });
|
|
108058
|
+
assertActionInputWorkspace(process.cwd(), options.input);
|
|
108059
|
+
const value = await readYamlOrJsonInput({
|
|
108060
|
+
path: options.input,
|
|
108061
|
+
label: "article retirement",
|
|
108062
|
+
missingNext: "Provide reason and targets with exact approved paths and optional replacement paths.",
|
|
108063
|
+
readFailureNext: "Use an input file in this workspace.",
|
|
108064
|
+
parseFailureNext: "Provide valid YAML or JSON."
|
|
108065
|
+
});
|
|
108066
|
+
const result = await retireArticles2({
|
|
108067
|
+
projectRoot: requireProjectRoot2(),
|
|
108068
|
+
value,
|
|
108069
|
+
...options.apply ? { apply: true } : {},
|
|
108070
|
+
...options.planDigest ? { plan_digest: options.planDigest } : {}
|
|
108071
|
+
});
|
|
108072
|
+
if (result.action === "preview" && result.blockers.length === 0)
|
|
108073
|
+
result.next_action.command = `context task retire --input '${options.input.replace(/'/gu, "'\\''")}' --apply --plan-digest '${result.revision}' --format json`;
|
|
108074
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}
|
|
108075
|
+
`);
|
|
108076
|
+
});
|
|
108077
|
+
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
108078
|
if (options.format !== "json")
|
|
107331
108079
|
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.");
|
|
108080
|
+
if (!["inspect", "writer-lock", "transactions"].includes(options.operation))
|
|
108081
|
+
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
108082
|
if (options.operation === "inspect" && options.apply)
|
|
107335
108083
|
throw new TypeError("Inspection is read-only; select a recovery operation to apply.");
|
|
107336
108084
|
const projectRoot = requireProjectRoot2();
|
|
107337
108085
|
const { inspectTaskRecovery: inspectTaskRecovery2, recoverTaskTransactions: recoverTaskTransactions2 } = await Promise.resolve().then(() => (init_taskRecovery(), exports_taskRecovery));
|
|
108086
|
+
const { recoverWriterLock: recoverWriterLock2 } = await Promise.resolve().then(() => (init_writeLockRecovery(), exports_writeLockRecovery));
|
|
107338
108087
|
const base = {
|
|
107339
108088
|
projectRoot,
|
|
107340
108089
|
...options.apply ? { apply: true } : {},
|
|
107341
108090
|
...options.planDigest ? { plan_digest: options.planDigest } : {}
|
|
107342
108091
|
};
|
|
107343
108092
|
try {
|
|
107344
|
-
const result = options.operation === "inspect" ? await inspectTaskRecovery2(projectRoot) : await recoverTaskTransactions2(base);
|
|
108093
|
+
const result = options.operation === "inspect" ? await inspectTaskRecovery2(projectRoot) : options.operation === "writer-lock" ? await recoverWriterLock2(base) : await recoverTaskTransactions2(base);
|
|
107345
108094
|
process.stdout.write(`${JSON.stringify(result, null, 2)}
|
|
107346
108095
|
`);
|
|
107347
108096
|
} catch (error) {
|
|
@@ -107408,9 +108157,19 @@ function registerDocumentRevisionCommand(program2) {
|
|
|
107408
108157
|
process.stdout.write(`${JSON.stringify(await cancelKnowledgeMaintenance2(requireProjectRoot2(), id3, options.discardRevision))}
|
|
107409
108158
|
`);
|
|
107410
108159
|
});
|
|
107411
|
-
task.command("adjust").description("Adjust current source/module inputs or reader organization while preserving unrelated work").
|
|
107412
|
-
if (options.
|
|
107413
|
-
|
|
108160
|
+
task.command("adjust").description("Adjust current source/module inputs or reader organization while preserving unrelated work").option("--input <file>", "YAML/JSON source scopes with instruction, or knowledge_map; - for stdin").option("--schema", "show source adjustment or knowledge map input schema").option("--format <format>", "output format: json", "json").action(async (options) => {
|
|
108161
|
+
if (options.schema) {
|
|
108162
|
+
const { taskSourceAdjustmentSchema: taskSourceAdjustmentSchema2 } = await Promise.resolve().then(() => (init_taskSourceAdjustment(), exports_taskSourceAdjustment));
|
|
108163
|
+
const { zodToJsonSchema: zodToJsonSchema3 } = await Promise.resolve().then(() => (init_esm(), exports_esm));
|
|
108164
|
+
const { writeSchemaOutput: writeSchemaOutput2, schemaOutputFormat: schemaOutputFormat2 } = await Promise.resolve().then(() => (init_schemaOutput(), exports_schemaOutput));
|
|
108165
|
+
writeSchemaOutput2(zodToJsonSchema3(taskSourceAdjustmentSchema2), schemaOutputFormat2(options.format));
|
|
108166
|
+
return;
|
|
108167
|
+
}
|
|
108168
|
+
if (options.format !== "json" || !options.input)
|
|
108169
|
+
throw new ContextError(ExitCode.UserError, "Use --input <file> --format json, or --schema.", {
|
|
108170
|
+
category: ErrorCategory.UserInputInvalid,
|
|
108171
|
+
next_action: { command: "context task adjust --schema --format json" }
|
|
108172
|
+
});
|
|
107414
108173
|
assertActionInputWorkspace(process.cwd(), options.input);
|
|
107415
108174
|
const value = await readYamlOrJsonInput({
|
|
107416
108175
|
path: options.input,
|
|
@@ -107465,7 +108224,7 @@ function registerDocumentRevisionCommand(program2) {
|
|
|
107465
108224
|
process.stdout.write(`${JSON.stringify(await beginKnowledgeUpdate(requireProjectRoot2(), value), null, 2)}
|
|
107466
108225
|
`);
|
|
107467
108226
|
});
|
|
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
|
|
108227
|
+
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
108228
|
if (options.format !== "json") {
|
|
107470
108229
|
throw new ContextError(ExitCode.UserError, "--format must be json", {
|
|
107471
108230
|
category: ErrorCategory.UserInputInvalid
|
|
@@ -107494,8 +108253,8 @@ function registerDocumentRevisionCommand(program2) {
|
|
|
107494
108253
|
init_workspace();
|
|
107495
108254
|
init_workspaceChangelog();
|
|
107496
108255
|
function registerVersionCommands(program2) {
|
|
107497
|
-
const
|
|
107498
|
-
|
|
108256
|
+
const command3 = program2.command("version").description("Inspect formal changes and record a knowledge workspace SemVer and changelog");
|
|
108257
|
+
command3.command("inspect").option("--publish", "include same-version dist changes before publishing").option("--format <format>", "json", "json").action(async (options) => {
|
|
107499
108258
|
const root2 = findContextProjectRoot(process.cwd())?.projectRoot;
|
|
107500
108259
|
if (!root2)
|
|
107501
108260
|
throw new TypeError("Run inside a Context workspace");
|
|
@@ -107507,7 +108266,7 @@ function registerVersionCommands(program2) {
|
|
|
107507
108266
|
}, null, 2) + `
|
|
107508
108267
|
`);
|
|
107509
108268
|
});
|
|
107510
|
-
|
|
108269
|
+
command3.command("publish-check").option("--format <format>", "json", "json").action(async () => {
|
|
107511
108270
|
const root2 = findContextProjectRoot(process.cwd())?.projectRoot;
|
|
107512
108271
|
if (!root2)
|
|
107513
108272
|
throw new TypeError("Run inside a Context workspace");
|
|
@@ -107515,7 +108274,7 @@ function registerVersionCommands(program2) {
|
|
|
107515
108274
|
process.stdout.write(JSON.stringify(await inspectWorkspacePublish2(root2), null, 2) + `
|
|
107516
108275
|
`);
|
|
107517
108276
|
});
|
|
107518
|
-
|
|
108277
|
+
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
108278
|
const root2 = findContextProjectRoot(process.cwd())?.projectRoot;
|
|
107520
108279
|
if (!root2)
|
|
107521
108280
|
throw new TypeError("Run inside a Context workspace");
|
|
@@ -107523,7 +108282,7 @@ function registerVersionCommands(program2) {
|
|
|
107523
108282
|
process.stdout.write(JSON.stringify(await markWorkspacePublished2(root2, options.hash, options.receipt)) + `
|
|
107524
108283
|
`);
|
|
107525
108284
|
});
|
|
107526
|
-
|
|
108285
|
+
command3.command("record").requiredOption("--input <file>", "YAML/JSON file or -").option("--format <format>", "json", "json").action(async (options) => {
|
|
107527
108286
|
const root2 = findContextProjectRoot(process.cwd())?.projectRoot;
|
|
107528
108287
|
if (!root2)
|
|
107529
108288
|
throw new TypeError("Run inside a Context workspace");
|
|
@@ -107641,10 +108400,10 @@ init_actionInputWorkspace();
|
|
|
107641
108400
|
|
|
107642
108401
|
// src/project/actionCompletionOutput.ts
|
|
107643
108402
|
init_atomicWrite();
|
|
107644
|
-
var
|
|
108403
|
+
var import_yaml43 = __toESM(require_dist(), 1);
|
|
107645
108404
|
import { Buffer as Buffer4 } from "node:buffer";
|
|
107646
|
-
import { createHash as
|
|
107647
|
-
import { join as
|
|
108405
|
+
import { createHash as createHash29 } from "node:crypto";
|
|
108406
|
+
import { join as join97 } from "node:path";
|
|
107648
108407
|
var INLINE_LIMIT = 16 * 1024;
|
|
107649
108408
|
function record4(value) {
|
|
107650
108409
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : undefined;
|
|
@@ -107657,7 +108416,7 @@ function shortText(value, limit = 400) {
|
|
|
107657
108416
|
}
|
|
107658
108417
|
function serializeActionCompletion(value, format2) {
|
|
107659
108418
|
return format2 === "json" ? `${JSON.stringify(value, null, 2)}
|
|
107660
|
-
` :
|
|
108419
|
+
` : import_yaml43.default.stringify(value);
|
|
107661
108420
|
}
|
|
107662
108421
|
async function prepareActionCompletionOutput(input) {
|
|
107663
108422
|
if (input.verbose)
|
|
@@ -107669,9 +108428,9 @@ async function prepareActionCompletionOutput(input) {
|
|
|
107669
108428
|
const production = typeof result.stage_state === "string";
|
|
107670
108429
|
if (production && Buffer4.byteLength(full) <= INLINE_LIMIT)
|
|
107671
108430
|
return input.result;
|
|
107672
|
-
const digest6 =
|
|
107673
|
-
const root2 =
|
|
107674
|
-
const resultFile =
|
|
108431
|
+
const digest6 = createHash29("sha256").update(full).digest("hex");
|
|
108432
|
+
const root2 = join97(input.projectRoot, ".tmp/context-runtime/action-results");
|
|
108433
|
+
const resultFile = join97(root2, `${digest6}.json`);
|
|
107675
108434
|
await atomicWriteFile(resultFile, full);
|
|
107676
108435
|
if (production)
|
|
107677
108436
|
return {
|
|
@@ -107681,10 +108440,10 @@ async function prepareActionCompletionOutput(input) {
|
|
|
107681
108440
|
details: resultFile,
|
|
107682
108441
|
...pick(result, ["next", "next_preparation"])
|
|
107683
108442
|
};
|
|
107684
|
-
const
|
|
107685
|
-
const nextFile =
|
|
108443
|
+
const next2 = record4(result.next) ?? record4(record4(result.workflow)?.current) ?? record4(record4(result.continuation)?.next);
|
|
108444
|
+
const nextFile = next2 === undefined ? undefined : join97(root2, `${digest6}.next.json`);
|
|
107686
108445
|
if (nextFile !== undefined)
|
|
107687
|
-
await atomicWriteFile(nextFile, serializeActionCompletion(
|
|
108446
|
+
await atomicWriteFile(nextFile, serializeActionCompletion(next2, "json"));
|
|
107688
108447
|
const outcomes = (Array.isArray(result.outcomes) ? result.outcomes : []).map(record4).filter((item) => item !== undefined);
|
|
107689
108448
|
const counts2 = {};
|
|
107690
108449
|
for (const item of outcomes) {
|
|
@@ -107721,12 +108480,12 @@ async function prepareActionCompletionOutput(input) {
|
|
|
107721
108480
|
"task_completion",
|
|
107722
108481
|
"pages"
|
|
107723
108482
|
]),
|
|
107724
|
-
next_route:
|
|
108483
|
+
next_route: next2 === undefined ? null : {
|
|
107725
108484
|
file: nextFile,
|
|
107726
|
-
digest: `sha256:${
|
|
107727
|
-
...pick(
|
|
107728
|
-
commands:
|
|
107729
|
-
gate:
|
|
108485
|
+
digest: `sha256:${createHash29("sha256").update(serializeActionCompletion(next2, "json")).digest("hex")}`,
|
|
108486
|
+
...pick(next2, ["revision", "node", "availability"]),
|
|
108487
|
+
commands: next2.commands,
|
|
108488
|
+
gate: next2.gate === undefined ? undefined : pick(record4(next2.gate), ["id", "resolution", "delegatable"])
|
|
107730
108489
|
},
|
|
107731
108490
|
...failure2 === undefined ? {} : { next_preparation: {
|
|
107732
108491
|
outcome: failure2.outcome,
|
|
@@ -107740,7 +108499,7 @@ async function prepareActionCompletionOutput(input) {
|
|
|
107740
108499
|
summary.outcomes.pop();
|
|
107741
108500
|
summary.outcomes_omitted++;
|
|
107742
108501
|
}
|
|
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 ||
|
|
108502
|
+
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
108503
|
return summary;
|
|
107745
108504
|
}
|
|
107746
108505
|
|
|
@@ -107770,34 +108529,34 @@ init_errors3();
|
|
|
107770
108529
|
init_cliFeedback();
|
|
107771
108530
|
init_exitCode();
|
|
107772
108531
|
init_productionFeedback();
|
|
107773
|
-
var
|
|
108532
|
+
var import_yaml44 = __toESM(require_dist(), 1);
|
|
107774
108533
|
import { relative as relative24, resolve as resolve32 } from "node:path";
|
|
107775
108534
|
async function completeCurrentProductionAction(input) {
|
|
107776
108535
|
return withProductionFeedback({ operation: "action", file: input.submissionPath }, () => withProjectWriteLock(input.projectRoot, "production-action", async () => {
|
|
107777
108536
|
await recoverDurableMultiFileTransactions(input.projectRoot);
|
|
107778
108537
|
const stage = await readProductionStage(input.projectRoot);
|
|
107779
|
-
const
|
|
108538
|
+
const invalid2 = (message) => new ContextError(ExitCode.UserError, message, {
|
|
107780
108539
|
category: ErrorCategory.UserInputInvalid,
|
|
107781
108540
|
reason_code: "invalid-production-submission",
|
|
107782
108541
|
next_action: { command: "context status --format json" }
|
|
107783
108542
|
});
|
|
107784
108543
|
if (!stage)
|
|
107785
|
-
throw
|
|
108544
|
+
throw invalid2("The production stage expired. Read the current route; do not restore a previous process.");
|
|
107786
108545
|
if (input.preview)
|
|
107787
|
-
throw
|
|
108546
|
+
throw invalid2("Stage files do not use the retired Author preview. Submit the current task files.");
|
|
107788
108547
|
if (!input.submissionPath || input.submissionPath === "-")
|
|
107789
|
-
throw
|
|
108548
|
+
throw invalid2("Production requires a stage-local manifest file, not stdin.");
|
|
107790
108549
|
const path3 = relative24(resolve32(input.projectRoot, productionAgentDirectory(stage.id)), resolve32(input.cwd, input.submissionPath));
|
|
107791
108550
|
const manifest = await readProductionFile({ projectRoot: input.projectRoot, stage: stage.id, path: path3 });
|
|
107792
|
-
const value =
|
|
108551
|
+
const value = import_yaml44.default.parse(manifest.text, { uniqueKeys: true });
|
|
107793
108552
|
if (!value || typeof value !== "object" || !("stage" in value) || value.stage !== stage.id) {
|
|
107794
|
-
throw
|
|
108553
|
+
throw invalid2("The manifest must identify the current production stage. No tasks were saved.");
|
|
107795
108554
|
}
|
|
107796
108555
|
const submission = { projectRoot: input.projectRoot, stage: stage.id, path: path3, manifest, multiAgent: input.multiAgent === true };
|
|
107797
108556
|
if ("decision" in value)
|
|
107798
108557
|
return approveProductionReport({ ...submission, revision: input.revision });
|
|
107799
108558
|
if (input.revision !== stage.id)
|
|
107800
|
-
throw
|
|
108559
|
+
throw invalid2("Use the current stage revision; task input handles protect independent submissions.");
|
|
107801
108560
|
if (!stage.planning_complete || "articles" in value)
|
|
107802
108561
|
return submitProductionPlan(submission);
|
|
107803
108562
|
return completeProductionSubmission(submission);
|
|
@@ -107936,7 +108695,7 @@ init_errors3();
|
|
|
107936
108695
|
init_cliFeedback();
|
|
107937
108696
|
init_exitCode();
|
|
107938
108697
|
init_productionFeedback();
|
|
107939
|
-
var
|
|
108698
|
+
var import_yaml45 = __toESM(require_dist(), 1);
|
|
107940
108699
|
import { relative as relative25, resolve as resolve33 } from "node:path";
|
|
107941
108700
|
var productionKnownTasksSchema = productionPlanInputSchema.omit({ stage: true });
|
|
107942
108701
|
async function prepareKnownProductionTasks(input) {
|
|
@@ -107944,29 +108703,29 @@ async function prepareKnownProductionTasks(input) {
|
|
|
107944
108703
|
await recoverDurableMultiFileTransactions(input.projectRoot);
|
|
107945
108704
|
const path3 = relative25(resolve33(input.projectRoot, ".tmp/agent-work"), resolve33(input.cwd, input.path));
|
|
107946
108705
|
const fixed2 = await readProductionPlanningFile({ projectRoot: input.projectRoot, path: path3 });
|
|
107947
|
-
const
|
|
108706
|
+
const invalid2 = (message) => new ContextError(ExitCode.UserError, message, {
|
|
107948
108707
|
category: ErrorCategory.UserInputInvalid,
|
|
107949
108708
|
reason_code: "invalid-known-production-tasks",
|
|
107950
108709
|
file: input.path,
|
|
107951
108710
|
input_schema: zodToJsonSchema(productionKnownTasksSchema, { $refStrategy: "none" }),
|
|
107952
108711
|
next_action: { command: "context status --format json" }
|
|
107953
108712
|
});
|
|
107954
|
-
const plan = productionKnownTasksSchema.parse(
|
|
108713
|
+
const plan = productionKnownTasksSchema.parse(import_yaml45.default.parse(fixed2.text, { uniqueKeys: true }));
|
|
107955
108714
|
const request = await productionPlanningRequest(input.projectRoot);
|
|
107956
108715
|
let stage = await readProductionStage(input.projectRoot);
|
|
107957
108716
|
if (!request || stage?.report_approved || (stage ? ![stage.id, request.revision].includes(input.revision) : request.revision !== input.revision)) {
|
|
107958
|
-
throw
|
|
108717
|
+
throw invalid2("Use known tasks before report approval, with the current preparation revision. Approved stages use ordinary task amendments.");
|
|
107959
108718
|
}
|
|
107960
108719
|
if (!stage) {
|
|
107961
108720
|
await prepareCurrentProductionStage({ projectRoot: input.projectRoot, revision: input.revision });
|
|
107962
108721
|
stage = await readProductionStage(input.projectRoot);
|
|
107963
108722
|
}
|
|
107964
|
-
const
|
|
108723
|
+
const text10 = import_yaml45.default.stringify({ ...plan, stage: stage.id });
|
|
107965
108724
|
const result = await submitProductionPlan({
|
|
107966
108725
|
projectRoot: input.projectRoot,
|
|
107967
108726
|
stage: stage.id,
|
|
107968
108727
|
path: fixed2.path,
|
|
107969
|
-
manifest: { path: fixed2.path, text:
|
|
108728
|
+
manifest: { path: fixed2.path, text: text10, bytes: Buffer.byteLength(text10), digest: durableContentDigest(text10) }
|
|
107970
108729
|
});
|
|
107971
108730
|
return { ...result, next_action: { command: "context status --format json" } };
|
|
107972
108731
|
}));
|
|
@@ -108083,9 +108842,9 @@ function registerProjectActionCommands(program2) {
|
|
|
108083
108842
|
// src/commands/cleanClaudePluginCache.ts
|
|
108084
108843
|
init_cliFeedback();
|
|
108085
108844
|
import { existsSync as existsSync27 } from "node:fs";
|
|
108086
|
-
import { readdir as
|
|
108845
|
+
import { readdir as readdir23, rm as rm20 } from "node:fs/promises";
|
|
108087
108846
|
import { homedir } from "node:os";
|
|
108088
|
-
import { join as
|
|
108847
|
+
import { join as join98 } from "node:path";
|
|
108089
108848
|
var ORPHAN_MARKER = ".orphaned_at";
|
|
108090
108849
|
var CLAUDE_PLUGIN_CACHE_ROOT_ENV = "C4A_CLAUDE_PLUGIN_CACHE_ROOT";
|
|
108091
108850
|
var CLAUDE_PLUGIN_CACHE_HOME_ENV = "C4A_CLAUDE_PLUGIN_CACHE_HOME";
|
|
@@ -108098,40 +108857,40 @@ async function cleanClaudePluginCache(opts = {}) {
|
|
|
108098
108857
|
lines.push("· claude plugin cache: missing — nothing to clean");
|
|
108099
108858
|
return { lines, removed, scanned };
|
|
108100
108859
|
}
|
|
108101
|
-
const marketplaces = await
|
|
108860
|
+
const marketplaces = await readdir23(cacheRoot, { withFileTypes: true });
|
|
108102
108861
|
for (const mp of marketplaces) {
|
|
108103
108862
|
if (!mp.isDirectory())
|
|
108104
108863
|
continue;
|
|
108105
|
-
const mpDir =
|
|
108106
|
-
const plugins = await
|
|
108864
|
+
const mpDir = join98(cacheRoot, mp.name);
|
|
108865
|
+
const plugins = await readdir23(mpDir, { withFileTypes: true });
|
|
108107
108866
|
for (const pl of plugins) {
|
|
108108
108867
|
if (!pl.isDirectory())
|
|
108109
108868
|
continue;
|
|
108110
|
-
const plDir =
|
|
108111
|
-
const versions = await
|
|
108869
|
+
const plDir = join98(mpDir, pl.name);
|
|
108870
|
+
const versions = await readdir23(plDir, { withFileTypes: true });
|
|
108112
108871
|
for (const ver of versions) {
|
|
108113
108872
|
if (!ver.isDirectory())
|
|
108114
108873
|
continue;
|
|
108115
108874
|
scanned += 1;
|
|
108116
|
-
const verDir =
|
|
108117
|
-
const markerPath =
|
|
108875
|
+
const verDir = join98(plDir, ver.name);
|
|
108876
|
+
const markerPath = join98(verDir, ORPHAN_MARKER);
|
|
108118
108877
|
if (!existsSync27(markerPath))
|
|
108119
108878
|
continue;
|
|
108120
108879
|
const label2 = `${mp.name}/${pl.name}/${ver.name}`;
|
|
108121
108880
|
if (opts.dryRun) {
|
|
108122
108881
|
lines.push(` - would remove: ${label2}`);
|
|
108123
108882
|
} else {
|
|
108124
|
-
await
|
|
108883
|
+
await rm20(verDir, { recursive: true, force: true });
|
|
108125
108884
|
removed += 1;
|
|
108126
108885
|
lines.push(` ✓ removed: ${label2}`);
|
|
108127
108886
|
}
|
|
108128
108887
|
}
|
|
108129
108888
|
if (!opts.dryRun && await isEmptyDir(plDir)) {
|
|
108130
|
-
await
|
|
108889
|
+
await rm20(plDir, { recursive: true, force: true });
|
|
108131
108890
|
}
|
|
108132
108891
|
}
|
|
108133
108892
|
if (!opts.dryRun && await isEmptyDir(mpDir)) {
|
|
108134
|
-
await
|
|
108893
|
+
await rm20(mpDir, { recursive: true, force: true });
|
|
108135
108894
|
}
|
|
108136
108895
|
}
|
|
108137
108896
|
if (scanned === 0) {
|
|
@@ -108146,11 +108905,11 @@ function resolveClaudePluginCacheRoot(opts) {
|
|
|
108146
108905
|
if (explicitRoot)
|
|
108147
108906
|
return explicitRoot;
|
|
108148
108907
|
const home = opts.home ?? process.env[CLAUDE_PLUGIN_CACHE_HOME_ENV] ?? homedir();
|
|
108149
|
-
return
|
|
108908
|
+
return join98(home, ".claude", "plugins", "cache");
|
|
108150
108909
|
}
|
|
108151
108910
|
async function isEmptyDir(dir) {
|
|
108152
108911
|
try {
|
|
108153
|
-
const entries2 = await
|
|
108912
|
+
const entries2 = await readdir23(dir);
|
|
108154
108913
|
return entries2.length === 0;
|
|
108155
108914
|
} catch {
|
|
108156
108915
|
return false;
|
|
@@ -108178,13 +108937,13 @@ init_exitCode();
|
|
|
108178
108937
|
|
|
108179
108938
|
// src/lib/packageVersion.ts
|
|
108180
108939
|
import { existsSync as existsSync28, readFileSync as readFileSync9 } from "node:fs";
|
|
108181
|
-
import { dirname as dirname41, join as
|
|
108940
|
+
import { dirname as dirname41, join as join99 } from "node:path";
|
|
108182
108941
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
108183
108942
|
function readPackageVersion() {
|
|
108184
108943
|
try {
|
|
108185
108944
|
let dir = dirname41(fileURLToPath7(import.meta.url));
|
|
108186
108945
|
for (let depth = 0;depth < 8; depth += 1) {
|
|
108187
|
-
const packagePath =
|
|
108946
|
+
const packagePath = join99(dir, "package.json");
|
|
108188
108947
|
if (existsSync28(packagePath)) {
|
|
108189
108948
|
const parsed = JSON.parse(readFileSync9(packagePath, "utf8"));
|
|
108190
108949
|
if (typeof parsed.version === "string" && parsed.version.length > 0) {
|
|
@@ -108207,12 +108966,12 @@ function readPackageVersion() {
|
|
|
108207
108966
|
|
|
108208
108967
|
// src/project/sourceCommands.ts
|
|
108209
108968
|
init_src2();
|
|
108210
|
-
import { readFile as
|
|
108969
|
+
import { readFile as readFile86 } from "node:fs/promises";
|
|
108211
108970
|
import { isAbsolute as isAbsolute22, resolve as resolve37 } from "node:path";
|
|
108212
108971
|
init_cliFeedback();
|
|
108213
108972
|
init_errors3();
|
|
108214
108973
|
init_exitCode();
|
|
108215
|
-
var
|
|
108974
|
+
var import_yaml49 = __toESM(require_dist(), 1);
|
|
108216
108975
|
|
|
108217
108976
|
// src/project/repoSourceRecovery.ts
|
|
108218
108977
|
init_cliFeedback();
|
|
@@ -108220,7 +108979,7 @@ init_errors3();
|
|
|
108220
108979
|
init_exitCode();
|
|
108221
108980
|
import { execFile as execFile10 } from "node:child_process";
|
|
108222
108981
|
import { existsSync as existsSync29 } from "node:fs";
|
|
108223
|
-
import { lstat as
|
|
108982
|
+
import { lstat as lstat11, mkdir as mkdir33, readlink as readlink2, realpath as realpath8, rm as rm21, symlink as symlink3 } from "node:fs/promises";
|
|
108224
108983
|
import { basename as basename11, dirname as dirname42, isAbsolute as isAbsolute19, relative as relative26, resolve as resolve34 } from "node:path";
|
|
108225
108984
|
import { promisify as promisify10 } from "node:util";
|
|
108226
108985
|
init_writeLock();
|
|
@@ -108316,7 +109075,9 @@ async function repositoryRecoveryPlan(input) {
|
|
|
108316
109075
|
if (input.source !== undefined && selected.length === 0) {
|
|
108317
109076
|
throw new ContextError(ExitCode.WorkspaceStateError, `repo source is not registered: ${input.source}`, {
|
|
108318
109077
|
category: ErrorCategory.SourceNotFound,
|
|
108319
|
-
sourceId: input.source
|
|
109078
|
+
sourceId: input.source,
|
|
109079
|
+
registered_names: registry2.repos.map((source2) => source2.name),
|
|
109080
|
+
next_action: { command: "context source recovery-plan --format json" }
|
|
108320
109081
|
});
|
|
108321
109082
|
}
|
|
108322
109083
|
const grouped = new Map;
|
|
@@ -108404,19 +109165,19 @@ async function cloneCheckout(input) {
|
|
|
108404
109165
|
next: `Use local mode with path ${JSON.stringify(target)} after inspecting the existing checkout.`
|
|
108405
109166
|
});
|
|
108406
109167
|
}
|
|
108407
|
-
await
|
|
109168
|
+
await mkdir33(dirname42(target), { recursive: true });
|
|
108408
109169
|
const cloneArgs = ["clone", "--no-checkout", "--depth=1", "--filter=blob:none", input.remote, target];
|
|
108409
109170
|
try {
|
|
108410
109171
|
await execFileAsync6("git", cloneArgs, { encoding: "utf8", maxBuffer: 4 * 1024 * 1024 });
|
|
108411
109172
|
} catch {
|
|
108412
|
-
await
|
|
109173
|
+
await rm21(target, { recursive: true, force: true });
|
|
108413
109174
|
try {
|
|
108414
109175
|
await execFileAsync6("git", ["clone", "--no-checkout", "--depth=1", input.remote, target], {
|
|
108415
109176
|
encoding: "utf8",
|
|
108416
109177
|
maxBuffer: 4 * 1024 * 1024
|
|
108417
109178
|
});
|
|
108418
109179
|
} catch (error) {
|
|
108419
|
-
await
|
|
109180
|
+
await rm21(target, { recursive: true, force: true });
|
|
108420
109181
|
const detail = error !== null && typeof error === "object" && "stderr" in error ? String(error.stderr ?? "").trim() : error instanceof Error ? error.message : String(error);
|
|
108421
109182
|
throw new ContextError(ExitCode.ExternalToolError, `cannot clone registered repository: ${input.remote}`, {
|
|
108422
109183
|
category: ErrorCategory.ExternalToolFailed,
|
|
@@ -108441,7 +109202,7 @@ async function cloneCheckout(input) {
|
|
|
108441
109202
|
await verifyCheckout({ checkout: target, remote: input.remote, ref: input.ref, subpaths: input.subpaths });
|
|
108442
109203
|
return target;
|
|
108443
109204
|
} catch (error) {
|
|
108444
|
-
await
|
|
109205
|
+
await rm21(target, { recursive: true, force: true });
|
|
108445
109206
|
throw error;
|
|
108446
109207
|
}
|
|
108447
109208
|
}
|
|
@@ -108450,14 +109211,14 @@ async function bindLocalAlias(input) {
|
|
|
108450
109211
|
return;
|
|
108451
109212
|
const projectRoot = await realpath8(input.projectRoot);
|
|
108452
109213
|
const alias = resolve34(projectRoot, input.declaredLocal);
|
|
108453
|
-
const stats = await
|
|
109214
|
+
const stats = await lstat11(alias).catch(() => null);
|
|
108454
109215
|
if (stats !== null) {
|
|
108455
109216
|
if (stats.isSymbolicLink()) {
|
|
108456
109217
|
const actual = resolve34(dirname42(alias), await readlink2(alias));
|
|
108457
109218
|
const actualReal = await realpath8(actual).catch(() => null);
|
|
108458
109219
|
if (actualReal !== null && actualReal === await realpath8(input.checkout))
|
|
108459
109220
|
return;
|
|
108460
|
-
await
|
|
109221
|
+
await rm21(alias);
|
|
108461
109222
|
} else {
|
|
108462
109223
|
const actual = await realpath8(alias);
|
|
108463
109224
|
if (actual === await realpath8(input.checkout))
|
|
@@ -108469,7 +109230,7 @@ async function bindLocalAlias(input) {
|
|
|
108469
109230
|
});
|
|
108470
109231
|
}
|
|
108471
109232
|
}
|
|
108472
|
-
await
|
|
109233
|
+
await mkdir33(dirname42(alias), { recursive: true });
|
|
108473
109234
|
await symlink3(relative26(dirname42(alias), input.checkout) || ".", alias);
|
|
108474
109235
|
}
|
|
108475
109236
|
function selectPhysicalGroup(sources, selector) {
|
|
@@ -108548,10 +109309,15 @@ async function restoreRepositorySources(input) {
|
|
|
108548
109309
|
}
|
|
108549
109310
|
if (registryChanged)
|
|
108550
109311
|
await writeRepoRegistry(input.projectRoot, registry2);
|
|
109312
|
+
const { readProductionStage: readProductionStage2 } = await Promise.resolve().then(() => (init_productionStageStore(), exports_productionStageStore));
|
|
109313
|
+
const stage = await readProductionStage2(input.projectRoot);
|
|
109314
|
+
const restoredScopes = new Set(restored.filter((result) => result.ready).flatMap((result) => result.sources.map((name3) => `repo:${name3}`)));
|
|
109315
|
+
const { readMaintenance: readMaintenance2 } = await Promise.resolve().then(() => (init_maintenanceStorage(), exports_maintenanceStorage));
|
|
109316
|
+
const refresh = stage && !stage.delivery && stage.scopes.some((source2) => restoredScopes.has(source2.scope)) && !(await readMaintenance2(input.projectRoot)).active;
|
|
108551
109317
|
return {
|
|
108552
109318
|
schema: "context.repository-source-recovery-result.v1",
|
|
108553
109319
|
restored,
|
|
108554
|
-
next_action: { command: "context status --format json" }
|
|
109320
|
+
next_action: { command: refresh ? `context action prepare-current --revision ${stage.id} --format json` : "context status --format json" }
|
|
108555
109321
|
};
|
|
108556
109322
|
});
|
|
108557
109323
|
}
|
|
@@ -108559,11 +109325,11 @@ async function restoreRepositorySources(input) {
|
|
|
108559
109325
|
// src/project/sourceDocumentStatus.ts
|
|
108560
109326
|
init_src2();
|
|
108561
109327
|
import { existsSync as existsSync30 } from "node:fs";
|
|
108562
|
-
import { readFile as
|
|
108563
|
-
import { join as
|
|
109328
|
+
import { readFile as readFile79 } from "node:fs/promises";
|
|
109329
|
+
import { join as join101 } from "node:path";
|
|
108564
109330
|
// src/project/sourceCommandViews.ts
|
|
108565
|
-
import { readFile as
|
|
108566
|
-
import { join as
|
|
109331
|
+
import { readFile as readFile78 } from "node:fs/promises";
|
|
109332
|
+
import { join as join100 } from "node:path";
|
|
108567
109333
|
init_workspace();
|
|
108568
109334
|
init_documentBatchManifest();
|
|
108569
109335
|
function repoSourceAgentView(source2) {
|
|
@@ -108626,7 +109392,7 @@ async function fileSourceAgentViewWithNextAction(input) {
|
|
|
108626
109392
|
};
|
|
108627
109393
|
}
|
|
108628
109394
|
function documentSourceManifestPath(source2) {
|
|
108629
|
-
return source2.snapshot?.manifest ??
|
|
109395
|
+
return source2.snapshot?.manifest ?? join100(source2.materializedAt, "manifest.json");
|
|
108630
109396
|
}
|
|
108631
109397
|
async function fileSourceDocumentSiteHint(input) {
|
|
108632
109398
|
const detection = await detectDocumentSiteFiles({
|
|
@@ -108636,7 +109402,7 @@ async function fileSourceDocumentSiteHint(input) {
|
|
|
108636
109402
|
let snapshotConfigured = false;
|
|
108637
109403
|
const manifest = documentSourceManifestPath(input.source);
|
|
108638
109404
|
try {
|
|
108639
|
-
const parsed = parseDocumentSnapshotForSource(JSON.parse(await
|
|
109405
|
+
const parsed = parseDocumentSnapshotForSource(JSON.parse(await readFile78(join100(input.projectRoot, manifest), "utf8")), input.source.name);
|
|
108640
109406
|
snapshotConfigured = manifestUsesMdxJsonDocs(parsed);
|
|
108641
109407
|
} catch {
|
|
108642
109408
|
snapshotConfigured = false;
|
|
@@ -108668,11 +109434,11 @@ async function larkSourceAgentViewWithNextAction(input) {
|
|
|
108668
109434
|
// src/project/sourceDocumentStatus.ts
|
|
108669
109435
|
init_documentBatchManifest();
|
|
108670
109436
|
function documentSourceManifestPath2(source2) {
|
|
108671
|
-
return source2.snapshot?.manifest ??
|
|
109437
|
+
return source2.snapshot?.manifest ?? join101(source2.materializedAt, "manifest.json");
|
|
108672
109438
|
}
|
|
108673
109439
|
async function documentSnapshotState(input) {
|
|
108674
109440
|
const manifest = documentSourceManifestPath2(input.source);
|
|
108675
|
-
const manifestPath =
|
|
109441
|
+
const manifestPath = join101(input.projectRoot, manifest);
|
|
108676
109442
|
if (!existsSync30(manifestPath)) {
|
|
108677
109443
|
return {
|
|
108678
109444
|
snapshotReady: false,
|
|
@@ -108683,7 +109449,7 @@ async function documentSnapshotState(input) {
|
|
|
108683
109449
|
};
|
|
108684
109450
|
}
|
|
108685
109451
|
try {
|
|
108686
|
-
const parsed = findDocumentSnapshotForSource(JSON.parse(await
|
|
109452
|
+
const parsed = findDocumentSnapshotForSource(JSON.parse(await readFile79(manifestPath, "utf8")), input.source.name);
|
|
108687
109453
|
if (parsed === null) {
|
|
108688
109454
|
return {
|
|
108689
109455
|
snapshotReady: false,
|
|
@@ -108751,7 +109517,7 @@ async function documentSnapshotState(input) {
|
|
|
108751
109517
|
const missing = [
|
|
108752
109518
|
...parsed.files.map((file) => file.path),
|
|
108753
109519
|
...(parsed.assets ?? []).filter((asset) => asset.content_hash !== undefined).map((asset) => asset.path)
|
|
108754
|
-
].find((path3) => !existsSync30(
|
|
109520
|
+
].find((path3) => !existsSync30(join101(input.projectRoot, input.source.materializedAt, path3)));
|
|
108755
109521
|
if (missing !== undefined) {
|
|
108756
109522
|
return {
|
|
108757
109523
|
snapshotReady: false,
|
|
@@ -108850,10 +109616,10 @@ init_atomicWrite();
|
|
|
108850
109616
|
init_cliFeedback();
|
|
108851
109617
|
init_errors3();
|
|
108852
109618
|
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
|
|
109619
|
+
var import_yaml46 = __toESM(require_dist(), 1);
|
|
109620
|
+
import { createHash as createHash30 } from "node:crypto";
|
|
109621
|
+
import { readFile as readFile80, realpath as realpath9 } from "node:fs/promises";
|
|
109622
|
+
import { basename as basename12, extname as extname15, isAbsolute as isAbsolute20, join as join102, relative as relative27, resolve as resolve35 } from "node:path";
|
|
108857
109623
|
init_writeLock();
|
|
108858
109624
|
var SOURCE_NAME_PATTERN3 = /^[a-z0-9][a-z0-9._-]*$/u;
|
|
108859
109625
|
function isDateSourceNamespace(value) {
|
|
@@ -108882,7 +109648,7 @@ function defaultLarkModule(input) {
|
|
|
108882
109648
|
if (titleSlug.length > 0)
|
|
108883
109649
|
return titleSlug;
|
|
108884
109650
|
}
|
|
108885
|
-
const opaqueSlug = (kind, identity) => `${kind}-${
|
|
109651
|
+
const opaqueSlug = (kind, identity) => `${kind}-${createHash30("sha256").update(identity).digest("hex").slice(0, 12)}`;
|
|
108886
109652
|
if (input.url !== undefined) {
|
|
108887
109653
|
try {
|
|
108888
109654
|
const parsed = new URL(input.url);
|
|
@@ -108949,8 +109715,8 @@ function assertSafeFileInclude(value) {
|
|
|
108949
109715
|
}
|
|
108950
109716
|
async function readRegistryDocument(projectRoot, registryPath2) {
|
|
108951
109717
|
try {
|
|
108952
|
-
const content3 = await
|
|
108953
|
-
return content3.trim().length === 0 ? { sources: [] } :
|
|
109718
|
+
const content3 = await readFile80(join102(projectRoot, registryPath2), "utf8");
|
|
109719
|
+
return content3.trim().length === 0 ? { sources: [] } : import_yaml46.default.parse(content3);
|
|
108954
109720
|
} catch (error) {
|
|
108955
109721
|
if (error instanceof Error && "code" in error && error.code === "ENOENT")
|
|
108956
109722
|
return { sources: [] };
|
|
@@ -109067,7 +109833,7 @@ async function addFileSourceUnlocked(input) {
|
|
|
109067
109833
|
const record6 = entry2;
|
|
109068
109834
|
return record6.name !== input.name && record6.id !== input.name;
|
|
109069
109835
|
}), nextEntry];
|
|
109070
|
-
await atomicWriteFile(
|
|
109836
|
+
await atomicWriteFile(join102(input.projectRoot, DEFAULT_FILE_SOURCES_REGISTRY_PATH), import_yaml46.default.stringify({ sources: nextSources }));
|
|
109071
109837
|
const updated = await loadSourcesRegistry({ rootDir: input.projectRoot });
|
|
109072
109838
|
const entry = updated.files.find((source2) => source2.name === input.name || source2.id === input.name);
|
|
109073
109839
|
if (entry === undefined) {
|
|
@@ -109123,7 +109889,7 @@ async function addLarkSourceUnlocked(input) {
|
|
|
109123
109889
|
const record6 = entry2;
|
|
109124
109890
|
return record6.name !== input.name && record6.id !== input.name;
|
|
109125
109891
|
}), nextEntry];
|
|
109126
|
-
await atomicWriteFile(
|
|
109892
|
+
await atomicWriteFile(join102(input.projectRoot, DEFAULT_LARK_SOURCES_REGISTRY_PATH), import_yaml46.default.stringify({ sources: nextSources }));
|
|
109127
109893
|
const updated = await loadSourcesRegistry({ rootDir: input.projectRoot });
|
|
109128
109894
|
const entry = updated.larks.find((source2) => source2.name === input.name || source2.id === input.name);
|
|
109129
109895
|
if (entry === undefined) {
|
|
@@ -109323,11 +110089,11 @@ init_candidateLedger();
|
|
|
109323
110089
|
init_documentBatchManifest();
|
|
109324
110090
|
init_workspace();
|
|
109325
110091
|
init_writeLock();
|
|
109326
|
-
var
|
|
110092
|
+
var import_yaml47 = __toESM(require_dist(), 1);
|
|
109327
110093
|
import { existsSync as existsSync31 } from "node:fs";
|
|
109328
|
-
import { createHash as
|
|
109329
|
-
import { readFile as
|
|
109330
|
-
import { isAbsolute as isAbsolute21, join as
|
|
110094
|
+
import { createHash as createHash31 } from "node:crypto";
|
|
110095
|
+
import { readFile as readFile81, readdir as readdir24, rm as rm22 } from "node:fs/promises";
|
|
110096
|
+
import { isAbsolute as isAbsolute21, join as join103, relative as relative28, resolve as resolve36, sep as sep8 } from "node:path";
|
|
109331
110097
|
function sourceIdentity(source2) {
|
|
109332
110098
|
if (source2.kind === "source.collection")
|
|
109333
110099
|
return;
|
|
@@ -109359,10 +110125,10 @@ function collectStrings(value, output) {
|
|
|
109359
110125
|
}
|
|
109360
110126
|
}
|
|
109361
110127
|
async function yamlReferences(input) {
|
|
109362
|
-
const absolutePath =
|
|
110128
|
+
const absolutePath = join103(input.projectRoot, input.path);
|
|
109363
110129
|
if (!existsSync31(absolutePath))
|
|
109364
110130
|
return false;
|
|
109365
|
-
const parsed =
|
|
110131
|
+
const parsed = import_yaml47.default.parse(await readFile81(absolutePath, "utf8"));
|
|
109366
110132
|
const strings = [];
|
|
109367
110133
|
collectStrings(parsed, strings);
|
|
109368
110134
|
return strings.some((value) => stringReferencesSource(value, input.source));
|
|
@@ -109488,11 +110254,11 @@ async function registryRemovalWrite(projectRoot, source2) {
|
|
|
109488
110254
|
const path3 = registryPath2(source2.type);
|
|
109489
110255
|
if (path3 === null)
|
|
109490
110256
|
return;
|
|
109491
|
-
const absolutePath =
|
|
109492
|
-
const document4 = existsSync31(absolutePath) ?
|
|
110257
|
+
const absolutePath = join103(projectRoot, path3);
|
|
110258
|
+
const document4 = existsSync31(absolutePath) ? import_yaml47.default.parse(await readFile81(absolutePath, "utf8")) : { sources: [] };
|
|
109493
110259
|
return {
|
|
109494
110260
|
path: absolutePath,
|
|
109495
|
-
bytes:
|
|
110261
|
+
bytes: import_yaml47.default.stringify(removeDocumentEntry(document4, source2))
|
|
109496
110262
|
};
|
|
109497
110263
|
}
|
|
109498
110264
|
function safeManagedMaterializedPath(projectRoot, source2) {
|
|
@@ -109507,7 +110273,7 @@ function safeManagedMaterializedPath(projectRoot, source2) {
|
|
|
109507
110273
|
return absolute;
|
|
109508
110274
|
}
|
|
109509
110275
|
function safeManagedManifestPath(projectRoot, source2) {
|
|
109510
|
-
const manifest = source2.manifest ??
|
|
110276
|
+
const manifest = source2.manifest ?? join103(source2.materializedAt, "manifest.json");
|
|
109511
110277
|
if (isAbsolute21(manifest))
|
|
109512
110278
|
throw unsafeOwnership(source2, manifest);
|
|
109513
110279
|
const absolute = resolve36(projectRoot, manifest);
|
|
@@ -109542,7 +110308,7 @@ function projectRelative(projectRoot, path3) {
|
|
|
109542
110308
|
return relative28(projectRoot, path3).split(sep8).join("/");
|
|
109543
110309
|
}
|
|
109544
110310
|
function digest6(value) {
|
|
109545
|
-
return `sha256:${
|
|
110311
|
+
return `sha256:${createHash31("sha256").update(JSON.stringify(value)).digest("hex")}`;
|
|
109546
110312
|
}
|
|
109547
110313
|
async function sharedMaterializedOwners(projectRoot, source2) {
|
|
109548
110314
|
const target = safeManagedMaterializedPath(projectRoot, source2);
|
|
@@ -109636,12 +110402,12 @@ async function createRemovalPlan(projectRoot, selector) {
|
|
|
109636
110402
|
source: source2,
|
|
109637
110403
|
registry: registryPath2(source2.type),
|
|
109638
110404
|
registryBytes: registryWrite?.bytes ?? null,
|
|
109639
|
-
managedBytes: source2.type === "note" || source2.type === "sessions" ? await
|
|
110405
|
+
managedBytes: source2.type === "note" || source2.type === "sessions" ? await readFile81(absoluteRemovals[0], "utf8") : null,
|
|
109640
110406
|
references,
|
|
109641
110407
|
cleanup,
|
|
109642
110408
|
manifestBytes: manifestWrite?.bytes ?? null
|
|
109643
110409
|
});
|
|
109644
|
-
const
|
|
110410
|
+
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
110411
|
return {
|
|
109646
110412
|
action: "preview",
|
|
109647
110413
|
source: source2,
|
|
@@ -109650,7 +110416,7 @@ async function createRemovalPlan(projectRoot, selector) {
|
|
|
109650
110416
|
references,
|
|
109651
110417
|
plan_digest: planDigest,
|
|
109652
110418
|
cleanup,
|
|
109653
|
-
next,
|
|
110419
|
+
next: next2,
|
|
109654
110420
|
...registryWrite === undefined ? {} : { registryWrite },
|
|
109655
110421
|
...manifestWrite !== undefined ? { manifestWrite } : {},
|
|
109656
110422
|
absoluteRemovals: [...new Set(absoluteRemovals)].sort()
|
|
@@ -109669,12 +110435,12 @@ function publicRemovalResult(plan, action) {
|
|
|
109669
110435
|
};
|
|
109670
110436
|
}
|
|
109671
110437
|
async function pruneExtractRuntime(projectRoot, source2) {
|
|
109672
|
-
const fingerprintPath =
|
|
110438
|
+
const fingerprintPath = join103(projectRoot, ".tmp/context-runtime/extract/source-fingerprints.json");
|
|
109673
110439
|
const removedPhaseIds = new Set;
|
|
109674
110440
|
if (existsSync31(fingerprintPath)) {
|
|
109675
|
-
const parsed = JSON.parse(await
|
|
110441
|
+
const parsed = JSON.parse(await readFile81(fingerprintPath, "utf8"));
|
|
109676
110442
|
const phases = parsed.phases ?? {};
|
|
109677
|
-
const
|
|
110443
|
+
const next2 = Object.fromEntries(Object.entries(phases).filter(([phaseId, raw]) => {
|
|
109678
110444
|
if (raw === null || typeof raw !== "object" || Array.isArray(raw))
|
|
109679
110445
|
return true;
|
|
109680
110446
|
const sources = raw.sources;
|
|
@@ -109683,30 +110449,30 @@ async function pruneExtractRuntime(projectRoot, source2) {
|
|
|
109683
110449
|
removedPhaseIds.add(phaseId);
|
|
109684
110450
|
return keep;
|
|
109685
110451
|
}));
|
|
109686
|
-
await atomicWriteFile(fingerprintPath, `${JSON.stringify({ ...parsed, phases:
|
|
110452
|
+
await atomicWriteFile(fingerprintPath, `${JSON.stringify({ ...parsed, phases: next2 }, null, 2)}
|
|
109687
110453
|
`);
|
|
109688
110454
|
}
|
|
109689
|
-
const phaseOwnershipPath =
|
|
110455
|
+
const phaseOwnershipPath = join103(projectRoot, ".tmp/context-runtime/extract/custom-phase-candidates.json");
|
|
109690
110456
|
if (existsSync31(phaseOwnershipPath) && removedPhaseIds.size > 0) {
|
|
109691
|
-
const parsed = JSON.parse(await
|
|
110457
|
+
const parsed = JSON.parse(await readFile81(phaseOwnershipPath, "utf8"));
|
|
109692
110458
|
const phases = Object.fromEntries(Object.entries(parsed.phases ?? {}).filter(([phaseId]) => !removedPhaseIds.has(phaseId)));
|
|
109693
110459
|
await atomicWriteFile(phaseOwnershipPath, `${JSON.stringify({ ...parsed, phases }, null, 2)}
|
|
109694
110460
|
`);
|
|
109695
110461
|
}
|
|
109696
|
-
const symbolPath =
|
|
110462
|
+
const symbolPath = join103(projectRoot, ".tmp/context-runtime/extract/source-symbols.json");
|
|
109697
110463
|
if (existsSync31(symbolPath)) {
|
|
109698
|
-
const parsed = JSON.parse(await
|
|
110464
|
+
const parsed = JSON.parse(await readFile81(symbolPath, "utf8"));
|
|
109699
110465
|
const symbols = Array.isArray(parsed.symbols) ? parsed.symbols.filter((entry) => entry === null || typeof entry !== "object" || Array.isArray(entry) || entry.source !== source2.name) : [];
|
|
109700
110466
|
const phaseFingerprints = Object.fromEntries(Object.entries(parsed.phaseFingerprints ?? {}).filter(([phaseId]) => !removedPhaseIds.has(phaseId)));
|
|
109701
110467
|
await atomicWriteFile(symbolPath, `${JSON.stringify({ ...parsed, phaseFingerprints, symbols }, null, 2)}
|
|
109702
110468
|
`);
|
|
109703
110469
|
}
|
|
109704
|
-
const snapshotRoot =
|
|
110470
|
+
const snapshotRoot = join103(projectRoot, ".tmp/context-runtime/extract/candidates");
|
|
109705
110471
|
const visit4 = async (directory) => {
|
|
109706
110472
|
if (!existsSync31(directory))
|
|
109707
110473
|
return;
|
|
109708
|
-
for (const entry of await
|
|
109709
|
-
const path3 =
|
|
110474
|
+
for (const entry of await readdir24(directory, { withFileTypes: true })) {
|
|
110475
|
+
const path3 = join103(directory, entry.name);
|
|
109710
110476
|
if (entry.isDirectory()) {
|
|
109711
110477
|
await visit4(path3);
|
|
109712
110478
|
continue;
|
|
@@ -109714,10 +110480,10 @@ async function pruneExtractRuntime(projectRoot, source2) {
|
|
|
109714
110480
|
if (!entry.isFile() || !entry.name.endsWith(".json"))
|
|
109715
110481
|
continue;
|
|
109716
110482
|
try {
|
|
109717
|
-
const parsed = JSON.parse(await
|
|
110483
|
+
const parsed = JSON.parse(await readFile81(path3, "utf8"));
|
|
109718
110484
|
const refs = Array.isArray(parsed.source_refs) ? parsed.source_refs : [];
|
|
109719
110485
|
if (parsed.source === source2.name || refs.some((ref2) => typeof ref2 === "string" && stringReferencesSource(ref2, source2))) {
|
|
109720
|
-
await
|
|
110486
|
+
await rm22(path3, { force: true });
|
|
109721
110487
|
}
|
|
109722
110488
|
} catch {}
|
|
109723
110489
|
}
|
|
@@ -109756,7 +110522,7 @@ async function removeProjectSource(input) {
|
|
|
109756
110522
|
});
|
|
109757
110523
|
}
|
|
109758
110524
|
await applyAtomicFileBatch({
|
|
109759
|
-
transactionRoot:
|
|
110525
|
+
transactionRoot: join103(input.projectRoot, ".tmp", "context-runtime", "source-remove-transactions"),
|
|
109760
110526
|
writes: [...plan.registryWrite === undefined ? [] : [plan.registryWrite], ...plan.manifestWrite !== undefined ? [plan.manifestWrite] : []],
|
|
109761
110527
|
removals: plan.absoluteRemovals
|
|
109762
110528
|
});
|
|
@@ -109772,11 +110538,11 @@ init_workspace();
|
|
|
109772
110538
|
init_writeLock();
|
|
109773
110539
|
init_durableMultiFileTransaction();
|
|
109774
110540
|
init_durableSingleFileTransaction();
|
|
109775
|
-
import { readFile as
|
|
110541
|
+
import { readFile as readFile82 } from "node:fs/promises";
|
|
109776
110542
|
import ts from "typescript";
|
|
109777
|
-
function generateSourceConfiguration(
|
|
109778
|
-
const file = ts.createSourceFile("index.ts",
|
|
109779
|
-
if (ts.transpileModule(
|
|
110543
|
+
function generateSourceConfiguration(text10, selected) {
|
|
110544
|
+
const file = ts.createSourceFile("index.ts", text10, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
110545
|
+
if (ts.transpileModule(text10, { reportDiagnostics: true }).diagnostics?.some((item) => item.category === ts.DiagnosticCategory.Error))
|
|
109780
110546
|
return;
|
|
109781
110547
|
const imports = file.statements.filter(ts.isImportDeclaration).filter((node3) => ts.isStringLiteral(node3.moduleSpecifier) && node3.moduleSpecifier.text === "@c4a/context");
|
|
109782
110548
|
if (imports.length !== 1)
|
|
@@ -109887,7 +110653,7 @@ function generateSourceConfiguration(text9, selected) {
|
|
|
109887
110653
|
}
|
|
109888
110654
|
}
|
|
109889
110655
|
if (!additions.length && !captures.length)
|
|
109890
|
-
return
|
|
110656
|
+
return text10;
|
|
109891
110657
|
const identifiers = new Set;
|
|
109892
110658
|
const visit4 = (node3) => {
|
|
109893
110659
|
if (ts.isIdentifier(node3))
|
|
@@ -109907,12 +110673,12 @@ function generateSourceConfiguration(text9, selected) {
|
|
|
109907
110673
|
}
|
|
109908
110674
|
if (needed.size)
|
|
109909
110675
|
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),
|
|
110676
|
+
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
110677
|
}
|
|
109912
110678
|
async function configureRegisteredSources(projectRoot, selected) {
|
|
109913
110679
|
return withProjectWriteLock(projectRoot, "source-project-configuration", async () => {
|
|
109914
110680
|
const path3 = "src/index.ts";
|
|
109915
|
-
const config = JSON.parse(await
|
|
110681
|
+
const config = JSON.parse(await readFile82(await safeProjectTarget(projectRoot, "package.json"), "utf8"));
|
|
109916
110682
|
if (config.context?.entry !== path3)
|
|
109917
110683
|
return {
|
|
109918
110684
|
status: "manual",
|
|
@@ -109921,8 +110687,8 @@ async function configureRegisteredSources(projectRoot, selected) {
|
|
|
109921
110687
|
sources: selected
|
|
109922
110688
|
};
|
|
109923
110689
|
const target = await safeProjectTarget(projectRoot, path3);
|
|
109924
|
-
const
|
|
109925
|
-
const updated = generateSourceConfiguration(
|
|
110690
|
+
const text10 = await readFile82(target, "utf8");
|
|
110691
|
+
const updated = generateSourceConfiguration(text10, selected);
|
|
109926
110692
|
if (updated === undefined)
|
|
109927
110693
|
return {
|
|
109928
110694
|
status: "manual",
|
|
@@ -109930,15 +110696,15 @@ async function configureRegisteredSources(projectRoot, selected) {
|
|
|
109930
110696
|
message: "Registration is saved. Preserve the custom project entry and configure only these sources manually.",
|
|
109931
110697
|
sources: selected
|
|
109932
110698
|
};
|
|
109933
|
-
if (updated !==
|
|
110699
|
+
if (updated !== text10)
|
|
109934
110700
|
await runDurableSingleFileTransaction({
|
|
109935
110701
|
projectRoot,
|
|
109936
110702
|
kind: "source-project-configuration",
|
|
109937
110703
|
target_path: path3,
|
|
109938
|
-
expected_base_digest: durableContentDigest(
|
|
110704
|
+
expected_base_digest: durableContentDigest(text10),
|
|
109939
110705
|
target_content: updated
|
|
109940
110706
|
});
|
|
109941
|
-
return { status: updated ===
|
|
110707
|
+
return { status: updated === text10 ? "unchanged" : "configured", file: path3 };
|
|
109942
110708
|
});
|
|
109943
110709
|
}
|
|
109944
110710
|
|
|
@@ -110001,7 +110767,7 @@ async function readIncludeList(projectRoot, path3) {
|
|
|
110001
110767
|
}
|
|
110002
110768
|
let content3;
|
|
110003
110769
|
try {
|
|
110004
|
-
content3 = await
|
|
110770
|
+
content3 = await readFile86(isAbsolute22(trimmed) ? resolve37(trimmed) : resolve37(projectRoot, trimmed), "utf8");
|
|
110005
110771
|
} catch (error) {
|
|
110006
110772
|
throw new ContextError(ExitCode.UserError, `cannot read include list: ${trimmed}`, {
|
|
110007
110773
|
category: ErrorCategory.UserInputInvalid,
|
|
@@ -110042,7 +110808,7 @@ function rowsFromValue(value) {
|
|
|
110042
110808
|
return value.map((item) => item && typeof item === "object" && !Array.isArray(item) ? item : { value: item });
|
|
110043
110809
|
}
|
|
110044
110810
|
if (value && typeof value === "object") {
|
|
110045
|
-
return Object.entries(value).map(([key,
|
|
110811
|
+
return Object.entries(value).map(([key, next2]) => ({ key, value: next2 }));
|
|
110046
110812
|
}
|
|
110047
110813
|
return [{ value }];
|
|
110048
110814
|
}
|
|
@@ -110069,7 +110835,7 @@ function writeFormatted(value, format2) {
|
|
|
110069
110835
|
return;
|
|
110070
110836
|
}
|
|
110071
110837
|
if (format2 === "yaml") {
|
|
110072
|
-
process.stdout.write(
|
|
110838
|
+
process.stdout.write(import_yaml49.default.stringify(value));
|
|
110073
110839
|
return;
|
|
110074
110840
|
}
|
|
110075
110841
|
process.stdout.write(renderTable2(value));
|
|
@@ -110390,16 +111156,16 @@ report shown above. A direct maintenance call outside that Route may omit it.
|
|
|
110390
111156
|
init_cliFeedback();
|
|
110391
111157
|
init_errors3();
|
|
110392
111158
|
init_exitCode();
|
|
110393
|
-
var
|
|
111159
|
+
var import_yaml51 = __toESM(require_dist(), 1);
|
|
110394
111160
|
|
|
110395
111161
|
// src/project/productionSkillCatalog.ts
|
|
110396
111162
|
init_errors3();
|
|
110397
111163
|
init_cliFeedback();
|
|
110398
111164
|
init_exitCode();
|
|
110399
|
-
var
|
|
111165
|
+
var import_yaml50 = __toESM(require_dist(), 1);
|
|
110400
111166
|
import { constants as constants6, existsSync as existsSync32 } from "node:fs";
|
|
110401
|
-
import { lstat as
|
|
110402
|
-
import { dirname as dirname43, join as
|
|
111167
|
+
import { lstat as lstat12, open as open5, readdir as readdir25 } from "node:fs/promises";
|
|
111168
|
+
import { dirname as dirname43, join as join105, resolve as resolve38 } from "node:path";
|
|
110403
111169
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
110404
111170
|
function bundledSkillRoot() {
|
|
110405
111171
|
const directory = dirname43(fileURLToPath8(import.meta.url));
|
|
@@ -110426,11 +111192,11 @@ async function listProductionSkills(root2) {
|
|
|
110426
111192
|
}
|
|
110427
111193
|
}
|
|
110428
111194
|
async function readProductionSkills(root2) {
|
|
110429
|
-
const entries2 = (await
|
|
111195
|
+
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
111196
|
const skills = [];
|
|
110431
111197
|
for (const directory of entries2) {
|
|
110432
|
-
const entry =
|
|
110433
|
-
if (!(await
|
|
111198
|
+
const entry = join105(root2, directory.name, "SKILL.md");
|
|
111199
|
+
if (!(await lstat12(entry)).isFile())
|
|
110434
111200
|
throw new TypeError(`Skill entry must be a regular file: ${entry}`);
|
|
110435
111201
|
const handle2 = await open5(entry, constants6.O_RDONLY | constants6.O_NOFOLLOW | constants6.O_NONBLOCK);
|
|
110436
111202
|
let header;
|
|
@@ -110446,7 +111212,7 @@ async function readProductionSkills(root2) {
|
|
|
110446
111212
|
const frontmatter2 = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/u.exec(header);
|
|
110447
111213
|
if (!frontmatter2)
|
|
110448
111214
|
throw new TypeError(`Skill entry needs complete frontmatter within 64 KiB: ${entry}`);
|
|
110449
|
-
const value =
|
|
111215
|
+
const value = import_yaml50.default.parse(frontmatter2[1], { uniqueKeys: true });
|
|
110450
111216
|
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
111217
|
throw new TypeError(`Skill entry needs a name and description: ${entry}`);
|
|
110452
111218
|
}
|
|
@@ -110509,7 +111275,7 @@ function outputFormat2(options) {
|
|
|
110509
111275
|
}
|
|
110510
111276
|
function writeOutput(value, format2) {
|
|
110511
111277
|
process.stdout.write(format2 === "json" ? `${JSON.stringify(value, null, 2)}
|
|
110512
|
-
` :
|
|
111278
|
+
` : import_yaml51.default.stringify(value));
|
|
110513
111279
|
}
|
|
110514
111280
|
function registerProjectIndexerCommands(program2) {
|
|
110515
111281
|
const indexer = program2.command("indexer").description("Discover bundled skills or inspect a benchmark result");
|
|
@@ -110593,7 +111359,7 @@ function initCommand2(input, projectDir) {
|
|
|
110593
111359
|
return args.map(shellQuote7).join(" ");
|
|
110594
111360
|
}
|
|
110595
111361
|
function readyResult(input, projectRoot, relocation) {
|
|
110596
|
-
const
|
|
111362
|
+
const command3 = workflowCommand(input);
|
|
110597
111363
|
return {
|
|
110598
111364
|
schema: "context.entry.v1",
|
|
110599
111365
|
guidance: {
|
|
@@ -110610,7 +111376,7 @@ function readyResult(input, projectRoot, relocation) {
|
|
|
110610
111376
|
},
|
|
110611
111377
|
next_action: {
|
|
110612
111378
|
kind: relocation ? "enter-workspace" : "evaluate-workflow",
|
|
110613
|
-
command: relocation ? `cd ${shellQuote7(projectRoot)} && ${
|
|
111379
|
+
command: relocation ? `cd ${shellQuote7(projectRoot)} && ${command3}` : command3,
|
|
110614
111380
|
effect: "read",
|
|
110615
111381
|
confirmation: "not-required"
|
|
110616
111382
|
}
|
|
@@ -110837,7 +111603,7 @@ init_cliFeedback();
|
|
|
110837
111603
|
init_errors3();
|
|
110838
111604
|
init_exitCode();
|
|
110839
111605
|
import { existsSync as existsSync35 } from "node:fs";
|
|
110840
|
-
import { dirname as dirname46, join as
|
|
111606
|
+
import { dirname as dirname46, join as join107, resolve as resolve40 } from "node:path";
|
|
110841
111607
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
110842
111608
|
|
|
110843
111609
|
// src/project/pluginInstallTargets.ts
|
|
@@ -110846,9 +111612,9 @@ init_errors3();
|
|
|
110846
111612
|
init_exitCode();
|
|
110847
111613
|
import { execFile as execFile11 } from "node:child_process";
|
|
110848
111614
|
import { existsSync as existsSync34 } from "node:fs";
|
|
110849
|
-
import { cp as cp2, mkdir as
|
|
111615
|
+
import { cp as cp2, mkdir as mkdir34, readdir as readdir26, readFile as readFile87, rename as rename8, rm as rm23, writeFile as writeFile25 } from "node:fs/promises";
|
|
110850
111616
|
import { homedir as homedir2 } from "node:os";
|
|
110851
|
-
import { dirname as dirname45, join as
|
|
111617
|
+
import { dirname as dirname45, join as join106 } from "node:path";
|
|
110852
111618
|
import { promisify as promisify11 } from "node:util";
|
|
110853
111619
|
var execFileAsync7 = promisify11(execFile11);
|
|
110854
111620
|
var MARKETPLACE_NAME = "c4a";
|
|
@@ -110864,31 +111630,31 @@ var CURSOR_PLUGIN_ROOT_ENV = "CONTEXT_CURSOR_PLUGIN_ROOT";
|
|
|
110864
111630
|
function shellQuote8(value) {
|
|
110865
111631
|
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
110866
111632
|
}
|
|
110867
|
-
function commandLine(
|
|
110868
|
-
return [
|
|
111633
|
+
function commandLine(command3, args) {
|
|
111634
|
+
return [command3, ...args.map((arg) => shellQuote8(arg))].join(" ");
|
|
110869
111635
|
}
|
|
110870
|
-
async function runExternal(
|
|
111636
|
+
async function runExternal(command3, args) {
|
|
110871
111637
|
try {
|
|
110872
|
-
await execFileAsync7(
|
|
111638
|
+
await execFileAsync7(command3, args, {
|
|
110873
111639
|
maxBuffer: 1024 * 1024
|
|
110874
111640
|
});
|
|
110875
111641
|
} catch (error) {
|
|
110876
111642
|
const message = error instanceof Error ? error.message : String(error);
|
|
110877
|
-
throw new ContextError(ExitCode.ExternalToolError, `${commandLine(
|
|
111643
|
+
throw new ContextError(ExitCode.ExternalToolError, `${commandLine(command3, args)} failed: ${message}`, {
|
|
110878
111644
|
category: ErrorCategory.ExternalToolFailed
|
|
110879
111645
|
});
|
|
110880
111646
|
}
|
|
110881
111647
|
}
|
|
110882
|
-
async function runExternalOptional(
|
|
111648
|
+
async function runExternalOptional(command3, args) {
|
|
110883
111649
|
try {
|
|
110884
|
-
await runExternal(
|
|
111650
|
+
await runExternal(command3, args);
|
|
110885
111651
|
return true;
|
|
110886
111652
|
} catch {
|
|
110887
111653
|
return false;
|
|
110888
111654
|
}
|
|
110889
111655
|
}
|
|
110890
|
-
async function commandAvailable(
|
|
110891
|
-
return runExternalOptional("sh", ["-lc", `command -v ${
|
|
111656
|
+
async function commandAvailable(command3) {
|
|
111657
|
+
return runExternalOptional("sh", ["-lc", `command -v ${command3} >/dev/null 2>&1`]);
|
|
110892
111658
|
}
|
|
110893
111659
|
async function claudePluginInstalled(pluginId) {
|
|
110894
111660
|
try {
|
|
@@ -110902,23 +111668,23 @@ async function claudePluginInstalled(pluginId) {
|
|
|
110902
111668
|
}
|
|
110903
111669
|
}
|
|
110904
111670
|
function codexHome() {
|
|
110905
|
-
return process.env.CODEX_HOME?.trim() ||
|
|
111671
|
+
return process.env.CODEX_HOME?.trim() || join106(homedir2(), ".codex");
|
|
110906
111672
|
}
|
|
110907
111673
|
function claudePluginCacheRoot() {
|
|
110908
111674
|
const explicitRoot = process.env[CLAUDE_PLUGIN_CACHE_ROOT_ENV2]?.trim();
|
|
110909
111675
|
if (explicitRoot)
|
|
110910
111676
|
return explicitRoot;
|
|
110911
111677
|
const home = process.env[CLAUDE_PLUGIN_CACHE_HOME_ENV2]?.trim() || homedir2();
|
|
110912
|
-
return
|
|
111678
|
+
return join106(home, ".claude", "plugins", "cache");
|
|
110913
111679
|
}
|
|
110914
111680
|
function sharedSkillsRoot() {
|
|
110915
|
-
return process.env[SHARED_SKILLS_ROOT_ENV]?.trim() ||
|
|
111681
|
+
return process.env[SHARED_SKILLS_ROOT_ENV]?.trim() || join106(homedir2(), ".agents", "skills");
|
|
110916
111682
|
}
|
|
110917
111683
|
function claudeSkillsRoot() {
|
|
110918
|
-
return process.env[CLAUDE_SKILLS_ROOT_ENV]?.trim() ||
|
|
111684
|
+
return process.env[CLAUDE_SKILLS_ROOT_ENV]?.trim() || join106(homedir2(), ".claude", "skills");
|
|
110919
111685
|
}
|
|
110920
111686
|
function cursorPluginRoot() {
|
|
110921
|
-
return process.env[CURSOR_PLUGIN_ROOT_ENV]?.trim() ||
|
|
111687
|
+
return process.env[CURSOR_PLUGIN_ROOT_ENV]?.trim() || join106(homedir2(), ".cursor", "plugins", "local", PLUGIN_NAME);
|
|
110922
111688
|
}
|
|
110923
111689
|
function blockHeader(line) {
|
|
110924
111690
|
const match = line.match(/^\s*\[([^\]]+)\]\s*$/u);
|
|
@@ -110929,9 +111695,9 @@ function isStaleMarketplaceBlock(header, block) {
|
|
|
110929
111695
|
return true;
|
|
110930
111696
|
if (header !== `marketplaces.${MARKETPLACE_NAME}`)
|
|
110931
111697
|
return false;
|
|
110932
|
-
const
|
|
111698
|
+
const text10 = block.join(`
|
|
110933
111699
|
`);
|
|
110934
|
-
return
|
|
111700
|
+
return text10.includes('source_type = "local"') || text10.includes("/c4a-plugins") || text10.includes("context4ai/context");
|
|
110935
111701
|
}
|
|
110936
111702
|
function isStalePluginBlock(header) {
|
|
110937
111703
|
return header === `plugins."context@context"` || header === `plugins."context@c4a"` || header === "plugins.context";
|
|
@@ -110969,27 +111735,27 @@ function pruneLegacyCodexConfigContent(content3) {
|
|
|
110969
111735
|
`), removed };
|
|
110970
111736
|
}
|
|
110971
111737
|
async function pruneLegacyCodexConfig(dryRun, steps) {
|
|
110972
|
-
const configPath =
|
|
110973
|
-
const current2 = await
|
|
111738
|
+
const configPath = join106(codexHome(), "config.toml");
|
|
111739
|
+
const current2 = await readFile87(configPath, "utf8").catch(() => "");
|
|
110974
111740
|
if (!current2)
|
|
110975
111741
|
return;
|
|
110976
|
-
const
|
|
110977
|
-
if (
|
|
111742
|
+
const next2 = pruneLegacyCodexConfigContent(current2);
|
|
111743
|
+
if (next2.removed.length === 0)
|
|
110978
111744
|
return;
|
|
110979
111745
|
steps.push({
|
|
110980
111746
|
agent: "codex",
|
|
110981
|
-
command: `prune stale Codex config blocks: ${
|
|
111747
|
+
command: `prune stale Codex config blocks: ${next2.removed.join(", ")}`,
|
|
110982
111748
|
status: dryRun ? "planned" : "ran"
|
|
110983
111749
|
});
|
|
110984
111750
|
if (!dryRun) {
|
|
110985
|
-
await writeFile25(configPath,
|
|
111751
|
+
await writeFile25(configPath, next2.content, "utf8");
|
|
110986
111752
|
}
|
|
110987
111753
|
}
|
|
110988
111754
|
async function pruneCodexPluginCacheForName(pluginName, keepVersion, dryRun, steps) {
|
|
110989
|
-
const cacheRoot =
|
|
111755
|
+
const cacheRoot = join106(codexHome(), "plugins", "cache", MARKETPLACE_NAME, pluginName);
|
|
110990
111756
|
if (!existsSync34(cacheRoot))
|
|
110991
111757
|
return;
|
|
110992
|
-
const versions = (await
|
|
111758
|
+
const versions = (await readdir26(cacheRoot, { withFileTypes: true }).catch(() => [])).filter((entry) => entry.isDirectory() && entry.name !== keepVersion).map((entry) => entry.name).sort();
|
|
110993
111759
|
if (versions.length === 0)
|
|
110994
111760
|
return;
|
|
110995
111761
|
steps.push({
|
|
@@ -110998,7 +111764,7 @@ async function pruneCodexPluginCacheForName(pluginName, keepVersion, dryRun, ste
|
|
|
110998
111764
|
status: dryRun ? "planned" : "ran"
|
|
110999
111765
|
});
|
|
111000
111766
|
if (!dryRun)
|
|
111001
|
-
await Promise.all(versions.map((version3) =>
|
|
111767
|
+
await Promise.all(versions.map((version3) => rm23(join106(cacheRoot, version3), { recursive: true, force: true })));
|
|
111002
111768
|
}
|
|
111003
111769
|
async function pruneCodexPluginCache(currentVersion, dryRun, steps) {
|
|
111004
111770
|
await pruneCodexPluginCacheForName(PLUGIN_NAME, currentVersion, dryRun, steps);
|
|
@@ -111008,7 +111774,7 @@ async function pruneCodexPluginCache(currentVersion, dryRun, steps) {
|
|
|
111008
111774
|
}
|
|
111009
111775
|
async function isEmptyDir2(dir) {
|
|
111010
111776
|
try {
|
|
111011
|
-
return (await
|
|
111777
|
+
return (await readdir26(dir)).length === 0;
|
|
111012
111778
|
} catch {
|
|
111013
111779
|
return false;
|
|
111014
111780
|
}
|
|
@@ -111018,31 +111784,31 @@ async function pruneClaudeOrphanContextCache(dryRun, steps) {
|
|
|
111018
111784
|
if (!existsSync34(cacheRoot))
|
|
111019
111785
|
return;
|
|
111020
111786
|
const removed = [];
|
|
111021
|
-
const marketplaces = await
|
|
111787
|
+
const marketplaces = await readdir26(cacheRoot, { withFileTypes: true }).catch(() => []);
|
|
111022
111788
|
for (const marketplace of marketplaces) {
|
|
111023
111789
|
if (!marketplace.isDirectory())
|
|
111024
111790
|
continue;
|
|
111025
|
-
const pluginDir =
|
|
111791
|
+
const pluginDir = join106(cacheRoot, marketplace.name, PLUGIN_NAME);
|
|
111026
111792
|
if (!existsSync34(pluginDir))
|
|
111027
111793
|
continue;
|
|
111028
|
-
const versions = await
|
|
111794
|
+
const versions = await readdir26(pluginDir, { withFileTypes: true }).catch(() => []);
|
|
111029
111795
|
for (const version3 of versions) {
|
|
111030
111796
|
if (!version3.isDirectory())
|
|
111031
111797
|
continue;
|
|
111032
|
-
const versionDir =
|
|
111033
|
-
if (!existsSync34(
|
|
111798
|
+
const versionDir = join106(pluginDir, version3.name);
|
|
111799
|
+
if (!existsSync34(join106(versionDir, ORPHAN_MARKER2)))
|
|
111034
111800
|
continue;
|
|
111035
111801
|
removed.push(`${marketplace.name}/${PLUGIN_NAME}/${version3.name}`);
|
|
111036
111802
|
if (!dryRun) {
|
|
111037
|
-
await
|
|
111803
|
+
await rm23(versionDir, { recursive: true, force: true });
|
|
111038
111804
|
}
|
|
111039
111805
|
}
|
|
111040
111806
|
if (!dryRun && await isEmptyDir2(pluginDir)) {
|
|
111041
|
-
await
|
|
111807
|
+
await rm23(pluginDir, { recursive: true, force: true });
|
|
111042
111808
|
}
|
|
111043
|
-
const marketplaceDir =
|
|
111809
|
+
const marketplaceDir = join106(cacheRoot, marketplace.name);
|
|
111044
111810
|
if (!dryRun && await isEmptyDir2(marketplaceDir)) {
|
|
111045
|
-
await
|
|
111811
|
+
await rm23(marketplaceDir, { recursive: true, force: true });
|
|
111046
111812
|
}
|
|
111047
111813
|
}
|
|
111048
111814
|
if (removed.length > 0) {
|
|
@@ -111061,12 +111827,12 @@ async function pruneClaudeLegacyPluginCache(dryRun, steps) {
|
|
|
111061
111827
|
return;
|
|
111062
111828
|
const removed = [];
|
|
111063
111829
|
for (const pluginName of LEGACY_PLUGIN_NAMES) {
|
|
111064
|
-
const pluginDir =
|
|
111830
|
+
const pluginDir = join106(cacheRoot, MARKETPLACE_NAME, pluginName);
|
|
111065
111831
|
if (!existsSync34(pluginDir))
|
|
111066
111832
|
continue;
|
|
111067
111833
|
removed.push(`${MARKETPLACE_NAME}/${pluginName}`);
|
|
111068
111834
|
if (!dryRun) {
|
|
111069
|
-
await
|
|
111835
|
+
await rm23(pluginDir, { recursive: true, force: true });
|
|
111070
111836
|
}
|
|
111071
111837
|
}
|
|
111072
111838
|
if (removed.length > 0) {
|
|
@@ -111078,12 +111844,12 @@ async function pruneClaudeLegacyPluginCache(dryRun, steps) {
|
|
|
111078
111844
|
}
|
|
111079
111845
|
}
|
|
111080
111846
|
async function pruneClaudeSupersededContextCache(root2, dryRun, steps) {
|
|
111081
|
-
const manifest = await
|
|
111847
|
+
const manifest = await readFile87(join106(root2, "claude", ".claude-plugin", "plugin.json"), "utf8").then((content3) => JSON.parse(content3)).catch(() => null);
|
|
111082
111848
|
const currentVersion = typeof manifest?.version === "string" ? manifest.version : null;
|
|
111083
111849
|
if (!currentVersion)
|
|
111084
111850
|
return;
|
|
111085
|
-
const pluginDir =
|
|
111086
|
-
const staleVersions = (await
|
|
111851
|
+
const pluginDir = join106(claudePluginCacheRoot(), MARKETPLACE_NAME, PLUGIN_NAME);
|
|
111852
|
+
const staleVersions = (await readdir26(pluginDir, { withFileTypes: true }).catch(() => [])).filter((entry) => entry.isDirectory() && entry.name !== currentVersion).map((entry) => entry.name);
|
|
111087
111853
|
if (staleVersions.length === 0)
|
|
111088
111854
|
return;
|
|
111089
111855
|
steps.push({
|
|
@@ -111092,7 +111858,7 @@ async function pruneClaudeSupersededContextCache(root2, dryRun, steps) {
|
|
|
111092
111858
|
status: dryRun ? "planned" : "ran"
|
|
111093
111859
|
});
|
|
111094
111860
|
if (!dryRun) {
|
|
111095
|
-
await Promise.all(staleVersions.map((version3) =>
|
|
111861
|
+
await Promise.all(staleVersions.map((version3) => rm23(join106(pluginDir, version3), { recursive: true, force: true })));
|
|
111096
111862
|
}
|
|
111097
111863
|
}
|
|
111098
111864
|
function enableCodexPluginConfig(content3) {
|
|
@@ -111156,56 +111922,56 @@ source = ${JSON.stringify(root2)}
|
|
|
111156
111922
|
`;
|
|
111157
111923
|
}
|
|
111158
111924
|
async function ensureCodexPluginEnabled() {
|
|
111159
|
-
const configPath =
|
|
111160
|
-
await
|
|
111161
|
-
const current2 = await
|
|
111162
|
-
const
|
|
111163
|
-
if (
|
|
111164
|
-
await writeFile25(configPath,
|
|
111925
|
+
const configPath = join106(codexHome(), "config.toml");
|
|
111926
|
+
await mkdir34(dirname45(configPath), { recursive: true });
|
|
111927
|
+
const current2 = await readFile87(configPath, "utf8").catch(() => "");
|
|
111928
|
+
const next2 = enableCodexPluginConfig(current2);
|
|
111929
|
+
if (next2 !== current2) {
|
|
111930
|
+
await writeFile25(configPath, next2, "utf8");
|
|
111165
111931
|
}
|
|
111166
111932
|
}
|
|
111167
111933
|
async function ensureCodexLocalMarketplace(root2) {
|
|
111168
|
-
const configPath =
|
|
111169
|
-
await
|
|
111170
|
-
const current2 = await
|
|
111171
|
-
const
|
|
111172
|
-
if (
|
|
111173
|
-
await writeFile25(configPath,
|
|
111934
|
+
const configPath = join106(codexHome(), "config.toml");
|
|
111935
|
+
await mkdir34(dirname45(configPath), { recursive: true });
|
|
111936
|
+
const current2 = await readFile87(configPath, "utf8").catch(() => "");
|
|
111937
|
+
const next2 = upsertCodexLocalMarketplaceConfig(current2, root2);
|
|
111938
|
+
if (next2 !== current2) {
|
|
111939
|
+
await writeFile25(configPath, next2, "utf8");
|
|
111174
111940
|
}
|
|
111175
111941
|
}
|
|
111176
111942
|
async function codexPluginVersion(root2) {
|
|
111177
|
-
const manifestPath =
|
|
111178
|
-
const manifest = JSON.parse(await
|
|
111943
|
+
const manifestPath = join106(root2, "codex", ".codex-plugin", "plugin.json");
|
|
111944
|
+
const manifest = JSON.parse(await readFile87(manifestPath, "utf8"));
|
|
111179
111945
|
if (typeof manifest.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/u.test(manifest.version)) {
|
|
111180
111946
|
throw new Error(`Codex plugin manifest has an invalid version: ${manifestPath}`);
|
|
111181
111947
|
}
|
|
111182
111948
|
return manifest.version;
|
|
111183
111949
|
}
|
|
111184
111950
|
function codexPluginCacheDir(version3) {
|
|
111185
|
-
return
|
|
111951
|
+
return join106(codexHome(), "plugins", "cache", MARKETPLACE_NAME, PLUGIN_NAME, version3);
|
|
111186
111952
|
}
|
|
111187
111953
|
async function replaceDirectoryFromSource(source2, target) {
|
|
111188
|
-
await
|
|
111954
|
+
await mkdir34(dirname45(target), { recursive: true });
|
|
111189
111955
|
const temporary = `${target}.tmp-${process.pid}-${Date.now()}`;
|
|
111190
111956
|
const previous3 = `${target}.previous-${process.pid}-${Date.now()}`;
|
|
111191
|
-
await
|
|
111957
|
+
await rm23(temporary, { recursive: true, force: true });
|
|
111192
111958
|
await cp2(source2, temporary, { recursive: true, force: true });
|
|
111193
111959
|
const hadPrevious = existsSync34(target);
|
|
111194
111960
|
try {
|
|
111195
111961
|
if (hadPrevious)
|
|
111196
|
-
await
|
|
111197
|
-
await
|
|
111962
|
+
await rename8(target, previous3);
|
|
111963
|
+
await rename8(temporary, target);
|
|
111198
111964
|
if (hadPrevious)
|
|
111199
|
-
await
|
|
111965
|
+
await rm23(previous3, { recursive: true, force: true });
|
|
111200
111966
|
} catch (error) {
|
|
111201
|
-
await
|
|
111967
|
+
await rm23(temporary, { recursive: true, force: true });
|
|
111202
111968
|
if (hadPrevious && !existsSync34(target) && existsSync34(previous3))
|
|
111203
|
-
await
|
|
111969
|
+
await rename8(previous3, target);
|
|
111204
111970
|
throw error;
|
|
111205
111971
|
}
|
|
111206
111972
|
}
|
|
111207
111973
|
async function materializeCodexPluginCache(root2, version3, dryRun, steps) {
|
|
111208
|
-
const source2 =
|
|
111974
|
+
const source2 = join106(root2, "codex");
|
|
111209
111975
|
const target = codexPluginCacheDir(version3);
|
|
111210
111976
|
steps.push({
|
|
111211
111977
|
agent: "codex",
|
|
@@ -111217,16 +111983,16 @@ async function materializeCodexPluginCache(root2, version3, dryRun, steps) {
|
|
|
111217
111983
|
await replaceDirectoryFromSource(source2, target);
|
|
111218
111984
|
}
|
|
111219
111985
|
async function bundledProviderSkillNames(root2) {
|
|
111220
|
-
const skillsRoot =
|
|
111221
|
-
const entries2 = await
|
|
111986
|
+
const skillsRoot = join106(root2, "skills");
|
|
111987
|
+
const entries2 = await readdir26(skillsRoot, { withFileTypes: true });
|
|
111222
111988
|
const names = [];
|
|
111223
111989
|
for (const entry of entries2) {
|
|
111224
111990
|
if (!entry.isDirectory() || entry.name === "context")
|
|
111225
111991
|
continue;
|
|
111226
|
-
const skillPath =
|
|
111992
|
+
const skillPath = join106(skillsRoot, entry.name, "SKILL.md");
|
|
111227
111993
|
if (!existsSync34(skillPath))
|
|
111228
111994
|
continue;
|
|
111229
|
-
const skill = await
|
|
111995
|
+
const skill = await readFile87(skillPath, "utf8");
|
|
111230
111996
|
if (!/^\s*context-role:\s*["']?indexer-provider["']?\s*$/mu.test(skill))
|
|
111231
111997
|
continue;
|
|
111232
111998
|
names.push(entry.name);
|
|
@@ -111238,10 +112004,10 @@ async function bundledProviderSkillNames(root2) {
|
|
|
111238
112004
|
return names;
|
|
111239
112005
|
}
|
|
111240
112006
|
async function materializeProviderSkills(root2, targetRoot, agent, dryRun, steps) {
|
|
111241
|
-
const sourceRoot2 =
|
|
112007
|
+
const sourceRoot2 = join106(root2, "skills");
|
|
111242
112008
|
for (const name3 of await bundledProviderSkillNames(root2)) {
|
|
111243
|
-
const source2 =
|
|
111244
|
-
const target =
|
|
112009
|
+
const source2 = join106(sourceRoot2, name3);
|
|
112010
|
+
const target = join106(targetRoot, name3);
|
|
111245
112011
|
steps.push({
|
|
111246
112012
|
agent,
|
|
111247
112013
|
command: `materialize lifecycle Provider skill: ${shellQuote8(source2)} -> ${shellQuote8(target)}`,
|
|
@@ -111252,7 +112018,7 @@ async function materializeProviderSkills(root2, targetRoot, agent, dryRun, steps
|
|
|
111252
112018
|
}
|
|
111253
112019
|
}
|
|
111254
112020
|
async function installCursor(root2, dryRun, steps) {
|
|
111255
|
-
const source2 =
|
|
112021
|
+
const source2 = join106(root2, "cursor");
|
|
111256
112022
|
const target = cursorPluginRoot();
|
|
111257
112023
|
steps.push({
|
|
111258
112024
|
agent: "cursor",
|
|
@@ -111307,12 +112073,12 @@ async function installCodex(root2, dryRun, steps) {
|
|
|
111307
112073
|
steps.push({ agent: "codex", command: commandLine("codex", addArgs), status: dryRun ? "planned" : "ran" });
|
|
111308
112074
|
steps.push({
|
|
111309
112075
|
agent: "codex",
|
|
111310
|
-
command: `ensure ${shellQuote8(
|
|
112076
|
+
command: `ensure ${shellQuote8(join106(codexHome(), "config.toml"))} registers local marketplace ${shellQuote8(MARKETPLACE_NAME)}`,
|
|
111311
112077
|
status: dryRun ? "planned" : "ran"
|
|
111312
112078
|
});
|
|
111313
112079
|
steps.push({
|
|
111314
112080
|
agent: "codex",
|
|
111315
|
-
command: `ensure ${shellQuote8(
|
|
112081
|
+
command: `ensure ${shellQuote8(join106(codexHome(), "config.toml"))} enables ${shellQuote8(PLUGIN_ID)}`,
|
|
111316
112082
|
status: dryRun ? "planned" : "ran"
|
|
111317
112083
|
});
|
|
111318
112084
|
if (dryRun) {
|
|
@@ -111367,13 +112133,13 @@ function pluginRootCandidates() {
|
|
|
111367
112133
|
return [resolve40(envRoot)];
|
|
111368
112134
|
const candidates = [];
|
|
111369
112135
|
for (const dir of packageCandidateDirs()) {
|
|
111370
|
-
candidates.push(
|
|
111371
|
-
candidates.push(
|
|
112136
|
+
candidates.push(join107(dir, "plugins"));
|
|
112137
|
+
candidates.push(join107(dir, "dist", "plugins"));
|
|
111372
112138
|
}
|
|
111373
112139
|
return [...new Set(candidates)];
|
|
111374
112140
|
}
|
|
111375
112141
|
function isInstallablePluginRoot(root2) {
|
|
111376
|
-
return existsSync35(
|
|
112142
|
+
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
112143
|
}
|
|
111378
112144
|
function resolveBundledPluginsRoot() {
|
|
111379
112145
|
const candidates = pluginRootCandidates();
|
|
@@ -111603,10 +112369,10 @@ function readQuickstartPath() {
|
|
|
111603
112369
|
try {
|
|
111604
112370
|
let dir = dirname47(fileURLToPath10(import.meta.url));
|
|
111605
112371
|
for (let i2 = 0;i2 < 8; i2++) {
|
|
111606
|
-
const candidate =
|
|
112372
|
+
const candidate = join108(dir, "docs", "quickstart.md");
|
|
111607
112373
|
if (existsSync36(candidate))
|
|
111608
112374
|
return candidate;
|
|
111609
|
-
const pkg =
|
|
112375
|
+
const pkg = join108(dir, "package.json");
|
|
111610
112376
|
if (existsSync36(pkg))
|
|
111611
112377
|
return candidate;
|
|
111612
112378
|
const parent = dirname47(dir);
|
|
@@ -111615,7 +112381,7 @@ function readQuickstartPath() {
|
|
|
111615
112381
|
dir = parent;
|
|
111616
112382
|
}
|
|
111617
112383
|
} catch {}
|
|
111618
|
-
return
|
|
112384
|
+
return join108(dirname47(fileURLToPath10(import.meta.url)), "docs", "quickstart.md");
|
|
111619
112385
|
}
|
|
111620
112386
|
var GREEN = "\x1B[32m";
|
|
111621
112387
|
var RESET = "\x1B[0m";
|
|
@@ -111641,7 +112407,7 @@ ${greenBox([
|
|
|
111641
112407
|
`;
|
|
111642
112408
|
}
|
|
111643
112409
|
function assertKnownTopLevelCommand(argv, program2) {
|
|
111644
|
-
const commands = new Set(["help", ...program2.commands.flatMap((
|
|
112410
|
+
const commands = new Set(["help", ...program2.commands.flatMap((command3) => [command3.name(), ...command3.aliases()])]);
|
|
111645
112411
|
for (const token of argv.slice(2)) {
|
|
111646
112412
|
if (token === "-h" || token === "--help" || token === "-V" || token === "--version")
|
|
111647
112413
|
return;
|
|
@@ -111867,9 +112633,9 @@ async function cli_main(argv = process.argv) {
|
|
|
111867
112633
|
await withContextRuntimeEventDelivery(async () => {
|
|
111868
112634
|
const program2 = createCliProgram();
|
|
111869
112635
|
assertKnownTopLevelCommand(argv, program2);
|
|
111870
|
-
const overrideExit = (
|
|
111871
|
-
|
|
111872
|
-
|
|
112636
|
+
const overrideExit = (command3) => {
|
|
112637
|
+
command3.exitOverride();
|
|
112638
|
+
command3.commands.forEach(overrideExit);
|
|
111873
112639
|
};
|
|
111874
112640
|
overrideExit(program2);
|
|
111875
112641
|
try {
|