@treeseed/core 0.8.8 → 0.8.10

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 (90) hide show
  1. package/dist/components/SiteTitle.astro +2 -2
  2. package/dist/components/content/ContentStatusLegend.astro +4 -4
  3. package/dist/components/docs/BookFontControls.astro +9 -9
  4. package/dist/components/docs/DesktopSidebarToggle.astro +8 -8
  5. package/dist/components/docs/Footer.astro +7 -91
  6. package/dist/components/docs/Header.astro +9 -2
  7. package/dist/components/docs/PageTitle.astro +1 -1
  8. package/dist/components/docs/ThemeSelect.astro +3 -1
  9. package/dist/components/forms/ContactForm.astro +21 -21
  10. package/dist/components/forms/FooterSubscribeForm.astro +9 -9
  11. package/dist/components/site/BookList.astro +7 -7
  12. package/dist/components/site/CTASection.astro +4 -4
  13. package/dist/components/site/ChronicleList.astro +6 -6
  14. package/dist/components/site/Hero.astro +3 -3
  15. package/dist/components/site/PathCard.astro +5 -5
  16. package/dist/components/site/ProfileList.astro +5 -5
  17. package/dist/components/site/RouteNotFound.astro +6 -6
  18. package/dist/components/site/SectionIntro.astro +3 -3
  19. package/dist/components/site/StageBanner.astro +2 -2
  20. package/dist/components/site/TrustCallout.astro +3 -3
  21. package/dist/components/ui/data/ActionList.astro +51 -0
  22. package/dist/components/ui/data/Badge.astro +19 -0
  23. package/dist/components/ui/data/DataTable.astro +51 -0
  24. package/dist/components/ui/data/KeyValueList.astro +28 -0
  25. package/dist/components/ui/data/MetricCard.astro +25 -0
  26. package/dist/components/ui/data/MetricGrid.astro +27 -0
  27. package/dist/components/ui/data/StatusPill.astro +20 -0
  28. package/dist/components/ui/forms/Button.astro +52 -0
  29. package/dist/components/ui/forms/Field.astro +39 -0
  30. package/dist/components/ui/forms/FormActions.astro +12 -0
  31. package/dist/components/ui/forms/PasswordMeter.astro +80 -0
  32. package/dist/components/ui/forms/RadioGroup.astro +55 -0
  33. package/dist/components/ui/forms/Select.astro +44 -0
  34. package/dist/components/ui/forms/TextInput.astro +58 -0
  35. package/dist/components/ui/forms/Textarea.astro +45 -0
  36. package/dist/components/ui/layout/PageHeader.astro +45 -0
  37. package/dist/components/ui/shell/AppShell.astro +112 -0
  38. package/dist/components/ui/shell/BottomNav.astro +35 -0
  39. package/dist/components/ui/shell/ProjectHeader.astro +66 -0
  40. package/dist/components/ui/shell/PublicFooter.astro +39 -0
  41. package/dist/components/ui/shell/PublicShell.astro +179 -0
  42. package/dist/components/ui/shell/RailNav.astro +35 -0
  43. package/dist/components/ui/shell/TopBar.astro +52 -0
  44. package/dist/components/ui/surface/Card.astro +46 -0
  45. package/dist/components/ui/surface/EmptyState.astro +45 -0
  46. package/dist/components/ui/surface/Panel.astro +54 -0
  47. package/dist/components/ui/theme/ThemeMenu.astro +32 -0
  48. package/dist/components/ui/theme/ThemePreviewSwatch.astro +18 -0
  49. package/dist/components/ui/theme/ThemeScript.astro +111 -0
  50. package/dist/components/ui/theme/ThemeSelector.astro +202 -0
  51. package/dist/components/ui/types.js +0 -0
  52. package/dist/dev-watch.d.ts +6 -2
  53. package/dist/dev-watch.js +12 -3
  54. package/dist/dev.d.ts +10 -2
  55. package/dist/dev.js +352 -68
  56. package/dist/layouts/AuthoredEntryLayout.astro +27 -27
  57. package/dist/layouts/BookLayout.astro +10 -10
  58. package/dist/layouts/ContentLayout.astro +4 -4
  59. package/dist/layouts/MainLayout.astro +66 -193
  60. package/dist/layouts/NoteLayout.astro +6 -6
  61. package/dist/layouts/ProfileLayout.astro +17 -17
  62. package/dist/middleware/starlightRouteData.js +20 -14
  63. package/dist/pages/404.astro +8 -8
  64. package/dist/pages/[slug].astro +1 -1
  65. package/dist/pages/books/[slug].astro +5 -5
  66. package/dist/pages/contact.astro +4 -4
  67. package/dist/pages/docs-runtime/[...slug].astro +12 -12
  68. package/dist/pages/docs-runtime/index.astro +13 -13
  69. package/dist/pages/index.astro +28 -28
  70. package/dist/pages/ui/index.astro +216 -0
  71. package/dist/scripts/dev-platform.js +7 -1
  72. package/dist/site.js +53 -5
  73. package/dist/styles/app-shell.css +597 -0
  74. package/dist/styles/forms.css +258 -0
  75. package/dist/styles/global.css +125 -120
  76. package/dist/styles/prose.css +11 -11
  77. package/dist/styles/theme.css +177 -0
  78. package/dist/styles/tokens.css +62 -22
  79. package/dist/styles/ui.css +551 -0
  80. package/dist/utils/color-schemes/cedar.js +53 -0
  81. package/dist/utils/color-schemes/fern.js +53 -0
  82. package/dist/utils/color-schemes/index.js +13 -0
  83. package/dist/utils/color-schemes/lichen.js +53 -0
  84. package/dist/utils/color-schemes/shared.js +33 -0
  85. package/dist/utils/color-schemes/tidepool.js +53 -0
  86. package/dist/utils/content-status.js +5 -5
  87. package/dist/utils/site-config.js +2 -2
  88. package/dist/utils/starlight-nav.js +13 -7
  89. package/dist/utils/theme.js +133 -41
  90. package/package.json +36 -2
