anentrypoint-design 0.0.414 → 0.0.416

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 (102) hide show
  1. package/dist/247420.js +62 -12
  2. package/dist/app-shell.css +40 -594
  3. package/dist/colors_and_type.css +607 -47
  4. package/dist/index.html +227 -277
  5. package/dist/preview/buttons.html +39 -28
  6. package/dist/preview/colors-core.html +18 -8
  7. package/dist/preview/colors-lore.html +26 -17
  8. package/dist/preview/colors-semantic.html +24 -18
  9. package/dist/preview/dateline.html +6 -5
  10. package/dist/preview/dropzone.html +4 -3
  11. package/dist/preview/file-grid.html +10 -9
  12. package/dist/preview/file-row.html +14 -13
  13. package/dist/preview/file-toolbar.html +4 -3
  14. package/dist/preview/file-viewer.html +4 -3
  15. package/dist/preview/header.html +26 -24
  16. package/dist/preview/icons-unicode.html +8 -5
  17. package/dist/preview/index-row.html +17 -9
  18. package/dist/preview/inputs.html +4 -3
  19. package/dist/preview/manifesto.html +34 -17
  20. package/dist/preview/motion-default.js +77 -57
  21. package/dist/preview/rules.html +4 -3
  22. package/dist/preview/spacing.html +13 -12
  23. package/dist/preview/stamps-lore.html +5 -4
  24. package/dist/preview/stamps.html +4 -3
  25. package/dist/preview/theme-ink.html +7 -6
  26. package/dist/preview/type-display.html +14 -5
  27. package/dist/preview/type-mono.html +6 -5
  28. package/dist/preview/type-prose.html +12 -10
  29. package/dist/preview/type-scale.html +4 -3
  30. package/dist/preview/wordmarks.html +10 -7
  31. package/dist/site/content/globals/site.yaml +5 -3
  32. package/dist/site/content/pages/freddie.yaml +2 -2
  33. package/dist/site/content/pages/home.yaml +55 -55
  34. package/dist/site/theme.mjs +96 -348
  35. package/dist/slides/index.html +13 -13
  36. package/dist/src/bootstrap.js +10 -1
  37. package/dist/src/components/chat.js +43 -195
  38. package/dist/src/components/community.js +18 -166
  39. package/dist/src/components/content.js +30 -210
  40. package/dist/src/components/files-modals.js +14 -106
  41. package/dist/src/components/files.js +15 -116
  42. package/dist/src/components/freddie/helpers.js +53 -8
  43. package/dist/src/components/freddie.js +35 -25
  44. package/dist/src/components/shell.js +16 -114
  45. package/dist/src/components/theme-toggle.js +69 -25
  46. package/dist/src/components.js +92 -13
  47. package/dist/src/deck-stage.js +6 -4
  48. package/dist/src/highlight.js +51 -7
  49. package/dist/src/index.js +58 -12
  50. package/dist/src/kits/os/about-app.js +2 -3
  51. package/dist/src/kits/os/app-panes.css +46 -70
  52. package/dist/src/kits/os/browser-app.js +28 -1
  53. package/dist/src/kits/os/files-app.js +7 -0
  54. package/dist/src/kits/os/freddie/pages-chat.js +90 -75
  55. package/dist/src/kits/os/freddie/pages-core.js +9 -9
  56. package/dist/src/kits/os/freddie/pages-os.js +8 -8
  57. package/dist/src/kits/os/freddie/pages-tools.js +14 -14
  58. package/dist/src/kits/os/freddie/routes.js +21 -19
  59. package/dist/src/kits/os/freddie-dashboard.css +42 -21
  60. package/dist/src/kits/os/freddie-dashboard.js +6 -6
  61. package/dist/src/kits/os/icons.js +38 -16
  62. package/dist/src/kits/os/index.js +11 -0
  63. package/dist/src/kits/os/launcher.css +26 -10
  64. package/dist/src/kits/os/launcher.js +3 -0
  65. package/dist/src/kits/os/shell.js +72 -108
  66. package/dist/src/kits/os/terminal-app.js +1 -1
  67. package/dist/src/kits/os/theme.css +1330 -150
  68. package/dist/src/kits/os/wm.css +68 -15
  69. package/dist/src/kits/os/wm.js +93 -17
  70. package/dist/src/markdown.js +121 -12
  71. package/dist/src/motion.js +18 -2
  72. package/dist/src/page-html.js +62 -134
  73. package/dist/src/theme.js +106 -13
  74. package/dist/src/web-components/ds-chat.js +80 -9
  75. package/dist/ui_kits/aicat/app.js +54 -6
  76. package/dist/ui_kits/aicat/index.html +2 -0
  77. package/dist/ui_kits/blog/index.html +33 -17
  78. package/dist/ui_kits/chat/app.js +90 -22
  79. package/dist/ui_kits/chat/index.html +2 -0
  80. package/dist/ui_kits/community/app.js +86 -24
  81. package/dist/ui_kits/community/index.html +1 -0
  82. package/dist/ui_kits/dashboard/app.js +123 -34
  83. package/dist/ui_kits/dashboard/index.html +1 -0
  84. package/dist/ui_kits/docs/index.html +43 -33
  85. package/dist/ui_kits/error_404/app.js +78 -23
  86. package/dist/ui_kits/file_browser/README.md +1 -1
  87. package/dist/ui_kits/file_browser/app.js +45 -10
  88. package/dist/ui_kits/file_browser/index.html +1 -0
  89. package/dist/ui_kits/gallery/app.js +130 -51
  90. package/dist/ui_kits/homepage/app.js +156 -138
  91. package/dist/ui_kits/project_page/app.js +142 -125
  92. package/dist/ui_kits/project_page/index.html +2 -1
  93. package/dist/ui_kits/search/app.js +52 -15
  94. package/dist/ui_kits/settings/app.js +166 -39
  95. package/dist/ui_kits/signin/app.js +175 -49
  96. package/dist/ui_kits/signin/index.html +1 -0
  97. package/dist/ui_kits/slide_deck/app.js +83 -49
  98. package/dist/ui_kits/system_primer/app.js +57 -40
  99. package/dist/ui_kits/terminal/app.js +160 -43
  100. package/package.json +1 -1
  101. package/src/page-html/client-script.js +40 -11
  102. package/src/page-html/page-styles.js +22 -1
