saeeol 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/package.json +14 -14
  2. package/src/cli/cmd/tui/component/dialog/dialog-agent.tsx +32 -0
  3. package/src/cli/cmd/tui/component/dialog/dialog-command.tsx +190 -0
  4. package/src/cli/cmd/tui/component/dialog/dialog-console-org.tsx +103 -0
  5. package/src/cli/cmd/tui/component/dialog/dialog-go-upsell.tsx +159 -0
  6. package/src/cli/cmd/tui/component/dialog/dialog-mcp.tsx +86 -0
  7. package/src/cli/cmd/tui/component/dialog/dialog-model.tsx +238 -0
  8. package/src/cli/cmd/tui/component/dialog/dialog-provider.tsx +343 -0
  9. package/src/cli/cmd/tui/component/dialog/dialog-session-delete-failed.tsx +103 -0
  10. package/src/cli/cmd/tui/component/dialog/dialog-session-list.tsx +301 -0
  11. package/src/cli/cmd/tui/component/dialog/dialog-session-rename.tsx +35 -0
  12. package/src/cli/cmd/tui/component/dialog/dialog-skill.tsx +37 -0
  13. package/src/cli/cmd/tui/component/dialog/dialog-stash.tsx +87 -0
  14. package/src/cli/cmd/tui/component/dialog/dialog-status.tsx +190 -0
  15. package/src/cli/cmd/tui/component/dialog/dialog-tag.tsx +44 -0
  16. package/src/cli/cmd/tui/component/dialog/dialog-theme-list.tsx +50 -0
  17. package/src/cli/cmd/tui/component/dialog/dialog-variant.tsx +39 -0
  18. package/src/cli/cmd/tui/component/dialog/dialog-workspace-create.tsx +200 -0
  19. package/src/cli/cmd/tui/component/dialog/dialog-workspace-unavailable.tsx +81 -0
  20. package/src/cli/cmd/tui/component/dialog-agent.tsx +1 -32
  21. package/src/cli/cmd/tui/component/dialog-command.tsx +1 -190
  22. package/src/cli/cmd/tui/component/dialog-console-org.tsx +1 -103
  23. package/src/cli/cmd/tui/component/dialog-go-upsell.tsx +1 -159
  24. package/src/cli/cmd/tui/component/dialog-mcp.tsx +1 -86
  25. package/src/cli/cmd/tui/component/dialog-model.tsx +1 -238
  26. package/src/cli/cmd/tui/component/dialog-provider.tsx +1 -343
  27. package/src/cli/cmd/tui/component/dialog-session-delete-failed.tsx +1 -103
  28. package/src/cli/cmd/tui/component/dialog-session-list.tsx +1 -301
  29. package/src/cli/cmd/tui/component/dialog-session-rename.tsx +1 -35
  30. package/src/cli/cmd/tui/component/dialog-skill.tsx +1 -37
  31. package/src/cli/cmd/tui/component/dialog-stash.tsx +1 -87
  32. package/src/cli/cmd/tui/component/dialog-status.tsx +1 -190
  33. package/src/cli/cmd/tui/component/dialog-tag.tsx +1 -44
  34. package/src/cli/cmd/tui/component/dialog-theme-list.tsx +1 -50
  35. package/src/cli/cmd/tui/component/dialog-variant.tsx +1 -39
  36. package/src/cli/cmd/tui/component/dialog-workspace-create.tsx +1 -200
  37. package/src/cli/cmd/tui/component/dialog-workspace-unavailable.tsx +1 -81
  38. package/src/session/compaction-helpers.ts +1 -169
  39. package/src/session/compaction.ts +1 -712
  40. package/src/session/core/compaction/compaction-helpers.ts +169 -0
  41. package/src/session/core/compaction/compaction.ts +712 -0
  42. package/src/session/core/compaction/overflow.ts +28 -0
  43. package/src/session/core/instruction.ts +234 -0
  44. package/src/session/core/llm.ts +504 -0
  45. package/src/session/core/network.ts +392 -0
  46. package/src/session/core/processor.ts +731 -0
  47. package/src/session/core/projectors.ts +139 -0
  48. package/src/session/core/resolve-tools.ts +241 -0
  49. package/src/session/core/retry.ts +149 -0
  50. package/src/session/core/revert.ts +173 -0
  51. package/src/session/core/run-state.ts +110 -0
  52. package/src/session/core/schema.ts +35 -0
  53. package/src/session/core/session-types.ts +160 -0
  54. package/src/session/core/session.sql.ts +124 -0
  55. package/src/session/core/session.ts +948 -0
  56. package/src/session/core/shell-exec.ts +205 -0
  57. package/src/session/core/status.ts +100 -0
  58. package/src/session/core/subtask.ts +268 -0
  59. package/src/session/core/summary.ts +173 -0
  60. package/src/session/core/system.ts +114 -0
  61. package/src/session/core/todo.ts +86 -0
  62. package/src/session/core/user-part.ts +293 -0
  63. package/src/session/instruction.ts +1 -234
  64. package/src/session/llm.ts +1 -504
  65. package/src/session/message/message-errors.ts +83 -0
  66. package/src/session/message/message-parts.ts +89 -0
  67. package/src/session/message/message-query.ts +107 -0
  68. package/src/session/message/message-transform.ts +156 -0
  69. package/src/session/message/message-types.ts +68 -0
  70. package/src/session/message/message-v2.ts +73 -0
  71. package/src/session/message/message.ts +192 -0
  72. package/src/session/message-errors.ts +1 -83
  73. package/src/session/message-parts.ts +1 -89
  74. package/src/session/message-query.ts +1 -107
  75. package/src/session/message-transform.ts +1 -156
  76. package/src/session/message-types.ts +1 -68
  77. package/src/session/message-v2.ts +1 -73
  78. package/src/session/message.ts +1 -192
  79. package/src/session/network.ts +1 -392
  80. package/src/session/overflow.ts +1 -28
  81. package/src/session/processor.ts +1 -731
  82. package/src/session/projectors.ts +2 -139
  83. package/src/session/prompt/prompt-command.ts +93 -0
  84. package/src/session/prompt/prompt-loop.ts +299 -0
  85. package/src/session/prompt/prompt-model.ts +44 -0
  86. package/src/session/prompt/prompt-reminders.ts +120 -0
  87. package/src/session/prompt/prompt-resolve.ts +42 -0
  88. package/src/session/prompt/prompt-schemas.ts +128 -0
  89. package/src/session/prompt/prompt-title.ts +55 -0
  90. package/src/session/prompt/prompt-types.ts +47 -0
  91. package/src/session/prompt/prompt-user-msg.ts +80 -0
  92. package/src/session/prompt/prompt.ts +211 -0
  93. package/src/session/prompt-command.ts +1 -93
  94. package/src/session/prompt-loop.ts +1 -299
  95. package/src/session/prompt-model.ts +1 -44
  96. package/src/session/prompt-reminders.ts +1 -120
  97. package/src/session/prompt-resolve.ts +1 -42
  98. package/src/session/prompt-schemas.ts +1 -128
  99. package/src/session/prompt-title.ts +1 -55
  100. package/src/session/prompt-types.ts +1 -47
  101. package/src/session/prompt-user-msg.ts +1 -80
  102. package/src/session/prompt.ts +1 -211
  103. package/src/session/resolve-tools.ts +1 -241
  104. package/src/session/retry.ts +1 -149
  105. package/src/session/revert.ts +1 -173
  106. package/src/session/run-state.ts +1 -110
  107. package/src/session/schema.ts +1 -35
  108. package/src/session/session-types.ts +1 -160
  109. package/src/session/session.sql.ts +1 -124
  110. package/src/session/session.ts +1 -948
  111. package/src/session/shell-exec.ts +1 -205
  112. package/src/session/status.ts +1 -100
  113. package/src/session/subtask.ts +1 -268
  114. package/src/session/summary.ts +1 -173
  115. package/src/session/system.ts +1 -114
  116. package/src/session/todo.ts +1 -86
  117. package/src/session/user-part.ts +1 -293
  118. package/src/tool/apply_patch.ts +1 -334
  119. package/src/tool/bash.ts +1 -656
  120. package/src/tool/core/external-directory.ts +55 -0
  121. package/src/tool/core/invalid.ts +21 -0
  122. package/src/tool/core/recall.ts +164 -0
  123. package/src/tool/core/recall.txt +12 -0
  124. package/src/tool/core/schema.ts +16 -0
  125. package/src/tool/core/tool.ts +162 -0
  126. package/src/tool/core/truncate.ts +160 -0
  127. package/src/tool/core/truncation-dir.ts +4 -0
  128. package/src/tool/diagnostics.ts +1 -20
  129. package/src/tool/edit-replacers.ts +1 -288
  130. package/src/tool/edit-utils.ts +1 -86
  131. package/src/tool/edit.ts +1 -262
  132. package/src/tool/external-directory.ts +1 -55
  133. package/src/tool/file/apply_patch.ts +334 -0
  134. package/src/tool/file/apply_patch.txt +33 -0
  135. package/src/tool/file/bash.ts +656 -0
  136. package/src/tool/file/bash.txt +119 -0
  137. package/src/tool/file/edit-replacers.ts +288 -0
  138. package/src/tool/file/edit-utils.ts +86 -0
  139. package/src/tool/file/edit.ts +262 -0
  140. package/src/tool/file/edit.txt +10 -0
  141. package/src/tool/file/read.ts +389 -0
  142. package/src/tool/file/read.txt +14 -0
  143. package/src/tool/file/write.ts +114 -0
  144. package/src/tool/file/write.txt +8 -0
  145. package/src/tool/glob.ts +1 -115
  146. package/src/tool/grep.ts +1 -151
  147. package/src/tool/integration/diagnostics.ts +20 -0
  148. package/src/tool/integration/lsp.ts +113 -0
  149. package/src/tool/integration/lsp.txt +24 -0
  150. package/src/tool/integration/mcp-exa.ts +73 -0
  151. package/src/tool/integration/package.ts +168 -0
  152. package/src/tool/integration/registry.ts +375 -0
  153. package/src/tool/invalid.ts +1 -21
  154. package/src/tool/lsp.ts +1 -113
  155. package/src/tool/mcp-exa.ts +1 -73
  156. package/src/tool/package.ts +1 -168
  157. package/src/tool/plan.ts +1 -30
  158. package/src/tool/question.ts +1 -52
  159. package/src/tool/read.ts +1 -389
  160. package/src/tool/recall.ts +1 -164
  161. package/src/tool/registry.ts +1 -375
  162. package/src/tool/schema.ts +1 -16
  163. package/src/tool/search/glob.ts +115 -0
  164. package/src/tool/search/glob.txt +6 -0
  165. package/src/tool/search/grep.ts +151 -0
  166. package/src/tool/search/grep.txt +8 -0
  167. package/src/tool/search/warpgrep.ts +107 -0
  168. package/src/tool/search/warpgrep.txt +10 -0
  169. package/src/tool/search/webfetch.ts +202 -0
  170. package/src/tool/search/webfetch.txt +13 -0
  171. package/src/tool/search/websearch.ts +71 -0
  172. package/src/tool/search/websearch.txt +14 -0
  173. package/src/tool/skill.ts +1 -91
  174. package/src/tool/task.ts +1 -197
  175. package/src/tool/todo.ts +1 -62
  176. package/src/tool/tool.ts +1 -162
  177. package/src/tool/truncate.ts +1 -160
  178. package/src/tool/truncation-dir.ts +1 -4
  179. package/src/tool/warpgrep.ts +1 -107
  180. package/src/tool/webfetch.ts +1 -202
  181. package/src/tool/websearch.ts +1 -71
  182. package/src/tool/workflow/plan-enter.txt +14 -0
  183. package/src/tool/workflow/plan-exit.txt +13 -0
  184. package/src/tool/workflow/plan.ts +30 -0
  185. package/src/tool/workflow/question.ts +52 -0
  186. package/src/tool/workflow/question.txt +11 -0
  187. package/src/tool/workflow/skill.ts +91 -0
  188. package/src/tool/workflow/skill.txt +5 -0
  189. package/src/tool/workflow/task.ts +197 -0
  190. package/src/tool/workflow/task.txt +57 -0
  191. package/src/tool/workflow/todo.ts +62 -0
  192. package/src/tool/workflow/todowrite.txt +167 -0
  193. package/src/tool/write.ts +1 -114
