@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.
- package/CHANGELOG.md +35 -0
- package/README.md +1 -1
- package/dist/chrome/derive.d.ts +1 -1
- package/dist/chrome/derive.js +24 -2
- package/dist/config-assertions/index.d.ts +30 -0
- package/dist/config-assertions/index.js +41 -1
- package/dist/config.d.ts +18 -0
- package/dist/config.js +1 -0
- package/dist/doc-content-header/index.js +6 -0
- package/dist/doc-metainfo-area/index.js +1 -14
- package/dist/doc-page-renderer/index.d.ts +3 -3
- package/dist/doc-page-renderer/index.js +1 -1
- package/dist/doc-page-shell/index.d.ts +6 -0
- package/dist/doc-pager/index.d.ts +6 -0
- package/dist/doc-pager/index.js +5 -2
- package/dist/docs-schema/index.d.ts +11 -0
- package/dist/docs-schema/index.js +8 -1
- package/dist/format-date/index.d.ts +12 -0
- package/dist/format-date/index.js +64 -0
- package/dist/frontmatter-preview-defaults/index.js +6 -1
- package/dist/header/header.js +9 -1
- package/dist/home-page/index.js +3 -1
- package/dist/html-preview-wrapper/highlight-runtime.d.ts +7 -7
- package/dist/html-preview-wrapper/highlight-runtime.js +1 -1
- package/dist/i18n-defaults/index.js +3 -0
- package/dist/integrations/changelog/emit.js +19 -2
- package/dist/mdx-components/index.d.ts +4 -1
- package/dist/mdx-components/index.js +3 -1
- package/dist/nav-indexing/index.d.ts +2 -0
- package/dist/nav-indexing/index.js +2 -0
- package/dist/nav-indexing/note-tray-index.d.ts +29 -0
- package/dist/nav-indexing/note-tray-index.js +120 -0
- package/dist/note-tray-index/index.d.ts +45 -0
- package/dist/note-tray-index/index.js +52 -0
- package/dist/note-tray-model/index.d.ts +31 -0
- package/dist/note-tray-model/index.js +74 -0
- package/dist/plugins/codex-resources.d.ts +4 -0
- package/dist/plugins/codex-resources.js +31 -0
- package/dist/plugins/internal/claude-resources/generate.js +20 -291
- package/dist/plugins/internal/codex-resources/agents-md.d.ts +6 -0
- package/dist/plugins/internal/codex-resources/agents-md.js +70 -0
- package/dist/plugins/internal/codex-resources/agents.d.ts +7 -0
- package/dist/plugins/internal/codex-resources/agents.js +104 -0
- package/dist/plugins/internal/codex-resources/config.d.ts +6 -0
- package/dist/plugins/internal/codex-resources/config.js +111 -0
- package/dist/plugins/internal/codex-resources/generate.d.ts +20 -0
- package/dist/plugins/internal/codex-resources/generate.js +34 -0
- package/dist/plugins/internal/codex-resources/hooks.d.ts +6 -0
- package/dist/plugins/internal/codex-resources/hooks.js +174 -0
- package/dist/plugins/internal/codex-resources/index.d.ts +24 -0
- package/dist/plugins/internal/codex-resources/index.js +21 -0
- package/dist/plugins/internal/codex-resources/overview.d.ts +10 -0
- package/dist/plugins/internal/codex-resources/overview.js +33 -0
- package/dist/plugins/internal/codex-resources/rules.d.ts +6 -0
- package/dist/plugins/internal/codex-resources/rules.js +255 -0
- package/dist/plugins/internal/codex-resources/skills.d.ts +2 -0
- package/dist/plugins/internal/codex-resources/skills.js +84 -0
- package/dist/plugins/internal/codex-resources/utils.d.ts +14 -0
- package/dist/plugins/internal/codex-resources/utils.js +80 -0
- package/dist/plugins/internal/resource-docs-shared/fs.d.ts +3 -0
- package/dist/plugins/internal/resource-docs-shared/fs.js +19 -0
- package/dist/plugins/internal/resource-docs-shared/index.d.ts +7 -0
- package/dist/plugins/internal/resource-docs-shared/index.js +44 -0
- package/dist/plugins/internal/resource-docs-shared/links.d.ts +22 -0
- package/dist/plugins/internal/resource-docs-shared/links.js +44 -0
- package/dist/plugins/internal/resource-docs-shared/markdown-structure.d.ts +9 -0
- package/dist/plugins/internal/resource-docs-shared/markdown-structure.js +22 -0
- package/dist/plugins/internal/resource-docs-shared/mdx.d.ts +23 -0
- package/dist/plugins/internal/resource-docs-shared/mdx.js +63 -0
- package/dist/plugins/internal/resource-docs-shared/skills.d.ts +37 -0
- package/dist/plugins/internal/resource-docs-shared/skills.js +318 -0
- package/dist/plugins/internal/resource-docs-shared/walk.d.ts +20 -0
- package/dist/plugins/internal/resource-docs-shared/walk.js +41 -0
- package/dist/preset.d.ts +19 -0
- package/dist/preset.js +16 -1
- package/dist/safelist.css +1 -1
- package/dist/settings.d.ts +5 -0
- package/dist/sidebar/types.d.ts +6 -0
- package/dist/sidebar-tree/build-tree.js +8 -0
- package/dist/sidebar-tree/types.d.ts +12 -0
- package/dist/sidebar-tree-island/index.js +175 -1
- package/dist/sidebar-utils/index.d.ts +6 -0
- package/dist/site-schema/doc-route-entries.js +2 -0
- package/dist/site-schema/index.d.ts +1 -0
- package/dist/site-schema/index.js +3 -1
- package/dist/site-schema/nav-tree.js +17 -2
- package/dist/site-schema/note-tray-validate.d.ts +7 -0
- package/dist/site-schema/note-tray-validate.js +94 -0
- package/dist/site-schema/types.d.ts +11 -0
- package/dist/site-tree-nav-island/index.d.ts +5 -1
- package/dist/site-tree-nav-island/index.js +119 -12
- package/dist/theme-packs/drift/pack.css +6 -1
- package/dist/theme-packs/hearth/pack.css +5 -0
- package/dist/theme-packs/sakura/pack.css +6 -0
- package/dist/theme-packs/scandi/pack.css +7 -7
- package/dist/theme-packs/timberline/pack.css +5 -0
- package/eject/doc-pager/index.tsx +9 -0
- package/eject/header/header.tsx +26 -1
- package/eject/sidebar/types.ts +6 -0
- package/eject/sidebar-tree-island/index.tsx +238 -6
- package/eject/site-tree-nav-island/index.tsx +166 -16
- package/package.json +25 -8
- /package/dist/plugins/internal/{claude-resources → resource-docs-shared}/escape-for-mdx.d.ts +0 -0
- /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
|
|
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,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
|
+
};
|