@@ -1,33 +1,43 @@
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.
1
+ // Freddie page registry — REAL renderers (not stubs). Each page is a
2
+ // self-contained micro-app (see ./freddie/runtime.js) wired to freddie's
3
+ // gui-* plugin HTTP endpoints (/api/*). Consumers mount FREDDIE_PAGES[id]
4
+ // through their thin router; no per-page wiring needed downstream. This is
5
+ // the single maintenance point for freddie GUI per the dynamic-stack contract.
6
+ //
7
+ // This module is a barrel: every page lives in a single-responsibility
8
+ // submodule under ./freddie/, grouped by the surface it drives, and the
9
+ // public export surface here is unchanged — no consumer import needs to move.
6
10
 
7
- import { renderPageStub, getRecentPaths, saveRecentPath, skillLabel, renderChatMessages } from './freddie/helpers.js';
11
+ import { getRecentPaths, saveRecentPath, skillLabel, renderChatMessages } from './freddie/helpers.js';
12
+ import { home, agents, analytics } from './freddie/pages-overview.js';
13
+ import { chat, voice } from './freddie/pages-chat.js';
14
+ import { sessions, projects, git } from './freddie/pages-workspace.js';
15
+ import { models, skills, plugins } from './freddie/pages-models.js';
16
+ import { config, env } from './freddie/pages-config.js';
17
+ import { cron, tools, batch } from './freddie/pages-runners.js';
18
+ import { gateway, chains, machines, health } from './freddie/pages-infra.js';
19
+ import { logs, debug } from './freddie/pages-telemetry.js';
20
+ import { terminal, files, auth, settings, themePage as theme, worktree, sessionTree, notifications } from './freddie/pages-missing.js';
8
21
 
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');
22
+ // ---- registry --------------------------------------------------------------
27
23
 
28
24
  export const FREDDIE_PAGES = {
29
25
  home, chat, voice, sessions, projects, agents, analytics,
30
- models, cron, skills, config, env, tools, batch, gateway, chains
26
+ models, cron, skills, plugins, config, env, tools, batch, gateway, chains,
27
+ machines, health, debug, logs, git,
28
+ terminal, files, auth, settings, theme, worktree,
29
+ 'session-tree': sessionTree,
30
+ notifications,
31
+ };
32
+
33
+ export {
34
+ home, agents, analytics,
35
+ chat, voice,
36
+ sessions, projects, git,
37
+ models, skills, plugins, config, env,
38
+ cron, tools, batch,
39
+ gateway, chains, machines, health,
40
+ logs, debug,
31
41
  };
