Skip to content

Commit fd74a42

Browse files
TeigenTeigen
authored andcommitted
Merge remote-tracking branch 'origin/master' into dev
2 parents 1b10d9b + 7101e64 commit fd74a42

96 files changed

Lines changed: 459 additions & 989 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,12 @@ Thumbs.db
4848
# Generated output
4949
out/
5050
screenshots-echo-diag/
51-
tools/remotion/out/
51+
scripts/remotion/out/
52+
53+
# Artifacts that should not be tracked
54+
test-results/
55+
tmp/
56+
public
5257

5358
# Claude Code plan tracking
5459
plan.json

.prettierignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ src/web/public/app.js
66
src/web/public/styles.css
77
src/web/public/mobile.css
88
src/web/public/index.html
9-
tools/
9+
scripts/remotion/

CHANGELOG.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,51 @@
11
# aicodeman
22

3+
## 0.5.10
4+
5+
### Patch Changes
6+
7+
- fix: allow bracket characters in model validation regex so models like opus[1m] (1M context window) are accepted instead of silently dropped. Quote the model flag value in tmux spawn commands to prevent bash glob expansion of bracket patterns.
8+
9+
docs: update macOS launchd instructions to use `launchctl bootstrap` instead of deprecated `load`. Clean up README install and service sections.
10+
11+
## 0.5.9
12+
13+
### Patch Changes
14+
15+
- Mobile keyboard accessory bar: add configurable "Extended Keyboard Bar" setting (Settings > Display > Input) that toggles between simple mode (up/down arrows, /init, /clear, /compact, paste, dismiss) and extended mode (adds left/right arrows, Tab, Shift+Tab, Ctrl+O, Alt+Enter, Esc). Default is simple mode. Setting is device-specific (not synced to server).
16+
17+
Restyle dismiss button: muted steel-blue tone, fills remaining bar space via flex, larger tap target. Arrow buttons now blue.
18+
19+
Fix paste overlay visibility on mobile: dialog repositioned to top of screen (15vh from top) so the virtual keyboard doesn't cover it. Textarea enlarged for better usability.
20+
21+
(Also includes all v0.5.8 changes: case reorder/delete, XSS sanitization, auto-attach PTY on restart, mobile keyboard buttons, macOS installer fixes, terminal flicker fix, state store collision fix.)
22+
23+
## 0.5.8
24+
25+
### Patch Changes
26+
27+
- Case management: add Manage tab with reorder (up/down arrows) and delete for cases; linked cases are unlinked (folder preserved), CASES_DIR cases are permanently deleted. New endpoints: DELETE /api/cases/:name, PUT /api/cases/order. SSE events: case:deleted, case:order-changed.
28+
29+
Security: sanitize case names from filesystem with /^[a-zA-Z0-9_-]+$/ regex before returning from GET /api/cases to prevent XSS via maliciously-named directories reaching frontend inline onclick handlers.
30+
31+
Auto-attach PTY: server now calls startInteractive() for recovered tmux sessions during startup so all sessions resume capturing output immediately after deploy, instead of waiting for client selection. Frontend auto-attach condition relaxed from (pid===null && status==='idle') to (pid===null && !\_ended).
32+
33+
Mobile keyboard accessory: add Shift+Tab, Tab, Esc, Alt+Enter, Left/Right arrow, and Ctrl+O buttons.
34+
35+
Terminal: fix flicker regression by moving viewport clear inside dimension guard.
36+
37+
State store: fix temp file collisions on concurrent writes.
38+
39+
macOS: fix installer failures when piped via curl | bash, add HTML cache support, launchd service template, and trust dialog handling.
40+
41+
Housekeeping: remove accidentally committed dist/state-store.js build artifact.
42+
43+
## 0.5.7
44+
45+
### Patch Changes
46+
47+
- feat: support "Default (CLI default)" option for model selection. Adds a new empty-value option to the model dropdown that defers to the CLI's own default model instead of forcing a specific model. Ensures empty defaultModel values are treated as undefined when passed to session creation and Ralph loop start, preventing empty strings from being sent as model flags.
48+
349
## 0.5.6
450

551
### Patch Changes

