@takazudo/zudo-doc 5.8.0 → 5.10.0

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.
Files changed (104) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +1 -1
  3. package/dist/chrome/derive.d.ts +1 -1
  4. package/dist/chrome/derive.js +24 -2
  5. package/dist/config-assertions/index.d.ts +30 -0
  6. package/dist/config-assertions/index.js +41 -1
  7. package/dist/config.d.ts +18 -0
  8. package/dist/config.js +1 -0
  9. package/dist/doc-content-header/index.js +6 -0
  10. package/dist/doc-metainfo-area/index.js +1 -14
  11. package/dist/doc-page-renderer/index.d.ts +3 -3
  12. package/dist/doc-page-renderer/index.js +1 -1
  13. package/dist/doc-page-shell/index.d.ts +6 -0
  14. package/dist/doc-pager/index.d.ts +6 -0
  15. package/dist/doc-pager/index.js +5 -2
  16. package/dist/docs-schema/index.d.ts +11 -0
  17. package/dist/docs-schema/index.js +8 -1
  18. package/dist/format-date/index.d.ts +12 -0
  19. package/dist/format-date/index.js +64 -0
  20. package/dist/frontmatter-preview-defaults/index.js +6 -1
  21. package/dist/header/header.js +9 -1
  22. package/dist/home-page/index.js +3 -1
  23. package/dist/html-preview-wrapper/highlight-runtime.d.ts +7 -7
  24. package/dist/html-preview-wrapper/highlight-runtime.js +1 -1
  25. package/dist/i18n-defaults/index.js +3 -0
  26. package/dist/integrations/changelog/emit.js +19 -2
  27. package/dist/mdx-components/index.d.ts +4 -1
  28. package/dist/mdx-components/index.js +3 -1
  29. package/dist/nav-indexing/index.d.ts +2 -0
  30. package/dist/nav-indexing/index.js +2 -0
  31. package/dist/nav-indexing/note-tray-index.d.ts +29 -0
  32. package/dist/nav-indexing/note-tray-index.js +120 -0
  33. package/dist/note-tray-index/index.d.ts +45 -0
  34. package/dist/note-tray-index/index.js +52 -0
  35. package/dist/note-tray-model/index.d.ts +31 -0
  36. package/dist/note-tray-model/index.js +74 -0
  37. package/dist/plugins/codex-resources.d.ts +4 -0
  38. package/dist/plugins/codex-resources.js +31 -0
  39. package/dist/plugins/internal/claude-resources/generate.js +20 -291
  40. package/dist/plugins/internal/codex-resources/agents-md.d.ts +6 -0
  41. package/dist/plugins/internal/codex-resources/agents-md.js +70 -0
  42. package/dist/plugins/internal/codex-resources/agents.d.ts +7 -0
  43. package/dist/plugins/internal/codex-resources/agents.js +104 -0
  44. package/dist/plugins/internal/codex-resources/config.d.ts +6 -0
  45. package/dist/plugins/internal/codex-resources/config.js +111 -0
  46. package/dist/plugins/internal/codex-resources/generate.d.ts +20 -0
  47. package/dist/plugins/internal/codex-resources/generate.js +34 -0
  48. package/dist/plugins/internal/codex-resources/hooks.d.ts +6 -0
  49. package/dist/plugins/internal/codex-resources/hooks.js +174 -0
  50. package/dist/plugins/internal/codex-resources/index.d.ts +24 -0
  51. package/dist/plugins/internal/codex-resources/index.js +21 -0
  52. package/dist/plugins/internal/codex-resources/overview.d.ts +10 -0
  53. package/dist/plugins/internal/codex-resources/overview.js +33 -0
  54. package/dist/plugins/internal/codex-resources/rules.d.ts +6 -0
  55. package/dist/plugins/internal/codex-resources/rules.js +255 -0
  56. package/dist/plugins/internal/codex-resources/skills.d.ts +2 -0
  57. package/dist/plugins/internal/codex-resources/skills.js +84 -0
  58. package/dist/plugins/internal/codex-resources/utils.d.ts +14 -0
  59. package/dist/plugins/internal/codex-resources/utils.js +80 -0
  60. package/dist/plugins/internal/resource-docs-shared/fs.d.ts +3 -0
  61. package/dist/plugins/internal/resource-docs-shared/fs.js +19 -0
  62. package/dist/plugins/internal/resource-docs-shared/index.d.ts +7 -0
  63. package/dist/plugins/internal/resource-docs-shared/index.js +44 -0
  64. package/dist/plugins/internal/resource-docs-shared/links.d.ts +22 -0
  65. package/dist/plugins/internal/resource-docs-shared/links.js +44 -0
  66. package/dist/plugins/internal/resource-docs-shared/markdown-structure.d.ts +9 -0
  67. package/dist/plugins/internal/resource-docs-shared/markdown-structure.js +22 -0
  68. package/dist/plugins/internal/resource-docs-shared/mdx.d.ts +23 -0
  69. package/dist/plugins/internal/resource-docs-shared/mdx.js +63 -0
  70. package/dist/plugins/internal/resource-docs-shared/skills.d.ts +37 -0
  71. package/dist/plugins/internal/resource-docs-shared/skills.js +318 -0
  72. package/dist/plugins/internal/resource-docs-shared/walk.d.ts +20 -0
  73. package/dist/plugins/internal/resource-docs-shared/walk.js +41 -0
  74. package/dist/preset.d.ts +19 -0
  75. package/dist/preset.js +16 -1
  76. package/dist/safelist.css +1 -1
  77. package/dist/settings.d.ts +5 -0
  78. package/dist/sidebar/types.d.ts +6 -0
  79. package/dist/sidebar-tree/build-tree.js +8 -0
  80. package/dist/sidebar-tree/types.d.ts +12 -0
  81. package/dist/sidebar-tree-island/index.js +175 -1
  82. package/dist/sidebar-utils/index.d.ts +6 -0
  83. package/dist/site-schema/doc-route-entries.js +2 -0
  84. package/dist/site-schema/index.d.ts +1 -0
  85. package/dist/site-schema/index.js +3 -1
  86. package/dist/site-schema/nav-tree.js +17 -2
  87. package/dist/site-schema/note-tray-validate.d.ts +7 -0
  88. package/dist/site-schema/note-tray-validate.js +94 -0
  89. package/dist/site-schema/types.d.ts +11 -0
  90. package/dist/site-tree-nav-island/index.d.ts +5 -1
  91. package/dist/site-tree-nav-island/index.js +119 -12
  92. package/dist/theme-packs/drift/pack.css +6 -1
  93. package/dist/theme-packs/hearth/pack.css +5 -0
  94. package/dist/theme-packs/sakura/pack.css +6 -0
  95. package/dist/theme-packs/scandi/pack.css +7 -7
  96. package/dist/theme-packs/timberline/pack.css +5 -0
  97. package/eject/doc-pager/index.tsx +9 -0
  98. package/eject/header/header.tsx +26 -1
  99. package/eject/sidebar/types.ts +6 -0
  100. package/eject/sidebar-tree-island/index.tsx +238 -6
  101. package/eject/site-tree-nav-island/index.tsx +166 -16
  102. package/package.json +25 -8
  103. /package/dist/plugins/internal/{claude-resources → resource-docs-shared}/escape-for-mdx.d.ts +0 -0
  104. /package/dist/plugins/internal/{claude-resources → resource-docs-shared}/escape-for-mdx.js +0 -0