32
42
 
33
43
  export { skillLabel, getRecentPaths, saveRecentPath, renderChatMessages };
@@ -1,117 +1,19 @@
1
1
  // Chrome: Topbar, Crumb, Side, Status, AppShell, plus primitives
2
2
  // (Brand, Chip, Btn, Glyph, Heading, Lede). Pure factories — props in,
3
3
  // webjsx vnode out. CSS in app-shell.css uses these class names.
4
-
5
- import * as webjsx from '../../vendor/webjsx/index.js';
6
- const h = webjsx.createElement;
7
-
8
- export function Brand({ name = '247420', leaf } = {}) {
9
- return h('span', { class: 'brand' }, name,
10
- leaf ? h('span', { class: 'slash' }, ' / ') : null,
11
- leaf || null);
12
- }
13
-
14
- export function Chip({ tone = '', children }) {
15
- return h('span', { class: 'chip' + (tone ? ' tone-' + tone : '') }, children);
16
- }
17
-
18
- export function Btn({ href = '#', primary, ghost, children, onClick }) {
19
- const cls = primary ? 'btn-primary' : (ghost ? 'btn-ghost' : 'btn');
20
- return h('a', { class: cls, href, onclick: onClick }, children);
21
- }
22
-
23
- export function Glyph({ children, color }) {
24
- return h('span', { class: 'glyph', style: color ? `color:${color}` : '' }, children);
25
- }
26
-
27
- export function Topbar({ brand = '247420', leaf = '', items = [], active = '', onNav, search } = {}) {
28
- return h('header', { class: 'app-topbar' },
29
- Brand({ name: brand, leaf }),
30
- search ? h('label', { class: 'app-search' },
31
- h('span', { class: 'icon' }, '⌕'),
32
- h('input', { type: 'search', placeholder: search, 'aria-label': 'search' })
33
- ) : h('span', {}),
34
- h('nav', {}, ...items.map(([label, href]) =>
35
- h('a', {
36
- key: label,
37
- href,
38
- class: active === String(label).replace(' ↗', '') ? 'active' : '',
39
- onclick: (e) => {
40
- if (!String(href).startsWith('http') && onNav) {
41
- e.preventDefault();
42
- onNav(String(label).replace(' ↗', ''));
43
- }
44
- }
45
- }, label)
46
- ))
47
- );
48
- }
49
-
50
- export function Crumb({ trail = [], leaf = '', right } = {}) {
51
- const parts = [];
52
- trail.forEach((t, i) => {
53
- parts.push(h('span', { key: 't' + i }, t));
54
- parts.push(h('span', { key: 's' + i, class: 'sep' }, '›'));
55
- });
56
- parts.push(h('span', { key: 'leaf', class: 'leaf' }, leaf));
57
- if (right) parts.push(h('span', { key: 'r', class: 'crumb-right' }, ...(Array.isArray(right) ? right : [right])));
58
- return h('div', { class: 'app-crumb' }, ...parts);
59
- }
60
-
61
- export function Side({ sections = [] } = {}) {
62
- return h('aside', { class: 'app-side' }, ...sections.flatMap(sec => [
63
- h('div', { class: 'group', key: sec.group }, sec.group),
64
- ...sec.items.map((item, i) => {
65
- const { glyph, label, href = '#', active, count, color, onClick } = item;
66
- return h('a', {
67
- key: sec.group + i,
68
- href,
69
- class: active ? 'active' : '',
70
- onclick: onClick
71
- },
72
- glyph != null ? Glyph({ children: glyph, color }) : h('span', { class: 'glyph' }),
73
- h('span', {}, label),
74
- count != null ? h('span', { class: 'count' }, String(count)) : null
75
- );
76
- })
77
- ]));
78
- }
79
-
80
- export function Status({ left = [], right = [] } = {}) {
81
- return h('footer', { class: 'app-status' },
82
- ...left.map((t, i) => h('span', { key: 'l' + i, class: 'item' }, t)),
83
- h('span', { class: 'spread' }),
84
- ...right.map((t, i) => h('span', { key: 'r' + i, class: 'item' }, t))
85
- );
86
- }
87
-
88
- export function AppShell({ topbar, crumb, side, main, status, narrow } = {}) {
89
- const hasSide = Boolean(side);
90
- const sideNode = hasSide ? side : h('aside', { class: 'app-side', 'aria-hidden': 'true' });
91
- return h('div', { class: 'app' },
92
- topbar || null,
93
- crumb || null,
94
- h('div', { class: 'app-body' + (hasSide ? '' : ' no-side') },
95
- h('div', { class: 'app-side-shell' }, sideNode),
96
- h('main', { class: 'app-main' + (narrow ? ' narrow' : '') }, ...(Array.isArray(main) ? main : [main]))
97
- ),
98
- status || null
99
- );
100
- }
101
-
102
- export function Heading({ level = 1, children, style = '' }) {
103
- return h('h' + level, { style }, children);
104
- }
105
-
106
- export function Lede({ children }) {
107
- return h('p', { class: 'lede' }, children);
108
- }
109
-
110
- export function Dot({ tone = 'live' }) {
111
- const cls = tone === 'live' ? 'ds-dot-live' : 'ds-dot-idle';
112
- return h('span', { class: cls }, tone === 'live' ? '●' : '○');
113
- }
114
-
115
- export function Rail({ tone = 'green' }) {
116
- return h('span', { class: 'ds-rail tone-' + tone, 'aria-hidden': 'true' });
117
- }
4
+ //
5
+ // This module is a barrel: every component lives in a single-responsibility
6
+ // submodule under ./shell/, and the public export surface here is unchanged
7
+ // — no consumer import needs to move.
8
+
9
+ import { Brand, Chip, Btn, IconButton, Badge, Pill, Glyph, Heading, Lede, Dot, Rail } from './shell/atoms.js';
10
+ import { ICON_PATHS, iconMarkup, Icon } from './shell/icons.js';
11
+ import { Topbar, Crumb, Side, Status, AppShell } from './shell/app-shell.js';
12
+ import { WorkspaceShell, WorkspaceRail } from './shell/workspace-shell.js';
13
+
14
+ export {
15
+ Brand, Chip, Btn, IconButton, Badge, Pill, Glyph, Heading, Lede, Dot, Rail,
16
+ ICON_PATHS, iconMarkup, Icon,
17
+ Topbar, Crumb, Side, Status, AppShell,
18
+ WorkspaceShell, WorkspaceRail,
19
+ };
@@ -14,57 +14,101 @@ import { applyTheme, getTheme, resolvedTheme, onThemeChange } from '../theme.js'
14
14
  const h = webjsx.createElement;
