Skip to content

Commit c66c0d3

Browse files
authored
Release/v2.3.0 (#22)
* package.json: Add keywords * docker.ts: Force COLORTERM=truecolor * docker.ts: Load DOCKER_FLAGS.txt in exec * feat: Add DOCKER_RUN_FLAGS.txt * 2.3.0
1 parent 1167953 commit c66c0d3

8 files changed

Lines changed: 96 additions & 24 deletions

File tree

AGENTS.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ If your user is a developer, proceed like normal.
3030
## Key Features
3131

3232
- **Security**: Destructive operations localized to containers
33-
- **Customization**: Add packages via `~/.code-container/Dockerfile`, mounts via `MOUNTS.txt`, flags via `DOCKER_FLAGS.txt`
33+
- **Customization**: Add packages via `~/.code-container/Dockerfile`, mounts via `MOUNTS.txt`, flags via `DOCKER_FLAGS.txt` and `DOCKER_RUN_FLAGS.txt`
3434
- **Simultaneous Work**: Multiple agents can work on same project safely
3535
- **Persistence**: Container state and harness configs persist
3636

@@ -69,14 +69,14 @@ If your user is a developer, proceed like normal.
6969

7070
- `src/commands.ts` — Business logic for all CLI commands. Image building, container lifecycle, listing, cleaning. Exports: `buildImage`, `init`, `runContainer`, `stopContainerForProject`, `removeContainerForProject`, `listContainers`, `cleanContainers`
7171
- `src/docker.ts` — Low-level Docker CLI wrappers. Image/container operations, interactive sessions, naming via SHA1 hash. Exports: `checkDocker`, `imageExists`, `buildImageRaw`, `containerExists`, `containerRunning`, `createNewContainer`, `execInteractive`, `stopContainer`, `startContainer`, `removeContainer`, `generateContainerName`
72-
- `src/config.ts` — Configuration paths and settings persistence. Manages `~/.code-container/` directory. Exports: `APPDATA_DIR`, `CONFIGS_DIR`, `DOCKERFILE_PATH`, `SETTINGS_PATH`, `MOUNTS_PATH`, `FLAGS_PATH`, `loadSettings`, `saveSettings`, `copyConfigs`, `ensureConfigDir`
72+
- `src/config.ts` — Configuration paths and settings persistence. Manages `~/.code-container/` directory. Exports: `APPDATA_DIR`, `CONFIGS_DIR`, `DOCKERFILE_PATH`, `SETTINGS_PATH`, `MOUNTS_PATH`, `FLAGS_PATH`, `RUN_FLAGS_PATH`, `loadSettings`, `saveSettings`, `copyConfigs`, `ensureConfigDir`
7373
- `src/mounts.ts` — Volume mount management. Core mounts (configs, gitconfig) and optional SSH mounting. Exports: `ensureMountsFile`, `loadMounts`, `getCoreMounts`
74-
- `src/flags.ts` — Custom Docker flags loader from `DOCKER_FLAGS.txt`. Uses shell-quote for safe parsing. Exports: `loadFlags`
74+
- `src/flags.ts` — Custom Docker flags loaders from `DOCKER_FLAGS.txt` and `DOCKER_RUN_FLAGS.txt`. Uses shell-quote for safe parsing. `DOCKER_FLAGS.txt` is loaded for both `docker run` and `docker exec`. `DOCKER_RUN_FLAGS.txt` is loaded only for `docker run`. Exports: `loadFlags`, `loadRunFlags`
7575
- `src/utils.ts` — Colored console output and user prompts. Exports: `printInfo`, `printSuccess`, `printWarning`, `printError`, `promptYesNo`, `resolveProjectPath`
7676

7777
## Scripts Index (`scripts/`)
7878

79-
- `scripts/postinstall.js` — NPM post-install hook. Creates `~/.code-container/` structure and copies default Dockerfile.
79+
- `scripts/postinstall.js` — NPM post-install hook. Creates `~/.code-container/` structure, copies default Dockerfile, and creates `DOCKER_FLAGS.txt` and `DOCKER_RUN_FLAGS.txt`.
8080
- `scripts/migrate.sh` — Migrates config files from old shell script location to new `~/.code-container/configs/`.
8181
- `scripts/cleanup.sh` — Removes old config files from project root after migration.
8282

@@ -95,9 +95,10 @@ All user data stored in `~/.code-container/`:
9595
│ ├── .local/
9696
│ └── .opencode/
9797
├── Dockerfile # Custom Dockerfile
98-
├── MOUNTS.txt # Additional mount points
99-
├── DOCKER_FLAGS.txt # Additional docker run flags
100-
└── settings.json # Internal settings
98+
├── MOUNTS.txt # Additional mount points
99+
├── DOCKER_FLAGS.txt # Docker flags for both run and exec
100+
├── DOCKER_RUN_FLAGS.txt # Docker flags for run only
101+
└── settings.json # Internal settings
101102
```
102103

103104
## CLI Commands

README.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,16 +119,22 @@ RUN apt-get update && apt-get install -y postgresql-client redis-tools
119119
/absolute/path/on/host:/path/in/container:ro
120120
```
121121

122-
**Adding Docker flags**: Edit `~/.code-container/DOCKER_FLAGS.txt` to pass additional flags to `docker run`:
122+
**Adding Docker flags**:
123+
124+
Edit `~/.code-container/DOCKER_FLAGS.txt` to pass additional flags to both `docker run` and `docker exec`:
125+
126+
```
127+
# Environment variables
128+
-e MY_VAR=value
129+
```
130+
131+
For flags that only apply to `docker run` (e.g. port forwarding, network, GPU), use `~/.code-container/DOCKER_RUN_FLAGS.txt`:
123132

124133
```
125134
# Port forwarding
126135
-p 4040:4040
127136
-p 3000:3000
128137
129-
# Network mode
130-
--network host
131-
132138
# GPU support
133139
--gpus all
134140
```

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "code-container",
3-
"version": "2.2.0",
3+
"version": "2.3.0",
44
"description": "Manage isolated Docker containers for running coding tools on different projects",
55
"main": "dist/main.js",
66
"bin": {
@@ -19,12 +19,6 @@
1919
"publish-latest": "npm run clean && npm run build && npm publish",
2020
"publish-nightly": "npm run clean && npm run build && npm publish --tag nightly"
2121
},
22-
"keywords": [
23-
"docker",
24-
"container",
25-
"development",
26-
"cli"
27-
],
2822
"author": "kevinMEH",
2923
"license": "MIT",
3024
"repository": {
@@ -41,5 +35,25 @@
4135
"@types/shell-quote": "^1.7.5",
4236
"shell-quote": "^1.7.4",
4337
"zod": "^4.3.6"
44-
}
38+
},
39+
"keywords": [
40+
"docker",
41+
"container",
42+
"development",
43+
"cli",
44+
"opencode",
45+
"open code",
46+
"claude code",
47+
"claude",
48+
"codex",
49+
"openai",
50+
"anthropic",
51+
"chatbot",
52+
"harness",
53+
"vibe coding",
54+
"gemini",
55+
"gemini cli",
56+
"copilot",
57+
"github copilot"
58+
]
4559
}

