agent-facets 0.2.2 → 0.3.3

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 (59) hide show
  1. package/bin/facet +181 -0
  2. package/bin/package.json +3 -0
  3. package/package.json +17 -37
  4. package/postinstall.mjs +210 -0
  5. package/.package.json.bak +0 -44
  6. package/.turbo/turbo-build.log +0 -3
  7. package/CHANGELOG.md +0 -85
  8. package/bunfig.toml +0 -2
  9. package/dist/facet +0 -0
  10. package/src/__tests__/cli.test.ts +0 -195
  11. package/src/__tests__/create-build.test.ts +0 -227
  12. package/src/__tests__/edit-integration.test.ts +0 -171
  13. package/src/__tests__/resolve-dir.test.ts +0 -95
  14. package/src/commands/build.ts +0 -58
  15. package/src/commands/create/index.ts +0 -76
  16. package/src/commands/create/types.ts +0 -9
  17. package/src/commands/create/wizard.tsx +0 -75
  18. package/src/commands/create-scaffold.ts +0 -184
  19. package/src/commands/edit/index.ts +0 -144
  20. package/src/commands/edit/wizard.tsx +0 -74
  21. package/src/commands/resolve-dir.ts +0 -98
  22. package/src/commands.ts +0 -40
  23. package/src/help.ts +0 -43
  24. package/src/index.ts +0 -10
  25. package/src/run.ts +0 -82
  26. package/src/suggest.ts +0 -35
  27. package/src/tui/components/asset-description.tsx +0 -17
  28. package/src/tui/components/asset-field-picker.tsx +0 -78
  29. package/src/tui/components/asset-inline-input.tsx +0 -91
  30. package/src/tui/components/asset-item.tsx +0 -44
  31. package/src/tui/components/asset-section.tsx +0 -191
  32. package/src/tui/components/button.tsx +0 -92
  33. package/src/tui/components/editable-field.tsx +0 -172
  34. package/src/tui/components/exit-toast.tsx +0 -20
  35. package/src/tui/components/reconciliation-item.tsx +0 -129
  36. package/src/tui/components/stage-row.tsx +0 -45
  37. package/src/tui/components/version-selector.tsx +0 -79
  38. package/src/tui/context/focus-mode-context.ts +0 -36
  39. package/src/tui/context/focus-order-context.ts +0 -68
  40. package/src/tui/context/form-state-context.ts +0 -260
  41. package/src/tui/editor.ts +0 -40
  42. package/src/tui/gradient.ts +0 -1
  43. package/src/tui/hooks/use-exit-keys.ts +0 -75
  44. package/src/tui/hooks/use-navigation-keys.ts +0 -34
  45. package/src/tui/layouts/wizard-layout.tsx +0 -41
  46. package/src/tui/theme.ts +0 -1
  47. package/src/tui/views/build/build-view.tsx +0 -152
  48. package/src/tui/views/create/confirm-view.tsx +0 -74
  49. package/src/tui/views/create/create-view.tsx +0 -158
  50. package/src/tui/views/create/wizard.tsx +0 -97
  51. package/src/tui/views/edit/edit-confirm-view.tsx +0 -93
  52. package/src/tui/views/edit/edit-types.ts +0 -34
  53. package/src/tui/views/edit/edit-view.tsx +0 -140
  54. package/src/tui/views/edit/manifest-to-form.ts +0 -38
  55. package/src/tui/views/edit/reconciliation-view.tsx +0 -170
  56. package/src/tui/views/edit/use-edit-session.ts +0 -125
  57. package/src/tui/views/edit/wizard.tsx +0 -129
  58. package/src/version.ts +0 -3
  59. package/tsconfig.json +0 -4
