From fad32eeaab25a241251b522a28aea85c1c90f0f2 Mon Sep 17 00:00:00 2001 From: arkon Date: Wed, 10 Jun 2026 17:16:13 +0200 Subject: [PATCH] chore: version packages Co-Authored-By: Claude Fable 5 --- CHANGELOG.md | 10 + CLAUDE.md | 2 +- package-lock.json | 4 +- package.json | 2 +- src/templates/case-template.md | 498 +++++---------------------------- src/templates/claude-md.ts | 17 +- test/templates.test.ts | 57 ++-- 7 files changed, 122 insertions(+), 468 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c02a4e31..1291a4d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # aicodeman +## 0.9.10 + +### Patch Changes + +- Self-update now restarts automatically on headless Macs supervised by a system LaunchDaemon. + + New `launchd-daemon` supervisor kind: when Codeman runs under a bootstrapped, KeepAlive system-level LaunchDaemon (`/Library/LaunchDaemons/com.codeman.web.plist` — the right setup for headless Macs, where LaunchAgents never start because there is no GUI login), the updater no longer ends with "Update staged — restart Codeman to apply". It restarts rootlessly: the update script kills the server PID (passed via `--server-pid`) and launchd respawns it on the freshly built `dist/`. Detection is conservative — the daemon must be bootstrapped in the system domain AND have `KeepAlive` enabled. + + Also fixed: a lingering "restart Codeman to apply" status. After a manual restart of a staged update, boot reconciliation now flips `completed-needs-manual-restart` to `completed` once the running version matches the staged target, so the Updates tab stops showing the stale instruction. + ## 0.9.9 ### Patch Changes diff --git a/CLAUDE.md b/CLAUDE.md index 881a383f..4d410606 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -56,7 +56,7 @@ When user says "COM": CI runs `npm run check:lockfile` on every push/PR, so lockfile drift fails the build even if the `version-packages` script is bypassed. -**Version**: 0.9.9 (must match `package.json`) +**Version**: 0.9.10 (must match `package.json`) ## Project Overview diff --git a/package-lock.json b/package-lock.json index 38bc248f..65405eb0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "aicodeman", - "version": "0.9.9", + "version": "0.9.10", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "aicodeman", - "version": "0.9.9", + "version": "0.9.10", "hasInstallScript": true, "license": "MIT", "workspaces": [ diff --git a/package.json b/package.json index 21f08553..ed6bb0b1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "aicodeman", - "version": "0.9.9", + "version": "0.9.10", "description": "The missing control plane for AI coding agents - run 20 autonomous agents with real-time monitoring and session persistence", "type": "module", "main": "dist/index.js", diff --git a/src/templates/case-template.md b/src/templates/case-template.md index 97662c14..ff762be1 100644 --- a/src/templates/case-template.md +++ b/src/templates/case-template.md @@ -1,363 +1,84 @@ -# CLAUDE.md - Project Configuration +# CLAUDE.md -## Setup -Copy these files to your new project: -- `CLAUDE.md` → project root -- `.claude/settings.json` → `.claude/settings.json` + + +This file guides Claude Code when working in this repository. + +## Project -## Project Overview - - **Project Name**: [PROJECT_NAME] - **Description**: [PROJECT_DESCRIPTION] -- **Tech Stack**: [TECHNOLOGIES_USED] -- **Last Updated**: [DATE] ---- +## Commands + + + +## Code Style + + + +## Workflow + +- Full permissions are granted: read, write, edit, and execute without asking. +- Commit after every meaningful change; never batch unrelated work. +- Use conventional commits (`feat:` `fix:` `docs:` `refactor:` `test:` `chore:`); the message says what changed and why. +- Run the tests and linter before declaring any task done. +- Keep README and docs in sync with code changes. ## Codeman Environment -This session is managed by **Codeman** and runs within a tmux session. +This session is managed by Codeman and runs inside tmux (`CODEMAN_MUX=1` confirms it). -**Important**: Check for `CODEMAN_MUX=1` environment variable to confirm. -- Do NOT attempt to kill your own tmux session -- The session persists across disconnects - your work is safe -- Token usage, costs, and background tasks are tracked externally +- NEVER kill your own session: no `tmux kill-session`, `pkill tmux`, or `pkill claude`. +- The session persists across disconnects — your work is safe. +- Hooks may auto-format or validate after writes; unexpected tool behavior usually means a hook ran. Keep working. ---- +## Ralph Loop (Codeman Autonomous Mode) -## Work Principles +Start: `/ralph-loop:ralph-loop` · Cancel: `/ralph-loop:cancel-ralph` · Help: `/ralph-loop:help` -### Autonomy -Full permissions granted. Act decisively without asking - read, write, edit, execute freely. +You are in a Ralph loop when the prompt contains a completion phrase (e.g. `COMPLETE`). While looping: -### Git Discipline -- **Commit after every meaningful change** - never batch unrelated work -- Use conventional commits: `feat:`, `fix:`, `docs:`, `refactor:`, `test:`, `chore:` -- Commit message = what changed + why (not how) +- Work incrementally: one sub-task at a time — implement, verify, commit, move on. +- Fix failing tests and lint errors before starting the next task. +- Check `git log --oneline -10` / `git diff HEAD~1` before retrying an approach that already failed. +- Keep testing to ~20% of total effort; prioritize implementation. Don't refactor working code or add unrequested + features as busy work. +- If the prompt sets a minimum duration (e.g. "work for 4 hours"), record the start time (`date +%s`) and, when the + primary tasks finish early, keep generating useful related work (edge cases, coverage, docs, cleanup, hardening) + until the minimum time is reached. -### Documentation -- Update README.md when adding features or changing setup -- Update this file's session log after work sessions -- Keep docs in sync with code changes +Output the completion phrase ONLY when every requirement is verifiably done: all tests pass, lint is clean, the build +succeeds, and changes are committed. Never output it early — and never withhold it for busy work once everything is +genuinely done. -### Thinking -Extended thinking is enabled. Use deep reasoning for complex architectural decisions, difficult bugs, and multi-file changes. +### RALPH_STATUS block (required) -### Task Tracking (TodoWrite) -**ALWAYS use TodoWrite** to track tasks. This is non-negotiable for anything beyond trivial single-step work. - -**When to use TodoWrite:** -- Multi-step tasks (3+ steps) -- Bug fixes requiring investigation -- Feature implementations -- Any work where progress tracking helps -- When the user provides multiple requests - -**How to use it:** -1. **Before starting**: Break down the work into discrete todos -2. **During work**: Mark each todo `in_progress` before starting, `completed` when done -3. **One at a time**: Only ONE todo should be `in_progress` at any moment -4. **Immediately**: Mark todos complete the moment they're done - don't batch - -**Why this matters:** -- Gives the user visibility into your progress -- Prevents forgetting tasks mid-work -- Creates accountability checkpoints -- Makes complex work manageable - -**Example workflow:** -``` -User: "Add user authentication with JWT" - -→ TodoWrite: - - [ ] Research existing auth patterns in codebase - - [ ] Implement JWT token generation - - [ ] Add login endpoint - - [ ] Add token validation middleware - - [ ] Add protected route example - - [ ] Write tests - -→ Mark "Research existing auth patterns" as in_progress -→ Do the research -→ Mark as completed, mark next as in_progress -→ Continue until all done -``` - -**Anti-patterns to avoid:** -- Starting work without creating todos first -- Having multiple todos `in_progress` simultaneously -- Batching completions at the end -- Skipping TodoWrite for "simple" multi-step tasks - ---- - -## When to Use Agents - -**Explore agent**: Codebase investigation, finding files, understanding architecture -``` -"Use explore agent to find all authentication-related code" -``` - -**Parallel agents**: Independent tasks that don't conflict -``` -"Research auth, database, and API modules in parallel using separate agents" -``` - -**Background execution**: Long-running operations (tests, builds) -``` -"Run the test suite in the background while I continue" -``` - -**Sequential chaining**: When second task depends on first -``` -"Use code-reviewer to find issues, then use fixer to resolve them" -``` - ---- - -## Planning Mode (Automatic) - -**Automatically enter planning mode** when ANY of these conditions apply: -- Multi-file changes (3+ files affected) -- Architectural decisions -- Unclear or evolving requirements -- Risk mitigation on core systems -- New feature implementation -- Refactoring existing functionality - -**Do NOT ask** whether to enter planning mode - just enter it when conditions are met. - -Planning mode flow: read-only exploration → create plan → get approval → execute. - -**Skip planning mode** only for: -- Single-file bug fixes -- Typo corrections -- Simple config changes -- Tasks with explicit step-by-step instructions from user - ---- - -## Ralph Wiggum Loop (Autonomous Work Mode) - -Ralph loops enable persistent, autonomous work on large tasks. When active, you continue iterating until completion criteria are met or the loop is cancelled. - -### Starting a Ralph Loop -- Start: `/ralph-loop:ralph-loop` -- Cancel: `/ralph-loop:cancel-ralph` -- Help: `/ralph-loop:help` - -### Time-Aware Loops - -When the user specifies a **minimum duration** (e.g., "optimize for 8 hours", "work on this for 2 hours"), the loop becomes time-aware: - -**At loop start:** -```bash -# Record start time -date +%s > /tmp/ralph_start_time -echo "Loop started at $(date)" -``` - -**Check elapsed time periodically:** -```bash -START=$(cat /tmp/ralph_start_time) -NOW=$(date +%s) -ELAPSED_HOURS=$(echo "scale=2; ($NOW - $START) / 3600" | bc) -echo "Elapsed: $ELAPSED_HOURS hours" -``` - -**Time-aware behavior:** -1. Complete all primary tasks from the user's prompt -2. After primary tasks done, check elapsed time -3. If minimum duration NOT reached: - - **Do NOT output completion phrase** - - Self-generate additional related tasks - - Continue working until minimum time elapsed -4. Only output completion phrase when: - - ALL primary tasks complete AND - - Minimum duration reached (or exceeded) - -**Self-generating additional tasks when time remains:** -- Code optimization (performance, readability, DRY) -- Test coverage improvements -- Edge case handling -- Error message improvements -- Documentation gaps -- Security hardening -- Accessibility improvements -- Code cleanup and dead code removal -- Dependency updates -- Type safety improvements - -**Example time-aware prompt:** -``` -"Optimize the API endpoints for the next 4 hours. Focus on performance first, -then code quality. Minimum runtime: 4 hours." -Completion phrase: TIME_COMPLETE -``` - -**Time-aware loop behavior:** -``` -[Start loop, record timestamp] -[Complete primary optimization tasks - 2 hours elapsed] -[Check time: 2/4 hours - NOT done yet] -[Self-generate: "Add caching to database queries"] -[Self-generate: "Optimize N+1 queries"] -[Self-generate: "Add request batching"] -[Continue working... 4.5 hours elapsed] -[Check time: 4.5/4 hours - minimum reached] -[All tasks complete, tests pass] -TIME_COMPLETE -``` - -### How You Know You're in a Ralph Loop - -The user started the loop with a prompt containing: -- Clear task requirements -- A **completion phrase** (e.g., `COMPLETE`) -- **Optional: minimum duration** (e.g., "for the next 4 hours") -- Iteration limits (handled by the system) - -Your job: Keep working until ALL requirements are verifiably done AND minimum time reached (if specified), then output the exact completion phrase. - -### Core Behaviors During Ralph Loop - -**1. Work Incrementally** -- Complete one sub-task at a time -- Verify it works before moving to the next -- Don't try to do everything in one pass - -**2. Commit Frequently** -- Commit after each meaningful completion -- Creates recovery points if something breaks -- Shows progress in git history -``` -git add . && git commit -m "feat(auth): add token refresh endpoint" -``` - -**3. Self-Correct Relentlessly** -``` -Loop: - 1. Implement/fix - 2. Run tests - 3. If tests fail → read error, fix, go to 1 - 4. Run linter - 5. If lint errors → fix, go to 1 - 6. Commit - 7. Continue to next task -``` - -**4. Track Progress** -Update the session log in this file as you complete tasks: -```markdown -| Date | Tasks Completed | Files Changed | Notes | -|------|-----------------|---------------|-------| -| YYYY-MM-DD | Add auth endpoint | auth.ts, routes.ts | Tests passing | -``` - -**5. Use Git History When Stuck** -If something isn't working: -```bash -git log --oneline -10 -git diff HEAD~1 -``` -See what you already tried. Don't repeat failed approaches. - -**6. Completion Phrase = Contract** -Only output the completion phrase (e.g., `COMPLETE`) when: -- ALL requirements from the original prompt are done -- ALL tests pass -- ALL linting passes -- Changes are committed - -**Never output the completion phrase early.** The loop only ends when you say it's done. - -### What Makes Good Completion Criteria - -The user should provide criteria that are: -- **Verifiable**: Tests pass, lint clean, build succeeds -- **Measurable**: "5 endpoints", "all files in src/", "zero errors" -- **Binary**: Done or not done, no ambiguity - -If the original prompt has vague criteria, ask clarifying questions before starting heavy work. - -### Self-Correction Pattern (Include in Your Work) - -``` -FOR EACH TASK: -1. Implement the change -2. Run tests (npm test, pytest, go test, cargo test, etc.) - - If fail → read error, fix, retry -3. Run linter (npm run lint, ruff, golangci-lint, etc.) - - If fail → fix, go to step 2 -4. Verify manually if needed -5. Commit with descriptive message -6. Update session log -7. Move to next task - -WHEN ALL TASKS DONE: -1. Run full test suite -2. Run full lint -3. Verify build succeeds -4. Review all changes: git diff main -5. Only then output completion phrase -``` - -### Example: How to Think During Ralph Loop - -**Original prompt**: "Add CRUD endpoints for todos with validation" - -**Your approach**: -``` -Task breakdown: -- [ ] GET /todos (list) -- [ ] POST /todos (create with validation) -- [ ] GET /todos/:id (single) -- [ ] PUT /todos/:id (update with validation) -- [ ] DELETE /todos/:id -- [ ] Tests for all endpoints - -Starting with GET /todos... -[implement] -[test - passes] -[commit: "feat(todos): add GET /todos endpoint"] -[update session log] - -Moving to POST /todos... -[implement] -[test - fails: validation not working] -[fix validation] -[test - passes] -[commit: "feat(todos): add POST /todos with validation"] -[update session log] - -...continue until all done... - -Final verification: -[npm test - all pass] -[npm run lint - clean] -[npm run build - succeeds] - -COMPLETE -``` - -### When to NOT Output Completion Phrase - -- Tests are failing (even one) -- Lint errors exist -- Build is broken -- You skipped a requirement -- You're unsure if something works -- **Minimum duration not reached** (for time-aware loops) - -Instead: Fix the issue, verify, then complete. For time-aware loops: generate more tasks and keep improving until minimum time elapsed. - -### RALPH_STATUS Block (Required During Ralph Loop) - -At the **END of every response** during a Ralph Loop, output this structured status block: +End EVERY response during a Ralph loop with exactly this block — Codeman parses it to track the loop: ``` ---RALPH_STATUS--- @@ -367,95 +88,10 @@ FILES_MODIFIED: TESTS_STATUS: PASSING | FAILING | NOT_RUN WORK_TYPE: IMPLEMENTATION | TESTING | DOCUMENTATION | REFACTORING EXIT_SIGNAL: false | true -RECOMMENDATION: +RECOMMENDATION: ---END_RALPH_STATUS--- ``` -**Rules:** -- Output this block at the end of **every** response, no exceptions -- Set `EXIT_SIGNAL` to `true` ONLY when ALL tasks are verifiably done -- Set `STATUS` to `BLOCKED` when you need human intervention -- Do NOT continue with busy work when `EXIT_SIGNAL` should be `true` -- Do NOT forget the status block — it is required for loop tracking - -### Testing Limits - -- **LIMIT testing to ~20% of total effort** per loop -- PRIORITIZE: Implementation > Documentation > Tests -- Only write tests for NEW functionality -- Do NOT refactor existing tests unless broken -- Do NOT run tests repeatedly without implementing new features - -### Exit Scenarios (When to Set EXIT_SIGNAL) - -| Scenario | STATUS | EXIT_SIGNAL | Action | -|----------|--------|-------------|--------| -| All tasks completed, tests pass | COMPLETE | true | Output completion phrase | -| No work remaining, specs done | COMPLETE | true | Output completion phrase | -| Making normal progress | IN_PROGRESS | false | Continue to next task | -| Test-only loop (no implementation) | IN_PROGRESS | false | Warn and shift to implementation | -| Stuck on same error repeatedly | BLOCKED | false | Describe blocker, request help | -| Needs human decision/intervention | BLOCKED | false | Describe what's needed | - -**Anti-patterns to avoid:** -- Setting `EXIT_SIGNAL: true` when tests are failing -- Continuing to work when all tasks are genuinely done (busy work) -- Running the same failing test repeatedly without changing approach -- Adding features not in the original specifications -- Refactoring working code instead of completing assigned tasks - ---- - -## Code Standards - -### Before Writing -- Read existing code in the area you're modifying -- Follow existing patterns and conventions -- Check for similar implementations to reference - -### During Implementation -- Keep changes focused and minimal -- Don't over-engineer -- Write tests for new functionality - -### After Implementation -- Run tests -- Update docs if needed -- Commit with descriptive message - ---- - -## Hooks Awareness - -This project may have hooks that auto-format code after writes or validate operations. If a tool call behaves unexpectedly, hooks are likely the cause. Continue working - they're intentional. - ---- - -## Session Log - -| Date | Tasks Completed | Files Changed | Notes | -|------|-----------------|---------------|-------| -| [DATE] | Project created | CLAUDE.md | Initial setup | - ---- - -## Current Task Queue - -### Active Ralph Loop -**Status**: Not Active -**Completion Phrase**: - - -### Pending Tasks -- [ ] - ---- - -## Implementation Plans - - - ---- - -## Notes & Decisions - - +- `EXIT_SIGNAL: true` only when ALL tasks are verifiably done — then also output the completion phrase. +- `STATUS: BLOCKED` when you need human input; describe the blocker in RECOMMENDATION. +- Never set `EXIT_SIGNAL: true` while tests are failing. diff --git a/src/templates/claude-md.ts b/src/templates/claude-md.ts index dca10f83..3cbd26f8 100644 --- a/src/templates/claude-md.ts +++ b/src/templates/claude-md.ts @@ -15,18 +15,17 @@ import { fileURLToPath } from 'node:url'; const __dirname = dirname(fileURLToPath(import.meta.url)); const BUNDLED_TEMPLATE_PATH = join(__dirname, 'case-template.md'); -const MINIMAL_FALLBACK = `# CLAUDE.md - Project Configuration +const MINIMAL_FALLBACK = `# CLAUDE.md + + + +This file guides Claude Code when working in this repository. + +## Project -## Project Overview - **Project Name**: [PROJECT_NAME] - **Description**: [PROJECT_DESCRIPTION] -- **Last Updated**: [DATE] - -## Session Log - -| Date | Tasks Completed | Files Changed | Notes | -|------|-----------------|---------------|-------| -| [DATE] | Project created | CLAUDE.md | Initial setup | `; /** diff --git a/test/templates.test.ts b/test/templates.test.ts index 137ef695..2b8cd3ad 100644 --- a/test/templates.test.ts +++ b/test/templates.test.ts @@ -51,7 +51,7 @@ describe('generateClaudeMd', () => { const today = new Date().toISOString().split('T')[0]; const result = generateClaudeMd('my-project'); - expect(result).toContain(`**Last Updated**: ${today}`); + expect(result).toContain(`Generated by Codeman on ${today}`); }); it('should include Codeman environment section', () => { @@ -61,55 +61,61 @@ describe('generateClaudeMd', () => { expect(result).toContain('CODEMAN_MUX=1'); }); - it('should include work principles', () => { + it('should include workflow rules', () => { const result = generateClaudeMd('my-project'); - expect(result).toContain('## Work Principles'); - expect(result).toContain('### Autonomy'); - expect(result).toContain('### Git Discipline'); + expect(result).toContain('## Workflow'); + expect(result).toContain('conventional commits'); }); - it('should include TodoWrite guidance', () => { + it('should include Ralph Loop section with slash commands', () => { const result = generateClaudeMd('my-project'); - expect(result).toContain('### Task Tracking (TodoWrite)'); - expect(result).toContain('**ALWAYS use TodoWrite**'); - }); - - it('should include Ralph Wiggum Loop section', () => { - const result = generateClaudeMd('my-project'); - - expect(result).toContain('## Ralph Wiggum Loop'); + expect(result).toContain('## Ralph Loop'); expect(result).toContain('/ralph-loop:ralph-loop'); expect(result).toContain('/ralph-loop:cancel-ralph'); }); - it('should include planning mode section', () => { + it('should include the RALPH_STATUS contract parsed by ralph-status-parser', () => { const result = generateClaudeMd('my-project'); - expect(result).toContain('## Planning Mode'); - expect(result).toContain('Multi-file changes'); + expect(result).toContain('---RALPH_STATUS---'); + expect(result).toContain('---END_RALPH_STATUS---'); + expect(result).toContain('STATUS: IN_PROGRESS | COMPLETE | BLOCKED'); + expect(result).toContain('EXIT_SIGNAL: false | true'); + expect(result).toContain('completion phrase'); }); - it('should include session log table', () => { + it('should stay under the 200-line CLAUDE.md guidance', () => { const result = generateClaudeMd('my-project'); - expect(result).toContain('## Session Log'); - expect(result).toContain('| Date | Tasks Completed | Files Changed | Notes |'); + expect(result.split('\n').length).toBeLessThan(200); + }); + + it('should not include legacy bloat sections', () => { + const result = generateClaudeMd('my-project'); + + expect(result).not.toContain('## Session Log'); + expect(result).not.toContain('TodoWrite'); + expect(result).not.toContain('## Planning Mode'); + expect(result).not.toContain('[TECHNOLOGIES_USED]'); }); }); describe('custom template', () => { it('should use custom template when provided and exists', () => { const templatePath = join(testDir, 'custom-template.md'); - writeFileSync(templatePath, ` + writeFileSync( + templatePath, + ` # [PROJECT_NAME] Description: [PROJECT_DESCRIPTION] Date: [DATE] Custom content here. - `); + ` + ); const result = generateClaudeMd('my-project', 'Test desc', templatePath); @@ -120,11 +126,14 @@ Custom content here. it('should replace all placeholder occurrences', () => { const templatePath = join(testDir, 'multi-placeholder.md'); - writeFileSync(templatePath, ` + writeFileSync( + templatePath, + ` [PROJECT_NAME] is a project. The name is [PROJECT_NAME]. About [PROJECT_NAME]: [PROJECT_DESCRIPTION] - `); + ` + ); const result = generateClaudeMd('awesome-app', 'Cool stuff', templatePath);