@@ -2,7 +2,7 @@ import type { Settings } from "../settings.js";
2
2
  /** Any Preact-renderable component (function returning a VNode/children). */
3
3
  type AnyComponent = (props: Record<string, unknown>) => unknown;
4
4
  /**
5
- * The 4 host-supplied, locale-aware nav wrappers. Each accepts a `lang` prop;
5
+ * The host-supplied, locale-aware nav wrappers. Each accepts a `lang` prop;
6
6
  * the factory injects the active `locale` so the wrapper queries the correct
7
7
  * collection. `SiteTreeNav` is reused for both the `SiteTreeNav` and
8
8
  * `SiteTreeNavDemo` MDX tags (matching the showcase mapping).
@@ -11,6 +11,7 @@ export interface MdxNavData {
11
11
  CategoryNav: AnyComponent;
12
12
  CategoryTreeNav: AnyComponent;
13
13
  SiteTreeNav: AnyComponent;
14
+ NoteTrayIndex: AnyComponent;
14
15
  }
15
16
  export interface CreateMdxComponentsOptions {
16
17
  /**
@@ -35,6 +36,8 @@ export interface CreateMdxComponentsOptions {
35
36
  * which wrapper `navData` holds.
36
37
  */
37
38
  currentVersion?: string;
39
+ /** Canonical slug of the page being rendered, used to infer its containing note tray. */
40
+ currentSlug: string;
38
41
  /** Host-supplied locale-aware nav wrappers. */