@@ -1,343 +1 @@
1
- import { createMemo, createSignal, onMount, Show } from "solid-js"
2
- import { useSync } from "@tui/context/sync"
3
- import { map, pipe, sortBy } from "remeda"
4
- import { DialogSelect } from "@tui/ui/dialog-select"
5
- import { useDialog } from "@tui/ui/dialog"
6
- import { useSDK } from "../context/sdk"
7
- import { DialogPrompt } from "../ui/dialog-prompt"
8
- import { Link } from "../ui/link"
9
- import { useTheme } from "../context/theme"
10
- import { TextAttributes } from "@opentui/core"
11
- import type { ProviderAuthAuthorization, ProviderAuthMethod } from "@saeeol/sdk/v2"
12
- import { DialogModel } from "./dialog-model"
13
- import { useKeyboard } from "@opentui/solid"
14
- import * as Clipboard from "@tui/util/clipboard"
15
- import { useToast } from "../ui/toast"
16
- import { isConsoleManagedProvider } from "@tui/util/provider-origin"
17
- import * as Provider from "@/saeeol/cli/cmd/tui/component/dialog-provider"
18
- import { useConnected } from "./use-connected"
19
-
20
- const PROVIDER_PRIORITY: Record<string, number> = Provider.PROVIDER_PRIORITY
21
-
22
- export function createDialogProviderOptions() {
23
- const sync = useSync()
24
- const dialog = useDialog()
25
- const sdk = useSDK()
26
- const toast = useToast()
27
- const { theme } = useTheme()
28
- const onboarded = useConnected()
29
- const options = createMemo(() => {
30
- return pipe(
31
- sync.data.provider_next.all,
32
- sortBy((x) => PROVIDER_PRIORITY[x.id] ?? 99),
33
- map((provider) => {
34
- const consoleManaged = isConsoleManagedProvider(sync.data.console_state.consoleManagedProviders, provider.id)
35
- const connected = sync.data.provider_next.connected.includes(provider.id)
36
- const failed = sync.data.provider_next.failed ?? []
37
- const failedGutter = Provider.renderGutter(provider.id, failed, theme)
38
- const failedDesc = Provider.failedDescription(provider.id, failed)
39
- const baseDesc = Provider.PROVIDER_DESCRIPTIONS[provider.id]
40
-
41
- return {
42
- title: Provider.PROVIDER_TITLES[provider.id] ?? provider.name,
43
- value: provider.id,
44
- description: failedDesc ?? baseDesc,
45
- footer: consoleManaged ? sync.data.console_state.activeOrgName : undefined,
46
- category: provider.id in PROVIDER_PRIORITY ? "Popular" : "Other",
47
- gutter: failedGutter ?? (connected && onboarded() ? () => <text fg={theme.success}>✓</text> : undefined),
48
- async onSelect() {
49
- if (consoleManaged) return
50
-
51
- const methods = sync.data.provider_auth[provider.id] ?? [
52
- {
53
- type: "api",
54
- label: "API key",
55
- },
56
- ]
57
- let index: number | null = 0
58
- if (methods.length > 1) {
59
- index = await new Promise<number | null>((resolve) => {
60
- dialog.replace(
61
- () => (
62
- <DialogSelect
63
- title="Select auth method"
64
- options={methods.map((x, index) => ({
65
- title: x.label,
66
- value: index,
67
- }))}
68
- onSelect={(option) => resolve(option.value)}
69
- />
70
- ),
71
- () => resolve(null),
72
- )
73
- })
74
- }
75
- if (index == null) return
76
- const method = methods[index]
77
- if (method.type === "oauth") {
78
- let inputs: Record<string, string> | undefined
79
- if (method.prompts?.length) {
80
- const value = await PromptsMethod({
81
- dialog,
82
- prompts: method.prompts,
83
- })
84
- if (!value) return
85
- inputs = value
86
- }
87
-
88
- const result = await sdk.client.provider.oauth.authorize({
89
- providerID: provider.id,
90
- method: index,
91
- inputs,
92
- })
93
- if (result.error) {
94
- toast.show({
95
- variant: "error",
96
- message: JSON.stringify(result.error),
97
- })
98
- dialog.clear()
99
- return
100
- }
101
- if (result.data?.method === "code") {
102
- dialog.replace(() => (
103
- <CodeMethod
104
- providerID={provider.id}
105
- title={method.label}
106
- index={index}
107
- authorization={result.data!}
108
- />
109
- ))
110
- }
111
- if (result.data?.method === "auto") {
112
- const saeeol = Provider.renderAutoMethod({
113
- providerID: provider.id,
114
- title: method.label,
115
- index,
116
- authorization: result.data!,
117
- useSDK,
118
- useTheme,
119
- DialogModel,
120
- })
121
- if (saeeol) {
122
- dialog.replace(saeeol)
123
- } else {
124
- dialog.replace(() => (
125
- <AutoMethod
126
- providerID={provider.id}
127
- title={method.label}
128
- index={index}
129
- authorization={result.data!}
130
- />
131
- ))
132
- }
133
- }
134
- }
135
- if (method.type === "api") {
136
- let metadata: Record<string, string> | undefined
137
- if (method.prompts?.length) {
138
- const value = await PromptsMethod({ dialog, prompts: method.prompts })
139
- if (!value) return
140
- metadata = value
141
- }
142
- return dialog.replace(() => (
143
- <ApiMethod providerID={provider.id} title={method.label} metadata={metadata} />
144
- ))
145
- }
146
- },
147
- }
148
- }),
149
- )
150
- })
151
- return options
152
- }
153
-
154
- export function DialogProvider() {
155
- const options = createDialogProviderOptions()
156
- return <DialogSelect title="Connect a provider" options={options()} />
157
- }
158
-
159
- interface AutoMethodProps {
160
- index: number
161
- providerID: string
162
- title: string
163
- authorization: ProviderAuthAuthorization
164
- }
165
- function AutoMethod(props: AutoMethodProps) {
166
- const { theme } = useTheme()
167
- const sdk = useSDK()
168
- const dialog = useDialog()
169
- const sync = useSync()
170
- const toast = useToast()
171
-
172
- useKeyboard((evt) => {
173
- if (evt.name === "c" && !evt.ctrl && !evt.meta) {
174
- const code = props.authorization.instructions.match(/[A-Z0-9]{4}-[A-Z0-9]{4,5}/)?.[0] ?? props.authorization.url
175
- Clipboard.copy(code)
176
- .then(() => toast.show({ message: "Copied to clipboard", variant: "info" }))
177
- .catch(toast.error)
178
- }
179
- })
180
-
181
- onMount(async () => {
182
- const result = await sdk.client.provider.oauth.callback({
183
- providerID: props.providerID,
184
- method: props.index,
185
- })
186
- if (result.error) {
187
- dialog.clear()
188
- return
189
- }
190
- await sdk.client.instance.dispose()
191
- await sync.bootstrap()
192
- dialog.replace(() => <DialogModel providerID={props.providerID} />)
193
- })
194
-
195
- return (
196
- <box paddingLeft={2} paddingRight={2} gap={1} paddingBottom={1}>
197
- <box flexDirection="row" justifyContent="space-between">
198
- <text attributes={TextAttributes.BOLD} fg={theme.text}>
199
- {props.title}
200
- </text>
201
- <text fg={theme.textMuted} onMouseUp={() => dialog.clear()}>
202
- esc
203
- </text>
204
- </box>
205
- <box gap={1}>
206
- <Link href={props.authorization.url} fg={theme.primary} />
207
- <text fg={theme.textMuted}>{props.authorization.instructions}</text>
208
- </box>
209
- <text fg={theme.textMuted}>Waiting for authorization...</text>
210
- <text fg={theme.text}>
211
- c <span style={{ fg: theme.textMuted }}>copy</span>
212
- </text>
213
- </box>
214
- )
215
- }
216
-
217
- interface CodeMethodProps {
218
- index: number
219
- title: string
220
- providerID: string
221
- authorization: ProviderAuthAuthorization
222
- }
223
- function CodeMethod(props: CodeMethodProps) {
224
- const { theme } = useTheme()
225
- const sdk = useSDK()
226
- const sync = useSync()
227
- const dialog = useDialog()
228
- const [error, setError] = createSignal(false)
229
-
230
- return (
231
- <DialogPrompt
232
- title={props.title}
233
- placeholder="Authorization code"
234
- onConfirm={async (value) => {
235
- const { error } = await sdk.client.provider.oauth.callback({
236
- providerID: props.providerID,
237
- method: props.index,
238
- code: value,
239
- })
240
- if (!error) {
241
- await sdk.client.instance.dispose()
242
- await sync.bootstrap()
243
- dialog.replace(() => <DialogModel providerID={props.providerID} />)
244
- return
245
- }
246
- setError(true)
247
- }}
248
- description={() => (
249
- <box gap={1}>
250
- <text fg={theme.textMuted}>{props.authorization.instructions}</text>
251
- <Link href={props.authorization.url} fg={theme.primary} />
252
- <Show when={error()}>
253
- <text fg={theme.error}>Invalid code</text>
254
- </Show>
255
- </box>
256
- )}
257
- />
258
- )
259
- }
260
-
261
- interface ApiMethodProps {
262
- providerID: string
263
- title: string
264
- metadata?: Record<string, string>
265
- }
266
- function ApiMethod(props: ApiMethodProps) {
267
- const dialog = useDialog()
268
- const sdk = useSDK()
269
- const sync = useSync()
270
- const { theme } = useTheme()
271
-
272
- return (
273
- <DialogPrompt
274
- title={props.title}
275
- placeholder="API key"
276
- description={Provider.renderApiDescription(props.providerID, theme)}
277
- onConfirm={async (value) => {
278
- if (!value) return
279
- await sdk.client.auth.set({
280
- providerID: props.providerID,
281
- auth: {
282
- type: "api",
283
- key: value,
284
- ...(props.metadata ? { metadata: props.metadata } : {}),
285
- },
286
- })
287
- await sdk.client.instance.dispose()
288
- await sync.bootstrap()
289
- dialog.replace(() => <DialogModel providerID={props.providerID} />)
290
- }}
291
- />
292
- )
293
- }
294
-
295
- interface PromptsMethodProps {
296
- dialog: ReturnType<typeof useDialog>
297
- prompts: NonNullable<ProviderAuthMethod["prompts"]>[number][]
298
- }
299
- async function PromptsMethod(props: PromptsMethodProps) {
300
- const inputs: Record<string, string> = {}
301
- for (const prompt of props.prompts) {
302
- if (prompt.when) {
303
- const value = inputs[prompt.when.key]
304
- if (value === undefined) continue
305
- const matches = prompt.when.op === "eq" ? value === prompt.when.value : value !== prompt.when.value
306
- if (!matches) continue
307
- }
308
-
309
- if (prompt.type === "select") {
310
- const value = await new Promise<string | null>((resolve) => {
311
- props.dialog.replace(
312
- () => (
313
- <DialogSelect
314
- title={prompt.message}
315
- options={prompt.options.map((x) => ({
316
- title: x.label,
317
- value: x.value,
318
- description: x.hint,
319
- }))}
320
- onSelect={(option) => resolve(option.value)}
321
- />
322
- ),
323
- () => resolve(null),
324
- )
325
- })
326
- if (value === null) return null
327
- inputs[prompt.key] = value
328
- continue
329
- }
330
-
331
- const value = await new Promise<string | null>((resolve) => {
332
- props.dialog.replace(
333
- () => (
334
- <DialogPrompt title={prompt.message} placeholder={prompt.placeholder} onConfirm={(value) => resolve(value)} />
335
- ),
336
- () => resolve(null),
337
- )
338
- })
339
- if (value === null) return null
340
- inputs[prompt.key] = value
341
- }
342
- return inputs
343
- }
1
+ export * from "./dialog/dialog-provider"
@@ -1,103 +1 @@
1
- import { TextAttributes } from "@opentui/core"
2
- import { useTheme } from "../context/theme"
3
- import { useDialog } from "../ui/dialog"
4
- import { createStore } from "solid-js/store"
5
- import { For } from "solid-js"
6
- import { useKeyboard } from "@opentui/solid"
7
-
8
- export function DialogSessionDeleteFailed(props: {
9
- session: string
10
- workspace: string
11
- onDelete?: () => boolean | void | Promise<boolean | void>
12
- onRestore?: () => boolean | void | Promise<boolean | void>
13
- onDone?: () => void
14
- }) {
15
- const dialog = useDialog()
16
- const { theme } = useTheme()
17
- const [store, setStore] = createStore({
18
- active: "delete" as "delete" | "restore",
19
- })
20
-
21
- const options = [
22
- {
23
- id: "delete" as const,
24
- title: "Delete workspace",
25
- description: "Delete the workspace and all sessions attached to it.",
26
- run: props.onDelete,
27
- },
28
- {
29
- id: "restore" as const,
30
- title: "Restore to new workspace",
31
- description: "Try to restore this session into a new workspace.",
32
- run: props.onRestore,
33
- },
34
- ]
35
-
36
- async function confirm() {
37
- const result = await options.find((item) => item.id === store.active)?.run?.()
38
- if (result === false) return
39
- props.onDone?.()
40
- if (!props.onDone) dialog.clear()
41
- }
42
-
43
- useKeyboard((evt) => {
44
- if (evt.name === "return") {
45
- evt.preventDefault()
46
- evt.stopPropagation()
47
- void confirm()
48
- }
49
- if (evt.name === "left" || evt.name === "up") {
50
- setStore("active", "delete")
51
- }
52
- if (evt.name === "right" || evt.name === "down") {
53
- setStore("active", "restore")
54
- }
55
- })
56
-
57
- return (
58
- <box paddingLeft={2} paddingRight={2} gap={1}>
59
- <box flexDirection="row" justifyContent="space-between">
60
- <text attributes={TextAttributes.BOLD} fg={theme.text}>
61
- Failed to Delete Session
62
- </text>
63
- <text fg={theme.textMuted} onMouseUp={() => dialog.clear()}>
64
- esc
65
- </text>
66
- </box>
67
- <text fg={theme.textMuted} wrapMode="word">
68
- {`The session "${props.session}" could not be deleted because the workspace "${props.workspace}" is not available.`}
69
- </text>
70
- <text fg={theme.textMuted} wrapMode="word">
71
- Choose how you want to recover this broken workspace session.
72
- </text>
73
- <box flexDirection="column" paddingBottom={1} gap={1}>
74
- <For each={options}>
75
- {(item) => (
76
- <box
77
- flexDirection="column"
78
- paddingLeft={1}
79
- paddingRight={1}
80
- paddingTop={1}
81
- paddingBottom={1}
82
- backgroundColor={item.id === store.active ? theme.primary : undefined}
83
- onMouseUp={() => {
84
- setStore("active", item.id)
85
- void confirm()
86
- }}
87
- >
88
- <text
89
- attributes={TextAttributes.BOLD}
90
- fg={item.id === store.active ? theme.selectedListItemText : theme.text}
91
- >
92
- {item.title}
93
- </text>
94
- <text fg={item.id === store.active ? theme.selectedListItemText : theme.textMuted} wrapMode="word">
95
- {item.description}
96
- </text>
97
- </box>
98
- )}
99
- </For>
100
- </box>
101
- </box>
102
- )
103
- }
1
+ export * from "./dialog/dialog-session-delete-failed"