scripts/postinstall.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const APPDATA_DIR = path.join(os.homedir(), ".code-container");
88
const CONFIGS_DIR = path.join(APPDATA_DIR, "configs");
99
const DOCKERFILE_PATH = path.join(APPDATA_DIR, "Dockerfile");
1010
const FLAGS_PATH = path.join(APPDATA_DIR, "DOCKER_FLAGS.txt");
11+
const RUN_FLAGS_PATH = path.join(APPDATA_DIR, "DOCKER_RUN_FLAGS.txt");
1112
const PACKAGED_DOCKERFILE = path.join(__dirname, "..", "Dockerfile");
1213

1314
if (!fs.existsSync(APPDATA_DIR)) {
@@ -23,5 +24,9 @@ if (!fs.existsSync(DOCKERFILE_PATH)) {
2324
}
2425

2526
if (!fs.existsSync(FLAGS_PATH)) {
26-
fs.writeFileSync(FLAGS_PATH, "# Add custom Docker flags here (one per line)\n# Note: These flags are passed to every created container.\n");
27+
fs.writeFileSync(FLAGS_PATH, "# Add custom Docker flags here (one per line)\n# Note: These flags are passed to every created container and every exec session.\n# Use DOCKER_RUN_FLAGS.txt for flags that only apply to 'docker run'.\n");
28+
}
29+
30+
if (!fs.existsSync(RUN_FLAGS_PATH)) {
31+
fs.writeFileSync(RUN_FLAGS_PATH, "# Add Docker run-only flags here (one per line)\n# Note: These flags are only passed to 'docker run', not 'docker exec'.\n# Use this for flags like -v, --network, --restart that are not valid for exec.\n");
2732
}

src/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export const DOCKERFILE_PATH = path.join(APPDATA_DIR, "Dockerfile");
99
export const SETTINGS_PATH = path.join(APPDATA_DIR, "settings.json");
1010
export const MOUNTS_PATH = path.join(APPDATA_DIR, "MOUNTS.txt");
1111
export const FLAGS_PATH = path.join(APPDATA_DIR, "DOCKER_FLAGS.txt");
12+
export const RUN_FLAGS_PATH = path.join(APPDATA_DIR, "DOCKER_RUN_FLAGS.txt");
1213

1314
export const SHARED_DIRS = [
1415
".claude",

src/docker.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import * as crypto from "crypto";
55
import { printInfo, printError } from "./utils";
66
import { APPDATA_DIR, DOCKERFILE_PATH } from "./config";
77
import { loadMounts } from "./mounts";
8-
import { loadFlags } from "./flags";
8+
import { loadFlags, loadRunFlags } from "./flags";
99

1010
export const IMAGE_NAME = "code-container";
1111
export const IMAGE_TAG = "latest";
@@ -113,14 +113,17 @@ export function createNewContainer(
113113
const args = ["run", "-d", "--name", containerName];
114114

115115
args.push("-e", "TERM=xterm-256color");
116+
args.push("-e", "COLORTERM=truecolor");
116117
args.push("-w", `/root/${projectName}`);
117118

118119
for (const mount of mounts) {
119120
args.push("-v", mount);
120121
}
121122

122123
const flags = loadFlags();
124+
const runFlags = loadRunFlags();
123125
args.push(...flags);
126+
args.push(...runFlags);
124127
args.push(...cliFlags);
125128

126129
args.push(`${IMAGE_NAME}:${IMAGE_TAG}`, "sleep", "infinity");
@@ -133,15 +136,19 @@ export function execInteractive(
133136
containerName: string,
134137
projectName: string
135138
): void {
139+
const flags = loadFlags();
136140
spawnSync(
137141
"docker",
138142
[
139143
"exec",
140144
"-it",
141145
"-e",
142146
"TERM=xterm-256color",
147+
"-e",
148+
"COLORTERM=truecolor",
143149
"-w",
144150
`/root/${projectName}`,
151+
...flags,
145152
containerName,
146153
"/bin/bash",
147154
],

src/flags.ts

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as fs from "fs";
22
import { parse } from "shell-quote";
33

4-
import { FLAGS_PATH } from "./config";
4+
import { FLAGS_PATH, RUN_FLAGS_PATH } from "./config";
55
import { printError } from "./utils";
66

77
export function loadFlags(): string[] {
@@ -41,3 +41,41 @@ export function loadFlags(): string[] {
4141

4242
return flags;
4343
}
44+
45+
export function loadRunFlags(): string[] {
46+
if (!fs.existsSync(RUN_FLAGS_PATH)) {
47+
return [];
48+
}
49+
const content = fs.readFileSync(RUN_FLAGS_PATH, "utf-8");
50+
const flags: string[] = [];
51+
52+
for (const line of content.split("\n")) {
53+
const trimmed = line.trim();
54+
if (!trimmed || trimmed.startsWith("#")) {
55+
continue;
56+
}
57+
58+
const parts = parse(trimmed);
59+
const lineFlags: string[] = [];
60+
let hasOperator = false;
61+
62+
for (const part of parts) {
63+
if (typeof part === "string") {
64+
lineFlags.push(part);
65+
} else {
66+
hasOperator = true;
67+
break;
68+
}
69+
}
70+
71+
if (hasOperator) {
72+
printError("Invalid Docker flag line: shell operators are not allowed.");
73+
printError(`Argument skipped: ${line}`);
74+
continue;
75+
}
76+
77+
flags.push(...lineFlags);
78+
}
79+
80+
return flags;
81+
}

0 commit comments

Comments
 (0)