39
42
  navData: MdxNavData;
40
43
  /**
@@ -109,7 +109,7 @@ function makeEnlargeableParagraph(imageEnlarge, ContentImg) {
109
109
  };
110
110
  }
111
111
  function createMdxComponents(options) {
112
- const { settings, locale, currentVersion, navData, extras } = options;
112
+ const { settings, locale, currentVersion, currentSlug, navData, extras } = options;
113
113
  const ContentImg = makeContentImg(settings.base);
114
114
  const EnlargeableParagraph = makeEnlargeableParagraph(
115
115
  settings.imageEnlarge,
@@ -118,6 +118,7 @@ function createMdxComponents(options) {
118
118
  const CategoryNavBound = (props) => navData.CategoryNav({ ...props, lang: locale, currentVersion });
119
119
  const CategoryTreeNavBound = (props) => navData.CategoryTreeNav({ ...props, lang: locale, currentVersion });
120
120
  const SiteTreeNavBound = (props) => navData.SiteTreeNav({ ...props, lang: locale, currentVersion });
121
+ const NoteTrayIndexBound = (props) => navData.NoteTrayIndex({ ...props, lang: locale, currentVersion, currentSlug });
121
122
  return {
122
123
  ...defaultComponents,
123
124
  // img override: rewrites root-relative src to include settings.base.
@@ -151,6 +152,7 @@ function createMdxComponents(options) {
151
152
  CategoryTreeNav: CategoryTreeNavBound,
152
153
  SiteTreeNav: SiteTreeNavBound,
153
154
  SiteTreeNavDemo: SiteTreeNavBound,
155
+ NoteTrayIndex: NoteTrayIndexBound,
154
156
  // Host extras win over any same-named default above (Details, HtmlPreview,
155
157
  // Island, PresetGenerator, showcase stubs, etc.).
156
158
  ...extras ?? {}
@@ -34,4 +34,6 @@ export { DocCardGrid } from "./doc-card-grid.js";
34
34
  export type { DocCardGridProps, DocCardItem } from "./doc-card-grid.js";
35
35
  export { VersionsPageContent } from "./versions-page-content.js";
36
36
  export type { VersionsPageContentProps } from "./versions-page-content.js";
37
+ export { NoteTrayIndex } from "./note-tray-index.js";
38
+ export type { NoteTrayIndexItem, NoteTrayIndexProps, NoteTrayIndexStyle, } from "./note-tray-index.js";
37
39
  export type { NavNode, TagItem, TagLink, TagNavLabels, VersionPageEntry, VersionsPageLabels, } from "./types.js";
@@ -6,12 +6,14 @@ import { DocsSitemap } from "./docs-sitemap.js";
6
6
  import { NavCardGrid } from "./nav-card-grid.js";
7
7
  import { DocCardGrid } from "./doc-card-grid.js";
8
8
  import { VersionsPageContent } from "./versions-page-content.js";
9
+ import { NoteTrayIndex } from "./note-tray-index.js";
9
10
  export {
10
11
  CategoryNav,
11
12
  CategoryTreeNav,
12
13
  DocCardGrid,
13
14
  DocsSitemap,
14
15
  NavCardGrid,
16
+ NoteTrayIndex,
15
17
  SiteTreeNavDemo,
16
18
  TagNav,
17
19
  VersionsPageContent
@@ -0,0 +1,29 @@
1
+ /** @jsxRuntime automatic */
2
+ /** @jsxImportSource preact */
3
+ import type { JSX } from "preact";
4
+ import { type NoteTrayOrder } from "../note-tray-model/index.js";
5
+ import type { TagLink, TagNavLabels } from "./types.js";
6
+ export type NoteTrayIndexStyle = "index" | "cards" | "timeline";
7
+ export interface NoteTrayIndexItem {
8
+ slug: string;
9
+ label: string;
10
+ description?: string;
11
+ href?: string;
12
+ hasPage?: boolean;
13
+ children: NoteTrayIndexItem[];
14
+ rank?: number;
15
+ date?: string;
16
+ updated?: string;
17
+ tagLinks?: TagLink[];
18
+ }
19
+ export interface NoteTrayIndexProps {
20
+ items: NoteTrayIndexItem[];
21
+ style?: NoteTrayIndexStyle;
22
+ showDate?: boolean;
23
+ locale: string;
24
+ updatedLabel: string;
25
+ dated: boolean;
26
+ order?: NoteTrayOrder;
27
+ tagLabels?: TagNavLabels;
28
+ }
29
+ export declare function NoteTrayIndex(props: NoteTrayIndexProps): JSX.Element | null;
@@ -0,0 +1,120 @@
1
+ import { jsx, jsxs } from "preact/jsx-runtime";
2
+ import {
3
+ formatDate,
4
+ formatYearMonthLabel,
5
+ groupItems,
6
+ rankWidth
7
+ } from "../note-tray-model/index.js";
8
+ import { TagNav } from "./tag-nav.js";
9
+ function DateLine({
10
+ item,
11
+ locale,
12
+ updatedLabel
13
+ }) {
14
+ if (!item.date && !item.updated) return null;
15
+ return /* @__PURE__ */ jsxs("span", { class: "tabular-nums text-caption text-muted", children: [
16
+ item.date && /* @__PURE__ */ jsx("time", { datetime: item.date, children: formatDate(item.date, locale) }),
17
+ item.date && item.updated && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: " \xB7 " }),
18
+ item.updated && /* @__PURE__ */ jsxs("span", { children: [
19
+ updatedLabel,
20
+ " ",
21
+ /* @__PURE__ */ jsx("time", { datetime: item.updated, children: formatDate(item.updated, locale) })
22
+ ] })
23
+ ] });
24
+ }
25
+ function ItemTags({ item, labels }) {
26
+ if (!labels || !item.tagLinks?.length) return null;
27
+ return /* @__PURE__ */ jsx(TagNav, { variant: "page", tagLinks: item.tagLinks, labels });
28
+ }
29
+ function IndexList(props) {
30
+ const width = rankWidth(props.items);
31
+ return /* @__PURE__ */ jsx("ol", { class: "border-t border-muted", children: props.items.map((item) => /* @__PURE__ */ jsxs(
32
+ "li",
33
+ {
34
+ class: "grid grid-cols-[auto_1fr] gap-x-hsp-lg border-b border-muted py-vsp-md",
35
+ children: [
36
+ /* @__PURE__ */ jsx(
37
+ "span",
38
+ {
39
+ class: "tabular-nums text-heading leading-none text-muted",
40
+ style: { width: `${width}ch` },
41
+ children: item.rank === void 0 ? "" : String(item.rank).padStart(width, "0")
42
+ }
43
+ ),
44
+ /* @__PURE__ */ jsxs("div", { class: "min-w-0", children: [
45
+ item.href ? /* @__PURE__ */ jsx(
46
+ "a",
47
+ {
48
+ class: "font-medium text-fg hover:text-accent hover:underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
49
+ href: item.href,
50
+ children: item.label
51
+ }
52
+ ) : /* @__PURE__ */ jsx("span", { class: "font-medium text-fg", children: item.label }),
53
+ item.description && /* @__PURE__ */ jsx("p", { class: "mt-vsp-2xs text-small text-muted", children: item.description }),
54
+ props.showDate && /* @__PURE__ */ jsx("span", { class: "mt-vsp-2xs block", children: /* @__PURE__ */ jsx(DateLine, { item, locale: props.locale, updatedLabel: props.updatedLabel }) })
55
+ ] })
56
+ ]
57
+ },
58
+ item.slug
59
+ )) });
60
+ }
61
+ function CardList(props) {
62
+ return /* @__PURE__ */ jsx("div", { class: "grid grid-cols-1 gap-vsp-md", children: props.items.map((item) => /* @__PURE__ */ jsxs("article", { class: "rounded border border-muted bg-surface px-hsp-xl py-vsp-lg", children: [
63
+ props.showDate && /* @__PURE__ */ jsx("div", { class: "mb-vsp-xs", children: /* @__PURE__ */ jsx(DateLine, { item, locale: props.locale, updatedLabel: props.updatedLabel }) }),
64
+ /* @__PURE__ */ jsx("h2", { class: "text-title font-medium", children: item.href ? /* @__PURE__ */ jsx(
65
+ "a",
66
+ {
67
+ class: "text-fg hover:text-accent hover:underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
68
+ href: item.href,
69
+ children: item.label
70
+ }
71
+ ) : item.label }),
72
+ item.description && /* @__PURE__ */ jsx("p", { class: "mt-vsp-xs text-muted", children: item.description }),
73
+ item.tagLinks?.length ? /* @__PURE__ */ jsx("div", { class: "mt-vsp-md", children: /* @__PURE__ */ jsx(ItemTags, { item, labels: props.tagLabels }) }) : null
74
+ ] }, item.slug)) });
75
+ }
76
+ function Timeline(props) {
77
+ const groups = groupItems(props.items, "month", props.order ?? "asc");
78
+ return /* @__PURE__ */ jsx("div", { class: "space-y-vsp-lg", children: groups.map((group) => /* @__PURE__ */ jsxs("section", { children: [
79
+ /* @__PURE__ */ jsx("h2", { class: "mb-vsp-sm text-small font-medium text-fg", children: formatYearMonthLabel(group.key, props.locale) }),
80
+ /* @__PURE__ */ jsx("ol", { class: "ml-hsp-xs border-l border-muted", children: group.items.map((item) => /* @__PURE__ */ jsxs("li", { class: "relative grid gap-vsp-2xs pb-vsp-lg pl-hsp-lg last:pb-0", children: [
81
+ /* @__PURE__ */ jsx(
82
+ "span",
83
+ {
84
+ class: "absolute -left-hsp-xs top-vsp-2xs size-icon-xs rounded-full border border-bg bg-muted",
85
+ "aria-hidden": "true"
86
+ }
87
+ ),
88
+ /* @__PURE__ */ jsxs("div", { class: "flex flex-wrap items-baseline gap-x-hsp-sm gap-y-vsp-2xs", children: [
89
+ /* @__PURE__ */ jsx(DateLine, { item, locale: props.locale, updatedLabel: props.updatedLabel }),
90
+ item.href ? /* @__PURE__ */ jsx(
91
+ "a",
92
+ {
93
+ class: "font-medium text-fg hover:text-accent hover:underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
94
+ href: item.href,
95
+ children: item.label
96
+ }
97
+ ) : /* @__PURE__ */ jsx("span", { class: "font-medium text-fg", children: item.label })
98
+ ] }),
99
+ item.description && /* @__PURE__ */ jsx("p", { class: "text-small text-muted", children: item.description }),
100
+ /* @__PURE__ */ jsx(ItemTags, { item, labels: props.tagLabels })
101
+ ] }, item.slug)) })
102
+ ] }, group.key)) });
103
+ }
104
+ function NoteTrayIndex(props) {
105
+ if (props.items.length === 0) return null;
106
+ if (props.style === "timeline" && !props.dated) {
107
+ throw new Error('[zudo-doc] <NoteTrayIndex style="timeline"> requires a dated note tray.');
108
+ }
109
+ switch (props.style ?? "index") {
110
+ case "cards":
111
+ return /* @__PURE__ */ jsx(CardList, { ...props });
112
+ case "timeline":
113
+ return /* @__PURE__ */ jsx(Timeline, { ...props });
114
+ default:
115
+ return /* @__PURE__ */ jsx(IndexList, { ...props });
116
+ }
117
+ }
118
+ export {
119
+ NoteTrayIndex
120
+ };
@@ -0,0 +1,45 @@
1
+ /** @jsxRuntime automatic */
2
+ /** @jsxImportSource preact */
3
+ import type { JSX } from "preact";
4
+ import { type NoteTrayIndexItem, type NoteTrayIndexStyle } from "../nav-indexing/index.js";
5
+ export interface NoteTrayIndexNode extends NoteTrayIndexItem {
6
+ shape?: "note-tray";
7
+ sortOrder?: "asc" | "desc";
8
+ noteTrayDated?: boolean;
9
+ children: NoteTrayIndexNode[];
10
+ }
11
+ export interface NoteTrayIndexDoc {
12
+ slug: string;
13
+ data: {
14
+ slug?: string;
15
+ tags?: string[];
16
+ };
17
+ }
18
+ export interface NoteTrayIndexSource {
19
+ navDocs: NoteTrayIndexDoc[];
20
+ categoryMeta: Map<string, unknown>;
21
+ }
22
+ export interface NoteTrayIndexWrapperProps {
23
+ style?: NoteTrayIndexStyle;
24
+ showDate?: boolean;
25
+ category?: string;
26
+ lang?: string;
27
+ currentVersion?: string;
28
+ currentSlug?: string;
29
+ }
30
+ export interface NoteTrayIndexDeps {
31
+ defaultLocale: string;
32
+ docTags: boolean;
33
+ resolveNavSource: (lang: string, currentVersion: string | undefined, options?: {
34
+ applyDefaultLocaleOnlyFilter?: boolean;
35
+ keepUnlisted?: boolean;
36
+ }) => NoteTrayIndexSource;
37
+ buildNavTree: (docs: NoteTrayIndexDoc[], locale: string, categoryMeta: Map<string, unknown>) => NoteTrayIndexNode[];
38
+ findNode: (tree: NoteTrayIndexNode[], slug: string) => NoteTrayIndexNode | undefined;
39
+ toRouteSlug: (slug: string) => string;
40
+ resolveTag: (raw: string) => string;
41
+ tagHref: (tag: string, locale: string) => string;
42
+ t: (key: string, locale: string) => string;
43
+ versionedDocsUrl: (slug: string, versionSlug: string, lang: string) => string;
44
+ }
45
+ export declare function createNoteTrayIndexWrapper(deps: NoteTrayIndexDeps): (props: NoteTrayIndexWrapperProps) => JSX.Element | null;
@@ -0,0 +1,52 @@
1
+ import { jsx } from "preact/jsx-runtime";
2
+ import { remapVersionedHrefs } from "../nav-data-prep/index.js";
3
+ import {
4
+ NoteTrayIndex
5
+ } from "../nav-indexing/index.js";
6
+ import { findContainingNoteTray, getNoteTrayItems } from "../note-tray-model/index.js";
7
+ function createNoteTrayIndexWrapper(deps) {
8
+ return function NoteTrayIndexWrapper({
9
+ style = "index",
10
+ showDate = false,
11
+ category,
12
+ lang = deps.defaultLocale,
13
+ currentVersion,
14
+ currentSlug
15
+ }) {
16
+ const source = deps.resolveNavSource(lang, currentVersion, { keepUnlisted: true });
17
+ const rawTree = deps.buildNavTree(source.navDocs, lang, source.categoryMeta);
18
+ const tree = currentVersion ? remapVersionedHrefs(rawTree, currentVersion, lang, deps.versionedDocsUrl) : rawTree;
19
+ const tray = category ? deps.findNode(tree, category) : currentSlug ? findContainingNoteTray(tree, currentSlug) : void 0;
20
+ if (!tray || tray.shape !== "note-tray") return null;
21
+ const docsBySlug = new Map(
22
+ source.navDocs.map((doc) => [doc.data.slug ?? deps.toRouteSlug(doc.slug), doc])
23
+ );
24
+ const items = getNoteTrayItems(tray).map((item) => {
25
+ const rawTags = docsBySlug.get(item.slug)?.data.tags ?? [];
26
+ const tags = [...new Set(rawTags.map(deps.resolveTag))];
27
+ return {
28
+ ...item,
29
+ tagLinks: deps.docTags ? tags.map((tag) => ({ tag, href: deps.tagHref(tag, lang) })) : void 0
30
+ };
31
+ });
32
+ return /* @__PURE__ */ jsx(
33
+ NoteTrayIndex,
34
+ {
35
+ items,
36
+ style,
37
+ showDate,
38
+ locale: lang,
39
+ updatedLabel: deps.t("doc.updated", lang),
40
+ dated: tray.noteTrayDated === true,
41
+ order: tray.sortOrder ?? "asc",
42
+ tagLabels: {
43
+ tags: deps.t("doc.tags", lang),
44
+ taggedWith: deps.t("doc.taggedWith", lang)
45
+ }
46
+ }
47
+ );
48
+ };
49
+ }
50
+ export {
51
+ createNoteTrayIndexWrapper
52
+ };
@@ -0,0 +1,31 @@
1
+ import { formatDate, parseIsoDate, type IsoDateParts } from "../format-date/index.js";
2
+ export { formatDate, parseIsoDate };
3
+ export type { IsoDateParts };
4
+ export type NoteTrayOrder = "asc" | "desc";
5
+ export type NoteTrayGrouping = "year" | "month";
6
+ /** Minimal structural node accepted by every note-tray consumer. */
7
+ export interface NoteTrayNode {
8
+ slug: string;
9
+ shape?: "note-tray";
10
+ hasPage?: boolean;
11
+ sortOrder?: NoteTrayOrder;
12
+ rank?: number;
13
+ date?: string;
14
+ children: NoteTrayNode[];
15
+ }
16
+ export interface NoteTrayGroup<T extends NoteTrayNode = NoteTrayNode> {
17
+ key: string;
18
+ items: T[];
19
+ }
20
+ export declare function findNoteTray<T extends NoteTrayNode>(tree: readonly T[], slug: string): T | undefined;
21
+ /** Find the tray whose slug is the longest prefix of a page slug. */
22
+ export declare function findContainingNoteTray<T extends NoteTrayNode>(tree: readonly T[], pageSlug: string): T | undefined;
23
+ /** Direct routed children are the items in a valid (flat) tray. */
24
+ export declare function getNoteTrayItems<T extends NoteTrayNode>(tray: T): T[];
25
+ /** Rank labels use at least two digits: 01..99, then widen with item count. */
26
+ export declare function rankWidth(itemsOrCount: readonly unknown[] | number): number;
27
+ export declare function yearKey(iso: string): string;
28
+ export declare function yearMonthKey(iso: string): string;
29
+ export declare function formatYearMonthLabel(isoOrKey: string, locale: string): string;
30
+ /** Group dated items chronologically and keep rank order within each group. */
31
+ export declare function groupItems<T extends NoteTrayNode>(items: readonly T[], grouping: NoteTrayGrouping, order: NoteTrayOrder): NoteTrayGroup<T>[];
@@ -0,0 +1,74 @@
1
+ import {
2
+ formatDate,
3
+ formatYearMonth,
4
+ parseIsoDate
5
+ } from "../format-date/index.js";
6
+ function findNoteTray(tree, slug) {
7
+ for (const node of tree) {
8
+ if (node.slug === slug && node.shape === "note-tray") return node;
9
+ const found = findNoteTray(node.children, slug);
10
+ if (found) return found;
11
+ }
12
+ return void 0;
13
+ }
14
+ function findContainingNoteTray(tree, pageSlug) {
15
+ let found;
16
+ const visit = (nodes) => {
17
+ for (const node of nodes) {
18
+ if (node.shape === "note-tray" && (pageSlug === node.slug || pageSlug.startsWith(`${node.slug}/`)) && (!found || node.slug.length > found.slug.length)) {
19
+ found = node;
20
+ }
21
+ visit(node.children);
22
+ }
23
+ };
24
+ visit(tree);
25
+ return found;
26
+ }
27
+ function getNoteTrayItems(tray) {
28
+ return tray.children.filter((item) => item.hasPage !== false);
29
+ }
30
+ function rankWidth(itemsOrCount) {
31
+ const count = typeof itemsOrCount === "number" ? itemsOrCount : itemsOrCount.length;
32
+ return Math.max(2, String(Math.max(0, count)).length);
33
+ }
34
+ function yearKey(iso) {
35
+ const parts = parseIsoDate(iso);
36
+ return parts ? String(parts.year).padStart(4, "0") : "";
37
+ }
38
+ function yearMonthKey(iso) {
39
+ const parts = parseIsoDate(iso);
40
+ return parts ? `${String(parts.year).padStart(4, "0")}-${String(parts.month).padStart(2, "0")}` : "";
41
+ }
42
+ function formatYearMonthLabel(isoOrKey, locale) {
43
+ return formatYearMonth(isoOrKey, locale);
44
+ }
45
+ function groupItems(items, grouping, order) {
46
+ const groups = /* @__PURE__ */ new Map();
47
+ for (const item of items) {
48
+ if (!item.date) continue;
49
+ const key = grouping === "year" ? yearKey(item.date) : yearMonthKey(item.date);
50
+ if (!key) continue;
51
+ const group = groups.get(key) ?? [];
52
+ group.push(item);
53
+ groups.set(key, group);
54
+ }
55
+ const direction = order === "desc" ? -1 : 1;
56
+ return [...groups.entries()].sort(([a], [b]) => direction * a.localeCompare(b)).map(([key, group]) => ({
57
+ key,
58
+ items: group.sort(
59
+ (a, b) => direction * ((a.rank ?? Number.MAX_SAFE_INTEGER) - (b.rank ?? Number.MAX_SAFE_INTEGER))
60
+ )
61
+ }));
62
+ }
63
+ export {
64
+ findContainingNoteTray,
65
+ findNoteTray,
66
+ formatDate,
67
+ formatYearMonthLabel,
68
+ getNoteTrayItems,
69
+ groupItems,
70
+ parseIsoDate,
71
+ rankWidth,
72
+ yearKey,
73
+ yearMonthKey
74
+ };
@@ -0,0 +1,4 @@
1
+ import type { ZfbPlugin } from "@takazudo/zfb/plugins";
2
+ export { runCodexResourcesPreStep } from "./internal/codex-resources/index.js";
3
+ declare const plugin: ZfbPlugin;
4
+ export default plugin;
@@ -0,0 +1,31 @@
1
+ import { runCodexResourcesPreStep } from "./internal/codex-resources/index.js";
2
+ import { runCodexResourcesPreStep as runCodexResourcesPreStep2 } from "./internal/codex-resources/index.js";
3
+ const PLUGIN_NAME = "@takazudo/zudo-doc-codex-resources";
4
+ const plugin = {
5
+ name: PLUGIN_NAME,
6
+ async preBuild(ctx) {
7
+ const codexDir = ctx.options["codexDir"];
8
+ if (typeof codexDir !== "string" || codexDir.length === 0) {
9
+ throw new Error(
10
+ `[${PLUGIN_NAME}] preBuild: options.codexDir must be a non-empty string (got ${JSON.stringify(codexDir)})`
11
+ );
12
+ }
13
+ const projectRootOpt = ctx.options["projectRoot"];
14
+ const scanRootOpt = ctx.options["scanRoot"];
15
+ const docsDirOpt = ctx.options["docsDir"];
16
+ const result = runCodexResourcesPreStep({
17
+ codexDir,
18
+ projectRoot: typeof projectRootOpt === "string" ? projectRootOpt : ctx.projectRoot,
19
+ scanRoot: typeof scanRootOpt === "string" ? scanRootOpt : void 0,
20
+ docsDir: typeof docsDirOpt === "string" ? docsDirOpt : "src/content/docs"
21
+ });
22
+ ctx.logger.info(
23
+ `codex-resources: ${result.agentsMd} AGENTS.md, ${result.config} config, ${result.agents} agents, ${result.hooks} hooks, ${result.rules} rules, ${result.skills} skills`
24
+ );
25
+ }
26
+ };
27
+ var codex_resources_default = plugin;
28
+ export {
29
+ codex_resources_default as default,
30
+ runCodexResourcesPreStep2 as runCodexResourcesPreStep
31
+ };