@@ -0,0 +1,54 @@
1
+ ---
2
+ import Button from '../forms/Button.astro';
3
+ import type { ButtonAction, Tone } from '../types.js';
4
+
5
+ interface Props {
6
+ eyebrow?: string;
7
+ title?: string;
8
+ description?: string;
9
+ tone?: Tone;
10
+ actions?: ButtonAction[];
11
+ class?: string;
12
+ }
13
+
14
+ const {
15
+ eyebrow,
16
+ title,
17
+ description,
18
+ tone = 'default',
19
+ actions = [],
20
+ class: className,
21
+ } = Astro.props as Props;
22
+ ---
23
+
24
+ <section class:list={['ts-panel', className]} data-tone={tone}>
25
+ {eyebrow || title || description || actions.length > 0 || Astro.slots.has('actions') ? (
26
+ <header class="ts-panel__header">
27
+ <div class="ts-panel__heading">
28
+ {eyebrow ? <p class="ts-panel__eyebrow">{eyebrow}</p> : null}
29
+ {title ? <h2 class="ts-panel__title">{title}</h2> : null}
30
+ {description ? <p class="ts-panel__description">{description}</p> : null}
31
+ </div>
32
+ {actions.length > 0 || Astro.slots.has('actions') ? (
33
+ <div class="ts-panel__actions">
34
+ {actions.map((action) => (
35
+ <Button
36
+ href={action.href}
37
+ type={action.type}
38
+ variant={action.variant ?? 'secondary'}
39
+ ariaLabel={action.ariaLabel}
40
+ disabled={action.disabled}
41
+ size="sm"
42
+ >
43
+ {action.label}
44
+ </Button>
45
+ ))}
46
+ <slot name="actions" />
47
+ </div>
48
+ ) : null}
49
+ </header>
50
+ ) : null}
51
+ <div class="ts-panel__body">
52
+ <slot />
53
+ </div>
54
+ </section>
@@ -0,0 +1,32 @@
1
+ ---
2
+ import ThemeSelector from './ThemeSelector.astro';
3
+ import type { ThemePreference } from '../../../utils/theme.js';
4
+
5
+ interface Props {
6
+ selectedScheme?: ThemePreference['scheme'];
7
+ selectedMode?: ThemePreference['mode'];
8
+ label?: string;
9
+ }
10
+
11
+ const {
12
+ selectedScheme,
13
+ selectedMode,
14
+ label = 'Appearance',
15
+ } = Astro.props as Props;
16
+ ---
17
+
18
+ <details class="ts-theme-menu" data-ts-theme-menu>
19
+ <summary class="ts-theme-menu__trigger" aria-label={label} title={label}>
20
+ <svg aria-hidden="true" viewBox="0 0 24 24" focusable="false">
21
+ <path d="M12 3.25a8.75 8.75 0 0 0 0 17.5h1.1a2.05 2.05 0 0 0 1.46-3.49 0.55 0.55 0 0 1 .39-.94h1.45a4.35 4.35 0 0 0 4.35-4.35A8.72 8.72 0 0 0 12 3.25Zm-4.1 9.1a1.35 1.35 0 1 1 0-2.7 1.35 1.35 0 0 1 0 2.7Zm2.3-4.1a1.35 1.35 0 1 1 0-2.7 1.35 1.35 0 0 1 0 2.7Zm3.9 0a1.35 1.35 0 1 1 0-2.7 1.35 1.35 0 0 1 0 2.7Zm2.6 4.1a1.35 1.35 0 1 1 0-2.7 1.35 1.35 0 0 1 0 2.7Z" />
22
+ </svg>
23
+ </summary>
24
+ <div class="ts-theme-menu__panel">
25
+ <ThemeSelector
26
+ label={label}
27
+ selectedScheme={selectedScheme}
28
+ selectedMode={selectedMode}
29
+ compact={false}
30
+ />
31
+ </div>
32
+ </details>
@@ -0,0 +1,18 @@
1
+ ---
2
+ interface Props {
3
+ swatches: string[];
4
+ label?: string;
5
+ }
6
+
7
+ const { swatches, label = 'Color scheme preview' } = Astro.props as Props;
8
+ const visibleSwatches = swatches.slice(0, 4);
9
+ const swatchStyle = visibleSwatches
10
+ .map((swatch, index) => `--ts-preview-swatch-${index + 1}: ${swatch}`)
11
+ .join('; ');
12
+ ---
13
+
14
+ <span class="ts-theme-swatch" style={swatchStyle} role="img" aria-label={label}>
15
+ {visibleSwatches.map((_, index) => (
16
+ <span class="ts-theme-swatch__dot" data-swatch-index={index + 1} aria-hidden="true"></span>
17
+ ))}
18
+ </span>
@@ -0,0 +1,111 @@
1
+ ---
2
+ import {
3
+ buildTreeseedThemeCss,
4
+ getBuiltInColorSchemes,
5
+ normalizeThemePreference,
6
+ type ThemePreference,
7
+ } from '../../../utils/theme.js';
8
+
9
+ interface Props {
10
+ defaultScheme?: ThemePreference['scheme'];
11
+ defaultMode?: ThemePreference['mode'];
12
+ includeCss?: boolean;
13
+ preferDefaultPreference?: boolean;
14
+ }
15
+
16
+ const preference = normalizeThemePreference({
17
+ scheme: (Astro.props as Props).defaultScheme,
18
+ mode: (Astro.props as Props).defaultMode,
19
+ });
20
+ const { includeCss = true, preferDefaultPreference = false } = Astro.props as Props;
21
+ const builtInSchemeIds = getBuiltInColorSchemes().map((scheme) => scheme.id);
22
+ const themeCss = buildTreeseedThemeCss();
23
+ ---
24
+
25
+ {includeCss ? <style is:inline set:html={themeCss}></style> : null}
26
+
27
+ <script
28
+ is:inline
29
+ define:vars={{
30
+ builtInSchemeIds,
31
+ defaultScheme: preference.scheme,
32
+ defaultMode: preference.mode,
33
+ preferDefaultPreference,
34
+ }}
35
+ >
36
+ (() => {
37
+ const schemeKey = 'treeseed_color_scheme';
38
+ const modeKey = 'treeseed_theme_mode';
39
+ const modes = new Set(['light', 'dark', 'system']);
40
+ const schemes = new Set(builtInSchemeIds);
41
+ const root = document.documentElement;
42
+
43
+ function readCookie(name) {
44
+ const pair = document.cookie
45
+ .split('; ')
46
+ .find((entry) => entry.startsWith(`${name}=`));
47
+ return pair ? decodeURIComponent(pair.slice(name.length + 1)) : '';
48
+ }
49
+
50
+ function readStored(name) {
51
+ try {
52
+ return window.sessionStorage.getItem(name) || window.localStorage.getItem(name) || '';
53
+ } catch {
54
+ return '';
55
+ }
56
+ }
57
+
58
+ function cookie(name, value) {
59
+ const secure = window.location.protocol === 'https:' ? '; Secure' : '';
60
+ document.cookie = `${name}=${encodeURIComponent(value)}; Max-Age=${60 * 60 * 24 * 365}; Path=/; SameSite=Lax${secure}`;
61
+ }
62
+
63
+ function store(name, value) {
64
+ try {
65
+ window.sessionStorage.setItem(name, value);
66
+ } catch {
67
+ // Session storage can be disabled; local storage/cookies still carry the preference.
68
+ }
69
+ try {
70
+ window.localStorage.setItem(name, value);
71
+ } catch {
72
+ // Local storage can be disabled; cookies still carry the preference for SSR.
73
+ }
74
+ cookie(name, value);
75
+ }
76
+
77
+ function resolveScheme(value) {
78
+ return schemes.has(value) ? value : defaultScheme;
79
+ }
80
+
81
+ function resolveMode(value) {
82
+ return modes.has(value) ? value : defaultMode;
83
+ }
84
+
85
+ function resolveRenderedMode(mode) {
86
+ if (mode !== 'system') return mode;
87
+ return window.matchMedia?.('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
88
+ }
89
+
90
+ const storedScheme = readCookie(schemeKey) || readStored(schemeKey);
91
+ const storedModeValue = readCookie(modeKey) || readStored(modeKey);
92
+ const scheme = preferDefaultPreference ? resolveScheme(defaultScheme) : resolveScheme(storedScheme || defaultScheme);
93
+ const storedMode = preferDefaultPreference ? resolveMode(defaultMode) : resolveMode(storedModeValue || defaultMode);
94
+ const renderedMode = resolveRenderedMode(storedMode);
95
+
96
+ root.dataset.tsScheme = scheme;
97
+ root.dataset.tsMode = renderedMode;
98
+ if (storedMode === 'system') {
99
+ root.dataset.tsModeSource = 'system';
100
+ } else {
101
+ delete root.dataset.tsModeSource;
102
+ }
103
+ store(schemeKey, scheme);
104
+ store(modeKey, storedMode);
105
+ window.matchMedia?.('(prefers-color-scheme: dark)').addEventListener?.('change', () => {
106
+ if (root.dataset.tsModeSource === 'system') {
107
+ root.dataset.tsMode = resolveRenderedMode('system');
108
+ }
109
+ });
110
+ })();
111
+ </script>
@@ -0,0 +1,202 @@
1
+ ---
2
+ import {
3
+ getBuiltInColorSchemes,
4
+ normalizeThemePreference,
5
+ type ThemePreference,
6
+ } from '../../../utils/theme.js';
7
+ import ThemePreviewSwatch from './ThemePreviewSwatch.astro';
8
+
9
+ interface Props {
10
+ label?: string;
11
+ selectedScheme?: ThemePreference['scheme'];
12
+ selectedMode?: ThemePreference['mode'];
13
+ includeHiddenFields?: boolean;
14
+ schemeFieldName?: string;
15
+ modeFieldName?: string;
16
+ compact?: boolean;
17
+ }
18
+
19
+ const {
20
+ label = 'Appearance',
21
+ selectedScheme,
22
+ selectedMode,
23
+ includeHiddenFields = false,
24
+ schemeFieldName = 'colorScheme',
25
+ modeFieldName = 'themeMode',
26
+ compact = true,
27
+ } = Astro.props as Props;
28
+
29
+ const schemes = getBuiltInColorSchemes();
30
+ const preference = normalizeThemePreference({ scheme: selectedScheme, mode: selectedMode });
31
+ const activeScheme = schemes.find((scheme) => scheme.id === preference.scheme) ?? schemes[0];
32
+ const initialSwatches = preference.mode === 'dark'
33
+ ? activeScheme.modeSwatches.dark
34
+ : activeScheme.modeSwatches.light;
35
+ const modes = [
36
+ { value: 'system', label: 'System' },
37
+ { value: 'light', label: 'Light' },
38
+ { value: 'dark', label: 'Dark' },
39
+ ];
40
+ ---
41
+
42
+ <div
43
+ class:list={['ts-theme-selector', compact && 'ts-theme-selector--compact']}
44
+ data-ts-theme-selector
45
+ data-selected-scheme={preference.scheme}
46
+ data-selected-mode={preference.mode}
47
+ data-scheme-field={schemeFieldName}
48
+ data-mode-field={modeFieldName}
49
+ >
50
+ <div class="ts-theme-selector__summary">
51
+ <ThemePreviewSwatch swatches={initialSwatches} label={`${activeScheme.name} preview`} />
52
+ <span class="ts-theme-selector__label">
53
+ <span>{label}</span>
54
+ <small data-ts-theme-preview-label>{activeScheme.name} · {preference.mode}</small>
55
+ </span>
56
+ </div>
57
+ <div class="ts-theme-selector__controls">
58
+ <label class="ts-theme-selector__field">
59
+ <span>Color scheme</span>
60
+ <select data-ts-theme-scheme-select aria-label="Color scheme">
61
+ {schemes.map((scheme) => (
62
+ <option value={scheme.id} selected={scheme.id === preference.scheme}>
63
+ {scheme.name}
64
+ </option>
65
+ ))}
66
+ </select>
67
+ </label>
68
+ <label class="ts-theme-selector__field">
69
+ <span>Mode</span>
70
+ <select data-ts-theme-mode-select aria-label="Theme mode">
71
+ {modes.map((mode) => (
72
+ <option value={mode.value} selected={mode.value === preference.mode}>
73
+ {mode.label}
74
+ </option>
75
+ ))}
76
+ </select>
77
+ </label>
78
+ </div>
79
+ {includeHiddenFields ? (
80
+ <>
81
+ <input type="hidden" name={schemeFieldName} value={preference.scheme} data-ts-theme-scheme-field />
82
+ <input type="hidden" name={modeFieldName} value={preference.mode} data-ts-theme-mode-field />
83
+ </>
84
+ ) : null}
85
+ </div>
86
+
87
+ <script is:inline define:vars={{ schemes }}>
88
+ (() => {
89
+ const schemeKey = 'treeseed_color_scheme';
90
+ const modeKey = 'treeseed_theme_mode';
91
+ const maxAge = 60 * 60 * 24 * 365;
92
+ const modeValues = new Set(['light', 'dark', 'system']);
93
+ const schemeValues = new Set(schemes.map((scheme) => scheme.id));
94
+ const schemeMap = new Map(schemes.map((scheme) => [scheme.id, scheme]));
95
+ const media = window.matchMedia?.('(prefers-color-scheme: dark)');
96
+
97
+ function cookie(name, value) {
98
+ const secure = window.location.protocol === 'https:' ? '; Secure' : '';
99
+ document.cookie = `${name}=${encodeURIComponent(value)}; Max-Age=${maxAge}; Path=/; SameSite=Lax${secure}`;
100
+ }
101
+
102
+ function store(name, value) {
103
+ try {
104
+ window.sessionStorage.setItem(name, value);
105
+ } catch {
106
+ // Session storage can be disabled; local storage/cookies still carry the preference.
107
+ }
108
+ try {
109
+ window.localStorage.setItem(name, value);
110
+ } catch {
111
+ // Storage can be disabled; cookies still carry the preference for SSR.
112
+ }
113
+ }
114
+
115
+ function renderedMode(mode) {
116
+ if (mode !== 'system') return mode;
117
+ return media?.matches ? 'dark' : 'light';
118
+ }
119
+
120
+ function applyTheme(scheme, mode, persist = true) {
121
+ const root = document.documentElement;
122
+ const safeScheme = schemeValues.has(scheme) ? scheme : 'fern';
123
+ const safeMode = modeValues.has(mode) ? mode : 'system';
124
+ root.dataset.tsScheme = safeScheme;
125
+ root.dataset.tsMode = renderedMode(safeMode);
126
+ if (safeMode === 'system') {
127
+ root.dataset.tsModeSource = 'system';
128
+ } else {
129
+ delete root.dataset.tsModeSource;
130
+ }
131
+ if (persist) {
132
+ cookie(schemeKey, safeScheme);
133
+ cookie(modeKey, safeMode);
134
+ store(schemeKey, safeScheme);
135
+ store(modeKey, safeMode);
136
+ }
137
+ window.dispatchEvent(new CustomEvent('treeseed:theme-change', {
138
+ detail: { scheme: safeScheme, mode: safeMode, renderedMode: renderedMode(safeMode) },
139
+ }));
140
+ }
141
+
142
+ function modeSwatches(scheme, mode) {
143
+ const rendered = renderedMode(mode);
144
+ return scheme.modeSwatches?.[rendered] || scheme.swatches || [];
145
+ }
146
+
147
+ function updateSwatch(selector, schemeId, mode) {
148
+ const scheme = schemeMap.get(schemeId);
149
+ const swatch = selector.querySelector('.ts-theme-swatch');
150
+ const previewLabel = selector.querySelector('[data-ts-theme-preview-label]');
151
+ if (!scheme || !swatch) return;
152
+ swatch.setAttribute('aria-label', `${scheme.name} preview`);
153
+ modeSwatches(scheme, mode).slice(0, 4).forEach((value, index) => {
154
+ swatch.style.setProperty(`--ts-preview-swatch-${index + 1}`, value);
155
+ });
156
+ if (previewLabel) {
157
+ previewLabel.textContent = `${scheme.name} · ${mode === 'system' ? `System ${renderedMode(mode)}` : mode}`;
158
+ }
159
+ }
160
+
161
+ function currentPreference() {
162
+ const root = document.documentElement;
163
+ const scheme = schemeValues.has(root.dataset.tsScheme) ? root.dataset.tsScheme : '';
164
+ const mode = root.dataset.tsModeSource === 'system' ? 'system' : root.dataset.tsMode;
165
+ return {
166
+ scheme,
167
+ mode: modeValues.has(mode) ? mode : '',
168
+ };
169
+ }
170
+
171
+ function bind(selector) {
172
+ const schemeSelect = selector.querySelector('[data-ts-theme-scheme-select]');
173
+ const modeSelect = selector.querySelector('[data-ts-theme-mode-select]');
174
+ const schemeField = selector.querySelector('[data-ts-theme-scheme-field]');
175
+ const modeField = selector.querySelector('[data-ts-theme-mode-field]');
176
+ if (!(schemeSelect instanceof HTMLSelectElement) || !(modeSelect instanceof HTMLSelectElement)) return;
177
+
178
+ const activePreference = currentPreference();
179
+ if (activePreference.scheme) schemeSelect.value = activePreference.scheme;
180
+ if (activePreference.mode) modeSelect.value = activePreference.mode;
181
+
182
+ function sync(persist = true) {
183
+ const scheme = schemeSelect.value;
184
+ const mode = modeSelect.value;
185
+ if (schemeField instanceof HTMLInputElement) schemeField.value = scheme;
186
+ if (modeField instanceof HTMLInputElement) modeField.value = mode;
187
+ updateSwatch(selector, scheme, mode);
188
+ applyTheme(scheme, mode, persist);
189
+ }
190
+
191
+ schemeSelect.addEventListener('change', () => sync(true));
192
+ modeSelect.addEventListener('change', () => sync(true));
193
+ sync(false);
194
+ }
195
+
196
+ document.querySelectorAll('[data-ts-theme-selector]').forEach(bind);
197
+ media?.addEventListener?.('change', () => {
198
+ const mode = document.documentElement.dataset.tsModeSource === 'system' ? 'system' : document.documentElement.dataset.tsMode;
199
+ applyTheme(document.documentElement.dataset.tsScheme || 'fern', mode || 'system', false);
200
+ });
201
+ })();
202
+ </script>
File without changes
@@ -1,13 +1,17 @@
1
1
  export type TreeseedDevWatchEntry = {
2
- kind: 'tenant' | 'package' | 'sdk';
2
+ kind: 'tenant' | 'core' | 'sdk' | 'agent' | 'cli';
3
3
  root: string;
4
+ restartRequired?: boolean;
4
5
  };
5
6
  export type TreeseedDevWatchChange = {
6
7
  changedPaths: string[];
7
8
  tenantChanged: boolean;
8
9
  tenantApiChanged: boolean;
9
- packageChanged: boolean;
10
+ coreChanged: boolean;
10
11
  sdkChanged: boolean;
12
+ agentChanged: boolean;
13
+ cliChanged: boolean;
14
+ commandImplementationChanged: boolean;
11
15
  };
12
16
  export type TreeseedDevWatchController = {
13
17
  stop: () => void;
package/dist/dev-watch.js CHANGED
@@ -95,11 +95,20 @@ function classifyChanges(changedPaths, watchEntries) {
95
95
  sdkChanged: changedPaths.some(
96
96
  (filePath) => watchEntries.some((entry) => entry.kind === "sdk" && matchesEntry(filePath, entry))
97
97
  ),
98
- packageChanged: changedPaths.some(
99
- (filePath) => watchEntries.some((entry) => entry.kind === "package" && matchesEntry(filePath, entry))
98
+ coreChanged: changedPaths.some(
99
+ (filePath) => watchEntries.some((entry) => entry.kind === "core" && matchesEntry(filePath, entry))
100
+ ),
101
+ agentChanged: changedPaths.some(
102
+ (filePath) => watchEntries.some((entry) => entry.kind === "agent" && matchesEntry(filePath, entry))
103
+ ),
104
+ cliChanged: changedPaths.some(
105
+ (filePath) => watchEntries.some((entry) => entry.kind === "cli" && matchesEntry(filePath, entry))
100
106
  ),
101
107
  tenantChanged,
102
- tenantApiChanged: tenantChanged && changedPaths.some(isTenantApiInput)
108
+ tenantApiChanged: tenantChanged && changedPaths.some(isTenantApiInput),
109
+ commandImplementationChanged: changedPaths.some(
110
+ (filePath) => watchEntries.some((entry) => entry.restartRequired === true && matchesEntry(filePath, entry))
111
+ )
103
112
  };
104
113
  }
105
114
  function startPollingWatch({ watchEntries, onChange }) {
package/dist/dev.d.ts CHANGED
@@ -8,12 +8,13 @@ export declare const TREESEED_DEFAULT_API_PORT = 3000;
8
8
  export declare const TREESEED_DEFAULT_LOCAL_SMTP_HOST = "127.0.0.1";
9
9
  export declare const TREESEED_DEFAULT_LOCAL_SMTP_PORT = 1025;
10
10
  export declare const TREESEED_DEFAULT_MAILPIT_UI_PORT = 8025;
11
- export type TreeseedIntegratedDevSurface = 'integrated' | 'web';
11
+ export type TreeseedIntegratedDevSurface = 'integrated' | 'web' | 'api' | 'manager' | 'worker' | 'agents' | 'services';
12
12
  export type TreeseedIntegratedDevSetupMode = 'auto' | 'check' | 'off';
13
13
  export type TreeseedIntegratedDevFeedbackMode = 'live' | 'restart' | 'off';
14
14
  export type TreeseedIntegratedDevOpenMode = 'auto' | 'on' | 'off';
15
15
  export type TreeseedLocalRuntimeMode = 'auto' | 'provider' | 'local';
16
16
  export type TreeseedSelectedLocalRuntime = 'astro-local' | 'cloudflare-wrangler-local' | 'node-local';
17
+ export type TreeseedIntegratedDevCommandId = 'web' | 'api' | 'manager' | 'worker' | 'agents';
17
18
  export type TreeseedLocalRuntimeSelection = {
18
19
  requested: TreeseedLocalRuntimeMode;
19
20
  selected: TreeseedSelectedLocalRuntime;
@@ -44,7 +45,7 @@ export type TreeseedIntegratedDevOptions = {
44
45
  shutdownGraceMs?: number;
45
46
  };
46
47
  export type TreeseedIntegratedDevCommand = {
47
- id: 'web';
48
+ id: TreeseedIntegratedDevCommandId;
48
49
  label: string;
49
50
  command: string;
50
51
  args: string[];
@@ -96,6 +97,13 @@ export type TreeseedIntegratedDevPlan = {
96
97
  watchEntries: TreeseedIntegratedDevWatchEntry[];
97
98
  commands: TreeseedIntegratedDevCommand[];
98
99
  localRuntimes: Record<string, TreeseedLocalRuntimeSelection>;
100
+ restartPolicy: {
101
+ initialBackoffMs: number;
102
+ maxBackoffMs: number;
103
+ setupRetryBackoffMs: number;
104
+ commandImplementationChangesRequireRestart: boolean;
105
+ agentChanges: 'defer';
106
+ };
99
107
  reset: TreeseedIntegratedDevResetPlan | null;
100
108
  };
101
109
  type SpawnLike = (command: string, args: string[], options: SpawnOptions) => ChildProcess;