@prover-coder-ai/docker-git 1.0.21 → 1.0.22
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.
- package/.package.json.release.bak +4 -3
- package/CHANGELOG.md +6 -0
- package/README.md +28 -1
- package/dist/src/docker-git/main.js +10256 -12
- package/dist/src/docker-git/main.js.map +1 -0
- package/package.json +3 -4
- package/src/docker-git/cli/parser-options.ts +6 -0
- package/src/docker-git/cli/usage.ts +5 -2
- package/src/docker-git/menu-actions.ts +5 -2
- package/src/docker-git/menu-create.ts +9 -13
- package/src/docker-git/menu-render.ts +1 -1
- package/tests/docker-git/parser-network-options.test.ts +47 -0
- package/tests/docker-git/parser.test.ts +16 -1
- package/vite.docker-git.config.ts +34 -0
- package/dist/main.js +0 -930
- package/dist/main.js.map +0 -1
- package/dist/src/app/main.js +0 -15
- package/dist/src/app/program.js +0 -61
- package/dist/src/docker-git/cli/input.js +0 -21
- package/dist/src/docker-git/cli/parser-apply.js +0 -22
- package/dist/src/docker-git/cli/parser-attach.js +0 -19
- package/dist/src/docker-git/cli/parser-auth.js +0 -90
- package/dist/src/docker-git/cli/parser-clone.js +0 -40
- package/dist/src/docker-git/cli/parser-create.js +0 -1
- package/dist/src/docker-git/cli/parser-mcp-playwright.js +0 -18
- package/dist/src/docker-git/cli/parser-options.js +0 -134
- package/dist/src/docker-git/cli/parser-panes.js +0 -19
- package/dist/src/docker-git/cli/parser-scrap.js +0 -74
- package/dist/src/docker-git/cli/parser-sessions.js +0 -69
- package/dist/src/docker-git/cli/parser-shared.js +0 -26
- package/dist/src/docker-git/cli/parser-state.js +0 -62
- package/dist/src/docker-git/cli/parser.js +0 -47
- package/dist/src/docker-git/cli/read-command.js +0 -17
- package/dist/src/docker-git/cli/usage.js +0 -113
- package/dist/src/docker-git/menu-actions.js +0 -135
- package/dist/src/docker-git/menu-auth-data.js +0 -90
- package/dist/src/docker-git/menu-auth-helpers.js +0 -20
- package/dist/src/docker-git/menu-auth.js +0 -159
- package/dist/src/docker-git/menu-buffer-input.js +0 -9
- package/dist/src/docker-git/menu-create.js +0 -199
- package/dist/src/docker-git/menu-input-handler.js +0 -109
- package/dist/src/docker-git/menu-input-utils.js +0 -47
- package/dist/src/docker-git/menu-input.js +0 -2
- package/dist/src/docker-git/menu-labeled-env.js +0 -33
- package/dist/src/docker-git/menu-menu.js +0 -46
- package/dist/src/docker-git/menu-project-auth-claude.js +0 -43
- package/dist/src/docker-git/menu-project-auth-data.js +0 -165
- package/dist/src/docker-git/menu-project-auth.js +0 -124
- package/dist/src/docker-git/menu-render-auth.js +0 -45
- package/dist/src/docker-git/menu-render-common.js +0 -26
- package/dist/src/docker-git/menu-render-layout.js +0 -14
- package/dist/src/docker-git/menu-render-project-auth.js +0 -37
- package/dist/src/docker-git/menu-render-select.js +0 -129
- package/dist/src/docker-git/menu-render.js +0 -137
- package/dist/src/docker-git/menu-select-actions.js +0 -66
- package/dist/src/docker-git/menu-select-connect.js +0 -6
- package/dist/src/docker-git/menu-select-load.js +0 -12
- package/dist/src/docker-git/menu-select-order.js +0 -21
- package/dist/src/docker-git/menu-select-runtime.js +0 -82
- package/dist/src/docker-git/menu-select-view.js +0 -15
- package/dist/src/docker-git/menu-select.js +0 -98
- package/dist/src/docker-git/menu-shared.js +0 -180
- package/dist/src/docker-git/menu-startup.js +0 -57
- package/dist/src/docker-git/menu-types.js +0 -21
- package/dist/src/docker-git/menu.js +0 -226
- package/dist/src/docker-git/program.js +0 -43
- package/dist/src/docker-git/tmux.js +0 -176
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prover-coder-ai/docker-git",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.22",
|
|
4
4
|
"description": "Minimal Vite-powered TypeScript console starter using Effect",
|
|
5
5
|
"main": "dist/src/docker-git/main.js",
|
|
6
6
|
"bin": {
|
|
@@ -35,8 +35,7 @@
|
|
|
35
35
|
"@effect/schema": "^0.75.5",
|
|
36
36
|
"effect": "^3.19.14",
|
|
37
37
|
"ink": "^5.0.1",
|
|
38
|
-
"react": "^18.3.1"
|
|
39
|
-
"@effect-template/lib": "1.0.0"
|
|
38
|
+
"react": "^18.3.1"
|
|
40
39
|
},
|
|
41
40
|
"scripts": {
|
|
42
41
|
"prebuild": "pnpm -C ../lib build",
|
|
@@ -48,7 +47,7 @@
|
|
|
48
47
|
"lint:tests": "PATH=../../scripts:$PATH vibecode-linter tests/",
|
|
49
48
|
"lint:effect": "PATH=../../scripts:$PATH eslint --config eslint.effect-ts-check.config.mjs .",
|
|
50
49
|
"prebuild:docker-git": "pnpm -C ../lib build",
|
|
51
|
-
"build:docker-git": "
|
|
50
|
+
"build:docker-git": "vite build --config vite.docker-git.config.ts",
|
|
52
51
|
"check": "pnpm run typecheck",
|
|
53
52
|
"clone": "pnpm -C ../.. run clone",
|
|
54
53
|
"docker-git": "node dist/src/docker-git/main.js",
|
|
@@ -20,6 +20,8 @@ interface ValueOptionSpec {
|
|
|
20
20
|
| "envProjectPath"
|
|
21
21
|
| "codexAuthPath"
|
|
22
22
|
| "codexHome"
|
|
23
|
+
| "dockerNetworkMode"
|
|
24
|
+
| "dockerSharedNetworkName"
|
|
23
25
|
| "archivePath"
|
|
24
26
|
| "scrapMode"
|
|
25
27
|
| "label"
|
|
@@ -51,6 +53,8 @@ const valueOptionSpecs: ReadonlyArray<ValueOptionSpec> = [
|
|
|
51
53
|
{ flag: "--env-project", key: "envProjectPath" },
|
|
52
54
|
{ flag: "--codex-auth", key: "codexAuthPath" },
|
|
53
55
|
{ flag: "--codex-home", key: "codexHome" },
|
|
56
|
+
{ flag: "--network-mode", key: "dockerNetworkMode" },
|
|
57
|
+
{ flag: "--shared-network", key: "dockerSharedNetworkName" },
|
|
54
58
|
{ flag: "--archive", key: "archivePath" },
|
|
55
59
|
{ flag: "--mode", key: "scrapMode" },
|
|
56
60
|
{ flag: "--label", key: "label" },
|
|
@@ -102,6 +106,8 @@ const valueFlagUpdaters: { readonly [K in ValueKey]: (raw: RawOptions, value: st
|
|
|
102
106
|
envProjectPath: (raw, value) => ({ ...raw, envProjectPath: value }),
|
|
103
107
|
codexAuthPath: (raw, value) => ({ ...raw, codexAuthPath: value }),
|
|
104
108
|
codexHome: (raw, value) => ({ ...raw, codexHome: value }),
|
|
109
|
+
dockerNetworkMode: (raw, value) => ({ ...raw, dockerNetworkMode: value }),
|
|
110
|
+
dockerSharedNetworkName: (raw, value) => ({ ...raw, dockerSharedNetworkName: value }),
|
|
105
111
|
archivePath: (raw, value) => ({ ...raw, archivePath: value }),
|
|
106
112
|
scrapMode: (raw, value) => ({ ...raw, scrapMode: value }),
|
|
107
113
|
label: (raw, value) => ({ ...raw, label: value }),
|
|
@@ -3,7 +3,7 @@ import { Match } from "effect"
|
|
|
3
3
|
import type { ParseError } from "@effect-template/lib/core/domain"
|
|
4
4
|
|
|
5
5
|
export const usageText = `docker-git menu
|
|
6
|
-
docker-git create --repo-url <url> [options]
|
|
6
|
+
docker-git create [--repo-url <url>] [options]
|
|
7
7
|
docker-git clone <url> [options]
|
|
8
8
|
docker-git apply [<url>] [options]
|
|
9
9
|
docker-git mcp-playwright [<url>] [options]
|
|
@@ -20,7 +20,7 @@ docker-git state <action> [options]
|
|
|
20
20
|
|
|
21
21
|
Commands:
|
|
22
22
|
menu Interactive menu (default when no args)
|
|
23
|
-
create, init Generate docker development environment
|
|
23
|
+
create, init Generate docker development environment (repo URL optional)
|
|
24
24
|
clone Create + run container and clone repo
|
|
25
25
|
apply Apply docker-git config to an existing project/container (current dir by default)
|
|
26
26
|
mcp-playwright Enable Playwright MCP + Chromium sidecar for an existing project dir
|
|
@@ -34,6 +34,7 @@ Commands:
|
|
|
34
34
|
state Manage docker-git state directory via git (sync across machines)
|
|
35
35
|
|
|
36
36
|
Options:
|
|
37
|
+
--repo-url <url> Repository URL (create: optional; clone: required via positional arg or flag)
|
|
37
38
|
--repo-ref <ref> Git ref/branch (default: main)
|
|
38
39
|
--branch, -b <ref> Alias for --repo-ref
|
|
39
40
|
--target-dir <path> Target dir inside container (create default: /home/dev/app, clone default: ~/workspaces/<org>/<repo>[/issue-<id>|/pr-<id>])
|
|
@@ -47,6 +48,8 @@ Options:
|
|
|
47
48
|
--env-project <path> Host path to project env file (default: ./.orch/env/project.env)
|
|
48
49
|
--codex-auth <path> Host path for Codex auth cache (default: <projectsRoot>/.orch/auth/codex)
|
|
49
50
|
--codex-home <path> Container path for Codex auth (default: /home/dev/.codex)
|
|
51
|
+
--network-mode <mode> Compose network mode: shared|project (default: shared)
|
|
52
|
+
--shared-network <name> Shared Docker network name when network-mode=shared (default: docker-git-shared)
|
|
50
53
|
--out-dir <path> Output directory (default: <projectsRoot>/<org>/<repo>[/issue-<id>|/pr-<id>])
|
|
51
54
|
--project-dir <path> Project directory for attach (default: .)
|
|
52
55
|
--archive <path> Scrap snapshot directory (default: .orch/scrap/session)
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
listProjectStatus,
|
|
10
10
|
listRunningProjectItems
|
|
11
11
|
} from "@effect-template/lib/usecases/projects"
|
|
12
|
+
import { gcProjectNetworkByTemplate } from "@effect-template/lib/usecases/docker-network-gc"
|
|
12
13
|
import { runDockerComposeUpWithPortCheck } from "@effect-template/lib/usecases/projects-up"
|
|
13
14
|
import { Effect, Match, pipe } from "effect"
|
|
14
15
|
|
|
@@ -149,8 +150,10 @@ const handleMenuAction = (
|
|
|
149
150
|
withProjectConfig(state, setMessage, () =>
|
|
150
151
|
runDockerComposeLogs(state.activeDir ?? state.cwd))),
|
|
151
152
|
Match.when({ _tag: "Down" }, () =>
|
|
152
|
-
withProjectConfig(state, setMessage, () =>
|
|
153
|
-
runDockerComposeDown(state.activeDir ?? state.cwd)
|
|
153
|
+
withProjectConfig(state, setMessage, (config) =>
|
|
154
|
+
runDockerComposeDown(state.activeDir ?? state.cwd).pipe(
|
|
155
|
+
Effect.zipRight(gcProjectNetworkByTemplate(state.activeDir ?? state.cwd, config.template))
|
|
156
|
+
))),
|
|
154
157
|
Match.when({ _tag: "DownAll" }, () =>
|
|
155
158
|
pipe(
|
|
156
159
|
downAllDockerGitProjects,
|
|
@@ -46,11 +46,16 @@ type CreateReturnContext = CreateContext & {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
export const buildCreateArgs = (input: CreateInputs): ReadonlyArray<string> => {
|
|
49
|
-
const args: Array<string> = ["create"
|
|
49
|
+
const args: Array<string> = ["create"]
|
|
50
|
+
if (input.repoUrl.length > 0) {
|
|
51
|
+
args.push("--repo-url", input.repoUrl)
|
|
52
|
+
}
|
|
50
53
|
if (input.repoRef.length > 0) {
|
|
51
54
|
args.push("--repo-ref", input.repoRef)
|
|
52
55
|
}
|
|
53
|
-
|
|
56
|
+
if (input.outDir.length > 0) {
|
|
57
|
+
args.push("--out-dir", input.outDir)
|
|
58
|
+
}
|
|
54
59
|
if (!input.runUp) {
|
|
55
60
|
args.push("--no-up")
|
|
56
61
|
}
|
|
@@ -106,8 +111,8 @@ export const resolveCreateInputs = (
|
|
|
106
111
|
values: Partial<CreateInputs>
|
|
107
112
|
): CreateInputs => {
|
|
108
113
|
const repoUrl = values.repoUrl ?? ""
|
|
109
|
-
const resolvedRepoRef =
|
|
110
|
-
const outDir = values.outDir ??
|
|
114
|
+
const resolvedRepoRef = resolveRepoInput(repoUrl).repoRef
|
|
115
|
+
const outDir = values.outDir ?? resolveDefaultOutDir(cwd, repoUrl)
|
|
111
116
|
|
|
112
117
|
return {
|
|
113
118
|
repoUrl,
|
|
@@ -179,10 +184,6 @@ const applyCreateStep = (input: {
|
|
|
179
184
|
}): boolean =>
|
|
180
185
|
Match.value(input.step).pipe(
|
|
181
186
|
Match.when("repoUrl", () => {
|
|
182
|
-
if (input.buffer.length === 0) {
|
|
183
|
-
input.setMessage("Repo URL is required.")
|
|
184
|
-
return false
|
|
185
|
-
}
|
|
186
187
|
input.nextValues.repoUrl = input.buffer
|
|
187
188
|
input.nextValues.outDir = resolveDefaultOutDir(input.cwd, input.buffer)
|
|
188
189
|
return true
|
|
@@ -222,11 +223,6 @@ const finalizeCreateFlow = (input: {
|
|
|
222
223
|
readonly setActiveDir: (dir: string | null) => void
|
|
223
224
|
}) => {
|
|
224
225
|
const inputs = resolveCreateInputs(input.state.cwd, input.nextValues)
|
|
225
|
-
if (inputs.repoUrl.length === 0) {
|
|
226
|
-
input.setMessage("Repo URL is required.")
|
|
227
|
-
return
|
|
228
|
-
}
|
|
229
|
-
|
|
230
226
|
const parsed = parseArgs(buildCreateArgs(inputs))
|
|
231
227
|
if (Either.isLeft(parsed)) {
|
|
232
228
|
input.setMessage(formatParseError(parsed.left))
|
|
@@ -28,7 +28,7 @@ import { createSteps, menuItems } from "./menu-types.js"
|
|
|
28
28
|
|
|
29
29
|
export const renderStepLabel = (step: CreateStep, defaults: CreateInputs): string =>
|
|
30
30
|
Match.value(step).pipe(
|
|
31
|
-
Match.when("repoUrl", () => "Repo URL"),
|
|
31
|
+
Match.when("repoUrl", () => "Repo URL (optional for empty workspace)"),
|
|
32
32
|
Match.when("repoRef", () => `Repo ref [${defaults.repoRef}]`),
|
|
33
33
|
Match.when("outDir", () => `Output dir [${defaults.outDir}]`),
|
|
34
34
|
Match.when("runUp", () => `Run docker compose up now? [${defaults.runUp ? "Y" : "n"}]`),
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { describe, expect, it } from "@effect/vitest"
|
|
2
|
+
import { Effect, Either } from "effect"
|
|
3
|
+
|
|
4
|
+
import { parseArgs } from "../../src/docker-git/cli/parser.js"
|
|
5
|
+
|
|
6
|
+
describe("parseArgs network options", () => {
|
|
7
|
+
it.effect("parses create network mode options", () =>
|
|
8
|
+
Effect.sync(() => {
|
|
9
|
+
const parsed = parseArgs([
|
|
10
|
+
"create",
|
|
11
|
+
"--repo-url",
|
|
12
|
+
"https://github.com/org/repo.git",
|
|
13
|
+
"--network-mode",
|
|
14
|
+
"project",
|
|
15
|
+
"--shared-network",
|
|
16
|
+
"ignored-shared-network"
|
|
17
|
+
])
|
|
18
|
+
if (Either.isLeft(parsed)) {
|
|
19
|
+
throw new Error(`unexpected parse error: ${parsed.left._tag}`)
|
|
20
|
+
}
|
|
21
|
+
const command = parsed.right
|
|
22
|
+
if (command._tag !== "Create") {
|
|
23
|
+
throw new Error("expected Create command")
|
|
24
|
+
}
|
|
25
|
+
expect(command.config.dockerNetworkMode).toBe("project")
|
|
26
|
+
expect(command.config.dockerSharedNetworkName).toBe("ignored-shared-network")
|
|
27
|
+
}))
|
|
28
|
+
|
|
29
|
+
it.effect("fails on invalid network mode", () =>
|
|
30
|
+
Effect.sync(() => {
|
|
31
|
+
const command = parseArgs([
|
|
32
|
+
"create",
|
|
33
|
+
"--repo-url",
|
|
34
|
+
"https://github.com/org/repo.git",
|
|
35
|
+
"--network-mode",
|
|
36
|
+
"invalid"
|
|
37
|
+
])
|
|
38
|
+
Either.match(command, {
|
|
39
|
+
onLeft: (error) => {
|
|
40
|
+
expect(error._tag).toBe("InvalidOption")
|
|
41
|
+
},
|
|
42
|
+
onRight: () => {
|
|
43
|
+
throw new Error("expected parse error")
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
}))
|
|
47
|
+
})
|
|
@@ -71,6 +71,8 @@ const expectCreateDefaults = (command: CreateCommand) => {
|
|
|
71
71
|
expect(command.outDir).toBe(".docker-git/org/repo")
|
|
72
72
|
expect(command.runUp).toBe(true)
|
|
73
73
|
expect(command.forceEnv).toBe(false)
|
|
74
|
+
expect(command.config.dockerNetworkMode).toBe("shared")
|
|
75
|
+
expect(command.config.dockerSharedNetworkName).toBe("docker-git-shared")
|
|
74
76
|
}
|
|
75
77
|
|
|
76
78
|
const expandDefaultTargetDir = (path: string): string => expandContainerHome(defaultTemplateConfig.sshUser, path)
|
|
@@ -99,7 +101,20 @@ describe("parseArgs", () => {
|
|
|
99
101
|
expect(command.config.volumeName).toBe("dg-repo-issue-9-home")
|
|
100
102
|
}))
|
|
101
103
|
|
|
102
|
-
it.effect("
|
|
104
|
+
it.effect("parses create command without repo url into empty workspace defaults", () =>
|
|
105
|
+
expectCreateCommand(["create"], (command) => {
|
|
106
|
+
expect(command.config.repoUrl).toBe("")
|
|
107
|
+
expect(command.config.repoRef).toBe(defaultTemplateConfig.repoRef)
|
|
108
|
+
expect(command.outDir).toBe(".docker-git/app")
|
|
109
|
+
expect(command.openSsh).toBe(false)
|
|
110
|
+
expect(command.waitForClone).toBe(false)
|
|
111
|
+
expect(command.config.containerName).toBe("dg-app")
|
|
112
|
+
expect(command.config.serviceName).toBe("dg-app")
|
|
113
|
+
expect(command.config.volumeName).toBe("dg-app-home")
|
|
114
|
+
expect(command.config.targetDir).toBe(expandDefaultTargetDir(defaultTemplateConfig.targetDir))
|
|
115
|
+
}))
|
|
116
|
+
|
|
117
|
+
it.effect("fails clone when repo url is missing", () => expectParseErrorTag(["clone"], "MissingRequiredOption"))
|
|
103
118
|
|
|
104
119
|
it.effect("parses clone command with positional repo url", () =>
|
|
105
120
|
expectCreateCommand(["clone", "https://github.com/org/repo.git"], (command) => {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import path from "node:path"
|
|
2
|
+
import { fileURLToPath } from "node:url"
|
|
3
|
+
import { defineConfig } from "vite"
|
|
4
|
+
import tsconfigPaths from "vite-tsconfig-paths"
|
|
5
|
+
|
|
6
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
7
|
+
const __dirname = path.dirname(__filename)
|
|
8
|
+
|
|
9
|
+
export default defineConfig({
|
|
10
|
+
plugins: [tsconfigPaths()],
|
|
11
|
+
publicDir: false,
|
|
12
|
+
resolve: {
|
|
13
|
+
alias: {
|
|
14
|
+
"@": path.resolve(__dirname, "src"),
|
|
15
|
+
"@effect-template/lib": path.resolve(__dirname, "../lib/src")
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
build: {
|
|
19
|
+
target: "node20",
|
|
20
|
+
outDir: "dist",
|
|
21
|
+
sourcemap: true,
|
|
22
|
+
ssr: "src/docker-git/main.ts",
|
|
23
|
+
rollupOptions: {
|
|
24
|
+
output: {
|
|
25
|
+
format: "es",
|
|
26
|
+
entryFileNames: "src/docker-git/main.js",
|
|
27
|
+
inlineDynamicImports: true
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
ssr: {
|
|
32
|
+
target: "node"
|
|
33
|
+
}
|
|
34
|
+
})
|