CLAUDE.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ When user says "COM":
5252
4. **Sync CLAUDE.md version**: Update the `**Version**` line below to match the new version from `package.json`
5353
5. **Commit and deploy**: `git add -A && git commit -m "chore: version packages" && git push && npm run build && systemctl --user restart codeman-web`
5454
55-
**Version**: 0.5.6 (must match `package.json`)
55+
**Version**: 0.5.10 (must match `package.json`)
5656
5757
## Project Overview
5858
@@ -80,7 +80,7 @@ Codeman is a Claude Code session manager with web interface and autonomous Ralph
8080
8181
**CI**: `.github/workflows/ci.yml` runs `typecheck`, `lint`, `format:check` on push to master/main and on PRs (Node 22). Tests excluded (they spawn tmux).
8282
83-
**Code style**: Prettier (`singleQuote: true`, `printWidth: 120`, `trailingComma: "es5"`). ESLint flat config (`eslint.config.js`) allows `no-console`, warns on `@typescript-eslint/no-explicit-any`. Ignores: `app.js`, `scripts/**/*.mjs`, `src/web/public/vendor/**`, `tools/**`, `remotion/**`.
83+
**Code style**: Prettier (`singleQuote: true`, `printWidth: 120`, `trailingComma: "es5"`). ESLint flat config (`config/eslint.config.js`) allows `no-console`, warns on `@typescript-eslint/no-explicit-any`. Ignores: `app.js`, `scripts/**/*.mjs`, `src/web/public/vendor/**`, `scripts/remotion/**`.
8484
8585
## Common Gotchas
8686
@@ -136,7 +136,7 @@ Codeman is a Claude Code session manager with web interface and autonomous Ralph
136136
137137
**Hook events**: Claude Code hooks trigger via `/api/hook-event`. Key events: `permission_prompt`, `elicitation_dialog`, `idle_prompt`, `stop`, `teammate_idle`, `task_completed`. See `src/hooks-config.ts`.
138138
139-
**Agent Teams**: `TeamWatcher` polls `~/.claude/teams/`, matches to sessions via `leadSessionId`. Teammates are in-process threads appearing as subagents. Enable: `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1`. See `agent-teams/`.
139+
**Agent Teams**: `TeamWatcher` polls `~/.claude/teams/`, matches to sessions via `leadSessionId`. Teammates are in-process threads appearing as subagents. Enable: `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1`. See `docs/agent-teams/`.
140140
141141
**Circuit breaker**: Prevents respawn thrashing. States: `CLOSED` → `HALF_OPEN` → `OPEN`. Reset: `/api/sessions/:id/ralph-circuit-breaker/reset`.
142142
@@ -204,7 +204,7 @@ npx vitest run -t "pattern" # By name (SAFE)
204204
205205
**Ports**: Pick unique ports manually. Search `const PORT =` before adding new tests.
206206
207-
**Respawn tests**: Use `MockSession` from `test/respawn-test-utils.ts`. **Route tests**: `app.inject()` in `test/routes/`. **Mobile tests**: Playwright suite in `mobile-test/` (135 device profiles).
207+
**Respawn tests**: Use `MockSession` from `test/respawn-test-utils.ts`. **Route tests**: `app.inject()` in `test/routes/`. **Mobile tests**: Playwright suite in `test/mobile/` (135 device profiles).
208208
209209
## Screenshots
210210
@@ -226,7 +226,7 @@ Target: 20 sessions, 50 agent windows at 60fps. Limits in `src/config/`: termina
226226
227227
## References
228228
229-
Deep-dive docs in `docs/`: `respawn-state-machine.md`, `ralph-wiggum-guide.md`, `claude-code-hooks-reference.md`, `terminal-anti-flicker.md`, `opencode-integration.md`, `qr-auth-plan.md`, `orchestrator-loop-architecture.md`, `browser-testing-guide.md`. Agent Teams: `agent-teams/README.md`. SSE events: `src/web/sse-events.ts` + `constants.js`.
229+
Deep-dive docs in `docs/`: `respawn-state-machine.md`, `ralph-wiggum-guide.md`, `claude-code-hooks-reference.md`, `terminal-anti-flicker.md`, `opencode-integration.md`, `qr-auth-plan.md`, `orchestrator-loop-architecture.md`, `browser-testing-guide.md`. Agent Teams: `docs/agent-teams/README.md`. SSE events: `src/web/sse-events.ts` + `constants.js`.
230230
231231
## Scripts
232232

README.md

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,24 +30,6 @@ curl -fsSL https://raw.githubusercontent.com/Ark0N/Codeman/master/install.sh | b
3030

3131
This installs Node.js and tmux if missing, clones Codeman to `~/.codeman/app`, and builds it.
3232