@@ -1,79 +0,0 @@
1
- import { Box, Text, useInput } from 'ink'
2
- import { useState } from 'react'
3
-
4
- export function VersionSelector({
5
- value,
6
- onChange,
7
- onSubmit,
8
- active,
9
- }: {
10
- value: string
11
- onChange: (v: string) => void
12
- onSubmit: () => void
13
- active: boolean
14
- }) {
15
- const parts = value.split('.').map(Number)
16
- const [cursor, setCursor] = useState(0) // 0=major, 1=minor, 2=patch
17
-
18
- useInput(
19
- (input, key) => {
20
- if (!active) return
21
-
22
- if (key.return) {
23
- onSubmit()
24
- return
25
- }
26
- // Tab and left/right all move between segments
27
- if (key.leftArrow || (key.shift && key.tab)) {
28
- setCursor((c) => Math.max(0, c - 1))
29
- return
30
- }
31
- if (key.rightArrow || key.tab) {
32
- setCursor((c) => Math.min(2, c + 1))
33
- return
34
- }
35
- if (key.upArrow) {
36
- const next = [...parts]
37
- next[cursor] = (next[cursor] ?? 0) + 1
38
- onChange(next.join('.'))
39
- return
40
- }
41
- if (key.downArrow) {
42
- const next = [...parts]
43
- next[cursor] = Math.max(0, (next[cursor] ?? 0) - 1)
44
- onChange(next.join('.'))
45
- return
46
- }
47
- // Allow typing a full version directly
48
- if (key.backspace) {
49
- onChange(value.slice(0, -1))
50
- return
51
- }
52
- if (/[0-9.]/.test(input)) {
53
- onChange(value + input)
54
- return
55
- }
56
- },
57
- { isActive: active },
58
- )
59
-
60
- const segments = value.split('.')
61
- return (
62
- <Box gap={0}>
63
- {segments.map((seg, i) => (
64
- // biome-ignore lint/suspicious/noArrayIndexKey: version segments are always positional (major.minor.patch)
65
- <Box key={i}>
66
- {i > 0 && <Text dimColor>.</Text>}
67
- <Text
68
- bold={active && cursor === i}
69
- color={active && cursor === i ? 'cyan' : undefined}
70
- inverse={active && cursor === i}
71
- >
72
- {seg}
73
- </Text>
74
- </Box>
75
- ))}
76
- {active && <Text dimColor>← → to select, ↑ ↓ to change, Enter to confirm</Text>}
77
- </Box>
78
- )
79
- }
@@ -1,36 +0,0 @@
1
- import type { Dispatch, ReactNode, SetStateAction } from 'react'
2
- import { createContext, createElement, useContext, useMemo, useState } from 'react'
3
-
4
- export type FocusMode =
5
- | 'form-navigation'
6
- | 'field-initial-entry'
7
- | 'field-revision'
8
- | 'exit-modal'
9
- | 'form-confirmation'
10
-
11
- interface FocusModeState {
12
- mode: FocusMode
13
- setMode: (mode: FocusMode) => void
14
- exitSecondsLeft: number
15
- setExitSecondsLeft: Dispatch<SetStateAction<number>>
16
- }
17
-
18
- const FocusModeContext = createContext<FocusModeState>({
19
- mode: 'form-navigation',
20
- setMode: () => {},
21
- exitSecondsLeft: 0,
22
- setExitSecondsLeft: () => {},
23
- })
24
-
25
- export function FocusModeProvider({ children }: { children: ReactNode }) {
26
- const [mode, setMode] = useState<FocusMode>('form-navigation')
27
- const [exitSecondsLeft, setExitSecondsLeft] = useState(0)
28
-
29
- const value = useMemo(() => ({ mode, setMode, exitSecondsLeft, setExitSecondsLeft }), [mode, exitSecondsLeft])
30
-
31
- return createElement(FocusModeContext.Provider, { value }, children)
32
- }
33
-
34
- export function useFocusMode() {
35
- return useContext(FocusModeContext)
36
- }
@@ -1,68 +0,0 @@
1
- import type { Dispatch, ReactNode, SetStateAction } from 'react'
2
- import { createContext, createElement, useCallback, useContext, useMemo, useState } from 'react'
3
-
4
- interface FocusOrderState {
5
- focusedId: string | null
6
- focusIds: string[]
7
- setFocusIds: (ids: string[]) => void
8
- setFocusedId: Dispatch<SetStateAction<string | null>>
9
- focusNext: () => void
10
- focusPrevious: () => void
11
- focus: (id: string) => void
12
- }
13
-
14
- const FocusOrderContext = createContext<FocusOrderState>({
15
- focusedId: null,
16
- focusIds: [],
17
- setFocusIds: () => {},
18
- setFocusedId: () => {},
19
- focusNext: () => {},
20
- focusPrevious: () => {},
21
- focus: () => {},
22
- })
23
-
24
- export function FocusOrderProvider({
25
- children,
26
- initialFocusId,
27
- }: {
28
- children: ReactNode
29
- initialFocusId?: string | null
30
- }) {
31
- const [focusIds, setFocusIds] = useState<string[]>([])
32
- const [focusedId, setFocusedId] = useState<string | null>(initialFocusId ?? null)
33
-
34
- const focusNext = useCallback(() => {
35
- setFocusedId((current) => {
36
- if (!current || focusIds.length === 0) return focusIds[0] ?? null
37
- const idx = focusIds.indexOf(current)
38
- if (idx === -1) return focusIds[0] ?? null
39
- if (idx === focusIds.length - 1) return current
40
- return focusIds[idx + 1] ?? null
41
- })
42
- }, [focusIds])
43
-
44
- const focusPrevious = useCallback(() => {
45
- setFocusedId((current) => {
46
- if (!current || focusIds.length === 0) return focusIds[0] ?? null
47
- const idx = focusIds.indexOf(current)
48
- if (idx === -1) return focusIds[0] ?? null
49
- if (idx === 0) return current
50
- return focusIds[idx - 1] ?? null
51
- })
52
- }, [focusIds])
53
-
54
- const focus = useCallback((id: string) => {
55
- setFocusedId(id)
56
- }, [])
57
-
58
- const value = useMemo(
59
- () => ({ focusedId, focusIds, setFocusIds, setFocusedId, focusNext, focusPrevious, focus }),
60
- [focusedId, focusIds, focusNext, focusPrevious, focus],
61
- )
62
-
63
- return createElement(FocusOrderContext.Provider, { value }, children)
64
- }
65
-
66
- export function useFocusOrder() {
67
- return useContext(FocusOrderContext)
68
- }
@@ -1,260 +0,0 @@
1
- import type { ReactNode } from 'react'
2
- import { createContext, createElement, useCallback, useContext, useMemo, useState } from 'react'
3
- import type { CreateOptions } from '../../commands/create-scaffold.ts'
4
- import { isValidKebabCase } from '../../commands/create-scaffold.ts'
5
-
6
- // --- Types ---
7
-
8
- export type FieldStatus = 'empty' | 'editing' | 'confirmed'
9
- export type RequiredFieldKey = 'name' | 'description' | 'version'
10
- export type AssetSectionKey = 'skill' | 'command' | 'agent'
11
-
12
- export interface FieldState {
13
- value: string
14
- status: FieldStatus
15
- }
16
-
17
- export interface AssetSectionState {
18
- items: string[]
19
- descriptions: Record<string, string>
20
- editing?: string
21
- adding: boolean
22
- }
23
-
24
- export interface FormState {
25
- fields: {
26
- name: FieldState
27
- description: FieldState
28
- version: FieldState
29
- }
30
- assets: {
31
- skill: AssetSectionState
32
- command: AssetSectionState
33
- agent: AssetSectionState
34
- }
35
- }
36
-
37
- // --- Context value ---
38
-
39
- interface FormStateContextValue {
40
- form: FormState
41
-
42
- // Field operations
43
- setFieldValue: (field: RequiredFieldKey, value: string) => void
44
- setFieldStatus: (field: RequiredFieldKey, status: FieldStatus) => void
45
-
46
- // Asset operations
47
- addAsset: (section: AssetSectionKey, name: string) => void
48
- removeAsset: (section: AssetSectionKey, name: string) => void
49
- renameAsset: (section: AssetSectionKey, oldName: string, newName: string) => void
50
- setAssetDescription: (section: AssetSectionKey, name: string, description: string) => void
51
- setAssetAdding: (section: AssetSectionKey, adding: boolean) => void
52
- setAssetEditing: (section: AssetSectionKey, name?: string) => void
53
-
54
- // Build CreateOptions for scaffold
55
- toCreateOptions: () => CreateOptions
56
- }
57
-
58
- // --- Defaults ---
59
-
60
- const defaultAssetSection: AssetSectionState = {
61
- items: [],
62
- descriptions: {},
63
- editing: undefined,
64
- adding: false,
65
- }
66
-
67
- const defaultForm: FormState = {
68
- fields: {
69
- name: { value: '', status: 'empty' },
70
- description: { value: '', status: 'empty' },
71
- version: { value: '', status: 'empty' },
72
- },
73
- assets: {
74
- skill: { ...defaultAssetSection },
75
- command: { ...defaultAssetSection },
76
- agent: { ...defaultAssetSection },
77
- },
78
- }
79
-
80
- const FormStateContext = createContext<FormStateContextValue>({
81
- form: defaultForm,
82
- setFieldValue: () => {},
83
- setFieldStatus: () => {},
84
- addAsset: () => {},
85
- removeAsset: () => {},
86
- renameAsset: () => {},
87
- setAssetDescription: () => {},
88
- setAssetAdding: () => {},
89
- setAssetEditing: () => {},
90
- toCreateOptions: () => ({ name: '', version: '', description: '', skills: [], commands: [], agents: [] }),
91
- })
92
-
93
- // --- Provider ---
94
-
95
- export function FormStateProvider({ children, initialState }: { children: ReactNode; initialState?: FormState }) {
96
- const [form, setForm] = useState<FormState>(initialState ?? defaultForm)
97
-
98
- const setFieldValue = useCallback((field: RequiredFieldKey, value: string) => {
99
- setForm((prev) => ({
100
- ...prev,
101
- fields: {
102
- ...prev.fields,
103
- [field]: { ...prev.fields[field], value },
104
- },
105
- }))
106
- }, [])
107
-
108
- const setFieldStatus = useCallback((field: RequiredFieldKey, status: FieldStatus) => {
109
- setForm((prev) => ({
110
- ...prev,
111
- fields: {
112
- ...prev.fields,
113
- [field]: { ...prev.fields[field], status },
114
- },
115
- }))
116
- }, [])
117
-
118
- const addAsset = useCallback((section: AssetSectionKey, name: string) => {
119
- if (!isValidKebabCase(name)) return
120
- setForm((prev) => {
121
- const current = prev.assets[section]
122
- if (current.items.includes(name)) return prev
123
- const defaultDesc = `The ${name} ${section} description`
124
- return {
125
- ...prev,
126
- assets: {
127
- ...prev.assets,
128
- [section]: {
129
- ...current,
130
- items: [...current.items, name],
131
- descriptions: { ...current.descriptions, [name]: defaultDesc },
132
- },
133
- },
134
- }
135
- })
136
- }, [])
137
-
138
- const removeAsset = useCallback((section: AssetSectionKey, name: string) => {
139
- setForm((prev) => {
140
- const current = prev.assets[section]
141
- const { [name]: _, ...remainingDescs } = current.descriptions
142
- return {
143
- ...prev,
144
- assets: {
145
- ...prev.assets,
146
- [section]: {
147
- ...current,
148
- items: current.items.filter((item) => item !== name),
149
- descriptions: remainingDescs,
150
- editing: current.editing === name ? undefined : current.editing,
151
- },
152
- },
153
- }
154
- })
155
- }, [])
156
-
157
- const renameAsset = useCallback((section: AssetSectionKey, oldName: string, newName: string) => {
158
- if (!isValidKebabCase(newName)) return
159
- setForm((prev) => {
160
- const current = prev.assets[section]
161
- if (current.items.includes(newName)) return prev
162
- const { [oldName]: desc, ...restDescs } = current.descriptions
163
- return {
164
- ...prev,
165
- assets: {
166
- ...prev.assets,
167
- [section]: {
168
- ...current,
169
- items: current.items.map((item) => (item === oldName ? newName : item)),
170
- descriptions: { ...restDescs, [newName]: desc ?? `A ${newName} ${section}` },
171
- editing: current.editing === oldName ? newName : current.editing,
172
- },
173
- },
174
- }
175
- })
176
- }, [])
177
-
178
- const setAssetDescription = useCallback((section: AssetSectionKey, name: string, description: string) => {
179
- setForm((prev) => {
180
- const current = prev.assets[section]
181
- return {
182
- ...prev,
183
- assets: {
184
- ...prev.assets,
185
- [section]: {
186
- ...current,
187
- descriptions: { ...current.descriptions, [name]: description },
188
- },
189
- },
190
- }
191
- })
192
- }, [])
193
-
194
- const setAssetAdding = useCallback((section: AssetSectionKey, adding: boolean) => {
195
- setForm((prev) => ({
196
- ...prev,
197
- assets: {
198
- ...prev.assets,
199
- [section]: { ...prev.assets[section], adding },
200
- },
201
- }))
202
- }, [])
203
-
204
- const setAssetEditing = useCallback((section: AssetSectionKey, name?: string) => {
205
- setForm((prev) => ({
206
- ...prev,
207
- assets: {
208
- ...prev.assets,
209
- [section]: { ...prev.assets[section], editing: name },
210
- },
211
- }))
212
- }, [])
213
-
214
- const toCreateOptions = useCallback(
215
- (): CreateOptions => ({
216
- name: form.fields.name.value,
217
- version: form.fields.version.value,
218
- description: form.fields.description.value,
219
- skills: form.assets.skill.items,
220
- commands: form.assets.command.items,
221
- agents: form.assets.agent.items,
222
- }),
223
- [form],
224
- )
225
-
226
- const value = useMemo<FormStateContextValue>(
227
- () => ({
228
- form,
229
- setFieldValue,
230
- setFieldStatus,
231
- addAsset,
232
- removeAsset,
233
- renameAsset,
234
- setAssetDescription,
235
- setAssetAdding,
236
- setAssetEditing,
237
- toCreateOptions,
238
- }),
239
- [
240
- form,
241
- setFieldValue,
242
- setFieldStatus,
243
- addAsset,
244
- removeAsset,
245
- renameAsset,
246
- setAssetDescription,
247
- setAssetAdding,
248
- setAssetEditing,
249
- toCreateOptions,
250
- ],
251
- )
252
-
253
- return createElement(FormStateContext.Provider, { value }, children)
254
- }
255
-
256
- // --- Hook ---
257
-
258
- export function useFormState() {
259
- return useContext(FormStateContext)
260
- }
package/src/tui/editor.ts DELETED
@@ -1,40 +0,0 @@
1
- import { spawnSync } from 'node:child_process'
2
- import { readFileSync, unlinkSync, writeFileSync } from 'node:fs'
3
- import { tmpdir } from 'node:os'
4
- import { join } from 'node:path'
5
-
6
- /**
7
- * Opens the user's preferred terminal editor with the given content.
8
- * Returns the edited content after the editor closes.
9
- *
10
- * This is synchronous — it blocks the event loop while the editor is open.
11
- * Callers must ensure the TUI is in a safe state before calling.
12
- *
13
- * Uses $VISUAL, $EDITOR, or falls back to 'vi'.
14
- */
15
- export function openInEditorSync(content: string, filename = 'description.md'): string | null {
16
- const editor = process.env.VISUAL || process.env.EDITOR || 'vi'
17
- const tmpFile = join(tmpdir(), `facet-${Date.now()}-${filename}`)
18
-
19
- writeFileSync(tmpFile, content, 'utf-8')
20
-
21
- // Split editor command to support args (e.g., "code --wait")
22
- const [cmd, ...args] = editor.split(' ')
23
- if (!cmd) return null
24
-
25
- const result = spawnSync(cmd, [...args, tmpFile], {
26
- stdio: 'inherit',
27
- })
28
-
29
- if (result.status !== 0) return null
30
-
31
- const edited = readFileSync(tmpFile, 'utf-8')
32
-
33
- try {
34
- unlinkSync(tmpFile)
35
- } catch {
36
- // Ignore cleanup failures
37
- }
38
-
39
- return edited
40
- }
@@ -1 +0,0 @@
1
- export { GRADIENT_STOPS, getAnimatedGradient } from '@agent-facets/brand'
@@ -1,75 +0,0 @@
1
- import { useInput } from 'ink'
2
- import { useCallback, useEffect, useRef } from 'react'
3
- import { useFocusMode } from '../context/focus-mode-context.ts'
4
-
5
- const EXIT_WINDOW_MS = 3000
6
-
7
- /**
8
- * Handles exit via double-tap Escape with a visible countdown toast.
9
- *
10
- * First Escape (when not editing): sets mode to 'exit-modal', starts countdown.
11
- * Second Escape (while in exit-modal): exits.
12
- * After 3 seconds: returns to 'form-navigation'.
13
- * Any other key while in exit-modal: returns to previous mode.
14
- */
15
- export function useExitKeys(onExit: () => void) {
16
- const { mode, setMode, setExitSecondsLeft } = useFocusMode()
17
- const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
18
- const countdownRef = useRef<ReturnType<typeof setInterval> | null>(null)
19
- const previousModeRef = useRef(mode)
20
-
21
- const clearTimers = useCallback(() => {
22
- if (timerRef.current) {
23
- clearTimeout(timerRef.current)
24
- timerRef.current = null
25
- }
26
- if (countdownRef.current) {
27
- clearInterval(countdownRef.current)
28
- countdownRef.current = null
29
- }
30
- }, [])
31
-
32
- const dismiss = useCallback(() => {
33
- setExitSecondsLeft(0)
34
- clearTimers()
35
- setMode(previousModeRef.current === 'exit-modal' ? 'form-navigation' : previousModeRef.current)
36
- }, [clearTimers, setMode, setExitSecondsLeft])
37
-
38
- const startExitWindow = useCallback(() => {
39
- previousModeRef.current = mode
40
- setMode('exit-modal')
41
- setExitSecondsLeft(3)
42
-
43
- clearTimers()
44
-
45
- countdownRef.current = setInterval(() => {
46
- setExitSecondsLeft((prev: number) => {
47
- if (prev <= 1) return 0
48
- return prev - 1
49
- })
50
- }, 1000)
51
-
52
- timerRef.current = setTimeout(() => {
53
- dismiss()
54
- }, EXIT_WINDOW_MS)
55
- }, [clearTimers, dismiss, mode, setMode, setExitSecondsLeft])
56
-
57
- useEffect(() => clearTimers, [clearTimers])
58
-
59
- useInput((_input, key) => {
60
- if (key.escape) {
61
- if (mode === 'exit-modal') {
62
- clearTimers()
63
- onExit()
64
- } else if (mode !== 'field-revision') {
65
- startExitWindow()
66
- }
67
- return
68
- }
69
-
70
- // Any other key while in exit-modal dismisses it
71
- if (mode === 'exit-modal') {
72
- dismiss()
73
- }
74
- })
75
- }
@@ -1,34 +0,0 @@
1
- import { useInput } from 'ink'
2
- import { useFocusMode } from '../context/focus-mode-context.ts'
3
- import { useFocusOrder } from '../context/focus-order-context.ts'
4
-
5
- export function useNavigationKeys() {
6
- const { mode } = useFocusMode()
7
- const { focusNext, focusPrevious } = useFocusOrder()
8
-
9
- const isActive = mode === 'form-navigation' || mode === 'form-confirmation'
10
-
11
- useInput(
12
- (_input, key) => {
13
- if (key.downArrow || key.tab) {
14
- focusNext()
15
- return
16
- }
17
- if (key.upArrow || (key.shift && key.tab)) {
18
- focusPrevious()
19
- return
20
- }
21
- if (mode === 'form-confirmation') {
22
- if (key.rightArrow) {
23
- focusNext()
24
- return
25
- }
26
- if (key.leftArrow) {
27
- focusPrevious()
28
- return
29
- }
30
- }
31
- },
32
- { isActive },
33
- )
34
- }
@@ -1,41 +0,0 @@
1
- import { Box, Text } from 'ink'
2
- import Gradient from 'ink-gradient'
3
- import type { ReactNode } from 'react'
4
- import { useEffect, useState } from 'react'
5
- import { ExitFooter } from '../components/exit-toast.tsx'
6
- import { GRADIENT_STOPS, getAnimatedGradient } from '../gradient.ts'
7
- import { THEME } from '../theme.ts'
8
-
9
- const ANIMATION_INTERVAL_MS = 75
10
-
11
- function AnimatedGradientText({ text }: { text: string }) {
12
- const [offset, setOffset] = useState(0)
13
-
14
- useEffect(() => {
15
- const interval = setInterval(() => {
16
- setOffset((prev) => (prev + 1) % GRADIENT_STOPS.length)
17
- }, ANIMATION_INTERVAL_MS)
18
- return () => clearInterval(interval)
19
- }, [])
20
-
21
- return (
22
- <Gradient colors={getAnimatedGradient(offset)}>
23
- <Text bold>{text}</Text>
24
- </Gradient>
25
- )
26
- }
27
-
28
- export function WizardLayout({ children }: { children: ReactNode }) {
29
- return (
30
- <Box flexDirection="column" padding={1} gap={1}>
31
- <Box borderStyle="round" borderColor={THEME.brand} paddingX={2} gap={1}>
32
- <Text bold color={THEME.brand}>
33
- Create a new
34
- </Text>
35
- <AnimatedGradientText text="FACET" />
36
- </Box>
37
- {children}
38
- <ExitFooter />
39
- </Box>
40
- )
41
- }
package/src/tui/theme.ts DELETED
@@ -1 +0,0 @@
1
- export { THEME } from '@agent-facets/brand'