@prover-coder-ai/docker-git 1.0.23 → 1.0.24

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 (74) hide show
  1. package/package.json +4 -1
  2. package/.jscpd.json +0 -16
  3. package/.package.json.release.bak +0 -111
  4. package/CHANGELOG.md +0 -139
  5. package/biome.json +0 -34
  6. package/eslint.config.mts +0 -305
  7. package/eslint.effect-ts-check.config.mjs +0 -220
  8. package/linter.config.json +0 -33
  9. package/src/app/main.ts +0 -18
  10. package/src/app/program.ts +0 -78
  11. package/src/docker-git/cli/input.ts +0 -29
  12. package/src/docker-git/cli/parser-apply.ts +0 -28
  13. package/src/docker-git/cli/parser-attach.ts +0 -22
  14. package/src/docker-git/cli/parser-auth.ts +0 -154
  15. package/src/docker-git/cli/parser-clone.ts +0 -50
  16. package/src/docker-git/cli/parser-create.ts +0 -3
  17. package/src/docker-git/cli/parser-mcp-playwright.ts +0 -24
  18. package/src/docker-git/cli/parser-options.ts +0 -211
  19. package/src/docker-git/cli/parser-panes.ts +0 -22
  20. package/src/docker-git/cli/parser-scrap.ts +0 -106
  21. package/src/docker-git/cli/parser-sessions.ts +0 -101
  22. package/src/docker-git/cli/parser-shared.ts +0 -51
  23. package/src/docker-git/cli/parser-state.ts +0 -86
  24. package/src/docker-git/cli/parser.ts +0 -83
  25. package/src/docker-git/cli/read-command.ts +0 -26
  26. package/src/docker-git/cli/usage.ts +0 -131
  27. package/src/docker-git/main.ts +0 -18
  28. package/src/docker-git/menu-actions.ts +0 -273
  29. package/src/docker-git/menu-auth-data.ts +0 -184
  30. package/src/docker-git/menu-auth-helpers.ts +0 -30
  31. package/src/docker-git/menu-auth.ts +0 -311
  32. package/src/docker-git/menu-buffer-input.ts +0 -18
  33. package/src/docker-git/menu-create.ts +0 -310
  34. package/src/docker-git/menu-input-handler.ts +0 -183
  35. package/src/docker-git/menu-input-utils.ts +0 -85
  36. package/src/docker-git/menu-input.ts +0 -2
  37. package/src/docker-git/menu-labeled-env.ts +0 -37
  38. package/src/docker-git/menu-menu.ts +0 -58
  39. package/src/docker-git/menu-project-auth-claude.ts +0 -70
  40. package/src/docker-git/menu-project-auth-data.ts +0 -292
  41. package/src/docker-git/menu-project-auth.ts +0 -271
  42. package/src/docker-git/menu-render-auth.ts +0 -65
  43. package/src/docker-git/menu-render-common.ts +0 -67
  44. package/src/docker-git/menu-render-layout.ts +0 -30
  45. package/src/docker-git/menu-render-project-auth.ts +0 -70
  46. package/src/docker-git/menu-render-select.ts +0 -250
  47. package/src/docker-git/menu-render.ts +0 -292
  48. package/src/docker-git/menu-select-actions.ts +0 -150
  49. package/src/docker-git/menu-select-connect.ts +0 -27
  50. package/src/docker-git/menu-select-load.ts +0 -33
  51. package/src/docker-git/menu-select-order.ts +0 -37
  52. package/src/docker-git/menu-select-runtime.ts +0 -143
  53. package/src/docker-git/menu-select-view.ts +0 -25
  54. package/src/docker-git/menu-select.ts +0 -145
  55. package/src/docker-git/menu-shared.ts +0 -256
  56. package/src/docker-git/menu-startup.ts +0 -83
  57. package/src/docker-git/menu-types.ts +0 -170
  58. package/src/docker-git/menu.ts +0 -303
  59. package/src/docker-git/program.ts +0 -154
  60. package/src/docker-git/tmux.ts +0 -292
  61. package/tests/app/main.test.ts +0 -65
  62. package/tests/docker-git/entrypoint-auth.test.ts +0 -40
  63. package/tests/docker-git/fixtures/project-item.ts +0 -24
  64. package/tests/docker-git/menu-select-connect.test.ts +0 -55
  65. package/tests/docker-git/menu-select-order.test.ts +0 -84
  66. package/tests/docker-git/menu-startup.test.ts +0 -51
  67. package/tests/docker-git/parser-helpers.ts +0 -76
  68. package/tests/docker-git/parser-network-options.test.ts +0 -47
  69. package/tests/docker-git/parser.test.ts +0 -284
  70. package/tsconfig.build.json +0 -8
  71. package/tsconfig.json +0 -20
  72. package/vite.config.ts +0 -32
  73. package/vite.docker-git.config.ts +0 -34
  74. package/vitest.config.ts +0 -85