15
15
 
16
16
  const MODES = [
17
- ['auto', '⌗', 'auto'],
18
- ['paper', '☀', 'light'],
19
- ['ink', '☾', 'dark'],
17
+ ['auto', 'auto'],
18
+ ['paper', 'light'],
19
+ ['ink', 'dark'],
20
20
  ];
21
21
 
22
- // Track instances so an OS-theme change while in 'auto' re-renders the
23
- // glyph in the compact variant (the segmented variant doesn't need it).
24
- const refresh = new Set();
25
- let _bound = false;
26
- function bindOnce() {
27
- if (_bound) return;
28
- _bound = true;
29
- onThemeChange(() => { for (const cb of refresh) cb(); });
22
+ // Both variants render from `getTheme()` at the moment their vnode is built,
23
+ // but nothing re-renders this control when the theme changes: a host kit's view
24
+ // is not subscribed to the theme, and applyTheme() only touches <html> and the
25
+ // theme listeners. So each instance repaints itself from the live theme through
26
+ // a ref — once on mount, then on every theme change. `el._dsThemeBound` makes
27
+ // that idempotent, since a ref callback runs again on each re-render of the
28
+ // host. (This replaces a `refresh` Set that nothing ever added to, so the
29
+ // onThemeChange subscription it fed always iterated an empty set.)
30
+ function bindThemePaint(el, paint) {
31
+ if (!el || el._dsThemeBound) return;
32
+ el._dsThemeBound = true;
33
+ paint();
34
+ onThemeChange(paint);
30
35
  }
31
36
 
32
37
  export function ThemeToggle({ compact = false, onChange } = {}) {
33
- bindOnce();
34
38
  const current = getTheme();
35
39
 
36
40
  if (compact) {
37
- const resolved = resolvedTheme();
38
- const glyph = current === 'auto' ? '⌗' : (resolved === 'ink' ? '☾' : '☀');
39
- const label = current === 'auto' ? `auto (${resolved})` : (current === 'ink' ? 'dark' : 'light');
41
+ // Plain words only - 'ink'/'paper' are internal theme codenames a user
42
+ // never chose; the resolved scheme rides in the title, not the label.
43
+ const wordFor = (t) => (t === 'auto' ? 'auto' : (t === 'ink' ? 'dark' : 'light'));
44
+ const labelFor = (t) => 'theme: ' + wordFor(t);
45
+ const titleFor = (t) => labelFor(t)
46
+ + (t === 'auto' ? ' (currently ' + (resolvedTheme() === 'ink' ? 'dark' : 'light') + ')' : '')
47
+ + ' — click to cycle';
40
48
  return h('button', {
41
49
  class: 'btn ds-theme-toggle',
42
50
  type: 'button',
43
- 'aria-label': 'theme: ' + label,
44
- title: 'theme: ' + label + ' — click to cycle',
51
+ 'aria-label': labelFor(current),
52
+ title: titleFor(current),
53
+ // getTheme() at click time, not the `current` captured when this
54
+ // vnode was built. Nothing re-renders this button on a theme
55
+ // change, so a captured value goes stale after the first click and
56
+ // the cycle sticks: auto -> paper, then every later click computes
57
+ // from a stale 'auto' and lands on paper again.
45
58
  onclick: () => {
46
- const next = current === 'auto' ? 'paper' : (current === 'paper' ? 'ink' : 'auto');
59
+ const now = getTheme();
60
+ const next = now === 'auto' ? 'paper' : (now === 'paper' ? 'ink' : 'auto');
47
61
  applyTheme(next);
48
- if (onChange) try { onChange(next); } catch {}
49
- }
50
- }, h('span', { class: 'glyph' }, glyph), ' ', label);
62
+ if (onChange) try { onChange(next); } catch { /* swallow: consumer onChange callback must not break the toggle */ }
63
+ },
64
+ ref: (el) => bindThemePaint(el, () => {
65
+ const now = getTheme();
66
+ el.setAttribute('aria-label', labelFor(now));
67
+ el.setAttribute('title', titleFor(now));
68
+ const lab = el.querySelector('.ds-theme-toggle-label');
69
+ if (lab) lab.textContent = labelFor(now);
70
+ })
71
+ },
72
+ // CSS-drawn half-disc so the control still reads as the theme switch
73
+ // when the label is hidden (icon-only rail strip).
74
+ h('span', { class: 'ds-theme-disc', 'aria-hidden': 'true' }),
75
+ h('span', { class: 'ds-theme-toggle-label' }, labelFor(current)));
51
76
  }
