anentrypoint-design 0.0.121 → 0.0.124

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 (202) hide show
  1. package/README.md +253 -253
  2. package/app-shell.css +931 -594
  3. package/colors_and_type.css +226 -226
  4. package/community.css +817 -1222
  5. package/dist/247420.css +2202 -2084
  6. package/dist/247420.js +13 -13
  7. package/package.json +80 -80
  8. package/src/bootstrap.js +25 -25
  9. package/src/components/chat.js +199 -199
  10. package/src/components/community.js +190 -208
  11. package/src/components/content.js +269 -269
  12. package/src/components/editor-primitives.js +100 -0
  13. package/src/components/files-modals.js +107 -107
  14. package/src/components/files.js +118 -118
  15. package/src/components/freddie/helpers.js +50 -50
  16. package/src/components/freddie.js +33 -33
  17. package/src/components/shell.js +117 -117
  18. package/src/components/theme-toggle.js +70 -70
  19. package/src/components.js +59 -57
  20. package/src/debug.js +30 -30
  21. package/src/deck-stage.js +21 -21
  22. package/src/highlight.js +65 -32
  23. package/src/index.js +86 -86
  24. package/src/kits/os/about-app.js +52 -52
  25. package/src/kits/os/app-panes.css +152 -152
  26. package/src/kits/os/browser-app.js +58 -58
  27. package/src/kits/os/files-app.js +44 -44
  28. package/src/kits/os/freddie/helpers.js +59 -59
  29. package/src/kits/os/freddie/pages-chat.js +143 -143
  30. package/src/kits/os/freddie/pages-core.js +101 -101
  31. package/src/kits/os/freddie/pages-os.js +51 -51
  32. package/src/kits/os/freddie/pages-tools.js +183 -183
  33. package/src/kits/os/freddie/routes.js +24 -24
  34. package/src/kits/os/freddie-dashboard.css +51 -51
  35. package/src/kits/os/freddie-dashboard.js +101 -101
  36. package/src/kits/os/icons.js +17 -17
  37. package/src/kits/os/index.js +17 -17
  38. package/src/kits/os/launcher.css +61 -61
  39. package/src/kits/os/launcher.js +79 -79
  40. package/src/kits/os/monitor-app.js +34 -34
  41. package/src/kits/os/shell.js +214 -214
  42. package/src/kits/os/terminal-app.js +45 -45
  43. package/src/kits/os/theme.css +450 -450
  44. package/src/kits/os/validate.css +19 -19
  45. package/src/kits/os/validator-app.js +55 -55
  46. package/src/kits/os/wm.css +115 -115
  47. package/src/kits/os/wm.js +111 -111
  48. package/src/markdown.js +39 -39
  49. package/src/motion.js +35 -35
  50. package/src/page-html.js +196 -196
  51. package/src/styles.js +25 -25
  52. package/src/theme.js +99 -99
  53. package/src/web-components/ds-chat.js +116 -116
  54. package/dist/.nojekyll +0 -0
  55. package/dist/app-shell.css +0 -594
  56. package/dist/colors_and_type.css +0 -197
  57. package/dist/favicon.svg +0 -1
  58. package/dist/index.html +0 -308
  59. package/dist/preview/buttons.html +0 -28
  60. package/dist/preview/colors-core.html +0 -45
  61. package/dist/preview/colors-lore.html +0 -28
  62. package/dist/preview/colors-semantic.html +0 -34
  63. package/dist/preview/dateline.html +0 -19
  64. package/dist/preview/dropzone.html +0 -30
  65. package/dist/preview/file-grid.html +0 -19
  66. package/dist/preview/file-row.html +0 -20
  67. package/dist/preview/file-toolbar.html +0 -40
  68. package/dist/preview/file-viewer.html +0 -31
  69. package/dist/preview/header.html +0 -24
  70. package/dist/preview/icons-unicode.html +0 -26
  71. package/dist/preview/index-row.html +0 -25
  72. package/dist/preview/inputs.html +0 -22
  73. package/dist/preview/manifesto.html +0 -52
  74. package/dist/preview/motion-default.js +0 -106
  75. package/dist/preview/rules.html +0 -16
  76. package/dist/preview/spacing.html +0 -18
  77. package/dist/preview/stamps-lore.html +0 -20
  78. package/dist/preview/stamps.html +0 -14
  79. package/dist/preview/theme-ink.html +0 -15
  80. package/dist/preview/type-display.html +0 -16
  81. package/dist/preview/type-mono.html +0 -15
  82. package/dist/preview/type-prose.html +0 -11
  83. package/dist/preview/type-scale.html +0 -20
  84. package/dist/preview/wordmarks.html +0 -28
  85. package/dist/robots.txt +0 -8
  86. package/dist/site/content/globals/navigation.yaml +0 -5
  87. package/dist/site/content/globals/site.yaml +0 -16
  88. package/dist/site/content/pages/freddie.yaml +0 -88
  89. package/dist/site/content/pages/home.yaml +0 -190
  90. package/dist/site/theme.mjs +0 -368
  91. package/dist/sitemap.xml +0 -31
  92. package/dist/slides/deck-stage-overlay.js +0 -63
  93. package/dist/slides/deck-stage-state.js +0 -81
  94. package/dist/slides/deck-stage-style.js +0 -117
  95. package/dist/slides/deck-stage.js +0 -159
  96. package/dist/slides/index.html +0 -276
  97. package/dist/src/bootstrap.js +0 -25
  98. package/dist/src/components/chat.js +0 -199
  99. package/dist/src/components/community.js +0 -167
  100. package/dist/src/components/content.js +0 -213
  101. package/dist/src/components/files-modals.js +0 -107
  102. package/dist/src/components/files.js +0 -118
  103. package/dist/src/components/freddie/helpers.js +0 -50
  104. package/dist/src/components/freddie.js +0 -33
  105. package/dist/src/components/shell.js +0 -117
  106. package/dist/src/components/theme-toggle.js +0 -70
  107. package/dist/src/components.js +0 -52
  108. package/dist/src/debug.js +0 -30
  109. package/dist/src/deck-stage.js +0 -21
  110. package/dist/src/highlight.js +0 -32
  111. package/dist/src/index.js +0 -86
  112. package/dist/src/kits/os/about-app.js +0 -52
  113. package/dist/src/kits/os/app-panes.css +0 -152
  114. package/dist/src/kits/os/browser-app.js +0 -58
  115. package/dist/src/kits/os/files-app.js +0 -44
  116. package/dist/src/kits/os/freddie/helpers.js +0 -59
  117. package/dist/src/kits/os/freddie/pages-chat.js +0 -143
  118. package/dist/src/kits/os/freddie/pages-core.js +0 -101
  119. package/dist/src/kits/os/freddie/pages-os.js +0 -51
  120. package/dist/src/kits/os/freddie/pages-tools.js +0 -183
  121. package/dist/src/kits/os/freddie/routes.js +0 -24
  122. package/dist/src/kits/os/freddie-dashboard.css +0 -51
  123. package/dist/src/kits/os/freddie-dashboard.js +0 -101
  124. package/dist/src/kits/os/icons.js +0 -17
  125. package/dist/src/kits/os/index.js +0 -5
  126. package/dist/src/kits/os/launcher.css +0 -61
  127. package/dist/src/kits/os/launcher.js +0 -79
  128. package/dist/src/kits/os/monitor-app.js +0 -34
  129. package/dist/src/kits/os/shell.js +0 -214
  130. package/dist/src/kits/os/terminal-app.js +0 -45
  131. package/dist/src/kits/os/theme.css +0 -412
  132. package/dist/src/kits/os/validate.css +0 -19
  133. package/dist/src/kits/os/validator-app.js +0 -55
  134. package/dist/src/kits/os/wm.css +0 -115
  135. package/dist/src/kits/os/wm.js +0 -111
  136. package/dist/src/markdown.js +0 -39
  137. package/dist/src/motion.js +0 -35
  138. package/dist/src/page-html.js +0 -196
  139. package/dist/src/styles.js +0 -25
  140. package/dist/src/theme.js +0 -99
  141. package/dist/src/web-components/ds-chat.js +0 -45
  142. package/dist/ui_kits/aicat/README.md +0 -7
  143. package/dist/ui_kits/aicat/app.js +0 -156
  144. package/dist/ui_kits/aicat/index.html +0 -26
  145. package/dist/ui_kits/aicat/sample-square.png +0 -0
  146. package/dist/ui_kits/aicat/sample-svg.svg +0 -1
  147. package/dist/ui_kits/aicat/sample.pdf +0 -32
  148. package/dist/ui_kits/blog/README.md +0 -3
  149. package/dist/ui_kits/blog/index.html +0 -90
  150. package/dist/ui_kits/chat/README.md +0 -5
  151. package/dist/ui_kits/chat/app.js +0 -110
  152. package/dist/ui_kits/chat/index.html +0 -26
  153. package/dist/ui_kits/chat/sample-square.png +0 -0
  154. package/dist/ui_kits/chat/sample-svg.svg +0 -1
  155. package/dist/ui_kits/chat/sample.pdf +0 -32
  156. package/dist/ui_kits/community/app.js +0 -134
  157. package/dist/ui_kits/community/index.html +0 -24
  158. package/dist/ui_kits/dashboard/app.js +0 -92
  159. package/dist/ui_kits/dashboard/index.html +0 -26
  160. package/dist/ui_kits/docs/README.md +0 -3
  161. package/dist/ui_kits/docs/index.html +0 -123
  162. package/dist/ui_kits/error_404/app.js +0 -56
  163. package/dist/ui_kits/error_404/index.html +0 -26
  164. package/dist/ui_kits/file_browser/README.md +0 -48
  165. package/dist/ui_kits/file_browser/app.js +0 -231
  166. package/dist/ui_kits/file_browser/index.html +0 -33
  167. package/dist/ui_kits/gallery/app.js +0 -121
  168. package/dist/ui_kits/gallery/index.html +0 -26
  169. package/dist/ui_kits/homepage/README.md +0 -7
  170. package/dist/ui_kits/homepage/app.js +0 -167
  171. package/dist/ui_kits/homepage/index.html +0 -46
  172. package/dist/ui_kits/project_page/README.md +0 -3
  173. package/dist/ui_kits/project_page/app.js +0 -154
  174. package/dist/ui_kits/project_page/index.html +0 -45
  175. package/dist/ui_kits/search/app.js +0 -107
  176. package/dist/ui_kits/search/index.html +0 -26
  177. package/dist/ui_kits/settings/app.js +0 -133
  178. package/dist/ui_kits/settings/index.html +0 -26
  179. package/dist/ui_kits/signin/app.js +0 -115
  180. package/dist/ui_kits/signin/index.html +0 -26
  181. package/dist/ui_kits/slide_deck/app.js +0 -174
  182. package/dist/ui_kits/slide_deck/index.html +0 -26
  183. package/dist/ui_kits/system_primer/app.js +0 -152
  184. package/dist/ui_kits/system_primer/index.html +0 -26
  185. package/dist/ui_kits/terminal/app.js +0 -150
  186. package/dist/ui_kits/terminal/index.html +0 -26
  187. package/dist/vendor/webjsx/applyDiff.js +0 -182
  188. package/dist/vendor/webjsx/attributes.js +0 -154
  189. package/dist/vendor/webjsx/constants.js +0 -4
  190. package/dist/vendor/webjsx/createDOMElement.js +0 -52
  191. package/dist/vendor/webjsx/createElement.js +0 -75
  192. package/dist/vendor/webjsx/elementTags.js +0 -115
  193. package/dist/vendor/webjsx/factory.js +0 -6
  194. package/dist/vendor/webjsx/index.js +0 -6
  195. package/dist/vendor/webjsx/jsx-dev-runtime.js +0 -2
  196. package/dist/vendor/webjsx/jsx-runtime.js +0 -30
  197. package/dist/vendor/webjsx/jsx.js +0 -2
  198. package/dist/vendor/webjsx/package.json +0 -39
  199. package/dist/vendor/webjsx/renderSuspension.js +0 -25
  200. package/dist/vendor/webjsx/types.js +0 -5
  201. package/dist/vendor/webjsx/utils.js +0 -84
  202. package/src/components/overlays.js +0 -151
