kitfly 0.1.2

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 (62) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/LICENSE +21 -0
  3. package/README.md +136 -0
  4. package/VERSION +1 -0
  5. package/package.json +63 -0
  6. package/schemas/README.md +32 -0
  7. package/schemas/site.schema.json +5 -0
  8. package/schemas/theme.schema.json +5 -0
  9. package/schemas/v0/site.schema.json +172 -0
  10. package/schemas/v0/theme.schema.json +210 -0
  11. package/scripts/build-all.ts +121 -0
  12. package/scripts/build.ts +601 -0
  13. package/scripts/bundle.ts +781 -0
  14. package/scripts/dev.ts +777 -0
  15. package/scripts/generate-checksums.sh +78 -0
  16. package/scripts/release/export-release-key.sh +28 -0
  17. package/scripts/release/release-guard-tag-version.sh +79 -0
  18. package/scripts/release/sign-release-assets.sh +123 -0
  19. package/scripts/release/upload-release-assets.sh +76 -0
  20. package/scripts/release/upload-release-provenance.sh +52 -0
  21. package/scripts/release/verify-public-key.sh +48 -0
  22. package/scripts/release/verify-signatures.sh +117 -0
  23. package/scripts/version-sync.ts +82 -0
  24. package/src/__tests__/build.test.ts +240 -0
  25. package/src/__tests__/bundle.test.ts +786 -0
  26. package/src/__tests__/cli.test.ts +706 -0
  27. package/src/__tests__/crucible.test.ts +1043 -0
  28. package/src/__tests__/engine.test.ts +157 -0
  29. package/src/__tests__/init.test.ts +450 -0
  30. package/src/__tests__/pipeline.test.ts +1087 -0
  31. package/src/__tests__/productbook.test.ts +1206 -0
  32. package/src/__tests__/runbook.test.ts +974 -0
  33. package/src/__tests__/server-registry.test.ts +1251 -0
  34. package/src/__tests__/servicebook.test.ts +1248 -0
  35. package/src/__tests__/shared.test.ts +2005 -0
  36. package/src/__tests__/styles.test.ts +14 -0
  37. package/src/__tests__/theme-schema.test.ts +47 -0
  38. package/src/__tests__/theme.test.ts +554 -0
  39. package/src/cli.ts +582 -0
  40. package/src/commands/init.ts +92 -0
  41. package/src/commands/update.ts +444 -0
  42. package/src/engine.ts +20 -0
  43. package/src/logger.ts +15 -0
  44. package/src/migrations/0000_schema_versioning.ts +67 -0
  45. package/src/migrations/0001_server_port.ts +52 -0
  46. package/src/migrations/0002_brand_logo.ts +49 -0
  47. package/src/migrations/index.ts +26 -0
  48. package/src/migrations/schema.ts +24 -0
  49. package/src/server-registry.ts +405 -0
  50. package/src/shared.ts +1239 -0
  51. package/src/site/styles.css +931 -0
  52. package/src/site/template.html +193 -0
  53. package/src/templates/crucible.ts +1163 -0
  54. package/src/templates/driver.ts +876 -0
  55. package/src/templates/handbook.ts +339 -0
  56. package/src/templates/minimal.ts +139 -0
  57. package/src/templates/pipeline.ts +966 -0
  58. package/src/templates/productbook.ts +1032 -0
  59. package/src/templates/runbook.ts +829 -0
  60. package/src/templates/schema.ts +119 -0
  61. package/src/templates/servicebook.ts +1242 -0
  62. package/src/theme.ts +245 -0