52
77
 
53
78
  return h('div', {
54
79
  class: 'ds-theme-toggle ds-segmented',
55
80
  role: 'radiogroup',
56
- 'aria-label': 'theme'
57
- }, ...MODES.map(([mode, glyph, label]) =>
81
+ 'aria-label': 'theme',
82
+ // Paint the selected segment from the live theme rather than only from
83
+ // `current` (captured when this vnode was built). Nothing re-renders
84
+ // this control when it is clicked: the host kit's view is not
85
+ // subscribed to the theme, so applyTheme() correctly flipped
86
+ // <html data-theme> while the segment kept `is-on` on whatever was
87
+ // selected at mount — clicking "light" changed the theme but left
88
+ // "auto" looking selected, which reads as a control that did nothing.
89
+ // Doing it in a ref keeps this correct for BOTH triggers: a click here,
90
+ // and an external change (another toggle, or the OS scheme flipping
91
+ // while in auto) via the onThemeChange subscription.
92
+ ref: (el) => bindThemePaint(el, () => {
93
+ const now = getTheme();
94
+ for (const btn of el.querySelectorAll('.ds-seg-btn')) {
95
+ const on = btn.dataset.mode === now;
96
+ btn.classList.toggle('is-on', on);
97
+ btn.setAttribute('aria-checked', on ? 'true' : 'false');
98
+ }
99
+ })
100
+ }, ...MODES.map(([mode, label]) =>
58
101
  h('button', {
59
102
  key: mode,
60
103
  type: 'button',
61
104
  role: 'radio',
105
+ 'data-mode': mode,
62
106
  'aria-checked': current === mode ? 'true' : 'false',
63
107
  class: 'ds-seg-btn' + (current === mode ? ' is-on' : ''),
64
108
  onclick: () => {
65
109
  applyTheme(mode);
66
- if (onChange) try { onChange(mode); } catch {}
110
+ if (onChange) try { onChange(mode); } catch { /* swallow: consumer onChange callback must not break the toggle */ }
67
111
  }
68
- }, h('span', { class: 'glyph' }, glyph), ' ', label)
112
+ }, label)
69
113
  ));
