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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,4 @@ data/credentials.json
data/
.codex/
.mcp.json
.planning
.planning
10 changes: 10 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ RUN curl -fsSL https://opencode.ai/install | bash && \
echo "=== Checking OpenCode CLI installation ===" && \
ls -la /home/automaker/.local/bin/ && \
(which opencode && opencode --version) || echo "opencode installed (may need auth setup)"

USER root

# Add PATH to profile so it's available in all interactive shells (for login shells)
Expand Down Expand Up @@ -147,6 +148,15 @@ COPY --from=server-builder /app/apps/server/package*.json ./apps/server/
# Copy node_modules (includes symlinks to libs)
COPY --from=server-builder /app/node_modules ./node_modules

# Install Playwright Chromium browser for AI agent verification tests
# This adds ~300MB to the image but enables automated testing mode out of the box
# Using the locally installed playwright ensures we use the pinned version from package-lock.json
USER automaker
RUN ./node_modules/.bin/playwright install chromium && \
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

Minor - Logic: Misleading error handling in Playwright install RUN command

The || echo at the end is connected to the ls command due to operator precedence, not to the entire chain. If playwright install chromium fails, the build will fail (which is correct). However, if ls fails (unlikely but possible), the echo silently masks the error. This creates a misleading success message. More importantly, the || structure makes the overall RUN step always succeed even if ls fails, which could hide a misconfigured browser install path.

Problematic code:

RUN ./node_modules/.bin/playwright install chromium && \
    echo "=== Playwright Chromium installed ===" && \
    ls -la /home/automaker/.cache/ms-playwright/ || echo "Playwright browsers installed"

Suggested fix:

Use explicit grouping or just remove the fallback since the ls output is informational:
```dockerfile
RUN ./node_modules/.bin/playwright install chromium && \
    echo "=== Playwright Chromium installed ===" && \
    ls -la /home/automaker/.cache/ms-playwright/

echo "=== Playwright Chromium installed ===" && \
ls -la /home/automaker/.cache/ms-playwright/
USER root

# Create data and projects directories
RUN mkdir -p /data /projects && chown automaker:automaker /data /projects

Expand Down
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,42 @@ services:

The Docker image supports both AMD64 and ARM64 architectures. The GitHub CLI and Claude CLI are automatically downloaded for the correct architecture during build.

##### Playwright for Automated Testing

The Docker image includes **Playwright Chromium pre-installed** for AI agent verification tests. When agents implement features in automated testing mode, they use Playwright to verify the implementation works correctly.

**No additional setup required** - Playwright verification works out of the box.

#### Optional: Persist browsers for manual updates

By default, Playwright Chromium is pre-installed in the Docker image. If you need to manually update browsers or want to persist browser installations across container restarts (not image rebuilds), you can mount a volume.

**Important:** When you first add this volume mount to an existing setup, the empty volume will override the pre-installed browsers. You must re-install them:

```bash
# After adding the volume mount for the first time
docker exec --user automaker -w /app automaker-server npx playwright install chromium
```

Add this to your `docker-compose.override.yml`:

```yaml
services:
server:
volumes:
- playwright-cache:/home/automaker/.cache/ms-playwright

volumes:
playwright-cache:
name: automaker-playwright-cache
```

**Updating browsers manually:**

```bash
docker exec --user automaker -w /app automaker-server npx playwright install chromium
```

### Testing

#### End-to-End Tests (Playwright)
Expand Down
1 change: 1 addition & 0 deletions apps/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"yaml": "2.7.0"
},
"devDependencies": {
"@playwright/test": "1.57.0",
"@types/cookie": "0.6.0",
"@types/cookie-parser": "1.4.10",
"@types/cors": "2.8.19",
Expand Down
8 changes: 7 additions & 1 deletion apps/server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,13 @@ const BOX_CONTENT_WIDTH = 67;
pathsCheckedInfo = `
║ ║
║ ${'Paths checked:'.padEnd(BOX_CONTENT_WIDTH)}║
${pathsChecked.map((p) => `║ ${p.substring(0, BOX_CONTENT_WIDTH - 4).padEnd(BOX_CONTENT_WIDTH - 4)} ║`).join('\n')}`;
${pathsChecked
.map((p) => {
const maxLen = BOX_CONTENT_WIDTH - 4;
const display = p.length > maxLen ? '...' + p.slice(-(maxLen - 3)) : p;
return `║ ${display.padEnd(maxLen)} ║`;
})
.join('\n')}`;
}
}