@@ -0,0 +1,193 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>{{TITLE}} - {{SITE_TITLE}}</title>
7
+ <link rel="icon" type="image/png" sizes="32x32" href="{{PATH_PREFIX}}{{BRAND_FAVICON}}">
8
+ <link rel="icon" type="image/png" sizes="64x64" href="{{PATH_PREFIX}}{{BRAND_LOGO}}">
9
+ <link rel="stylesheet" href="{{PATH_PREFIX}}styles.css">
10
+ {{THEME_CSS}}
11
+ <!-- Syntax highlighting - Prism.js -->
12
+ <link rel="stylesheet" href="{{PRISM_LIGHT_URL}}" id="prism-light">
13
+ <link rel="stylesheet" href="{{PRISM_DARK_URL}}" id="prism-dark" disabled>
14
+ <script>
15
+ // Apply saved theme immediately to prevent flash
16
+ (function() {
17
+ const saved = localStorage.getItem('theme');
18
+ if (saved) {
19
+ document.documentElement.setAttribute('data-theme', saved);
20
+ }
21
+ // Set Prism theme based on saved or system preference
22
+ const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
23
+ const isDark = saved === 'dark' || (!saved && prefersDark);
24
+ if (isDark) {
25
+ document.getElementById('prism-light')?.setAttribute('disabled', '');
26
+ document.getElementById('prism-dark')?.removeAttribute('disabled');
27
+ }
28
+ })();
29
+ </script>
30
+ </head>
31
+ <body>
32
+ <div class="mobile-header">
33
+ <button class="nav-toggle" onclick="toggleNav()" aria-label="Toggle navigation">
34
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
35
+ <path d="M3 12h18M3 6h18M3 18h18"/>
36
+ </svg>
37
+ </button>
38
+ <a href="{{PATH_PREFIX}}" class="mobile-logo" title="Home">
39
+ <img src="{{PATH_PREFIX}}{{BRAND_LOGO}}" alt="{{BRAND_NAME}}" class="logo-img {{BRAND_LOGO_CLASS}}"/>
40
+ </a>
41
+ <button class="mobile-theme-toggle" onclick="toggleTheme()" title="Toggle theme" aria-label="Toggle theme">
42
+ <svg class="icon-sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
43
+ <circle cx="12" cy="12" r="5"/>
44
+ <path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/>
45
+ </svg>
46
+ <svg class="icon-moon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
47
+ <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
48
+ </svg>
49
+ </button>
50
+ </div>
51
+ <div class="layout">
52
+ <nav class="sidebar">
53
+ <div class="sidebar-header">
54
+ <div class="logo {{BRAND_LOGO_CLASS}}">
55
+ <a href="{{BRAND_URL}}" class="logo-icon"{{BRAND_TARGET}}>
56
+ <img src="{{PATH_PREFIX}}{{BRAND_LOGO}}" alt="{{BRAND_NAME}}" class="logo-img"/>
57
+ </a>
58
+ <span class="logo-text">
59
+ <a href="{{BRAND_URL}}" class="brand"{{BRAND_TARGET}}>{{BRAND_NAME}}</a>
60
+ <a href="{{PATH_PREFIX}}" class="product">{{SITE_TITLE}}</a>
61
+ </span>
62
+ </div>
63
+ <div class="header-tools">
64
+ <button class="theme-toggle" onclick="toggleTheme()" title="Toggle theme" aria-label="Toggle theme">
65
+ <svg class="icon-sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
66
+ <circle cx="12" cy="12" r="5"/>
67
+ <path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/>
68
+ </svg>
69
+ <svg class="icon-moon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
70
+ <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
71
+ </svg>
72
+ </button>
73
+ <div class="sidebar-meta">
74
+ <span class="meta-version">{{VERSION}}</span>
75
+ <span class="meta-branch">{{BRANCH}}</span>
76
+ </div>
77
+ </div>
78
+ </div>
79
+ <div class="sidebar-nav">
80
+ {{NAV}}
81
+ </div>
82
+ </nav>
83
+ <main class="content">
84
+ <article class="prose">
85
+ {{BREADCRUMBS}}
86
+ {{PAGE_META}}
87
+ {{CONTENT}}
88
+ </article>
89
+ {{TOC}}
90
+ </main>
91
+ </div>
92
+ {{FOOTER}}
93
+ <!-- Syntax highlighting - Prism.js -->
94
+ <script src="https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-core.min.js"></script>
95
+ <script src="https://cdn.jsdelivr.net/npm/prismjs@1/plugins/autoloader/prism-autoloader.min.js"></script>
96
+ <!-- Mermaid diagram support -->
97
+ <script type="module">
98
+ import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
99
+
100
+ function getMermaidTheme() {
101
+ const theme = document.documentElement.getAttribute('data-theme');
102
+ const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
103
+ const isDark = theme === 'dark' || (!theme && prefersDark);
104
+ return isDark ? 'dark' : 'neutral';
105
+ }
106
+
107
+ mermaid.initialize({
108
+ startOnLoad: true,
109
+ theme: getMermaidTheme()
110
+ });
111
+
112
+ // Re-render mermaid diagrams when theme changes
113
+ window.reinitMermaid = async function() {
114
+ mermaid.initialize({ startOnLoad: false, theme: getMermaidTheme() });
115
+ const diagrams = document.querySelectorAll('.mermaid');
116
+ for (const el of diagrams) {
117
+ const code = el.getAttribute('data-mermaid-source');
118
+ if (code) {
119
+ el.innerHTML = code;
120
+ el.removeAttribute('data-processed');
121
+ }
122
+ }
123
+ await mermaid.run({ nodes: diagrams });
124
+ };
125
+ </script>
126
+ <script>
127
+ function toggleTheme() {
128
+ const html = document.documentElement;
129
+ const current = html.getAttribute('data-theme');
130
+ const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
131
+
132
+ let next;
133
+ if (current === 'dark') {
134
+ next = 'light';
135
+ } else if (current === 'light') {
136
+ next = 'dark';
137
+ } else {
138
+ // No explicit theme set, toggle from system preference
139
+ next = prefersDark ? 'light' : 'dark';
140
+ }
141
+
142
+ html.setAttribute('data-theme', next);
143
+ localStorage.setItem('theme', next);
144
+
145
+ // Switch Prism theme
146
+ const prismLight = document.getElementById('prism-light');
147
+ const prismDark = document.getElementById('prism-dark');
148
+ if (next === 'dark') {
149
+ prismLight?.setAttribute('disabled', '');
150
+ prismDark?.removeAttribute('disabled');
151
+ } else {
152
+ prismLight?.removeAttribute('disabled');
153
+ prismDark?.setAttribute('disabled', '');
154
+ }
155
+
156
+ // Re-render mermaid diagrams with new theme
157
+ if (window.reinitMermaid) {
158
+ window.reinitMermaid();
159
+ }
160
+ }
161
+
162
+ // Copy code button
163
+ document.querySelectorAll('.prose pre code').forEach(block => {
164
+ const button = document.createElement('button');
165
+ button.className = 'copy-button';
166
+ button.textContent = 'Copy';
167
+ button.onclick = async () => {
168
+ await navigator.clipboard.writeText(block.textContent);
169
+ button.textContent = 'Copied!';
170
+ setTimeout(() => button.textContent = 'Copy', 2000);
171
+ };
172
+ block.parentElement.appendChild(button);
173
+ });
174
+
175
+ // Mobile nav toggle
176
+ function toggleNav() {
177
+ document.querySelector('.sidebar').classList.toggle('open');
178
+ }
179
+
180
+ // Close nav when clicking outside on mobile
181
+ document.addEventListener('click', (e) => {
182
+ const sidebar = document.querySelector('.sidebar');
183
+ const toggle = document.querySelector('.nav-toggle');
184
+ if (sidebar.classList.contains('open') &&
185
+ !sidebar.contains(e.target) &&
186
+ !toggle.contains(e.target)) {
187
+ sidebar.classList.remove('open');
188
+ }
189
+ });
190
+ </script>
191
+ {{HOT_RELOAD_SCRIPT}}
192
+ </body>
193
+ </html>