Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .changeset/separate-container-definition.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
"@prover-coder-ai/docker-git": patch
"@effect-template/lib": patch
---

Separate the container definition from the panel and the backend (issue #412).

The container definition — the pure layer that renders a project's `Dockerfile`,
`entrypoint.sh` and `docker-compose.yml` from a `TemplateConfig` — has been
extracted from the backend package (`@effect-template/lib`) into a new,
dependency-free leaf package `@prover-coder-ai/docker-git-container`. The backend
now depends on it and re-exports the moved symbols, so its public API is
unchanged.

The panel (`@prover-coder-ai/docker-git`) no longer carries a duplicate copy of
the container/backend logic: the dead `packages/app/src/lib` tree (165 files) and
its now-unused `@lib` / `@effect-template/lib` aliases and dependency were
removed. The `no-lib-imports` ESLint rule now forbids the panel from importing
either the backend or the container-definition package, keeping the boundary
enforced.

No runtime behaviour changes: the generated container files are byte-identical
(guaranteed by the unchanged property-based template test suite, which moved to
the new package).
10 changes: 10 additions & 0 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ jobs:
- uses: actions/checkout@v6
- name: Install dependencies
uses: ./.github/actions/setup
- name: Build (container package)
run: bun run --cwd packages/container build
- name: Build (terminal package)
run: bun run --cwd packages/terminal build
- name: Build (docker-git package)
Expand Down Expand Up @@ -60,6 +62,8 @@ jobs:
- uses: actions/checkout@v6
- name: Install dependencies
uses: ./.github/actions/setup
- name: Typecheck (container)
run: bun run --cwd packages/container typecheck
- name: Typecheck (terminal)
run: bun run --cwd packages/terminal typecheck
- name: Typecheck (app)
Expand All @@ -84,6 +88,8 @@ jobs:
- uses: actions/checkout@v6
- name: Install dependencies
uses: ./.github/actions/setup
- name: Lint (container)
run: bun run --cwd packages/container lint
- name: Lint (terminal)
run: bun run --cwd packages/terminal lint
- name: Lint (app)
Expand All @@ -109,6 +115,8 @@ jobs:
- uses: actions/checkout@v6
- name: Install dependencies
uses: ./.github/actions/setup
- name: Test (container)
run: bun run --cwd packages/container test
- name: Test (terminal)
run: bun run --cwd packages/terminal test
- name: Test (app)
Expand All @@ -133,6 +141,8 @@ jobs:
- uses: actions/checkout@v6
- name: Install dependencies
uses: ./.github/actions/setup
- name: Lint Effect-TS (container)
run: bun run --cwd packages/container lint:effect
- name: Lint Effect-TS (terminal)
run: bun run --cwd packages/terminal lint:effect
- name: Lint Effect-TS (app)
Expand Down
54 changes: 49 additions & 5 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"workspaces": [
"packages/api",
"packages/app",
"packages/container",
"packages/docker-git-session-sync",
"packages/lib",
"packages/terminal"
Expand Down
6 changes: 5 additions & 1 deletion packages/api/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,10 @@ RUN set -eu; \
FROM controller-base AS workspace-deps

COPY package.json bun.lock bunfig.toml tsconfig.base.json tsconfig.json ./
RUN mkdir -p packages/api packages/app packages/docker-git-session-sync packages/lib packages/terminal
RUN mkdir -p packages/api packages/app packages/container packages/docker-git-session-sync packages/lib packages/terminal
COPY packages/api/package.json ./packages/api/package.json
COPY packages/app/package.json ./packages/app/package.json
COPY packages/container/package.json ./packages/container/package.json
COPY packages/docker-git-session-sync/package.json ./packages/docker-git-session-sync/package.json
COPY packages/lib/package.json ./packages/lib/package.json
COPY packages/terminal/package.json ./packages/terminal/package.json
Expand All @@ -90,6 +91,7 @@ RUN set -eu; \
--silent \
--filter @effect-template/api \
--filter @effect-template/lib \
--filter @prover-coder-ai/docker-git-container \
--filter @prover-coder-ai/docker-git-terminal \
--filter @prover-coder-ai/docker-git-session-sync; then \
exit 0; \
Expand All @@ -105,12 +107,14 @@ FROM workspace-deps AS workspace-static

COPY patches ./patches
COPY scripts ./scripts
COPY packages/container ./packages/container
COPY packages/docker-git-session-sync ./packages/docker-git-session-sync
COPY packages/lib ./packages/lib
COPY packages/terminal ./packages/terminal

RUN bun run --cwd packages/docker-git-session-sync build
RUN bun run --cwd packages/terminal build
RUN bun run --cwd packages/container build
RUN bun run --cwd packages/lib build

FROM controller-base AS skiller-build
Expand Down
6 changes: 3 additions & 3 deletions packages/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
"type": "module",
"packageManager": "bun@1.3.11",
"scripts": {
"prebuild": "bun run --cwd ../terminal build && bun run --cwd ../lib build",
"prebuild": "bun run --cwd ../terminal build && bun run --cwd ../container build && bun run --cwd ../lib build",
"build": "tsc -p tsconfig.json",
"dev": "tsc -p tsconfig.json --watch",
"prestart": "bun run build",
"start": "bun dist/src/main.js",
"pretypecheck": "bun run --cwd ../terminal build && bun run --cwd ../lib build",
"pretypecheck": "bun run --cwd ../terminal build && bun run --cwd ../container build && bun run --cwd ../lib build",
"typecheck": "tsc --noEmit -p tsconfig.json",
"lint": "eslint .",
"pretest": "bun run --cwd ../terminal build && bun run --cwd ../lib build",
"pretest": "bun run --cwd ../terminal build && bun run --cwd ../container build && bun run --cwd ../lib build",
"test": "vitest run"
},
"dependencies": {
Expand Down
12 changes: 8 additions & 4 deletions packages/app/eslint/no-lib-imports.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
// @ts-check

const bannedPackageName = "@effect-template/lib"
// CHANGE: forbid the panel from importing BOTH the backend and the container-definition packages (issue #412)
// WHY: packages/app is the panel; container orchestration lives in @effect-template/lib (backend) and
// container definition in @prover-coder-ai/docker-git-container. The panel must reach them only via the API client.
// REF: issue-412
const bannedPackageNames = ["@effect-template/lib", "@prover-coder-ai/docker-git-container"]
const bannedLocalAlias = "@lib"

/** @param {string} value */
Expand Down Expand Up @@ -38,7 +42,7 @@ const isFrontendSurfaceFile = (filePath) => {

/** @param {string} value */
const isDirectLibImport = (value) =>
value === bannedPackageName || value.startsWith(`${bannedPackageName}/`)
bannedPackageNames.some((name) => value === name || value.startsWith(`${name}/`))

/**
* @param {unknown} value
Expand Down Expand Up @@ -198,12 +202,12 @@ export const noLibImportsRule = {
type: "problem",
docs: {
description:
"forbid direct imports, re-exports, and require calls from legacy lib surfaces inside package/app frontend surfaces and tests"
"forbid direct imports, re-exports, and require calls from the backend (@effect-template/lib) or container-definition (@prover-coder-ai/docker-git-container) packages inside package/app frontend surfaces and tests"
},
schema: [],
messages: {
noLibImport:
"Direct import or require '{{source}}' from legacy lib surfaces is forbidden in package/app frontend surfaces and tests. Use the API client or a local app adapter instead."
"Direct import or require '{{source}}' from the backend (@effect-template/lib) or container-definition (@prover-coder-ai/docker-git-container) packages is forbidden in package/app frontend surfaces and tests. Use the API client or a local app adapter instead."
}
},
create: createRuleListener
Expand Down
13 changes: 6 additions & 7 deletions packages/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"doc": "doc"
},
"scripts": {
"prebuild": "bun run --cwd ../docker-git-session-sync build && bun run --cwd ../terminal build && bun run --cwd ../lib build",
"prebuild": "bun run --cwd ../docker-git-session-sync build && bun run --cwd ../terminal build",
"build": "bun run build:app && bun run build:docker-git",
"build:app": "vite build --ssr src/app/main.ts",
"build:web": "vite build --config vite.web.config.ts",
Expand All @@ -22,13 +22,13 @@
"dev": "vite build --watch --ssr src/app/main.ts",
"dev:web": "vite --config vite.web.config.ts",
"serve:web": "bun scripts/serve-dist-web.mjs",
"prelint": "bun run --cwd ../docker-git-session-sync build && bun run --cwd ../terminal build && bun run --cwd ../lib build",
"prelint": "bun run --cwd ../docker-git-session-sync build && bun run --cwd ../terminal build",
"lint": "NODE_OPTIONS=--max-old-space-size=4096 PATH=../../scripts:$PATH vibecode-linter src/",
"lint:tests": "NODE_OPTIONS=--max-old-space-size=4096 PATH=../../scripts:$PATH vibecode-linter tests/",
"lint:effect": "NODE_OPTIONS=--max-old-space-size=4096 PATH=../../scripts:$PATH eslint --config eslint.effect-ts-check.config.mjs .",
"prebuild:docker-git": "bun install --cwd ../.. && bun run --cwd ../docker-git-session-sync build && bun run --cwd ../terminal build && bun run --cwd ../lib build",
"prebuild:docker-git": "bun install --cwd ../.. && bun run --cwd ../docker-git-session-sync build && bun run --cwd ../terminal build",
"build:docker-git": "vite build --config vite.docker-git.config.ts",
"prebuild:docker-git:reuse-install": "bun run --cwd ../docker-git-session-sync build && bun run --cwd ../terminal build && bun run --cwd ../lib build",
"prebuild:docker-git:reuse-install": "bun run --cwd ../docker-git-session-sync build && bun run --cwd ../terminal build",
"build:docker-git:reuse-install": "vite build --config vite.docker-git.config.ts",
"check": "bun run typecheck",
"clone": "bun run build:docker-git && bun dist/src/docker-git/main.js clone",
Expand All @@ -37,9 +37,9 @@
"list": "bun run build:docker-git && bun dist/src/docker-git/main.js ps",
"preview:web": "vite preview --config vite.web.config.ts",
"start": "bun run build:docker-git && bun dist/src/docker-git/main.js",
"pretest": "bun run --cwd ../docker-git-session-sync build && bun run --cwd ../terminal build && bun run --cwd ../lib build",
"pretest": "bun run --cwd ../docker-git-session-sync build && bun run --cwd ../terminal build",
"test": "bun run lint:tests && vitest run",
"pretypecheck": "bun run --cwd ../docker-git-session-sync build && bun run --cwd ../terminal build && bun run --cwd ../lib build",
"pretypecheck": "bun run --cwd ../docker-git-session-sync build && bun run --cwd ../terminal build",
"typecheck": "tsc --noEmit"
},
"repository": {
Expand Down Expand Up @@ -87,7 +87,6 @@
},
"devDependencies": {
"@biomejs/biome": "^2.5.0",
"@effect-template/lib": "workspace:*",
"@effect/eslint-plugin": "^0.3.2",
"@effect/language-service": "latest",
"@effect/vitest": "^0.29.0",
Expand Down
3 changes: 1 addition & 2 deletions packages/app/src/docker-git/api-terminal-codec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ type RawTerminalSession = {

const isTerminalSessionStatus = (
value: string
): value is ApiTerminalSession["status"] =>
["ready", "attached", "exited", "failed"].includes(value)
): value is ApiTerminalSession["status"] => ["ready", "attached", "exited", "failed"].includes(value)

const readOptionalNumber = (value: JsonValue | undefined): number | undefined =>
typeof value === "number" ? value : undefined
Expand Down
1 change: 0 additions & 1 deletion packages/app/src/docker-git/browser-frontend-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ const browserFrontendRevisionInputs: ReadonlyArray<string> = [
"packages/app/vite.web.config.ts",
"packages/app/scripts/serve-dist-web.mjs",
"packages/app/src/docker-git",
"packages/app/src/lib",
"packages/app/src/shared",
"packages/app/src/ui",
"packages/app/src/web"
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/docker-git/controller-docker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export const controllerContainerName = process.env["DOCKER_GIT_API_CONTAINER_NAM

const inspectNetworksTemplate = String
.raw`{{range $k,$v := .NetworkSettings.Networks}}{{printf "%s=%s\n" $k $v.IPAddress}}{{end}}`
const inspectEnvTemplate = String.raw`{{range .Config.Env}}{{println .}}{{end}}`
const inspectEnvTemplate = "{{range .Config.Env}}{{println .}}{{end}}"

const controllerBootstrapError = (message: string): ControllerBootstrapError => ({
_tag: "ControllerBootstrapError",
Expand Down
4 changes: 2 additions & 2 deletions packages/app/src/docker-git/controller-image-revision.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import { type ControllerRuntime, runDockerCapture, runDockerCaptureWithFailureOu
import { parseControllerRevisionLabelOutput } from "./controller-revision.js"
import type { ControllerBootstrapError } from "./host-errors.js"

const inspectControllerRevisionLabelTemplate = String
.raw`{{ index .Config.Labels "io.prover-coder-ai.docker-git.controller-rev" }}`
const inspectControllerRevisionLabelTemplate =
"{{ index .Config.Labels \"io.prover-coder-ai.docker-git.controller-rev\" }}"
const missingImageInspectionPatterns: ReadonlyArray<RegExp> = [/No such image/iu, /No such object/iu]

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const resolveAutoAgentFlags = (
if (requested === "auto") {
return Either.right({ agentMode: undefined, agentAuto: true })
}
const agentModes: readonly AgentMode[] = ["claude", "codex", "gemini", "grok"]
const agentModes: ReadonlyArray<AgentMode> = ["claude", "codex", "gemini", "grok"]
const matchedMode = agentModes.find((mode) => mode === requested)
if (matchedMode !== undefined) {
return Either.right({ agentMode: matchedMode, agentAuto: true })
Expand Down
9 changes: 8 additions & 1 deletion packages/app/src/docker-git/host-errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,14 @@ export type HostError =
export type CliError = ParseError | HostError

const isParseError = (error: CliError): error is ParseError =>
["UnknownCommand", "UnknownOption", "MissingOptionValue", "MissingRequiredOption", "InvalidOption", "UnexpectedArgument"].includes(error._tag)
[
"UnknownCommand",
"UnknownOption",
"MissingOptionValue",
"MissingRequiredOption",
"InvalidOption",
"UnexpectedArgument"
].includes(error._tag)

const renderApiRequestError = (error: ApiRequestError): string =>
error.displayOnlyMessage === true
Expand Down
4 changes: 3 additions & 1 deletion packages/app/src/docker-git/menu-auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ const submitAuthPrompt = (view: AuthPromptView, context: AuthInputContext) => {
const label = defaultLabel(nextValues["label"] ?? "")
const effect = resolveAuthPromptEffect(view, context.state.cwd, nextValues)
runAuthPromptEffect(effect, view, label, { ...context, cwd: context.state.cwd }, {
suspendTui: ["GithubOauth", "CodexOauth", "ClaudeOauth", "ClaudeLogout", "GeminiOauth", "GrokOauth"].includes(view.flow)
suspendTui: ["GithubOauth", "CodexOauth", "ClaudeOauth", "ClaudeLogout", "GeminiOauth", "GrokOauth"].includes(
view.flow
)
})
}
)
Expand Down
Loading