cantip 0.1.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/LICENSE +21 -0
- package/README.md +61 -0
- package/app/components/CanvasMount.tsx +62 -0
- package/app/components/CodeWrapToggle.tsx +78 -0
- package/app/components/FindOnPage.tsx +224 -0
- package/app/components/MobileBottomBar.tsx +93 -0
- package/app/components/MobileProjectsPanel.tsx +113 -0
- package/app/components/PageFloatingMenu.tsx +224 -0
- package/app/components/ProjectSwitcher.tsx +124 -0
- package/app/components/Search.tsx +930 -0
- package/app/components/ShortcutsHelp.tsx +113 -0
- package/app/components/Sidebar.tsx +1049 -0
- package/app/components/TabBar.tsx +227 -0
- package/app/components/Toc.tsx +129 -0
- package/app/components/TopBar.tsx +74 -0
- package/app/components/theme-toggle.tsx +71 -0
- package/app/components/ui/button.tsx +56 -0
- package/app/components/ui/card.tsx +55 -0
- package/app/components/ui/dropdown-menu.tsx +156 -0
- package/app/components/ui/input.tsx +21 -0
- package/app/entry.client.tsx +12 -0
- package/app/entry.server.tsx +155 -0
- package/app/generated/site.ts +19 -0
- package/app/generated/slots.ts +10 -0
- package/app/generated/theme.generated.css +60 -0
- package/app/lib/config/config.server.ts +50 -0
- package/app/lib/config/defaults.ts +120 -0
- package/app/lib/config/load.ts +82 -0
- package/app/lib/config/schema.ts +131 -0
- package/app/lib/config/site.ts +43 -0
- package/app/lib/content.server.ts +105 -0
- package/app/lib/projects.ts +86 -0
- package/app/lib/sidebar.server.ts +113 -0
- package/app/lib/site.ts +27 -0
- package/app/lib/slots.tsx +33 -0
- package/app/lib/tabs.tsx +128 -0
- package/app/lib/useKeyboardShortcuts.ts +149 -0
- package/app/lib/utils.ts +17 -0
- package/app/root.tsx +171 -0
- package/app/routes/$.tsx +158 -0
- package/app/routes/_index.tsx +60 -0
- package/app/styles/app.css +461 -0
- package/app/styles/obsidian.css +83 -0
- package/app/styles/tailwind.css +227 -0
- package/cli.js +119 -0
- package/components.json +21 -0
- package/dist/config.mjs +87 -0
- package/dist/generate-content.mjs +1665 -0
- package/package.json +112 -0
- package/scripts/build-search-index.ts +129 -0
- package/scripts/canonical.ts +34 -0
- package/scripts/canvas-to-md.ts +73 -0
- package/scripts/compile.ts +242 -0
- package/scripts/emit-config.ts +163 -0
- package/scripts/generate-content.ts +197 -0
- package/scripts/obsidian/files.ts +222 -0
- package/scripts/obsidian/fs.ts +34 -0
- package/scripts/obsidian/generate.ts +36 -0
- package/scripts/obsidian/html.ts +17 -0
- package/scripts/obsidian/logger.ts +10 -0
- package/scripts/obsidian/markdown.ts +56 -0
- package/scripts/obsidian/obsidian.ts +229 -0
- package/scripts/obsidian/path.ts +60 -0
- package/scripts/obsidian/rehype.ts +60 -0
- package/scripts/obsidian/remark.ts +712 -0
- package/scripts/obsidian/types.ts +31 -0
- package/vite.config.ts +62 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
@import 'tailwindcss';
|
|
2
|
+
@import 'tw-animate-css';
|
|
3
|
+
|
|
4
|
+
/* Dark mode is class-based: <html class="dark"> toggled by the theme switch. */
|
|
5
|
+
@custom-variant dark (&:where(.dark, .dark *));
|
|
6
|
+
|
|
7
|
+
/* ── shadcn neutral theme (default palette) ─────────────────────────────── */
|
|
8
|
+
:root {
|
|
9
|
+
--radius: 0.625rem;
|
|
10
|
+
/* Brand color (#4C3FB0) — drives interactive elements: links, buttons, focus rings. */
|
|
11
|
+
--brand: oklch(0.42 0.158 286);
|
|
12
|
+
--background: oklch(1 0 0);
|
|
13
|
+
--foreground: oklch(0.145 0 0);
|
|
14
|
+
--card: oklch(1 0 0);
|
|
15
|
+
--card-foreground: oklch(0.145 0 0);
|
|
16
|
+
--popover: oklch(1 0 0);
|
|
17
|
+
--popover-foreground: oklch(0.145 0 0);
|
|
18
|
+
--primary: var(--brand);
|
|
19
|
+
--primary-foreground: oklch(0.985 0 0);
|
|
20
|
+
--secondary: oklch(0.97 0 0);
|
|
21
|
+
--secondary-foreground: oklch(0.205 0 0);
|
|
22
|
+
--muted: oklch(0.97 0 0);
|
|
23
|
+
--muted-foreground: oklch(0.556 0 0);
|
|
24
|
+
--accent: oklch(0.97 0 0);
|
|
25
|
+
--accent-foreground: oklch(0.205 0 0);
|
|
26
|
+
--destructive: oklch(0.577 0.245 27.325);
|
|
27
|
+
--border: oklch(0.922 0 0);
|
|
28
|
+
--input: oklch(0.922 0 0);
|
|
29
|
+
--ring: oklch(0.708 0 0);
|
|
30
|
+
--sidebar: oklch(0.985 0 0);
|
|
31
|
+
--sidebar-foreground: oklch(0.145 0 0);
|
|
32
|
+
--sidebar-primary: oklch(0.205 0 0);
|
|
33
|
+
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
34
|
+
--sidebar-accent: oklch(0.97 0 0);
|
|
35
|
+
--sidebar-accent-foreground: oklch(0.205 0 0);
|
|
36
|
+
--sidebar-border: oklch(0.922 0 0);
|
|
37
|
+
--sidebar-ring: oklch(0.708 0 0);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.dark {
|
|
41
|
+
/* Lightened brand for contrast against the dark background. */
|
|
42
|
+
--brand: oklch(0.68 0.14 286);
|
|
43
|
+
--background: oklch(0.145 0 0);
|
|
44
|
+
--foreground: oklch(0.985 0 0);
|
|
45
|
+
--card: oklch(0.205 0 0);
|
|
46
|
+
--card-foreground: oklch(0.985 0 0);
|
|
47
|
+
--popover: oklch(0.205 0 0);
|
|
48
|
+
--popover-foreground: oklch(0.985 0 0);
|
|
49
|
+
--primary: var(--brand);
|
|
50
|
+
--primary-foreground: oklch(0.205 0 0);
|
|
51
|
+
--secondary: oklch(0.269 0 0);
|
|
52
|
+
--secondary-foreground: oklch(0.985 0 0);
|
|
53
|
+
--muted: oklch(0.269 0 0);
|
|
54
|
+
--muted-foreground: oklch(0.708 0 0);
|
|
55
|
+
--accent: oklch(0.269 0 0);
|
|
56
|
+
--accent-foreground: oklch(0.985 0 0);
|
|
57
|
+
--destructive: oklch(0.704 0.191 22.216);
|
|
58
|
+
--border: oklch(1 0 0 / 10%);
|
|
59
|
+
--input: oklch(1 0 0 / 15%);
|
|
60
|
+
--ring: oklch(0.556 0 0);
|
|
61
|
+
--sidebar: oklch(0.205 0 0);
|
|
62
|
+
--sidebar-foreground: oklch(0.985 0 0);
|
|
63
|
+
--sidebar-primary: oklch(0.488 0.243 264.376);
|
|
64
|
+
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
65
|
+
--sidebar-accent: oklch(0.269 0 0);
|
|
66
|
+
--sidebar-accent-foreground: oklch(0.985 0 0);
|
|
67
|
+
--sidebar-border: oklch(1 0 0 / 10%);
|
|
68
|
+
--sidebar-ring: oklch(0.556 0 0);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@theme inline {
|
|
72
|
+
--radius-sm: calc(var(--radius) - 4px);
|
|
73
|
+
--radius-md: calc(var(--radius) - 2px);
|
|
74
|
+
--radius-lg: var(--radius);
|
|
75
|
+
--radius-xl: calc(var(--radius) + 4px);
|
|
76
|
+
--color-background: var(--background);
|
|
77
|
+
--color-foreground: var(--foreground);
|
|
78
|
+
--color-card: var(--card);
|
|
79
|
+
--color-card-foreground: var(--card-foreground);
|
|
80
|
+
--color-popover: var(--popover);
|
|
81
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
82
|
+
--color-primary: var(--primary);
|
|
83
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
84
|
+
--color-secondary: var(--secondary);
|
|
85
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
86
|
+
--color-muted: var(--muted);
|
|
87
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
88
|
+
--color-accent: var(--accent);
|
|
89
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
90
|
+
--color-destructive: var(--destructive);
|
|
91
|
+
--color-border: var(--border);
|
|
92
|
+
--color-input: var(--input);
|
|
93
|
+
--color-ring: var(--ring);
|
|
94
|
+
--color-sidebar: var(--sidebar);
|
|
95
|
+
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
96
|
+
--color-sidebar-primary: var(--sidebar-primary);
|
|
97
|
+
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
98
|
+
--color-sidebar-accent: var(--sidebar-accent);
|
|
99
|
+
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
100
|
+
--color-sidebar-border: var(--sidebar-border);
|
|
101
|
+
--color-sidebar-ring: var(--sidebar-ring);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
@layer base {
|
|
105
|
+
* {
|
|
106
|
+
@apply border-border outline-ring/50;
|
|
107
|
+
}
|
|
108
|
+
body {
|
|
109
|
+
@apply bg-background text-foreground;
|
|
110
|
+
}
|
|
111
|
+
:root {
|
|
112
|
+
--mobile-bar-height: 3.25rem;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/* Slim, unobtrusive scrollbars. Firefox. */
|
|
116
|
+
* {
|
|
117
|
+
scrollbar-width: thin;
|
|
118
|
+
scrollbar-color: var(--border) transparent;
|
|
119
|
+
}
|
|
120
|
+
/* WebKit/Blink. */
|
|
121
|
+
*::-webkit-scrollbar {
|
|
122
|
+
width: 6px;
|
|
123
|
+
height: 6px;
|
|
124
|
+
}
|
|
125
|
+
*::-webkit-scrollbar-track {
|
|
126
|
+
background: transparent;
|
|
127
|
+
}
|
|
128
|
+
*::-webkit-scrollbar-thumb {
|
|
129
|
+
background-color: transparent;
|
|
130
|
+
border-radius: 9999px;
|
|
131
|
+
}
|
|
132
|
+
/* Reveal the thumb only while hovering the scrollable area. */
|
|
133
|
+
*:hover::-webkit-scrollbar-thumb {
|
|
134
|
+
background-color: var(--border);
|
|
135
|
+
}
|
|
136
|
+
*::-webkit-scrollbar-thumb:hover {
|
|
137
|
+
background-color: var(--muted-foreground);
|
|
138
|
+
}
|
|
139
|
+
*::-webkit-scrollbar-corner {
|
|
140
|
+
background: transparent;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/* Fully hide the native scrollbar (no track, no reserved space). Used by the
|
|
144
|
+
tab strip, which renders its own overlay scrollbar that fades in on hover.
|
|
145
|
+
Unlike the slim scrollbars above, this reserves zero layout space, so the
|
|
146
|
+
tab text never shifts when tabs overflow. */
|
|
147
|
+
.scrollbar-none {
|
|
148
|
+
scrollbar-width: none;
|
|
149
|
+
}
|
|
150
|
+
.scrollbar-none::-webkit-scrollbar {
|
|
151
|
+
width: 0;
|
|
152
|
+
height: 0;
|
|
153
|
+
display: none;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/* While the theme is being toggled, kill all transitions/animations so every
|
|
158
|
+
element re-colors instantly (the theme-toggle adds `.theme-switching` to <html>
|
|
159
|
+
for one frame). Without this, elements carrying a hover `transition-colors` /
|
|
160
|
+
`transition-all` (search input, project switcher, home cards, buttons) animate
|
|
161
|
+
their color change and visibly lag behind the sidebar/content, which have no
|
|
162
|
+
transition. Unlayered + !important so it beats the utility-class transitions. */
|
|
163
|
+
html.theme-switching *,
|
|
164
|
+
html.theme-switching *::before,
|
|
165
|
+
html.theme-switching *::after {
|
|
166
|
+
transition: none !important;
|
|
167
|
+
animation: none !important;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/* Locate pulse: flashes the active sidebar row when "locate" is pressed. */
|
|
171
|
+
.locate-flash {
|
|
172
|
+
animation: locate-pulse 1s ease-out;
|
|
173
|
+
}
|
|
174
|
+
@keyframes locate-pulse {
|
|
175
|
+
0% {
|
|
176
|
+
background-color: var(--primary);
|
|
177
|
+
}
|
|
178
|
+
100% {
|
|
179
|
+
background-color: var(--sidebar-accent);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/* ── Bridge: legacy --sl-* tokens → shadcn theme ─────────────────────────────
|
|
184
|
+
The generated markdown HTML and obsidian.css (callouts, tags, highlights)
|
|
185
|
+
still reference --sl-* variables. Rather than rewrite that generated content,
|
|
186
|
+
we redefine the tokens in terms of the shadcn neutral palette so the doc body
|
|
187
|
+
tracks the active theme and the dark/light toggle automatically. */
|
|
188
|
+
:root {
|
|
189
|
+
--sl-color-white: var(--foreground);
|
|
190
|
+
--sl-color-gray-1: var(--foreground);
|
|
191
|
+
--sl-color-gray-2: var(--muted-foreground);
|
|
192
|
+
--sl-color-gray-3: var(--muted-foreground);
|
|
193
|
+
--sl-color-gray-4: var(--border);
|
|
194
|
+
--sl-color-gray-5: var(--border);
|
|
195
|
+
--sl-color-gray-6: var(--muted);
|
|
196
|
+
--sl-color-black: var(--background);
|
|
197
|
+
|
|
198
|
+
--sl-color-accent-low: var(--accent);
|
|
199
|
+
--sl-color-accent: var(--primary);
|
|
200
|
+
--sl-color-accent-high: var(--foreground);
|
|
201
|
+
|
|
202
|
+
--sl-color-bg-nav: var(--sidebar);
|
|
203
|
+
--sl-color-bg-sidebar: var(--sidebar);
|
|
204
|
+
--sl-color-bg-inline-code: var(--muted);
|
|
205
|
+
--sl-color-hairline-light: var(--border);
|
|
206
|
+
--sl-color-hairline: var(--border);
|
|
207
|
+
--sl-color-hairline-shade: var(--muted);
|
|
208
|
+
--sl-color-bg: var(--background);
|
|
209
|
+
|
|
210
|
+
/* Semantic colours used by obsidian callouts — kept as fixed hues so notes /
|
|
211
|
+
tips / cautions / dangers stay legible in both themes. */
|
|
212
|
+
--sl-color-green-low: color-mix(in oklab, oklch(0.6 0.16 150) 12%, var(--background));
|
|
213
|
+
--sl-color-green: oklch(0.6 0.16 150);
|
|
214
|
+
--sl-color-green-high: oklch(0.72 0.17 150);
|
|
215
|
+
--sl-color-orange-low: color-mix(in oklab, oklch(0.7 0.16 70) 12%, var(--background));
|
|
216
|
+
--sl-color-orange: oklch(0.72 0.16 70);
|
|
217
|
+
--sl-color-orange-high: oklch(0.8 0.16 75);
|
|
218
|
+
--sl-color-blue-low: color-mix(in oklab, oklch(0.6 0.18 250) 12%, var(--background));
|
|
219
|
+
--sl-color-blue: oklch(0.6 0.18 250);
|
|
220
|
+
--sl-color-blue-high: oklch(0.72 0.16 250);
|
|
221
|
+
--sl-color-red-low: color-mix(in oklab, oklch(0.62 0.2 25) 12%, var(--background));
|
|
222
|
+
--sl-color-red: oklch(0.62 0.2 25);
|
|
223
|
+
--sl-color-red-high: oklch(0.72 0.18 25);
|
|
224
|
+
|
|
225
|
+
--sl-font: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
|
|
226
|
+
--sl-font-system-mono: ui-monospace, SFMono-Regular, Consolas, 'Liberation Mono', Menlo, monospace;
|
|
227
|
+
}
|
package/cli.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* `cantip` CLI — drives the docs engine from the USER's project directory.
|
|
4
|
+
*
|
|
5
|
+
* The engine (this package) ships the Remix `app/` + build `scripts/`. The CLI
|
|
6
|
+
* runs them with `cwd = the user's project`, so all artifacts (content/,
|
|
7
|
+
* app/generated/, public/, build/) land in the user's repo while the app code
|
|
8
|
+
* stays in node_modules. Vite/Remix always load the engine's vite.config.ts
|
|
9
|
+
* (which points `appDirectory` at the engine app/ and `publicDir`/build at cwd).
|
|
10
|
+
*
|
|
11
|
+
* Subcommands:
|
|
12
|
+
* cantip generate — ingest vaults + compile + emit manifest/config (from docs.config.ts)
|
|
13
|
+
* cantip dev — generate, then remix vite dev server
|
|
14
|
+
* cantip build — generate, then remix vite production build
|
|
15
|
+
* cantip start — serve the built server (build/server/index.js)
|
|
16
|
+
* cantip typecheck — tsc --noEmit against the engine
|
|
17
|
+
*/
|
|
18
|
+
import { spawn } from 'node:child_process'
|
|
19
|
+
import { fileURLToPath } from 'node:url'
|
|
20
|
+
import { existsSync } from 'node:fs'
|
|
21
|
+
import path from 'node:path'
|
|
22
|
+
import process from 'node:process'
|
|
23
|
+
|
|
24
|
+
const ENGINE_DIR = path.dirname(fileURLToPath(import.meta.url))
|
|
25
|
+
const VITE_CONFIG = path.join(ENGINE_DIR, 'vite.config.ts')
|
|
26
|
+
// Prefer the precompiled generator (dist/) — required when installed under
|
|
27
|
+
// node_modules, where Node won't strip types from `.ts`. Fall back to the `.ts`
|
|
28
|
+
// source via the strip-types runner in the monorepo dev setup (symlinked, where
|
|
29
|
+
// dist/ may be absent).
|
|
30
|
+
const GENERATE_JS = path.join(ENGINE_DIR, 'dist', 'generate-content.mjs')
|
|
31
|
+
const GENERATE_TS = path.join(ENGINE_DIR, 'scripts', 'generate-content.ts')
|
|
32
|
+
|
|
33
|
+
/** Run a command inheriting stdio; resolve on exit 0, reject otherwise. */
|
|
34
|
+
function run(cmd, args, opts = {}) {
|
|
35
|
+
return new Promise((resolve, reject) => {
|
|
36
|
+
const child = spawn(cmd, args, { stdio: 'inherit', shell: false, ...opts })
|
|
37
|
+
child.on('error', reject)
|
|
38
|
+
child.on('exit', (code) => (code === 0 ? resolve() : reject(new Error(`${cmd} ${args.join(' ')} exited with ${code}`))))
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Resolve a dependency's CLI binary. npm may install it in the engine's local
|
|
44
|
+
* `node_modules/.bin` OR hoist it to an ancestor `node_modules/.bin` (workspaces).
|
|
45
|
+
* Walk up from the engine dir to find the first `.bin/<name>` that exists; fall
|
|
46
|
+
* back to the bare name so PATH resolution can still find it.
|
|
47
|
+
*/
|
|
48
|
+
function engineBin(name) {
|
|
49
|
+
let dir = ENGINE_DIR
|
|
50
|
+
while (true) {
|
|
51
|
+
const candidate = path.join(dir, 'node_modules', '.bin', name)
|
|
52
|
+
if (existsSync(candidate)) return candidate
|
|
53
|
+
const parent = path.dirname(dir)
|
|
54
|
+
if (parent === dir) break
|
|
55
|
+
dir = parent
|
|
56
|
+
}
|
|
57
|
+
return name
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Run the content generator from the user's cwd: compiled dist/ if present, else the .ts source. */
|
|
61
|
+
function generate() {
|
|
62
|
+
const args = existsSync(GENERATE_JS)
|
|
63
|
+
? [GENERATE_JS]
|
|
64
|
+
: ['--experimental-strip-types', GENERATE_TS]
|
|
65
|
+
return run(process.execPath, args, { cwd: process.cwd() })
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Run the Remix Vite CLI with the engine config from the user's cwd. The vite
|
|
70
|
+
* config sets Vite `root` = cwd (so baked asset paths are cwd-relative and
|
|
71
|
+
* remix-serve finds them) and `appDirectory` = the engine app/. The engine ships
|
|
72
|
+
* explicit entry.server/.client, so Remix skips runtime auto-detection — no
|
|
73
|
+
* REMIX_ROOT override needed.
|
|
74
|
+
*/
|
|
75
|
+
function remixVite(sub) {
|
|
76
|
+
return run(engineBin('remix'), ['vite:' + sub, '--config', VITE_CONFIG], {
|
|
77
|
+
cwd: process.cwd(),
|
|
78
|
+
})
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async function main() {
|
|
82
|
+
const command = process.argv[2]
|
|
83
|
+
switch (command) {
|
|
84
|
+
case 'generate':
|
|
85
|
+
await generate()
|
|
86
|
+
break
|
|
87
|
+
case 'dev':
|
|
88
|
+
await generate()
|
|
89
|
+
await remixVite('dev')
|
|
90
|
+
break
|
|
91
|
+
case 'build':
|
|
92
|
+
await generate()
|
|
93
|
+
await remixVite('build')
|
|
94
|
+
break
|
|
95
|
+
case 'start':
|
|
96
|
+
await run(engineBin('remix-serve'), [path.join(process.cwd(), 'build', 'server', 'index.js')], { cwd: process.cwd() })
|
|
97
|
+
break
|
|
98
|
+
case 'typecheck':
|
|
99
|
+
await run(engineBin('tsc'), ['--noEmit'], { cwd: ENGINE_DIR })
|
|
100
|
+
break
|
|
101
|
+
default:
|
|
102
|
+
console.error(
|
|
103
|
+
`cantip — config-driven Remix docs engine\n\n` +
|
|
104
|
+
`Usage: cantip <command>\n\n` +
|
|
105
|
+
`Commands:\n` +
|
|
106
|
+
` generate Ingest vaults + compile content from docs.config.ts\n` +
|
|
107
|
+
` dev Generate, then start the dev server\n` +
|
|
108
|
+
` build Generate, then build for production\n` +
|
|
109
|
+
` start Serve the production build\n` +
|
|
110
|
+
` typecheck Type-check the engine\n`,
|
|
111
|
+
)
|
|
112
|
+
process.exit(command ? 1 : 0)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
main().catch((err) => {
|
|
117
|
+
console.error(err.message ?? err)
|
|
118
|
+
process.exit(1)
|
|
119
|
+
})
|
package/components.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema.json",
|
|
3
|
+
"style": "new-york",
|
|
4
|
+
"rsc": false,
|
|
5
|
+
"tsx": true,
|
|
6
|
+
"tailwind": {
|
|
7
|
+
"config": "",
|
|
8
|
+
"css": "app/styles/tailwind.css",
|
|
9
|
+
"baseColor": "neutral",
|
|
10
|
+
"cssVariables": true,
|
|
11
|
+
"prefix": ""
|
|
12
|
+
},
|
|
13
|
+
"iconLibrary": "lucide",
|
|
14
|
+
"aliases": {
|
|
15
|
+
"components": "~/components",
|
|
16
|
+
"utils": "~/lib/utils",
|
|
17
|
+
"ui": "~/components/ui",
|
|
18
|
+
"lib": "~/lib",
|
|
19
|
+
"hooks": "~/hooks"
|
|
20
|
+
}
|
|
21
|
+
}
|
package/dist/config.mjs
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// app/lib/config/schema.ts
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
var colorMap = z.record(z.string(), z.string());
|
|
4
|
+
var projectSchema = z.object({
|
|
5
|
+
/** First id segment + output dir name, e.g. `krista`. */
|
|
6
|
+
id: z.string().min(1),
|
|
7
|
+
/** Display name in the switcher / home cards. */
|
|
8
|
+
name: z.string().min(1),
|
|
9
|
+
/** Directory of markdown/canvas files. Submodule, loose folder, or any path. */
|
|
10
|
+
source: z.string().min(1),
|
|
11
|
+
/** Logo under the user's `/public`. Defaults to `/projects/<id>.svg`. */
|
|
12
|
+
logo: z.string().optional(),
|
|
13
|
+
/** Landing URL when switching to this project. Defaults to its first doc. */
|
|
14
|
+
landing: z.string().optional(),
|
|
15
|
+
/** Short blurb, reused on home cards. */
|
|
16
|
+
description: z.string().default(""),
|
|
17
|
+
/** Ingest `.canvas` files from this source too. */
|
|
18
|
+
canvas: z.boolean().default(false),
|
|
19
|
+
/** Globs (relative to `source`) to skip, e.g. `['CLAUDE.md']`. */
|
|
20
|
+
ignore: z.array(z.string()).default([])
|
|
21
|
+
});
|
|
22
|
+
var generalSchema = z.object({
|
|
23
|
+
enabled: z.boolean().default(false),
|
|
24
|
+
name: z.string().default("\u0411\u0435\u0437 \u043F\u0440\u043E\u0435\u043A\u0442\u0430"),
|
|
25
|
+
/** Directory of loose docs. When unset, the bucket has no docs. */
|
|
26
|
+
source: z.string().optional(),
|
|
27
|
+
logo: z.string().default("/projects/general.svg"),
|
|
28
|
+
description: z.string().default(""),
|
|
29
|
+
ignore: z.array(z.string()).default([])
|
|
30
|
+
});
|
|
31
|
+
var siteSchema = z.object({
|
|
32
|
+
title: z.string().default("Docs"),
|
|
33
|
+
/** Home-page blurb under the title. */
|
|
34
|
+
description: z.string().default(""),
|
|
35
|
+
/** BCP-47-ish tag; drives `localeCompare` sorting + Pagefind `forceLanguage`. */
|
|
36
|
+
lang: z.string().default("ru"),
|
|
37
|
+
favicon: z.string().default("/favicon.svg"),
|
|
38
|
+
logo: z.object({
|
|
39
|
+
light: z.string().default("/iti-logo-light.svg"),
|
|
40
|
+
dark: z.string().default("/iti-logo-dark.svg")
|
|
41
|
+
}).prefault({}),
|
|
42
|
+
defaultTheme: z.enum(["dark", "light"]).default("dark")
|
|
43
|
+
});
|
|
44
|
+
var themeSchema = z.object({
|
|
45
|
+
/** OKLCH (or any CSS color) token overrides, merged OVER the shipped defaults. */
|
|
46
|
+
colors: z.object({
|
|
47
|
+
light: colorMap.default({}),
|
|
48
|
+
dark: colorMap.default({})
|
|
49
|
+
}).prefault({})
|
|
50
|
+
});
|
|
51
|
+
var componentsSchema = z.object({
|
|
52
|
+
Home: z.string().optional(),
|
|
53
|
+
DocPage: z.string().optional(),
|
|
54
|
+
Sidebar: z.string().optional(),
|
|
55
|
+
TopBar: z.string().optional(),
|
|
56
|
+
Toc: z.string().optional(),
|
|
57
|
+
Search: z.string().optional(),
|
|
58
|
+
Layout: z.string().optional()
|
|
59
|
+
}).default({});
|
|
60
|
+
var uiSchema = z.record(z.string(), z.string()).default({});
|
|
61
|
+
var docsConfigSchema = z.object({
|
|
62
|
+
site: siteSchema.prefault({}),
|
|
63
|
+
projects: z.array(projectSchema).default([]),
|
|
64
|
+
general: generalSchema.prefault({}),
|
|
65
|
+
theme: themeSchema.prefault({}),
|
|
66
|
+
components: componentsSchema,
|
|
67
|
+
ui: uiSchema,
|
|
68
|
+
/**
|
|
69
|
+
* Reserved for custom remark/rehype plugins + callout types. NOT wired in this
|
|
70
|
+
* phase (the markdown pipeline stays fixed); accepted so configs are
|
|
71
|
+
* forward-compatible.
|
|
72
|
+
*/
|
|
73
|
+
markdown: z.unknown().optional()
|
|
74
|
+
});
|
|
75
|
+
function defineConfig(config) {
|
|
76
|
+
return config;
|
|
77
|
+
}
|
|
78
|
+
export {
|
|
79
|
+
componentsSchema,
|
|
80
|
+
defineConfig,
|
|
81
|
+
docsConfigSchema,
|
|
82
|
+
generalSchema,
|
|
83
|
+
projectSchema,
|
|
84
|
+
siteSchema,
|
|
85
|
+
themeSchema,
|
|
86
|
+
uiSchema
|
|
87
|
+
};
|