Expand Down
5 changes: 3 additions & 2 deletions apps/server/src/routes/setup/routes/verify-claude-auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,11 +322,12 @@ export function createVerifyClaudeAuthHandler() {
});

// Determine specific auth type for success messages
const effectiveAuthMethod = authMethod ?? 'api_key';
let authType: 'oauth' | 'api_key' | 'cli' | undefined;
if (authenticated) {
if (authMethod === 'api_key') {
if (effectiveAuthMethod === 'api_key') {
authType = 'api_key';
} else if (authMethod === 'cli') {
} else if (effectiveAuthMethod === 'cli') {
// Check if CLI auth is via OAuth (Claude Code subscription) or generic CLI
try {
const indicators = await getClaudeAuthIndicators();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Nit - Performance: Redundant filesystem checks after successful auth verification

After successfully verifying authentication via a full SDK query (which already proved auth works), this code calls getClaudeAuthIndicators() again just to determine the auth type. This performs additional filesystem reads (checking settings files, stats cache, projects dir, credential files) on every successful CLI auth verification. While not a significant performance issue, the indicator data was already fetched during the startup check. Consider caching or reusing that data.

Problematic code:

const indicators = await getClaudeAuthIndicators();

Suggested fix:

This is acceptable for now since it only runs during setup verification (not a hot path). Could be improved by caching the indicators or passing them through context, but low priority.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ interface ThinkingLevelSelectorProps {
selectedLevel: ThinkingLevel;
onLevelSelect: (level: ThinkingLevel) => void;
testIdPrefix?: string;
/** Optional model ID to filter available thinking levels (e.g., Opus 4.6 only shows None/Adaptive) */
/** Model ID is required for correct thinking level filtering.
* Without it, adaptive thinking won't be available for Opus 4.6. */
model?: string;
}

Expand Down
2 changes: 1 addition & 1 deletion apps/ui/src/lib/agent-context-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const DEFAULT_MODEL = 'claude-opus-4-6';
*/
export function formatModelName(model: string): string {
// Claude models
if (model.includes('opus-4-6')) return 'Opus 4.6';
if (model.includes('opus-4-6') || model === 'claude-opus') return 'Opus 4.6';
if (model.includes('opus')) return 'Opus 4.5';
if (model.includes('sonnet')) return 'Sonnet 4.5';
if (model.includes('haiku')) return 'Haiku 4.5';
Expand Down
11 changes: 8 additions & 3 deletions docker-compose.override.yml.example
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,13 @@ services:
# - ~/.local/share/opencode:/home/automaker/.local/share/opencode
# - ~/.config/opencode:/home/automaker/.config/opencode

# Playwright browser cache - persists installed browsers across container restarts
# Run 'npx playwright install --with-deps chromium' once, and it will persist
# ===== Playwright Browser Cache (Optional) =====
# Playwright Chromium is PRE-INSTALLED in the Docker image for automated testing.
# Uncomment below to persist browser cache across container rebuilds (saves ~300MB download):
# - playwright-cache:/home/automaker/.cache/ms-playwright
#
# To update Playwright browsers manually:
# docker exec --user automaker -w /app automaker-server npx playwright install chromium
environment:
# Set root directory for all projects and file operations
# Users can only create/open projects within this directory
Expand All @@ -37,6 +41,7 @@ services:
# - CURSOR_API_KEY=${CURSOR_API_KEY:-}

volumes:
# Playwright cache volume (persists Chromium installs)
# Playwright cache volume - optional, persists browser updates across container rebuilds
# Uncomment if you mounted the playwright-cache volume above
# playwright-cache:
# name: automaker-playwright-cache