@c4a/context-cli 0.7.61 → 0.7.63

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cli.js CHANGED
@@ -32174,6 +32174,7 @@ var init_packageSite = __esm(() => {
32174
32174
  packageSiteNavLinkSchema = exports_external.object({
32175
32175
  text: exports_external.string().trim().min(1),
32176
32176
  link: siteHrefSchema,
32177
+ position: exports_external.enum(["start", "end"]).optional(),
32177
32178
  locales: localizedTextSchema.optional()
32178
32179
  }).strict();
32179
32180
  packageSiteMoreItemSchema = exports_external.object({
@@ -86607,6 +86608,9 @@ var init_packageBuildReceipt = __esm(() => {
86607
86608
  // src/project/knowledgeMapCoverage.ts
86608
86609
  import { readFile as readFile55 } from "node:fs/promises";
86609
86610
  import { join as join66 } from "node:path";
86611
+ function packageMenuTargets(packages) {
86612
+ return new Set(packages.flatMap((pkg) => pkg.kind === "package.kb" ? (pkg.site?.more ?? []).flatMap((item) => item.target ? [item.target.artifact_ref] : []) : []));
86613
+ }
86610
86614
  function knowledgeMapArticleTargets(files) {
86611
86615
  return files.flatMap((file) => {
86612
86616
  const meta = parseKnowledgeFrontmatter(file.content);
@@ -86677,6 +86681,7 @@ var init_knowledgeMapCoverage = __esm(() => {
86677
86681
  var exports_knowledgeMap = {};
86678
86682
  __export(exports_knowledgeMap, {
86679
86683
  readKnowledgeMap: () => readKnowledgeMap,
86684
+ projectMenuTargets: () => projectMenuTargets,
86680
86685
  inspectKnowledgeMap: () => inspectKnowledgeMap,
86681
86686
  applyKnowledgeMapUpdate: () => applyKnowledgeMapUpdate,
86682
86687
  acceptStructureDecision: () => acceptStructureDecision,
@@ -86697,6 +86702,12 @@ async function readKnowledgeMap(root) {
86697
86702
  const content3 = await optionalText(root, KNOWLEDGE_MAP_PATH);
86698
86703
  return content3 === undefined ? undefined : validateKnowledgeMap(import_yaml39.parse(content3));
86699
86704
  }
86705
+ async function projectMenuTargets(root) {
86706
+ const { isContextProjectRoot: isContextProjectRoot2, loadContextProjectModule: loadContextProjectModule2 } = await Promise.resolve().then(() => (init_workspace(), exports_workspace));
86707
+ if (!isContextProjectRoot2(root))
86708
+ return new Set;
86709
+ return packageMenuTargets((await loadContextProjectModule2(root)).project.packages);
86710
+ }
86700
86711
  async function inspectKnowledgeMap(root) {
86701
86712
  const current2 = await readKnowledgeMap(root);
86702
86713
  return {
@@ -86728,7 +86739,8 @@ async function acceptStructureDecision(input) {
86728
86739
  const next = input.knowledge_map === undefined ? current2 : updateKnowledgeMap(current2, input.knowledge_map);
86729
86740
  if (input.article_targets !== undefined) {
86730
86741
  const known = [...await approvedKnowledgeMapTargets(input.projectRoot), ...input.article_targets];
86731
- assertKnowledgeMapCoverage(next, known, { known, require_update: true, has_update: input.knowledge_map !== undefined, revision: input.revision, current_revision: current2?.revision ?? null });
86742
+ const menu = await projectMenuTargets(input.projectRoot);
86743
+ assertKnowledgeMapCoverage(next, known.filter((target) => !menu.has(target.artifact_ref)), { known, require_update: true, has_update: input.knowledge_map !== undefined, revision: input.revision, current_revision: current2?.revision ?? null });
86732
86744
  }
86733
86745
  const writes = [{ path: input.decisionPath, content: canonicalIndexerJson({ revision: input.revision, decision: "approved" }) }];
86734
86746
  if (input.knowledge_map !== undefined)
@@ -86762,7 +86774,8 @@ async function applyKnowledgeMapUpdate(projectRoot, update) {
86762
86774
  title: candidate.review.title,
86763
86775
  section_keys: candidate.indexer_candidate.sections.map((section) => section.section_key)
86764
86776
  }));
86765
- assertKnowledgeMapCoverage(next, approved, { known: [...approved, ...planned, ...accepted], current_revision: current2?.revision ?? null });
86777
+ const menu = await projectMenuTargets(projectRoot);
86778
+ assertKnowledgeMapCoverage(next, approved.filter((target) => !menu.has(target.artifact_ref)), { known: [...approved, ...planned, ...accepted], current_revision: current2?.revision ?? null });
86766
86779
  const content3 = import_yaml39.stringify(next);
86767
86780
  const previous2 = await optionalText(projectRoot, KNOWLEDGE_MAP_PATH);
86768
86781
  await runDurableMultiFileTransaction({
@@ -86820,7 +86833,8 @@ function packageKnowledgeMapTargets(pkg, files) {
86820
86833
  return targets;
86821
86834
  }
86822
86835
  async function writePackageKnowledgeMap(input) {
86823
- assertKnowledgeMapCoverage(input.structure, knowledgeMapArticleTargets(input.selected));
86836
+ const menu = packageMenuTargets([input.pkg]);
86837
+ assertKnowledgeMapCoverage(input.structure, knowledgeMapArticleTargets(input.selected).filter((target) => !menu.has(target.artifact_ref)));
86824
86838
  if (input.structure === undefined || input.pkg.kind !== "package.kb")
86825
86839
  return [];
86826
86840
  const projected = projectKnowledgeMap(input.structure, packageKnowledgeMapTargets(input.pkg, input.selected));
@@ -87588,6 +87602,17 @@ var init_packageSiteTheme = __esm(() => {
87588
87602
  return true;
87589
87603
  }, { alt: ['paragraph'] });
87590
87604
  md.renderer.rules.context_anchor = (tokens, index) => '<a id="' + md.utils.escapeHtml(tokens[index].content) + '"></a>\n';
87605
+ // Only the compiler writes section landing pages; accept exactly its card wrappers there.
87606
+ const sectionWrappers = new Set(['<div class="context-section-grid">', '<div class="context-section-card">', '</div>']);
87607
+ md.block.ruler.before('paragraph', 'context_section_card', (state, line, end, silent) => {
87608
+ if (!/(?:^|\/)sections\/[0-9a-f]+\.md$/.test(state.env.relativePath || '')) return false;
87609
+ const raw = state.src.slice(state.bMarks[line] + state.tShift[line], state.eMarks[line]);
87610
+ if (!sectionWrappers.has(raw)) return false;
87611
+ if (!silent) { const token = state.push('context_section_card', '', 0); token.content = raw; }
87612
+ state.line = line + 1;
87613
+ return true;
87614
+ }, { alt: ['paragraph'] });
87615
+ md.renderer.rules.context_section_card = (tokens, index) => tokens[index].content + '\n';
87591
87616
  // The generated website config declares contextLocaleMarker; null when the site has no translations.
87592
87617
  const contextLocale = typeof contextLocaleMarker === 'string' ? contextLocaleMarker : null;
87593
87618
  md.block.ruler.before('paragraph', 'context_locale', (state, line, end, silent) => {
@@ -87814,10 +87839,13 @@ export default {
87814
87839
  return part('year') + '-' + part('month') + '-' + part('day') + ' ' +
87815
87840
  part('hour') + ':' + part('minute') + ':' + part('second') + ' ' + part('timeZoneName');
87816
87841
  });
87842
+ const sitePath = () => {
87843
+ const base = data.site.value.base;
87844
+ return route.path.startsWith(base) ? '/' + route.path.slice(base.length) : route.path;
87845
+ };
87817
87846
  watch(() => route.path, () => {
87818
87847
  allSources.value = false;
87819
- const base = data.site.value.base;
87820
- const path = route.path.startsWith(base) ? '/' + route.path.slice(base.length) : route.path;
87848
+ const path = sitePath();
87821
87849
  const direct = sections.value.find(section => section.href === path);
87822
87850
  const current = sections.value.find(section => section.key === selected.value);
87823
87851
  selected.value = (direct || (current?.pages.includes(path) ? current :
@@ -87827,6 +87855,12 @@ export default {
87827
87855
  const inLlms = computed(() => route.path.startsWith(data.site.value.base + 'llms/'));
87828
87856
  const inHistory = computed(() => route.path === data.site.value.base + 'changelog.html');
87829
87857
  const inHome = computed(() => data.frontmatter.value.layout === 'home');
87858
+ // Articles outside the knowledge map, such as More menu targets, belong to no section.
87859
+ const inMore = computed(() => (data.theme.value.contextMore || []).some(item => !item.origin && item.link === sitePath()));
87860
+ const outsideSections = computed(() => inLlms.value || inHistory.value || inMore.value || (!inHome.value &&
87861
+ !sections.value.some(section => section.href === sitePath() || section.pages.includes(sitePath()))));
87862
+ const userNav = position => (data.theme.value.contextNav || [])
87863
+ .filter(item => (item.position === 'start') === (position === 'start')).map(navLink);
87830
87864
  // Descendants, including site extensions, read the reader language as lang.
87831
87865
  // The frontmatter carries it too so the content refreshes its outline on a switch.
87832
87866
  provide(dataSymbol, { ...data, lang: computed(() => locale.value), frontmatter: computed(() => {
@@ -87835,15 +87869,15 @@ export default {
87835
87869
  return { ...value, contextLocale: locale.value, ...(actions ? { hero: { ...value.hero, actions } } : {}) };
87836
87870
  }), theme: computed(() => ({ ...data.theme.value,
87837
87871
  ...data.theme.value.contextUiLabels?.[chinese.value ? 'zh' : 'en'],
87838
- sidebar: inLlms.value || inHistory.value ? [] : active.value?.items || [],
87839
- nav: [...sections.value.map(section => ({ text: section.label, link: section.href,
87840
- activeMatch: !inLlms.value && !inHistory.value && section.key === selected.value ? '^' : '(?!)' })),
87841
- ...(data.theme.value.contextNav || []).map(navLink),
87872
+ sidebar: outsideSections.value ? [] : active.value?.items || [],
87873
+ nav: [...userNav('start'), ...sections.value.map(section => ({ text: section.label, link: section.href,
87874
+ activeMatch: !outsideSections.value && section.key === selected.value ? '^' : '(?!)' })),
87875
+ ...userNav('end'),
87842
87876
  { text: bothHtml('更多', 'More'), items: [
87843
87877
  ...(data.theme.value.contextMore || []).map(navLink),
87844
87878
  { text: 'LLM Docs', link: '/llms/index.html' },
87845
87879
  { text: 'Changelog', link: '/changelog.html' }],
87846
- activeMatch: inLlms.value || inHistory.value ? '^' : '(?!)' }],
87880
+ activeMatch: inLlms.value || inHistory.value || inMore.value ? '^' : '(?!)' }],
87847
87881
  })) });
87848
87882
  const slots = {
87849
87883
  'nav-bar-title-before': () => extensions.brand ? h('span', { class: 'context-brand' }, custom('brand')) : null,
@@ -87911,7 +87945,7 @@ export default {
87911
87945
  };
87912
87946
  // History belongs between the page heading and footer metadata.
87913
87947
  return () => h(DefaultTheme.Layout, { class: inHome.value ? 'context-home' : data.page.value.isNotFound ? 'context-missing' :
87914
- inLlms.value || inHistory.value ? 'context-empty-sidebar' : undefined }, { ...slots, 'doc-after': undefined,
87948
+ outsideSections.value ? 'context-empty-sidebar' : undefined }, { ...slots, 'doc-after': undefined,
87915
87949
  'doc-footer-before': () => [slots['doc-after'](), slots['doc-footer-before']()] });
87916
87950
  }
87917
87951
  },
@@ -88190,6 +88224,19 @@ ${readerContentStyles(".vp-doc")}
88190
88224
  .context-sources li + li { margin-top: 6px; }
88191
88225
  .context-sources a { color: inherit; text-decoration: none; border-bottom: 1px solid transparent; }
88192
88226
  .context-sources a:hover { color: var(--vp-c-brand-1); border-color: currentColor; }
88227
+ /* Section landing pages: two cards per row, one on narrow screens. */
88228
+ .context-section-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; margin-top: 24px; }
88229
+ .vp-doc .context-section-card { min-width: 0; padding: 18px 20px; border: 1px solid var(--vp-c-divider); border-radius: 12px;
88230
+ background: color-mix(in srgb, var(--vp-c-bg) 88%, var(--vp-c-bg-soft)); }
88231
+ .vp-doc .context-section-card:hover { border-color: color-mix(in srgb, var(--vp-c-brand-1) 42%, var(--vp-c-divider)); }
88232
+ .vp-doc .context-section-card h2 { margin: 0 0 10px; padding: 0 0 10px; border-top: 0; border-bottom: 1px solid var(--vp-c-divider); font-size: 17px; line-height: 1.45; letter-spacing: 0; }
88233
+ .vp-doc .context-section-card h2 a { color: var(--vp-c-text-1); text-decoration: none; }
88234
+ .vp-doc .context-section-card > ul { margin: 0; padding: 0; list-style: none; }
88235
+ .vp-doc .context-section-card li { margin: 6px 0; font-size: 14px; line-height: 1.55; }
88236
+ .vp-doc .context-section-card li a { color: var(--vp-c-text-2); text-decoration: none; }
88237
+ .vp-doc .context-section-card li a:hover { color: var(--vp-c-brand-1); }
88238
+ .vp-doc .context-section-card ul ul { margin: 4px 0 8px; padding-left: 14px; border-left: 1px solid var(--vp-c-divider); list-style: none; }
88239
+ @media (max-width: 719px) { .context-section-grid { grid-template-columns: 1fr; } }
88193
88240
  ${DIAGRAM_STYLES}
88194
88241
  `;
88195
88242
  });
@@ -89634,6 +89681,7 @@ function siteNavigationConfig(site, pages) {
89634
89681
  text: item.text,
89635
89682
  link: item.link,
89636
89683
  ...item.link.startsWith("/") ? { origin: true } : {},
89684
+ ...item.position === "start" ? { position: "start" } : {},
89637
89685
  ...item.locales ? { locales: item.locales } : {}
89638
89686
  }));
89639
89687
  return { nav, more };
@@ -90104,11 +90152,28 @@ ${localized.body}`);
90104
90152
  lines.push(`${" ".repeat(level)}- ${entry.href ? `[${title}](${entry.href})` : title}`);
90105
90153
  menu(lines, entry.children, level + 1, tag);
90106
90154
  });
90155
+ const card = (lines, heading, entries2, tag) => {
90156
+ lines.push('<div class="context-section-card">', "");
90157
+ if (heading !== undefined)
90158
+ lines.push(`## ${heading}`, "");
90159
+ menu(lines, entries2, 0, tag);
90160
+ lines.push("", "</div>", "");
90161
+ };
90107
90162
  await mkdir28(join75(temporary, "sections"), { recursive: true });
90108
90163
  for (const section of sections) {
90109
90164
  await writeFile23(join75(temporary, section.href.slice(1).replace(/\.html$/u, ".md")), localizer.variants((tag) => {
90110
- const lines = [`# ${mdLabel(localizer.entryTitle(tag, section.entry))}`, ""];
90111
- menu(lines, section.entries, 0, tag);
90165
+ const lines = [`# ${mdLabel(localizer.entryTitle(tag, section.entry))}`, "", '<div class="context-section-grid">', ""];
90166
+ const groups = section.entries.filter((entry) => entry.children.length > 0);
90167
+ const articles = section.entries.filter((entry) => entry.children.length === 0);
90168
+ for (const group of groups) {
90169
+ card(lines, group.href ? `[${mdLabel(localizer.entryTitle(tag, group))}](${group.href})` : mdLabel(localizer.entryTitle(tag, group)), group.children, tag);
90170
+ }
90171
+ if (groups.length === 0)
90172
+ for (const article of articles)
90173
+ card(lines, undefined, [article], tag);
90174
+ else if (articles.length)
90175
+ card(lines, undefined, articles, tag);
90176
+ lines.push("</div>");
90112
90177
  return lines.join(`
90113
90178
  `) + `
90114
90179
  `;
@@ -108952,7 +109017,8 @@ async function writeReviewHtml(input) {
108952
109017
  }
108953
109018
  await writeFile28(outPath, renderReviewHtml(model, diagramScript), "utf8");
108954
109019
  await saveReviewReportScope(input.projectRoot, reviewScope, candidates, model.baselineHash);
108955
- const unplaced = model.pages.filter((page) => page.candidate_id && !model.nodes.some((node3) => node3.page === page.id && node3.parent !== "review-unplaced" && !node3.removed)).map((page) => ({ article_id: page.id, candidate_id: page.candidate_id, path: page.path, title: page.title }));
109020
+ const menu = await projectMenuTargets(input.projectRoot);
109021
+ const unplaced = model.pages.filter((page) => page.candidate_id && !menu.has(page.id) && !model.nodes.some((node3) => node3.page === page.id && node3.parent !== "review-unplaced" && !node3.removed)).map((page) => ({ article_id: page.id, candidate_id: page.candidate_id, path: page.path, title: page.title }));
108956
109022
  return {
108957
109023
  navigation: {
108958
109024
  current_revision: (await readKnowledgeMap(input.projectRoot))?.revision ?? null,