@@ -1,107 +1,107 @@
1
- // File modals — matches upstream signatures + class names.
2
-
3
- import * as webjsx from '../../vendor/webjsx/index.js';
4
- import { Btn } from './shell.js';
5
- import { fileGlyph, fmtFileSize } from './files.js';
6
- const h = webjsx.createElement;
7
-
8
- function Backdrop({ onClose, children, kind = '' } = {}) {
9
- return h('div', {
10
- class: 'ds-modal-backdrop',
11
- onclick: (e) => { if (e.target === e.currentTarget && onClose) onClose(); }
12
- },
13
- h('div', { class: 'ds-modal' + (kind ? ' ds-modal-' + kind : '') }, ...(Array.isArray(children) ? children : [children]))
14
- );
15
- }
16
-
17
- export function ConfirmDialog({ title = 'confirm', message, confirmLabel = 'confirm', cancelLabel = 'cancel', destructive, onConfirm, onCancel } = {}) {
18
- return Backdrop({
19
- onClose: onCancel,
20
- kind: 'small',
21
- children: [
22
- h('div', { class: 'ds-modal-head' }, title),
23
- h('div', { class: 'ds-modal-body' }, message || ''),
24
- h('div', { class: 'ds-modal-actions' },
25
- Btn({ onClick: onCancel, children: cancelLabel }),
26
- h('button', {
27
- class: destructive ? 'btn-primary danger' : 'btn-primary',
28
- onclick: onConfirm
29
- }, confirmLabel)
30
- )
31
- ]
32
- });
33
- }
34
-
35
- export function PromptDialog({ title = 'name', value = '', placeholder = '', confirmLabel = 'ok', cancelLabel = 'cancel', onConfirm, onCancel, onInput } = {}) {
36
- return Backdrop({
37
- onClose: onCancel,
38
- kind: 'small',
39
- children: [
40
- h('div', { class: 'ds-modal-head' }, title),
41
- h('div', { class: 'ds-modal-body' },
42
- h('input', {
43
- class: 'input ds-modal-input',
44
- type: 'text',
45
- value,
46
- placeholder,
47
- autofocus: true,
48
- oninput: (e) => onInput && onInput(e.target.value),
49
- onkeydown: (e) => {
50
- if (e.key === 'Enter') { e.preventDefault(); onConfirm && onConfirm(e.target.value); }
51
- if (e.key === 'Escape') { e.preventDefault(); onCancel && onCancel(); }
52
- }
53
- })
54
- ),
55
- h('div', { class: 'ds-modal-actions' },
56
- Btn({ onClick: onCancel, children: cancelLabel }),
57
- h('button', { class: 'btn-primary', onclick: () => onConfirm && onConfirm(value) }, confirmLabel)
58
- )
59
- ]
60
- });
61
- }
62
-
63
- export function FilePreviewMedia({ src, type = 'other', name } = {}) {
64
- if (type === 'image') return h('img', { class: 'ds-preview-media', src, alt: name || '' });
65
- if (type === 'video') return h('video', { class: 'ds-preview-media', src, controls: true });
66
- if (type === 'audio') return h('audio', { class: 'ds-preview-audio', src, controls: true });
67
- return h('div', { class: 'ds-preview-fallback' },
68
- h('span', { class: 'ds-preview-glyph' }, fileGlyph(type)),
69
- h('span', {}, 'no inline preview for ' + (type || 'this file'))
70
- );
71
- }
72
-
73
- export function FilePreviewCode({ content = '', lang } = {}) {
74
- return h('pre', { class: 'ds-preview-code' + (lang ? ' lang-' + lang : '') },
75
- h('code', { class: lang ? 'language-' + lang : '' }, content)
76
- );
77
- }
78
-
79
- export function FilePreviewText({ content = '', truncated } = {}) {
80
- return h('pre', { class: 'ds-preview-text' },
81
- h('code', {}, content),
82
- truncated ? h('div', { class: 'ds-preview-truncated' }, '… (truncated)') : null
83
- );
84
- }
85
-
86
- export function FileViewer({ file, body, onClose, onAction } = {}) {
87
- if (!file) return null;
88
- const meta = [file.type, file.size != null ? fmtFileSize(file.size) : null, file.modified || null]
89
- .filter(Boolean).join(' · ');
90
- return Backdrop({
91
- onClose,
92
- kind: 'preview',
93
- children: [
94
- h('div', { class: 'ds-modal-head ds-preview-head', 'data-file-type': file.type || 'other' },
95
- h('span', { class: 'ds-preview-name' }, file.name || ''),
96
- h('span', { class: 'ds-preview-meta' }, meta),
97
- h('span', { class: 'ds-preview-actions' },
98
- onAction ? h('button', { class: 'ds-file-act', title: 'download', onclick: () => onAction('download') }, '↓') : null,
99
- h('button', { class: 'ds-file-act', title: 'close', onclick: onClose }, '✕')
100
- )
101
- ),
102
- h('div', { class: 'ds-preview-body', 'data-file-type': file.type || 'other' },
103
- ...(Array.isArray(body) ? body : [body])
104
- )
105
- ]
106
- });
107
- }
1
+ // File modals — matches upstream signatures + class names.
2
+
3
+ import * as webjsx from '../../vendor/webjsx/index.js';
4
+ import { Btn } from './shell.js';
5
+ import { fileGlyph, fmtFileSize } from './files.js';
6
+ const h = webjsx.createElement;
7
+
8
+ function Backdrop({ onClose, children, kind = '' } = {}) {
9
+ return h('div', {
10
+ class: 'ds-modal-backdrop',
11
+ onclick: (e) => { if (e.target === e.currentTarget && onClose) onClose(); }
12
+ },
13
+ h('div', { class: 'ds-modal' + (kind ? ' ds-modal-' + kind : '') }, ...(Array.isArray(children) ? children : [children]))
14
+ );
15
+ }
16
+
17
+ export function ConfirmDialog({ title = 'confirm', message, confirmLabel = 'confirm', cancelLabel = 'cancel', destructive, onConfirm, onCancel } = {}) {
18
+ return Backdrop({
19
+ onClose: onCancel,
20
+ kind: 'small',
21
+ children: [
22
+ h('div', { class: 'ds-modal-head' }, title),
23
+ h('div', { class: 'ds-modal-body' }, message || ''),
24
+ h('div', { class: 'ds-modal-actions' },
25
+ Btn({ onClick: onCancel, children: cancelLabel }),
26
+ h('button', {
27
+ class: destructive ? 'btn-primary danger' : 'btn-primary',
28
+ onclick: onConfirm
29
+ }, confirmLabel)
30
+ )
31
+ ]
32
+ });
33
+ }
34
+
35
+ export function PromptDialog({ title = 'name', value = '', placeholder = '', confirmLabel = 'ok', cancelLabel = 'cancel', onConfirm, onCancel, onInput } = {}) {
36
+ return Backdrop({
37
+ onClose: onCancel,
38
+ kind: 'small',
39
+ children: [
40
+ h('div', { class: 'ds-modal-head' }, title),
41
+ h('div', { class: 'ds-modal-body' },
42
+ h('input', {
43
+ class: 'input ds-modal-input',
44
+ type: 'text',
45
+ value,
46
+ placeholder,
47
+ autofocus: true,
48
+ oninput: (e) => onInput && onInput(e.target.value),
49
+ onkeydown: (e) => {
50
+ if (e.key === 'Enter') { e.preventDefault(); onConfirm && onConfirm(e.target.value); }
51
+ if (e.key === 'Escape') { e.preventDefault(); onCancel && onCancel(); }
52
+ }
53
+ })
54
+ ),
55
+ h('div', { class: 'ds-modal-actions' },
56
+ Btn({ onClick: onCancel, children: cancelLabel }),
57
+ h('button', { class: 'btn-primary', onclick: () => onConfirm && onConfirm(value) }, confirmLabel)
58
+ )
59
+ ]
60
+ });
61
+ }
62
+
63
+ export function FilePreviewMedia({ src, type = 'other', name } = {}) {
64
+ if (type === 'image') return h('img', { class: 'ds-preview-media', src, alt: name || '' });
65
+ if (type === 'video') return h('video', { class: 'ds-preview-media', src, controls: true });
66
+ if (type === 'audio') return h('audio', { class: 'ds-preview-audio', src, controls: true });
67
+ return h('div', { class: 'ds-preview-fallback' },
68
+ h('span', { class: 'ds-preview-glyph' }, fileGlyph(type)),
69
+ h('span', {}, 'no inline preview for ' + (type || 'this file'))
70
+ );
71
+ }
72
+
73
+ export function FilePreviewCode({ content = '', lang } = {}) {
74
+ return h('pre', { class: 'ds-preview-code' + (lang ? ' lang-' + lang : '') },
75
+ h('code', { class: lang ? 'language-' + lang : '' }, content)
76
+ );
77
+ }
78
+
79
+ export function FilePreviewText({ content = '', truncated } = {}) {
80
+ return h('pre', { class: 'ds-preview-text' },
81
+ h('code', {}, content),
82
+ truncated ? h('div', { class: 'ds-preview-truncated' }, '… (truncated)') : null
83
+ );
84
+ }
85
+
86
+ export function FileViewer({ file, body, onClose, onAction } = {}) {
87
+ if (!file) return null;
88
+ const meta = [file.type, file.size != null ? fmtFileSize(file.size) : null, file.modified || null]
89
+ .filter(Boolean).join(' · ');
90
+ return Backdrop({
91
+ onClose,
92
+ kind: 'preview',
93
+ children: [
94
+ h('div', { class: 'ds-modal-head ds-preview-head', 'data-file-type': file.type || 'other' },
95
+ h('span', { class: 'ds-preview-name' }, file.name || ''),
96
+ h('span', { class: 'ds-preview-meta' }, meta),
97
+ h('span', { class: 'ds-preview-actions' },
98
+ onAction ? h('button', { class: 'ds-file-act', title: 'download', onclick: () => onAction('download') }, '↓') : null,
99
+ h('button', { class: 'ds-file-act', title: 'close', onclick: onClose }, '✕')
100
+ )
101
+ ),
102
+ h('div', { class: 'ds-preview-body', 'data-file-type': file.type || 'other' },
103
+ ...(Array.isArray(body) ? body : [body])
104
+ )
105
+ ]
106
+ });
107
+ }
@@ -1,118 +1,118 @@
1
- // File primitives — matches upstream signatures.
2
-
3
- import * as webjsx from '../../vendor/webjsx/index.js';
4
- import { Btn } from './shell.js';
5
- const h = webjsx.createElement;
6
-
7
- const FILE_TYPES = ['dir', 'image', 'video', 'audio', 'code', 'text', 'archive', 'document', 'symlink', 'other'];
8
- const TYPE_GLYPH = {
9
- dir: '▣', image: '◰', video: '▰', audio: '◎', code: '⌘',
10
- text: '§', archive: '◐', document: '▢', symlink: '↗', other: '◌'
11
- };
12
-
13
- export function fileGlyph(type) {
14
- return TYPE_GLYPH[type] || TYPE_GLYPH.other;
15
- }
16
-
17
- export function fmtFileSize(bytes) {
18
- if (bytes == null || bytes === 0) return '—';
19
- const u = ['B', 'KB', 'MB', 'GB', 'TB'];
20
- let i = 0, n = bytes;
21
- while (n >= 1024 && i < u.length - 1) { n /= 1024; i++; }
22
- return n.toFixed(i === 0 ? 0 : 1) + ' ' + u[i];
23
- }
24
-
25
- export function FileIcon({ type = 'other' } = {}) {
26
- return h('span', { class: 'ds-file-icon', 'data-file-type': type }, fileGlyph(type));
27
- }
28
-
29
- export function FileRow({ name, type = 'other', size, modified, code, onOpen, onAction, active, key } = {}) {
30
- const meta = [type === 'dir' ? null : fmtFileSize(size), modified || null].filter(Boolean).join(' · ');
31
- return h('div', {
32
- key,
33
- class: 'ds-file-row row' + (active ? ' active' : ''),
34
- 'data-file-type': type,
35
- onclick: onOpen
36
- },
37
- code != null ? h('span', { class: 'code' }, code) : null,
38
- FileIcon({ type }),
39
- h('span', { class: 'title' }, name),
40
- h('span', { class: 'ds-file-meta meta' }, meta || '—'),
41
- onAction ? h('span', { class: 'ds-file-actions', onclick: (e) => e.stopPropagation() },
42
- h('button', { class: 'ds-file-act', title: 'download', onclick: () => onAction('download') }, '↓'),
43
- h('button', { class: 'ds-file-act', title: 'rename', onclick: () => onAction('rename') }, '✎'),
44
- h('button', { class: 'ds-file-act ds-file-act-warn', title: 'delete', onclick: () => onAction('delete') }, '✕')
45
- ) : null
46
- );
47
- }
48
-
49
- export function FileGrid({ files = [], onOpen, onAction, emptyText = 'no files here yet' } = {}) {
50
- if (!files.length) return EmptyState({ text: emptyText });
51
- return h('div', { class: 'ds-file-grid' },
52
- ...files.map((f, i) => FileRow({
53
- key: f.path || f.name + i,
54
- name: f.name, type: f.type, size: f.size, modified: f.modified, code: f.code, active: f.active,
55
- onOpen: onOpen ? () => onOpen(f) : null,
56
- onAction: onAction ? (act) => onAction(act, f) : null
57
- }))
58
- );
59
- }
60
-
61
- export function FileToolbar({ left = [], right = [] } = {}) {
62
- return h('div', { class: 'ds-file-toolbar' },
63
- h('div', { class: 'ds-file-toolbar-left' }, ...left),
64
- h('div', { class: 'ds-file-toolbar-right' }, ...right)
65
- );
66
- }
67
-
68
- export function DropZone({ children, dragover, onDrop, onDragOver, onDragLeave, label = 'drop files here', onPick } = {}) {
69
- return h('div', {
70
- class: 'ds-dropzone' + (dragover ? ' dragover' : ''),
71
- ondragover: (e) => { e.preventDefault(); onDragOver && onDragOver(e); },
72
- ondragleave: (e) => { onDragLeave && onDragLeave(e); },
73
- ondrop: (e) => { e.preventDefault(); onDrop && onDrop(e.dataTransfer.files); }
74
- },
75
- h('div', { class: 'ds-dropzone-inner' },
76
- h('span', { class: 'ds-dropzone-glyph' }, '⇪'),
77
- h('span', { class: 'ds-dropzone-label' }, label),
78
- onPick ? Btn({ onClick: onPick, children: 'pick files' }) : null
79
- ),
80
- ...(Array.isArray(children) ? children : children ? [children] : [])
81
- );
82
- }
83
-
84
- export function UploadProgress({ items = [] } = {}) {
85
- if (!items.length) return null;
86
- return h('div', { class: 'ds-upload-progress' },
87
- ...items.map((it, i) => h('div', {
88
- key: it.name + i,
89
- class: 'ds-upload-item' + (it.done ? ' done' : '') + (it.error ? ' error' : '')
90
- },
91
- h('span', { class: 'ds-upload-name' }, it.name),
92
- h('span', { class: 'ds-upload-bar' },
93
- h('span', { class: 'ds-upload-fill', 'data-pct': String(Math.max(0, Math.min(100, it.pct || 0))) })
94
- ),
95
- h('span', { class: 'ds-upload-pct' }, (it.error ? 'err' : (it.done ? 'ok' : (it.pct || 0) + '%')))
96
- ))
97
- );
98
- }
99
-
100
- export function EmptyState({ text = 'nothing here', glyph = '◌' } = {}) {
101
- return h('div', { class: 'ds-file-empty' },
102
- h('span', { class: 'ds-file-empty-glyph' }, glyph),
103
- h('span', { class: 'ds-file-empty-text' }, text)
104
- );
105
- }
106
-
107
- export function BreadcrumbPath({ segments = [], onNav, root = 'root' } = {}) {
108
- const parts = [h('button', { key: 'root', class: 'ds-crumb-seg', onclick: () => onNav && onNav(0) }, root)];
109
- segments.forEach((seg, i) => {
110
- parts.push(h('span', { key: 'sep' + i, class: 'ds-crumb-sep' }, '›'));
111
- parts.push(h('button', {
112
- key: 'seg' + i,
113
- class: 'ds-crumb-seg' + (i === segments.length - 1 ? ' leaf' : ''),
114
- onclick: () => onNav && onNav(i + 1)
115
- }, seg));
116
- });
117
- return h('div', { class: 'ds-crumb-path' }, ...parts);
118
- }
1
+ // File primitives — matches upstream signatures.
2
+
3
+ import * as webjsx from '../../vendor/webjsx/index.js';
4
+ import { Btn } from './shell.js';
5
+ const h = webjsx.createElement;
6
+
7
+ const FILE_TYPES = ['dir', 'image', 'video', 'audio', 'code', 'text', 'archive', 'document', 'symlink', 'other'];
8
+ const TYPE_GLYPH = {
9
+ dir: '▣', image: '◰', video: '▰', audio: '◎', code: '⌘',
10
+ text: '§', archive: '◐', document: '▢', symlink: '↗', other: '◌'
11
+ };
12
+
13
+ export function fileGlyph(type) {
14
+ return TYPE_GLYPH[type] || TYPE_GLYPH.other;
15
+ }
16
+
17
+ export function fmtFileSize(bytes) {
18
+ if (bytes == null || bytes === 0) return '—';
19
+ const u = ['B', 'KB', 'MB', 'GB', 'TB'];
20
+ let i = 0, n = bytes;
21
+ while (n >= 1024 && i < u.length - 1) { n /= 1024; i++; }
22
+ return n.toFixed(i === 0 ? 0 : 1) + ' ' + u[i];
23
+ }
24
+
25
+ export function FileIcon({ type = 'other' } = {}) {
26
+ return h('span', { class: 'ds-file-icon', 'data-file-type': type }, fileGlyph(type));
27
+ }
28
+
29
+ export function FileRow({ name, type = 'other', size, modified, code, onOpen, onAction, active, key } = {}) {
30
+ const meta = [type === 'dir' ? null : fmtFileSize(size), modified || null].filter(Boolean).join(' · ');
31
+ return h('div', {
32
+ key,
33
+ class: 'ds-file-row row' + (active ? ' active' : ''),
34
+ 'data-file-type': type,
35
+ onclick: onOpen
36
+ },
37
+ code != null ? h('span', { class: 'code' }, code) : null,
38
+ FileIcon({ type }),
39
+ h('span', { class: 'title' }, name),
40
+ h('span', { class: 'ds-file-meta meta' }, meta || '—'),
41
+ onAction ? h('span', { class: 'ds-file-actions', onclick: (e) => e.stopPropagation() },
42
+ h('button', { class: 'ds-file-act', title: 'download', onclick: () => onAction('download') }, '↓'),
43
+ h('button', { class: 'ds-file-act', title: 'rename', onclick: () => onAction('rename') }, '✎'),
44
+ h('button', { class: 'ds-file-act ds-file-act-warn', title: 'delete', onclick: () => onAction('delete') }, '✕')
45
+ ) : null
46
+ );
47
+ }
48
+
49
+ export function FileGrid({ files = [], onOpen, onAction, emptyText = 'no files here yet' } = {}) {
50
+ if (!files.length) return EmptyState({ text: emptyText });
51
+ return h('div', { class: 'ds-file-grid' },
52
+ ...files.map((f, i) => FileRow({
53
+ key: f.path || f.name + i,
54
+ name: f.name, type: f.type, size: f.size, modified: f.modified, code: f.code, active: f.active,
55
+ onOpen: onOpen ? () => onOpen(f) : null,
56
+ onAction: onAction ? (act) => onAction(act, f) : null
57
+ }))
58
+ );
59
+ }
60
+
61
+ export function FileToolbar({ left = [], right = [] } = {}) {
62
+ return h('div', { class: 'ds-file-toolbar' },
63
+ h('div', { class: 'ds-file-toolbar-left' }, ...left),
64
+ h('div', { class: 'ds-file-toolbar-right' }, ...right)
65
+ );
66
+ }
67
+
68
+ export function DropZone({ children, dragover, onDrop, onDragOver, onDragLeave, label = 'drop files here', onPick } = {}) {
69
+ return h('div', {
70
+ class: 'ds-dropzone' + (dragover ? ' dragover' : ''),
71
+ ondragover: (e) => { e.preventDefault(); onDragOver && onDragOver(e); },
72
+ ondragleave: (e) => { onDragLeave && onDragLeave(e); },
73
+ ondrop: (e) => { e.preventDefault(); onDrop && onDrop(e.dataTransfer.files); }
74
+ },
75
+ h('div', { class: 'ds-dropzone-inner' },
76
+ h('span', { class: 'ds-dropzone-glyph' }, '⇪'),
77
+ h('span', { class: 'ds-dropzone-label' }, label),
78
+ onPick ? Btn({ onClick: onPick, children: 'pick files' }) : null
79
+ ),
80
+ ...(Array.isArray(children) ? children : children ? [children] : [])
81
+ );
82
+ }
83
+
84
+ export function UploadProgress({ items = [] } = {}) {
85
+ if (!items.length) return null;
86
+ return h('div', { class: 'ds-upload-progress' },
87
+ ...items.map((it, i) => h('div', {
88
+ key: it.name + i,
89
+ class: 'ds-upload-item' + (it.done ? ' done' : '') + (it.error ? ' error' : '')
90
+ },
91
+ h('span', { class: 'ds-upload-name' }, it.name),
92
+ h('span', { class: 'ds-upload-bar' },
93
+ h('span', { class: 'ds-upload-fill', 'data-pct': String(Math.max(0, Math.min(100, it.pct || 0))) })
94
+ ),
95
+ h('span', { class: 'ds-upload-pct' }, (it.error ? 'err' : (it.done ? 'ok' : (it.pct || 0) + '%')))
96
+ ))
97
+ );
98
+ }
99
+
100
+ export function EmptyState({ text = 'nothing here', glyph = '◌' } = {}) {
101
+ return h('div', { class: 'ds-file-empty' },
102
+ h('span', { class: 'ds-file-empty-glyph' }, glyph),
103
+ h('span', { class: 'ds-file-empty-text' }, text)
104
+ );
105
+ }
106
+
107
+ export function BreadcrumbPath({ segments = [], onNav, root = 'root' } = {}) {
108
+ const parts = [h('button', { key: 'root', class: 'ds-crumb-seg', onclick: () => onNav && onNav(0) }, root)];
109
+ segments.forEach((seg, i) => {
110
+ parts.push(h('span', { key: 'sep' + i, class: 'ds-crumb-sep' }, '›'));
111
+ parts.push(h('button', {
112
+ key: 'seg' + i,
113
+ class: 'ds-crumb-seg' + (i === segments.length - 1 ? ' leaf' : ''),
114
+ onclick: () => onNav && onNav(i + 1)
115
+ }, seg));
116
+ });
117
+ return h('div', { class: 'ds-crumb-path' }, ...parts);
118
+ }
@@ -1,50 +1,50 @@
1
- // Freddie helpers — minimal stubs. Real freddie surfaces ship downstream
2
- // (gm-cc, foph, hermes-fork). The SDK exposes the registry shape and
3
- // localStorage helpers so consumer pages can wire to existing patterns.
4
-
5
- import * as webjsx from '../../../vendor/webjsx/index.js';
6
- const h = webjsx.createElement;
7
-
8
- export function renderPageStub({ id, title }) {
9
- return h('div', { class: 'ds-freddie-stub' },
10
- h('span', { class: 'eyebrow' }, 'freddie · ' + id),
11
- h('h2', {}, title || id),
12
- h('p', { class: 'dim' }, 'this page renderer is a stub. consumers override it on their own freddie router.')
13
- );
14
- }
15
-
16
- const SKILL_LABELS = {
17
- transcribe: 'transcribe',
18
- summarize: 'summarize',
19
- translate: 'translate',
20
- extract: 'extract',
21
- classify: 'classify',
22
- };
23
-
24
- export function skillLabel(slug) {
25
- return SKILL_LABELS[slug] || slug;
26
- }
27
-
28
- const RECENT_KEY = 'ds247420.recent.paths';
29
-
30
- export function getRecentPaths() {
31
- if (typeof localStorage === 'undefined') return [];
32
- try { return JSON.parse(localStorage.getItem(RECENT_KEY) || '[]'); }
33
- catch { return []; }
34
- }
35
-
36
- export function saveRecentPath(path) {
37
- if (typeof localStorage === 'undefined' || !path) return;
38
- const list = getRecentPaths().filter(p => p !== path);
39
- list.unshift(path);
40
- try { localStorage.setItem(RECENT_KEY, JSON.stringify(list.slice(0, 10))); } catch {}
41
- }
42
-
43
- // Helper used by consumers that want to render chat-message arrays with
44
- // our ChatMessage factory but pre-formatted for freddie's data shape.
45
- export function renderChatMessages(messages = [], opts = {}) {
46
- // Import lazily to keep this module light.
47
- return import('../chat.js').then(({ ChatMessage }) =>
48
- messages.map((m, i) => ChatMessage({ ...m, key: m.key != null ? m.key : i, ...opts }))
49
- );
50
- }
1
+ // Freddie helpers — minimal stubs. Real freddie surfaces ship downstream
2
+ // (gm-cc, foph, hermes-fork). The SDK exposes the registry shape and
3
+ // localStorage helpers so consumer pages can wire to existing patterns.
4
+
5
+ import * as webjsx from '../../../vendor/webjsx/index.js';
6
+ const h = webjsx.createElement;
7
+
8
+ export function renderPageStub({ id, title }) {
9
+ return h('div', { class: 'ds-freddie-stub' },
10
+ h('span', { class: 'eyebrow' }, 'freddie · ' + id),
11
+ h('h2', {}, title || id),
12
+ h('p', { class: 'dim' }, 'this page renderer is a stub. consumers override it on their own freddie router.')
13
+ );
14
+ }
15
+
16
+ const SKILL_LABELS = {
17
+ transcribe: 'transcribe',
18
+ summarize: 'summarize',
19
+ translate: 'translate',
20
+ extract: 'extract',
21
+ classify: 'classify',
22
+ };
23
+
24
+ export function skillLabel(slug) {
25
+ return SKILL_LABELS[slug] || slug;
26
+ }
27
+
28
+ const RECENT_KEY = 'ds247420.recent.paths';
29
+
30
+ export function getRecentPaths() {
31
+ if (typeof localStorage === 'undefined') return [];
32
+ try { return JSON.parse(localStorage.getItem(RECENT_KEY) || '[]'); }
33
+ catch { return []; }
34
+ }
35
+
36
+ export function saveRecentPath(path) {
37
+ if (typeof localStorage === 'undefined' || !path) return;
38
+ const list = getRecentPaths().filter(p => p !== path);
39
+ list.unshift(path);
40
+ try { localStorage.setItem(RECENT_KEY, JSON.stringify(list.slice(0, 10))); } catch {}
41
+ }
42
+
43
+ // Helper used by consumers that want to render chat-message arrays with
44
+ // our ChatMessage factory but pre-formatted for freddie's data shape.
45
+ export function renderChatMessages(messages = [], opts = {}) {
46
+ // Import lazily to keep this module light.
47
+ return import('../chat.js').then(({ ChatMessage }) =>
48
+ messages.map((m, i) => ChatMessage({ ...m, key: m.key != null ? m.key : i, ...opts }))
49
+ );
50
+ }
@@ -1,33 +1,33 @@
1
- // Freddie page registry. Matches upstream shape:
2
- // FREDDIE_PAGES is an OBJECT mapping id → page-renderer fn (not an array).
3
- // Per-page renderer functions are stubs by default — consumers (gm-cc,
4
- // foph, hermes-fork, etc.) provide their own page bodies or import the
5
- // richer upstream renderers.
6
-
7
- import { renderPageStub, getRecentPaths, saveRecentPath, skillLabel, renderChatMessages } from './freddie/helpers.js';
8
-
9
- const make = (label) => (props) => renderPageStub({ id: label, ...props });
10
-
11
- export const home = make('home');
12
- export const chat = make('chat');
13
- export const voice = make('voice');
14
- export const sessions = make('sessions');
15
- export const projects = make('projects');
16
- export const agents = make('agents');
17
- export const analytics = make('analytics');
18
- export const models = make('models');
19
- export const cron = make('cron');
20
- export const skills = make('skills');
21
- export const config = make('config');
22
- export const env = make('env');
23
- export const tools = make('tools');
24
- export const batch = make('batch');
25
- export const gateway = make('gateway');
26
- export const chains = make('chains');
27
-
28
- export const FREDDIE_PAGES = {
29
- home, chat, voice, sessions, projects, agents, analytics,
30
- models, cron, skills, config, env, tools, batch, gateway, chains
31
- };
32
-
33
- export { skillLabel, getRecentPaths, saveRecentPath, renderChatMessages };
1
+ // Freddie page registry. Matches upstream shape:
2
+ // FREDDIE_PAGES is an OBJECT mapping id → page-renderer fn (not an array).
3
+ // Per-page renderer functions are stubs by default — consumers (gm-cc,
4
+ // foph, hermes-fork, etc.) provide their own page bodies or import the
5
+ // richer upstream renderers.
6
+
7
+ import { renderPageStub, getRecentPaths, saveRecentPath, skillLabel, renderChatMessages } from './freddie/helpers.js';
8
+
9
+ const make = (label) => (props) => renderPageStub({ id: label, ...props });
10
+
11
+ export const home = make('home');
12
+ export const chat = make('chat');
13
+ export const voice = make('voice');
14
+ export const sessions = make('sessions');
15
+ export const projects = make('projects');
16
+ export const agents = make('agents');
17
+ export const analytics = make('analytics');
18
+ export const models = make('models');
19
+ export const cron = make('cron');
20
+ export const skills = make('skills');
21
+ export const config = make('config');
22
+ export const env = make('env');
23
+ export const tools = make('tools');
24
+ export const batch = make('batch');
25
+ export const gateway = make('gateway');
26
+ export const chains = make('chains');
27
+
28
+ export const FREDDIE_PAGES = {
29
+ home, chat, voice, sessions, projects, agents, analytics,
30
+ models, cron, skills, config, env, tools, batch, gateway, chains
31
+ };
32
+
33
+ export { skillLabel, getRecentPaths, saveRecentPath, renderChatMessages };