70
114
  }
@@ -4,34 +4,63 @@ import * as webjsx from '../vendor/webjsx/index.js';
4
4
  export const h = webjsx.createElement;
5
5
 
6
6
  export {
7
- Brand, Chip, Btn, Glyph,
7
+ Brand, Chip, Btn, Glyph, Icon, IconButton, Badge, Pill,
8
8
  Topbar, Crumb, Side, Status, AppShell,
9
+ WorkspaceShell, WorkspaceRail,
9
10
  Heading, Lede, Dot, Rail
10
11
  } from './components/shell.js';
11
12
 
12
13
  export {
13
- Panel, Row, RowLink,
14
- Hero, Install, Receipt, Changelog,
15
- WorksList, WritingList, Manifesto, Section,
16
- Kpi, Table,
17
- HomeView, ProjectView, Form
14
+ Panel, Card, Row, RowLink, PanelFromItems,
15
+ Hero, HeroFromPageData, Marquee, Install, CliBlock, Receipt, Changelog,
16
+ WorksList, WritingList, Manifesto, Section, PageHeader,
17
+ Kpi, Sparkline, BarChart, Table, HealthTable, ProcessRegistryTable, SearchInput, TextField, Select, EventList,
18
+ HomeView, ProjectView, Form,
19
+ Spinner, Skeleton, Alert, FilterPills, Avatar, avatarInitial
18
20
  } from './components/content.js';
19
21
 
20
22
  export {
21
- fmtBytes, renderInline,
22
- ChatMessage, ChatComposer, Chat,
23
+ fmtBytes, renderInline, hasSelectionInside,
24
+ ChatMessage, ChatComposer, Chat, flashComposerNote, ChatSuggestions,
23
25
  AICAT_FACE, AICatPortrait, AICat
24
26
  } from './components/chat.js';
25
27
 
28
+ export { AgentChat, MESSAGE_CAP } from './components/agent-chat.js';
29
+
30
+ export { ChatMinimap, CHAT_MINIMAP_WIDTH } from './components/chat-minimap.js';
31
+
32
+ export {
33
+ ConversationList, SessionCard, SessionDashboard, SessionMeta, fmtDuration, fmtTime, fmtAgo, AgentListSkeleton
34
+ } from './components/sessions.js';
35
+
36
+ export { ContextPane } from './components/context-pane.js';
37
+
38
+ export { SpreadsheetPreview } from './components/spreadsheet-preview.js';
39
+
40
+ export { GitStatusPanel, GitDiffView } from './components/git-status.js';
41
+
42
+ export { WorktreeSwitcher } from './components/worktree-switcher.js';
43
+
44
+ export { PluginsConfig } from './components/plugins-config.js';
45
+
46
+ export { SkillsConfig } from './components/skills-config.js';
47
+
48
+ export { ModelsConfig } from './components/models-config.js';
49
+
50
+ export {
51
+ DEFAULT_PHASES, PhaseWalk, TreeNode, BarRow, RateCell,
52
+ StatTile, StatsGrid, SubGrid, SessionRow, DevRow, LiveLogEntry, LiveLog
53
+ } from './components/data-density.js';
54
+
26
55
  export {
27
56
  fileGlyph, fmtFileSize,
28
- FileIcon, FileRow, FileGrid, FileToolbar,
29
- DropZone, UploadProgress, EmptyState, BreadcrumbPath
57
+ FileIcon, FileRow, FileGrid, FileSkeleton, sortFiles, FileToolbar, RootsPicker,
58
+ DropZone, UploadProgress, EmptyState, BreadcrumbPath, BulkBar
30
59
  } from './components/files.js';
31
60
 