33-
**Install from a fork or specific branch:**
34-
```bash
35-
curl -fsSL https://raw.githubusercontent.com/<user>/Codeman/<branch>/install.sh | \
36-
CODEMAN_REPO_URL=https://github.com/<user>/Codeman.git \
37-
CODEMAN_BRANCH=<branch> bash
38-
```
39-
40-
The installer supports these environment variables:
41-
42-
| Variable | Default | Description |
43-
|----------|---------|-------------|
44-
| `CODEMAN_REPO_URL` | upstream Codeman | Custom git repository URL |
45-
| `CODEMAN_BRANCH` | `master` | Git branch to install |
46-
| `CODEMAN_INSTALL_DIR` | `~/.codeman/app` | Custom install directory |
47-
| `CODEMAN_SKIP_SYSTEMD` | `0` | Skip systemd service setup prompt |
48-
| `CODEMAN_NODE_VERSION` | `22` | Node.js major version to install |
49-
| `CODEMAN_NONINTERACTIVE` | `0` | Skip all prompts (for CI/automation) |
50-
5133
You'll need at least one AI coding CLI installed — [Claude Code](https://docs.anthropic.com/en/docs/claude-code) or [OpenCode](https://opencode.ai) (or both). After install:
5234

5335
```bash
@@ -60,12 +42,53 @@ codeman web
6042

6143
**Linux (systemd):**
6244
```bash
63-
mkdir -p ~/.config/systemd/user && printf '[Unit]\nDescription=Codeman Web Server\nAfter=network.target\n\n[Service]\nType=simple\nExecStart=%s %s/dist/index.js web\nRestart=always\nRestartSec=10\n\n[Install]\nWantedBy=default.target\n' "$(which node)" "$HOME/.codeman/app" > ~/.config/systemd/user/codeman-web.service && systemctl --user daemon-reload && systemctl --user enable --now codeman-web && loginctl enable-linger $USER
45+
mkdir -p ~/.config/systemd/user
46+
cat > ~/.config/systemd/user/codeman-web.service << EOF
47+
[Unit]
48+
Description=Codeman Web Server
49+
After=network.target
50+
51+
[Service]
52+
Type=simple
53+
ExecStart=$(which node) $HOME/.codeman/app/dist/index.js web
54+
Restart=always
55+
RestartSec=10
56+
57+
[Install]
58+
WantedBy=default.target
59+
EOF
60+
systemctl --user daemon-reload
61+
systemctl --user enable --now codeman-web
62+
loginctl enable-linger $USER
6463
```
6564

6665
**macOS (launchd):**
6766
```bash
68-
mkdir -p ~/Library/LaunchAgents && printf '<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n<plist version="1.0"><dict><key>Label</key><string>com.codeman.web</string><key>ProgramArguments</key><array><string>%s</string><string>%s/dist/index.js</string><string>web</string></array><key>RunAtLoad</key><true/><key>KeepAlive</key><true/><key>StandardOutPath</key><string>/tmp/codeman.log</string><key>StandardErrorPath</key><string>/tmp/codeman.log</string></dict></plist>\n' "$(which node)" "$HOME/.codeman/app" > ~/Library/LaunchAgents/com.codeman.web.plist && launchctl load ~/Library/LaunchAgents/com.codeman.web.plist
67+
mkdir -p ~/Library/LaunchAgents
68+
cat > ~/Library/LaunchAgents/com.codeman.web.plist << EOF
69+
<?xml version="1.0" encoding="UTF-8"?>
70+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
71+
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
72+
<plist version="1.0">
73+
<dict>
74+
<key>Label</key>
75+
<string>com.codeman.web</string>
76+
<key>ProgramArguments</key>
77+
<array>
78+
<string>$(which node)</string>
79+
<string>$HOME/.codeman/app/dist/index.js</string>
80+
<string>web</string>
81+
</array>
82+
<key>RunAtLoad</key><true/>
83+
<key>KeepAlive</key><true/>
84+
<key>StandardOutPath</key>
85+
<string>/tmp/codeman.log</string>
86+
<key>StandardErrorPath</key>
87+
<string>/tmp/codeman.log</string>
88+
</dict>
89+
</plist>
90+
EOF
91+
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.codeman.web.plist
6992
```
7093
</details>
7194

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ export default tseslint.config(
2222
'src/web/public/vendor/**',
2323
'src/web/public/app.js',
2424
'scripts/**/*.mjs',
25-
'tools/**',
26-
'remotion/**',
25+
'scripts/remotion/**',
2726
],
2827
}
2928
);
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
import { resolve } from 'node:path';
12
import { defineConfig } from 'vitest/config';
23

4+
const root = resolve(import.meta.dirname, '..');
5+
36
export default defineConfig({
47
test: {
8+
root,
59
globals: true,
610
environment: 'node',
711
include: ['test/**/*.test.ts'],

0 commit comments

Comments
 (0)