@@ -1,256 +0,0 @@
1
- import type { MenuViewContext, ViewState } from "./menu-types.js"
2
-
3
- import { Effect, pipe } from "effect"
4
-
5
- // CHANGE: share menu escape handling across flows
6
- // WHY: avoid duplicated logic in TUI handlers
7
- // QUOTE(ТЗ): "А ты можешь сделать удобный выбор проектов?"
8
- // REF: user-request-2026-02-02-select-project
9
- // SOURCE: n/a
10
- // FORMAT THEOREM: forall s: escape(s) -> menu(s)
11
- // PURITY: SHELL
12
- // EFFECT: n/a
13
- // INVARIANT: always resets message on escape
14
- // COMPLEXITY: O(1)
15
-
16
- type MenuResetContext = Pick<MenuViewContext, "setView" | "setMessage">
17
-
18
- type OutputWrite = typeof process.stdout.write
19
-
20
- let stdoutPatched = false
21
- let stdoutMuted = false
22
- let baseStdoutWrite: OutputWrite | null = null
23
- let baseStderrWrite: OutputWrite | null = null
24
-
25
- const wrapWrite = (baseWrite: OutputWrite): OutputWrite =>
26
- (
27
- chunk: string | Uint8Array,
28
- encoding?: BufferEncoding | ((err?: Error | null) => void),
29
- cb?: (err?: Error | null) => void
30
- ) => {
31
- if (stdoutMuted) {
32
- const callback = typeof encoding === "function" ? encoding : cb
33
- if (typeof callback === "function") {
34
- callback()
35
- }
36
- return true
37
- }
38
- if (typeof encoding === "function") {
39
- return baseWrite(chunk, encoding)
40
- }
41
- return baseWrite(chunk, encoding, cb)
42
- }
43
-
44
- const disableMouseModes = (): void => {
45
- // Disable xterm/urxvt mouse tracking and "alternate scroll" mode (wheel -> arrow keys).
46
- process.stdout.write(
47
- "\u001B[?1000l\u001B[?1002l\u001B[?1003l\u001B[?1005l\u001B[?1006l\u001B[?1015l\u001B[?1007l"
48
- )
49
- }
50
-
51
- // CHANGE: mute Ink stdout writes while SSH is active
52
- // WHY: prevent Ink resize re-renders from corrupting the SSH terminal buffer
53
- // QUOTE(ТЗ): "при изменении разершения он всё ломает?"
54
- // REF: user-request-2026-02-05-ssh-resize
55
- // SOURCE: n/a
56
- // FORMAT THEOREM: ∀w: muted(w) → ¬writes(ink, stdout)
57
- // PURITY: SHELL
58
- // EFFECT: n/a
59
- // INVARIANT: wrapper preserves original stdout write when not muted
60
- // COMPLEXITY: O(1)
61
- const ensureStdoutPatched = (): void => {
62
- if (stdoutPatched) {
63
- return
64
- }
65
- baseStdoutWrite = process.stdout.write.bind(process.stdout)
66
- baseStderrWrite = process.stderr.write.bind(process.stderr)
67
-
68
- process.stdout.write = wrapWrite(baseStdoutWrite)
69
- process.stderr.write = wrapWrite(baseStderrWrite)
70
- stdoutPatched = true
71
- }
72
-
73
- // CHANGE: allow writing to the terminal even while stdout is muted
74
- // WHY: we mute Ink renders during interactive commands, but still need to show prompts/errors
75
- // REF: user-request-2026-02-18-tui-output-hidden
76
- // SOURCE: n/a
77
- // PURITY: SHELL
78
- // EFFECT: n/a
79
- // INVARIANT: bypasses the mute wrapper safely
80
- export const writeToTerminal = (text: string): void => {
81
- ensureStdoutPatched()
82
- const write = baseStdoutWrite ?? process.stdout.write.bind(process.stdout)
83
- write(text)
84
- }
85
-
86
- // CHANGE: keep the user on the primary screen until they acknowledge
87
- // WHY: otherwise output from failed docker/gh commands gets hidden again when TUI resumes
88
- // REF: user-request-2026-02-18-tui-output-hidden
89
- // SOURCE: n/a
90
- // PURITY: SHELL
91
- // EFFECT: Effect<void, never, never>
92
- // INVARIANT: no-op when stdin/stdout aren't TTY (CI/e2e)
93
- export const pauseForEnter = (
94
- prompt = "Press Enter to return to docker-git..."
95
- ): Effect.Effect<void> => {
96
- if (!process.stdin.isTTY || !process.stdout.isTTY) {
97
- return Effect.void
98
- }
99
-
100
- return Effect.async((resume) => {
101
- // Ensure the prompt isn't glued to the last command line.
102
- writeToTerminal(`\n${prompt}\n`)
103
- process.stdin.resume()
104
-
105
- const cleanup = () => {
106
- process.stdin.off("data", onData)
107
- }
108
-
109
- const onData = () => {
110
- cleanup()
111
- resume(Effect.void)
112
- }
113
-
114
- process.stdin.on("data", onData)
115
-
116
- return Effect.sync(() => {
117
- cleanup()
118
- })
119
- }).pipe(Effect.asVoid)
120
- }
121
-
122
- export const writeErrorAndPause = (renderedError: string): Effect.Effect<void> =>
123
- pipe(
124
- Effect.sync(() => {
125
- writeToTerminal(`\n[docker-git] ${renderedError}\n`)
126
- }),
127
- Effect.zipRight(pauseForEnter()),
128
- Effect.asVoid
129
- )
130
-
131
- export const withSuspendedTui = <A, E, R>(
132
- effect: Effect.Effect<A, E, R>,
133
- options?: {
134
- readonly onError?: (error: E) => Effect.Effect<void>
135
- readonly onResume?: () => void
136
- }
137
- ): Effect.Effect<A, E, R> => {
138
- const withError = options?.onError
139
- ? pipe(effect, Effect.tapError((error) => Effect.ignore(options.onError?.(error) ?? Effect.void)))
140
- : effect
141
-
142
- return pipe(
143
- Effect.sync(suspendTui),
144
- Effect.zipRight(withError),
145
- Effect.ensuring(
146
- Effect.sync(() => {
147
- resumeTui()
148
- options?.onResume?.()
149
- })
150
- )
151
- )
152
- }
153
-
154
- export type SkipInputsContext = {
155
- readonly setSkipInputs: (update: (value: number) => number) => void
156
- }
157
-
158
- export type SshActiveContext = {
159
- readonly setSshActive: (active: boolean) => void
160
- }
161
-
162
- export const resumeWithSkipInputs = (context: SkipInputsContext, extra?: () => void) => () => {
163
- extra?.()
164
- context.setSkipInputs(() => 2)
165
- }
166
-
167
- export const resumeSshWithSkipInputs = (context: SkipInputsContext & SshActiveContext) =>
168
- resumeWithSkipInputs(context, () => {
169
- context.setSshActive(false)
170
- })
171
-
172
- export const pauseOnError = <E>(render: (error: E) => string) => (error: E): Effect.Effect<void> =>
173
- writeErrorAndPause(render(error))
174
-
175
- // CHANGE: toggle stdout write muting for Ink rendering
176
- // WHY: allow SSH sessions to own the terminal without TUI redraws
177
- // QUOTE(ТЗ): "при изменении разершения он всё ломает?"
178
- // REF: user-request-2026-02-05-ssh-resize
179
- // SOURCE: n/a
180
- // FORMAT THEOREM: ∀m ∈ {true,false}: muted = m
181
- // PURITY: SHELL
182
- // EFFECT: n/a
183
- // INVARIANT: stdout wrapper is installed at most once
184
- // COMPLEXITY: O(1)
185
- const setStdoutMuted = (muted: boolean): void => {
186
- ensureStdoutPatched()
187
- stdoutMuted = muted
188
- }
189
-
190
- // CHANGE: temporarily suspend TUI rendering when running interactive commands
191
- // WHY: avoid mixed output from docker/ssh and the Ink UI
192
- // QUOTE(ТЗ): "Почему так кривокосо всё отображается?"
193
- // REF: user-request-2026-02-02-tui-output
194
- // SOURCE: n/a
195
- // FORMAT THEOREM: forall cmd: suspend -> cleanOutput(cmd)
196
- // PURITY: SHELL
197
- // EFFECT: n/a
198
- // INVARIANT: only toggles when TTY is available
199
- // COMPLEXITY: O(1)
200
- export const suspendTui = (): void => {
201
- if (!process.stdout.isTTY) {
202
- return
203
- }
204
- disableMouseModes()
205
- if (process.stdin.isTTY && typeof process.stdin.setRawMode === "function") {
206
- process.stdin.setRawMode(false)
207
- }
208
- // Switch back to the primary screen so interactive commands (ssh/gh/codex)
209
- // can render normally. Do not clear it: users may need scrollback (OAuth codes/URLs).
210
- process.stdout.write("\u001B[?1049l")
211
- setStdoutMuted(true)
212
- }
213
-
214
- // CHANGE: restore TUI rendering after interactive commands
215
- // WHY: return to Ink UI without broken terminal state
216
- // QUOTE(ТЗ): "Почему так кривокосо всё отображается?"
217
- // REF: user-request-2026-02-02-tui-output
218
- // SOURCE: n/a
219
- // FORMAT THEOREM: forall cmd: resume -> tuiVisible(cmd)
220
- // PURITY: SHELL
221
- // EFFECT: n/a
222
- // INVARIANT: only toggles when TTY is available
223
- // COMPLEXITY: O(1)
224
- export const resumeTui = (): void => {
225
- if (!process.stdout.isTTY) {
226
- return
227
- }
228
- setStdoutMuted(false)
229
- disableMouseModes()
230
- // Return to the alternate screen for Ink rendering.
231
- process.stdout.write("\u001B[?1049h\u001B[2J\u001B[H")
232
- if (process.stdin.isTTY && typeof process.stdin.setRawMode === "function") {
233
- process.stdin.setRawMode(true)
234
- }
235
- disableMouseModes()
236
- }
237
-
238
- export const leaveTui = (): void => {
239
- if (!process.stdout.isTTY) {
240
- return
241
- }
242
- // Ensure we don't leave the terminal in a broken "mouse reporting" mode.
243
- setStdoutMuted(false)
244
- disableMouseModes()
245
- // Restore the primary screen on exit without clearing it (keeps useful scrollback).
246
- process.stdout.write("\u001B[?1049l")
247
- if (process.stdin.isTTY && typeof process.stdin.setRawMode === "function") {
248
- process.stdin.setRawMode(false)
249
- }
250
- }
251
-
252
- export const resetToMenu = (context: MenuResetContext): void => {
253
- const view: ViewState = { _tag: "Menu" }
254
- context.setView(view)
255
- context.setMessage(null)
256
- }
@@ -1,83 +0,0 @@
1
- import type { ProjectItem } from "@effect-template/lib/usecases/projects"
2
-
3
- export type MenuStartupSnapshot = {
4
- readonly activeDir: string | null
5
- readonly runningDockerGitContainers: number
6
- readonly message: string | null
7
- }
8
-
9
- const dockerGitContainerPrefix = "dg-"
10
-
11
- const emptySnapshot = (): MenuStartupSnapshot => ({
12
- activeDir: null,
13
- runningDockerGitContainers: 0,
14
- message: null
15
- })
16
-
17
- const uniqueDockerGitContainerNames = (
18
- runningContainerNames: ReadonlyArray<string>
19
- ): ReadonlyArray<string> => [
20
- ...new Set(runningContainerNames.filter((name) => name.startsWith(dockerGitContainerPrefix)))
21
- ]
22
-
23
- const detectKnownRunningProjects = (
24
- items: ReadonlyArray<ProjectItem>,
25
- runningDockerGitNames: ReadonlyArray<string>
26
- ): ReadonlyArray<ProjectItem> => {
27
- const runningSet = new Set(runningDockerGitNames)
28
- return items.filter((item) => runningSet.has(item.containerName))
29
- }
30
-
31
- const renderRunningHint = (runningCount: number): string =>
32
- runningCount === 1
33
- ? "Detected 1 running docker-git container."
34
- : `Detected ${runningCount} running docker-git containers.`
35
-
36
- // CHANGE: infer initial menu state from currently running docker-git containers
37
- // WHY: avoid "(none)" confusion when containers are already up outside this TUI session
38
- // QUOTE(ISSUE): "У меня запущены контейнеры от docker-git но он говорит что они не запущены"
39
- // REF: issue-13
40
- // SOURCE: n/a
41
- // FORMAT THEOREM: forall startupState: snapshot(startupState) -> deterministic(menuState)
42
- // PURITY: CORE
43
- // EFFECT: n/a
44
- // INVARIANT: activeDir is set only when exactly one known project is running
45
- // COMPLEXITY: O(|containers| + |projects|)
46
- export const resolveMenuStartupSnapshot = (
47
- items: ReadonlyArray<ProjectItem>,
48
- runningContainerNames: ReadonlyArray<string>
49
- ): MenuStartupSnapshot => {
50
- const runningDockerGitNames = uniqueDockerGitContainerNames(runningContainerNames)
51
- if (runningDockerGitNames.length === 0) {
52
- return emptySnapshot()
53
- }
54
-
55
- const knownRunningProjects = detectKnownRunningProjects(items, runningDockerGitNames)
56
- if (knownRunningProjects.length === 1 && runningDockerGitNames.length === 1) {
57
- const selected = knownRunningProjects[0]
58
- if (!selected) {
59
- return emptySnapshot()
60
- }
61
- return {
62
- activeDir: selected.projectDir,
63
- runningDockerGitContainers: 1,
64
- message: `Auto-selected active project: ${selected.displayName}.`
65
- }
66
- }
67
-
68
- if (knownRunningProjects.length === 0) {
69
- return {
70
- activeDir: null,
71
- runningDockerGitContainers: runningDockerGitNames.length,
72
- message: `${renderRunningHint(runningDockerGitNames.length)} No matching project config found.`
73
- }
74
- }
75
-
76
- return {
77
- activeDir: null,
78
- runningDockerGitContainers: runningDockerGitNames.length,
79
- message: `${renderRunningHint(runningDockerGitNames.length)} Use Select project to choose active.`
80
- }
81
- }
82
-
83
- export const defaultMenuStartupSnapshot = emptySnapshot
@@ -1,170 +0,0 @@
1
- import type * as CommandExecutor from "@effect/platform/CommandExecutor"
2
- import type * as FileSystem from "@effect/platform/FileSystem"
3
- import type * as Path from "@effect/platform/Path"
4
- import type * as Effect from "effect/Effect"
5
-
6
- import type { MenuAction } from "@effect-template/lib/core/domain"
7
- import type { AppError } from "@effect-template/lib/usecases/errors"
8
- import type { ProjectItem } from "@effect-template/lib/usecases/projects"
9
-
10
- // CHANGE: isolate TUI types/constants into a shared module
11
- // WHY: keep menu rendering and input handling small and focused
12
- // QUOTE(ТЗ): "TUI? Красивый, удобный"
13
- // REF: user-request-2026-02-01-tui
14
- // SOURCE: n/a
15
- // FORMAT THEOREM: forall s: state(s) -> wellTyped(s)
16
- // PURITY: CORE
17
- // EFFECT: n/a
18
- // INVARIANT: createSteps is ordered and total over CreateStep
19
- // COMPLEXITY: O(1)
20
-
21
- export type MenuState = {
22
- readonly cwd: string
23
- readonly activeDir: string | null
24
- }
25
-
26
- export type MenuEnv = FileSystem.FileSystem | Path.Path | CommandExecutor.CommandExecutor
27
-
28
- export type MenuRunner = {
29
- readonly runEffect: (effect: Effect.Effect<void, AppError, MenuEnv>) => void
30
- }
31
-
32
- export type MenuViewContext = {
33
- readonly setView: (view: ViewState) => void
34
- readonly setMessage: (message: string | null) => void
35
- readonly setActiveDir: (dir: string | null) => void
36
- }
37
-
38
- export type MenuKeyInput = {
39
- readonly upArrow?: boolean
40
- readonly downArrow?: boolean
41
- readonly return?: boolean
42
- readonly escape?: boolean
43
- readonly backspace?: boolean
44
- readonly delete?: boolean
45
- }
46
-
47
- export type CreateInputs = {
48
- readonly repoUrl: string
49
- readonly repoRef: string
50
- readonly outDir: string
51
- readonly runUp: boolean
52
- readonly enableMcpPlaywright: boolean
53
- readonly force: boolean
54
- readonly forceEnv: boolean
55
- }
56
-
57
- export type CreateStep =
58
- | "repoUrl"
59
- | "repoRef"
60
- | "outDir"
61
- | "runUp"
62
- | "mcpPlaywright"
63
- | "force"
64
-
65
- export const createSteps: ReadonlyArray<CreateStep> = [
66
- "repoUrl",
67
- "repoRef",
68
- "outDir",
69
- "runUp",
70
- "mcpPlaywright",
71
- "force"
72
- ]
73
-
74
- export type AuthFlow =
75
- | "GithubOauth"
76
- | "GithubRemove"
77
- | "GitSet"
78
- | "GitRemove"
79
- | "ClaudeOauth"
80
- | "ClaudeLogout"
81
-
82
- export interface AuthSnapshot {
83
- readonly globalEnvPath: string
84
- readonly claudeAuthPath: string
85
- readonly totalEntries: number
86
- readonly githubTokenEntries: number
87
- readonly gitTokenEntries: number
88
- readonly gitUserEntries: number
89
- readonly claudeAuthEntries: number
90
- }
91
-
92
- export type ProjectAuthFlow =
93
- | "ProjectGithubConnect"
94
- | "ProjectGithubDisconnect"
95
- | "ProjectGitConnect"
96
- | "ProjectGitDisconnect"
97
- | "ProjectClaudeConnect"
98
- | "ProjectClaudeDisconnect"
99
-
100
- export interface ProjectAuthSnapshot {
101
- readonly projectDir: string
102
- readonly projectName: string
103
- readonly envGlobalPath: string
104
- readonly envProjectPath: string
105
- readonly claudeAuthPath: string
106
- readonly githubTokenEntries: number
107
- readonly gitTokenEntries: number
108
- readonly claudeAuthEntries: number
109
- readonly activeGithubLabel: string | null
110
- readonly activeGitLabel: string | null
111
- readonly activeClaudeLabel: string | null
112
- }
113
-
114
- export type ViewState =
115
- | { readonly _tag: "Menu" }
116
- | { readonly _tag: "Create"; readonly step: number; readonly buffer: string; readonly values: Partial<CreateInputs> }
117
- | { readonly _tag: "AuthMenu"; readonly selected: number; readonly snapshot: AuthSnapshot }
118
- | {
119
- readonly _tag: "AuthPrompt"
120
- readonly flow: AuthFlow
121
- readonly step: number
122
- readonly buffer: string
123
- readonly values: Readonly<Record<string, string>>
124
- readonly snapshot: AuthSnapshot
125
- }
126
- | {
127
- readonly _tag: "ProjectAuthMenu"
128
- readonly selected: number
129
- readonly project: ProjectItem
130
- readonly snapshot: ProjectAuthSnapshot
131
- }
132
- | {
133
- readonly _tag: "ProjectAuthPrompt"
134
- readonly flow: ProjectAuthFlow
135
- readonly step: number
136
- readonly buffer: string
137
- readonly values: Readonly<Record<string, string>>
138
- readonly project: ProjectItem
139
- readonly snapshot: ProjectAuthSnapshot
140
- }
141
- | {
142
- readonly _tag: "SelectProject"
143
- readonly purpose: "Connect" | "Down" | "Info" | "Delete" | "Auth"
144
- readonly items: ReadonlyArray<ProjectItem>
145
- readonly runtimeByProject: Readonly<Record<string, SelectProjectRuntime>>
146
- readonly selected: number
147
- readonly confirmDelete: boolean
148
- readonly connectEnableMcpPlaywright: boolean
149
- }
150
-
151
- export type SelectProjectRuntime = {
152
- readonly running: boolean
153
- readonly sshSessions: number
154
- readonly startedAtIso: string | null
155
- readonly startedAtEpochMs: number | null
156
- }
157
-
158
- export const menuItems: ReadonlyArray<{ readonly id: MenuAction; readonly label: string }> = [
159
- { id: { _tag: "Create" }, label: "Create project" },
160
- { id: { _tag: "Select" }, label: "Select project" },
161
- { id: { _tag: "Auth" }, label: "Auth profiles (keys)" },
162
- { id: { _tag: "ProjectAuth" }, label: "Project auth (bind labels)" },
163
- { id: { _tag: "Info" }, label: "Show connection info" },
164
- { id: { _tag: "Status" }, label: "docker compose ps" },
165
- { id: { _tag: "Logs" }, label: "docker compose logs --tail=200" },
166
- { id: { _tag: "Down" }, label: "docker compose down" },
167
- { id: { _tag: "DownAll" }, label: "docker compose down (ALL projects)" },
168
- { id: { _tag: "Delete" }, label: "Delete project (folder + container)" },
169
- { id: { _tag: "Quit" }, label: "Quit" }
170
- ]