32
61
  export {
33
- ConfirmDialog, PromptDialog,
34
- FilePreviewMedia, FilePreviewCode, FilePreviewText, FileViewer
62
+ ConfirmDialog, PromptDialog, CountdownDialog,
63
+ FilePreviewMedia, FilePreviewCode, FilePreviewText, FileViewer, FilePreviewPane
35
64
  } from './components/files-modals.js';
36
65
 
37
66
  export {
@@ -39,14 +68,64 @@ export {
39
68
  ChannelItem, ChannelCategory,
40
69
  VoiceUser, UserPanel, ChannelSidebar,
41
70
  MemberItem, MemberList,
42
- ChatHeader, VoiceStrip, CommunityShell
71
+ ChatHeader, VoiceStrip, CommunityShell,
72
+ MobileHeader, ReplyBar, Banner,
73
+ ThreadPanel, ForumView, PageView
43
74
  } from './components/community.js';
44
75
 
76
+ export {
77
+ PttButton, VadMeter, WebcamPreview, VoiceSettingsModal, AudioQueue, VoiceControls,
78
+ playCompletionCue
79
+ } from './components/voice.js';
80
+
45
81
  export { ThemeToggle } from './components/theme-toggle.js';
46
82
 
83
+ export {
84
+ Checkbox, Radio, RadioGroup, Toggle, Field, useFormValidation, focusFirstInvalidField
85
+ } from './components/form-primitives.js';
86
+
87
+ export {
88
+ useDraggable, useDropTarget, useNumberScrub, usePointerDrag, Reorderable,
89
+ useKeyboardShortcut, formatShortcut, ShortcutHint, ShortcutList,
90
+ useKeyboardShortcutHelp, ShortcutHelpDialog,
91
+ isMobileNow, onMobileChange
92
+ } from './components/interaction-primitives.js';
93
+
94
+ export {
95
+ Toolbar, ToolbarRow, Tabs,
96
+ TreeView, TreeItem,
97
+ PropertyGrid, PropertyField, PropertyGridRow, InlineEditableField,
98
+ Dock, IconButtonGroup,
99
+ ResizeHandle, SplitPanel,
100
+ ContextMenu, useContextMenu,
101
+ Drawer, Dialog, FocusTrap,
102
+ Toast, toast,
103
+ Pager, JsonViewer,
104
+ Grid, GridItem,
105
+ Collapse, CollapseGroup,
106
+ Divider,
107
+ useMediaQuery,
108
+ BP_SM, BP_MD, BP_LG, BP_XL,
109
+ InfoRow, InfoSection, DiagnosticsPanel,
110
+ BatchProgressLabel, formatBatchOutcome, runBatchSequential
111
+ } from './components/editor-primitives.js';
112
+
113
+ export {
114
+ Tooltip, Popover, Dropdown, useLongPress, useFloating,
115
+ CommandPalette, EmojiPicker, BootOverlay, SettingsPopover,
116
+ AuthModal, VideoLightbox, PermissionMenu, ApprovalPrompt, withBusy,
117
+ MenuButton
118
+ } from './components/overlay-primitives.js';
119
+
47
120
  export {
48
121
  FREDDIE_PAGES,
49
122
  home, chat, voice, sessions, projects, agents, analytics,
50
123
  models, cron, skills, config, env, tools, batch, gateway, chains,
51
124
  skillLabel, getRecentPaths, saveRecentPath, renderChatMessages
52
125
  } from './components/freddie.js';
126
+
127
+ export {
128
+ makePage, api, loadingState, errorState, emptyState, refreshError
129
+ } from './components/freddie/runtime.js';
130
+
131
+ export { mountCommunityApp } from './community-app.js';
@@ -1,13 +1,15 @@
1
- // deck-stage — lazy registration. Consumer calls registerDeckStage() in a
2
- // browser context; we side-effect import the upstream slides/deck-stage.js
3
- // (the starter-component web component that handles scaling + nav).
1
+ // deck-stage — compat re-export shim. registerDeckStage() lazily side-effect
2
+ // imports the real implementation, now living at src/kits/slides/deck-stage.js
3
+ // (moved from the top-level slides/ dir so the deck kit follows the same
4
+ // src/kits/<name>/ convention every other kit uses; this shim keeps the old
5
+ // src/deck-stage.js import path working for any existing consumer).
4
6
 
5
7
  let _registered = false;
6
8
  export async function registerDeckStage() {
7
9
  if (_registered) return (typeof customElements !== 'undefined') ? customElements.get('deck-stage') : null;
8
10
  if (typeof customElements === 'undefined' || typeof HTMLElement === 'undefined') return null;
9
11
  try {
10
- await import('../slides/deck-stage.js');
12
+ await import('./kits/slides/deck-stage.js');
11
13
  } catch (err) {
12
14
  console.warn('[247420] deck-stage import failed:', err);
13
15
  return null;
@@ -1,21 +1,65 @@
1
- // Syntax highlighting — lazy-loads Prism on first call. No-op safe.
1
+ // Syntax highlighting — lazy-loads Prism + common language grammars on first call. No-op safe.
2
+ // Grammars are injected as <script src="..."> so the browser's CSP allowlist
3
+ // (cdn.jsdelivr.net) covers them without needing 'unsafe-eval'. Prism core
4
+ // must finish before grammars; grammars within each tier are parallel.
2
5
 
3
6
  let _prism = null;
4
7
  let _ready = null;
5
8
 
6
- const PRISM_CORE = 'https://cdn.jsdelivr.net/npm/prismjs@1.30.0/components/prism-core.min.js';
9
+ const DEFAULT_PRISM_BASE = 'https://cdn.jsdelivr.net/npm/prismjs@1.30.0/components/';
10
+ let _prismBase = DEFAULT_PRISM_BASE;
11
+
12
+ // Optional override for where Prism's core + language grammars are fetched
13
+ // from (self-host, mirror, CSP-allowlisted proxy). Additive: a zero-config
14
+ // consumer keeps hitting the pinned jsDelivr default byte-for-byte. Call
15
+ // before the first highlight to take effect; forces a fresh load so a
16
+ // runtime override after an earlier failed load also takes.
17
+ export function configurePrismCdn({ baseUrl } = {}) {
18
+ _prismBase = baseUrl || DEFAULT_PRISM_BASE;
19
+ _prism = null;
20
+ _ready = null;
21
+ }
22
+
23
+ export function getPrismCdnConfig() {
24
+ return { baseUrl: _prismBase };
25
+ }
26
+
27
+ // Dependency tiers: each tier loads in parallel; the next tier waits for the previous.
28
+ // (clike must precede javascript; javascript must precede typescript/jsx/tsx.)
29
+ const PRISM_TIERS = [
30
+ ['prism-markup.min.js', 'prism-css.min.js', 'prism-clike.min.js'],
31
+ ['prism-javascript.min.js', 'prism-json.min.js', 'prism-bash.min.js', 'prism-yaml.min.js',
32
+ 'prism-markdown.min.js', 'prism-python.min.js', 'prism-rust.min.js', 'prism-go.min.js',
33
+ 'prism-diff.min.js', 'prism-sql.min.js', 'prism-toml.min.js'],
34
+ ['prism-typescript.min.js', 'prism-jsx.min.js'],
35
+ ['prism-tsx.min.js'],
36
+ ];
37
+
38
+ function loadScript(url) {
39
+ return new Promise((resolve) => {
40
+ const existing = document.querySelector('script[src="' + url + '"]');
41
+ if (existing) { resolve(); return; }
42
+ const s = document.createElement('script');
43
+ s.src = url;
44
+ s.crossOrigin = 'anonymous';
45
+ s.onload = resolve;
46
+ s.onerror = () => { console.warn('[247420] prism part failed:', url); resolve(); };
47
+ document.head.appendChild(s);
48
+ });
49
+ }
7
50
 
8
51
  export async function ensurePrism() {
9
52
  if (_prism) return _prism;
10
53
  if (_ready) return _ready;
11
54
  _ready = (async () => {
12
55
  try {
13
- // Prism is UMD; fetch & exec on the global.
14
- const res = await fetch(PRISM_CORE);
15
- const code = await res.text();
16
- // eslint-disable-next-line no-new-func
17
- new Function('window', code)(window);
56
+ await loadScript(_prismBase + 'prism-core.min.js');
18
57
  _prism = window.Prism || null;
58
+ if (_prism) {
59
+ for (const tier of PRISM_TIERS) {
60
+ await Promise.all(tier.map(f => loadScript(_prismBase + f)));
61
+ }
62
+ }
19
63
  return _prism;
20
64
  } catch (err) {
21
65
  console.warn('[247420] prism loader failed:', err);