tlc-claude-code 2.5.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/.claude/commands/tlc/autofix.md +34 -1
  2. package/.claude/commands/tlc/build.md +89 -6
  3. package/.claude/commands/tlc/ci.md +178 -414
  4. package/.claude/commands/tlc/coverage.md +34 -0
  5. package/.claude/commands/tlc/deploy.md +19 -6
  6. package/.claude/commands/tlc/discuss.md +34 -0
  7. package/.claude/commands/tlc/docs.md +35 -1
  8. package/.claude/commands/tlc/e2e.md +300 -0
  9. package/.claude/commands/tlc/edge-cases.md +35 -1
  10. package/.claude/commands/tlc/init.md +38 -8
  11. package/.claude/commands/tlc/new-project.md +46 -4
  12. package/.claude/commands/tlc/plan.md +33 -0
  13. package/.claude/commands/tlc/quick.md +33 -0
  14. package/.claude/commands/tlc/release.md +85 -135
  15. package/.claude/commands/tlc/restore.md +14 -0
  16. package/.claude/commands/tlc/review.md +76 -1
  17. package/.claude/commands/tlc/tlc.md +134 -0
  18. package/.claude/commands/tlc/verify.md +64 -65
  19. package/.claude/commands/tlc/watchci.md +10 -0
  20. package/.claude/hooks/tlc-block-tools.sh +13 -0
  21. package/.claude/hooks/tlc-session-init.sh +9 -0
  22. package/CODING-STANDARDS.md +35 -10
  23. package/package.json +1 -1
  24. package/server/lib/block-tools-hook.js +23 -0
  25. package/server/lib/e2e/acceptance-parser.js +132 -0
  26. package/server/lib/e2e/acceptance-parser.test.js +110 -0
  27. package/server/lib/e2e/framework-detector.js +47 -0
  28. package/server/lib/e2e/framework-detector.test.js +94 -0
  29. package/server/lib/e2e/log-assertions.js +107 -0
  30. package/server/lib/e2e/log-assertions.test.js +68 -0
  31. package/server/lib/e2e/test-generator.js +159 -0
  32. package/server/lib/e2e/test-generator.test.js +121 -0
  33. package/server/lib/e2e/verify-runner.js +191 -0
  34. package/server/lib/e2e/verify-runner.test.js +167 -0
  35. package/server/lib/hooks/block-tools-hook.test.js +54 -0
  36. package/server/lib/orchestration/cli-dispatch.js +16 -1
  37. package/server/lib/orchestration/cli-dispatch.test.js +94 -8
  38. package/server/lib/orchestration/completion-checker.js +101 -0
  39. package/server/lib/orchestration/completion-checker.test.js +177 -0
  40. package/server/lib/orchestration/result-verifier.js +143 -0
  41. package/server/lib/orchestration/result-verifier.test.js +291 -0
  42. package/server/lib/orchestration/session-dispatcher.js +99 -0
  43. package/server/lib/orchestration/session-dispatcher.test.js +215 -0
  44. package/server/lib/orchestration/session-status.js +147 -0
  45. package/server/lib/orchestration/session-status.test.js +130 -0
  46. package/server/lib/release/agent-runner-updates.js +24 -0
  47. package/server/lib/release/agent-runner-updates.test.js +22 -0
  48. package/server/lib/release/changelog-generator.js +142 -0
  49. package/server/lib/release/changelog-generator.test.js +113 -0
  50. package/server/lib/release/ci-watcher.js +83 -0
  51. package/server/lib/release/ci-watcher.test.js +81 -0
  52. package/server/lib/release/health-checker.js +111 -0
  53. package/server/lib/release/health-checker.test.js +121 -0
  54. package/server/lib/release/release-pipeline.js +187 -0
  55. package/server/lib/release/release-pipeline.test.js +262 -0
  56. package/server/lib/release/version-bumper.js +183 -0
  57. package/server/lib/release/version-bumper.test.js +142 -0
  58. package/server/lib/routing-preamble.integration.test.js +12 -0
  59. package/server/lib/routing-preamble.js +13 -2
  60. package/server/lib/routing-preamble.test.js +49 -0
  61. package/server/lib/scaffolding/ci-detector.js +139 -0
  62. package/server/lib/scaffolding/ci-detector.test.js +198 -0
  63. package/server/lib/scaffolding/ci-scaffolder.js +347 -0
  64. package/server/lib/scaffolding/ci-scaffolder.test.js +157 -0
  65. package/server/lib/scaffolding/deploy-detector.js +135 -0
  66. package/server/lib/scaffolding/deploy-detector.test.js +106 -0
  67. package/server/lib/scaffolding/health-scaffold.js +374 -0
  68. package/server/lib/scaffolding/health-scaffold.test.js +99 -0
  69. package/server/lib/scaffolding/logger-scaffold.js +196 -0
  70. package/server/lib/scaffolding/logger-scaffold.test.js +146 -0
  71. package/server/lib/scaffolding/migration-detector.js +78 -0
  72. package/server/lib/scaffolding/migration-detector.test.js +127 -0
  73. package/server/lib/scaffolding/snapshot-manager.js +142 -0
  74. package/server/lib/scaffolding/snapshot-manager.test.js +225 -0
  75. package/server/lib/task-router-config.js +50 -20
  76. package/server/lib/task-router-config.test.js +29 -15
@@ -95,7 +95,40 @@ process.stdout.write(JSON.stringify(result));" 2>/dev/null
95
95
  - Execute inline (Claude) AND dispatch to CLI models simultaneously
96
96
  - Collect and merge results
97
97
 
98
- **Override:** Pass `--model <name>` to route this specific run to a different model.
98
+ **Override:** Pass `--model <name>` to route this specific run to a different model.
99
+
100
+ After `resolveRouting` returns, immediately write `.tlc/.autofix-routing-active` with the active provider name from `models[0]` before doing any other autofix work. Remove `.tlc/.autofix-routing-active` on completion, cancellation, or failure cleanup.
101
+
102
+ **Routing decision:**
103
+ - If routing says external provider (`models[0] !== 'claude'`), follow **ONLY ORCHESTRATOR MODE** below.
104
+ - If routing says Claude (`models[0] === 'claude'`), follow **INLINE MODE** below.
105
+
106
+ ## ORCHESTRATOR MODE
107
+
108
+ Use this mode only when `models[0]` is **NOT** `claude`.
109
+
110
+ Claude does not execute the autofix instructions inline in this path. Claude acts as the orchestrator for the routed provider run:
111
+
112
+ 1. Claude acts as the orchestrator for routed test-failure recovery rather than applying the autofix flow inline.
113
+ 2. Gather the failing test context, error output, project conventions, and relevant files before dispatching each fix attempt.
114
+ 3. Dispatch focused repair prompts through the provider CLI path, using `codex exec` for Codex-style providers or `gemini -p` for Gemini-style providers, preferably via the shared dispatch layer when available.
115
+ 4. Verify every routed fix before accepting it:
116
+ - Confirm the proposed change addresses the actual failure mode rather than masking symptoms.
117
+ - Confirm the relevant tests were re-run or that the provider clearly identified what still needs verification.
118
+ - Reject speculative or unverified fixes and dispatch a narrower retry using the latest failure data.
119
+ 5. Continue the dispatch, verify, and retry loop until the targeted failures are fixed or an explicit blocker is reported.
120
+ 6. Handle failures explicitly:
121
+ - If dispatch fails because of model mismatch, auth, or missing CLI, check `.tlc/.router-state.json` for the provider's actual available model and retry once with the corrected model.
122
+ - If retry still fails, stop and report the exact failure to the user. Do not silently fall back to Claude inline execution.
123
+ - If a routed fix worsens the state or returns partial edits, stop that branch and issue a corrective follow-up with the exact observed regression.
124
+ 7. When finished, display the routed autofix result, persist any captured memory, remove `.tlc/.autofix-routing-active`, and stop. Do **not** execute Inline Mode afterward.
125
+
126
+ ## INLINE MODE
127
+
128
+ Use this mode only when `models[0]` **IS** `claude`.
129
+
130
+ The existing autofix instructions below are the Inline Mode instructions and should be followed unchanged.
131
+
99
132
 
100
133
  ## What This Does
101
134
 
@@ -103,6 +103,41 @@ process.stdout.write(JSON.stringify(result));" 2>/dev/null
103
103
 
104
104
  **Override:** Pass `--model <name>` to route this specific run to a different model.
105
105
 
106
+ After `resolveRouting` returns, immediately write `.tlc/.build-routing-active` with the active provider name from `models[0]` before doing any other build work. Remove `.tlc/.build-routing-active` on completion, cancellation, or failure cleanup.
107
+
108
+ **Routing decision:**
109
+ - If routing says external provider (`models[0] !== 'claude'`), follow **ONLY Orchestrator Mode** below.
110
+ - If routing says Claude (`models[0] === 'claude'`), follow **Inline Mode** below.
111
+
112
+ ## ORCHESTRATOR MODE
113
+
114
+ Use this mode only when `models[0]` is **NOT** `claude`.
115
+
116
+ Claude does not execute the build instructions inline in this path. Claude acts as the orchestrator for the routed provider run:
117
+
118
+ 1. Read the full build plan and break the work into the smallest practical execution slices for Codex-style `exec` dispatches.
119
+ 2. For each slice, prepare the exact task context, success criteria, test target, and file scope before dispatch.
120
+ 3. Resolve orchestration modules with fallback: try `tlc-claude-code/server/lib/...` first, then `$PROJECT_DIR/server/lib/...`.
121
+ 4. Build the full prompt with `buildFullPrompt` from `orchestration/prompt-builder`.
122
+ 5. Dispatch through unified CLI routing with `dispatch` from `orchestration/cli-dispatch`.
123
+ 6. After each provider response, capture output for memory with `captureFromProvider` from `capture`.
124
+ 7. Verify every returned result:
125
+ - Confirm the requested change was actually made.
126
+ - Confirm tests relevant to that slice were run or explain why not.
127
+ - Reject incomplete, unverifiable, or off-plan output.
128
+ 8. Handle failures explicitly:
129
+ - If dispatch fails because of model mismatch, auth, or missing CLI, check `.tlc/.router-state.json` for the provider's actual available model and retry once with the corrected model.
130
+ - If retry still fails, stop and report the exact failure to the user. Do not silently fall back to Claude inline execution.
131
+ - If a dispatched task returns partial or broken work, issue a focused follow-up dispatch for the fix instead of continuing blindly.
132
+ 9. Continue dispatch/verify/fix until the routed provider work is complete and validated.
133
+ 10. When finished, display the provider output summary, persist captured memory, remove `.tlc/.build-routing-active`, and stop. Do **not** execute Inline Mode instructions afterward.
134
+
135
+ ## INLINE MODE
136
+
137
+ Use this mode only when `models[0]` **IS** `claude`.
138
+
139
+ The existing build instructions below are the Inline Mode instructions and should be followed unchanged.
140
+
106
141
  ## Engineering Standards
107
142
 
108
143
  **Code like a senior engineer with 15+ years experience.** Every line should reflect:
@@ -391,7 +426,7 @@ All agents use **opus**. No opus, no opus. Cost is not a concern — quality is.
391
426
  **Provider round-robin (worktree mode):**
392
427
  Tasks alternate between available providers. If Claude + Codex are both available, odd tasks go to Claude, even to Codex. Respects router state — never dispatches to unavailable providers.
393
428
 
394
- ### Step 1b: Execute Parallel Build
429
+ ### Step 1c: Execute Parallel Build
395
430
 
396
431
  **Worktree + Tmux mode** (multi-provider):
397
432
 
@@ -519,7 +554,7 @@ After merge-back:
519
554
  4. If clean, the integration branch is ready for a single PR to main
520
555
  5. Continue to Step 8 (verification)
521
556
 
522
- ### Step 1c: Sync and Claim (Multi-User, Sequential Only)
557
+ ### Step 1d: Sync and Claim (Multi-User, Sequential Only)
523
558
 
524
559
  **Note:** Skip this step if using Overdrive mode - agents handle claiming automatically.
525
560
 
@@ -551,6 +586,19 @@ Before starting work, coordinate with teammates:
551
586
 
552
587
  If no markers exist in PLAN.md, skip this step (single-user mode).
553
588
 
589
+ ### Step 1b: Migration Snapshot
590
+
591
+ Check for migration files in the current diff:
592
+ ```bash
593
+ MIGRATION_FILES=$(git diff --name-only main...HEAD | grep -E "prisma/migrations|drizzle/|migrations/.*\.(ts|js|sql)|alembic/versions" | grep -v "\.test\.")
594
+ ```
595
+
596
+ If `MIGRATION_FILES` is not empty:
597
+ 1. Detect DB connection from `.env` or config
598
+ 2. Take snapshot: run `server/lib/scaffolding/snapshot-manager.js takeSnapshot()`
599
+ 3. Report: `DB snapshot taken: .tlc/snapshots/{filename}. Run /tlc:restore to rollback if needed.`
600
+ 4. If snapshot fails (DB not running): warn but continue build
601
+
554
602
  ### Step 2: Detect Test Framework
555
603
 
556
604
  #### Check TLC Config First
@@ -705,7 +753,24 @@ def test_login_raises_for_invalid_password():
705
753
  login("user@test.com", "wrong")
706
754
  ```
707
755
 
708
- #### 4b. Run this test file
756
+ #### 4b. Generate E2E Tests
757
+
758
+ After writing the unit test file for the task, generate matching end-to-end coverage from the task's acceptance criteria in `PLAN.md`.
759
+
760
+ Process:
761
+ - Parse acceptance criteria for the current task from `PLAN.md` using `server/lib/e2e/acceptance-parser.js`
762
+ - Detect the existing E2E framework, or scaffold one if missing, using `server/lib/e2e/framework-detector.js`
763
+ - Generate E2E test files for the current task using `server/lib/e2e/test-generator.js`
764
+ - Place generated E2E coverage alongside the task's unit tests in the same red/green workflow
765
+
766
+ Requirements:
767
+ - E2E tests must map directly to acceptance criteria for the current task
768
+ - Generated files must follow the detected or scaffolded framework conventions
769
+ - If no E2E framework exists, scaffold it before generating tests
770
+ - E2E tests should be committed alongside the unit tests for that task
771
+ - Do NOT write implementation code while generating tests
772
+
773
+ #### 4c. Run this test file
709
774
 
710
775
  ```bash
711
776
  npm test -- tests/auth/login.test.ts # vitest
@@ -717,16 +782,18 @@ Verify:
717
782
  - ✅ Tests FAIL (not pass, not skip)
718
783
  - ❌ If import errors, add mocks/stubs and retry
719
784
 
720
- #### 4c. Commit this test file
785
+ #### 4d. Commit this test file
721
786
 
722
787
  ```bash
723
788
  git add tests/auth/login.test.ts
724
789
  git commit -m "test: add login tests (red) - phase {N}"
725
790
  ```
726
791
 
727
- #### 4d. Move to next task
792
+ If E2E files were generated for the task, stage and commit them in the same commit as the unit tests.
728
793
 
729
- Repeat 4a-4c for each task in the test plan.
794
+ #### 4e. Move to next task
795
+
796
+ Repeat 4a-4d for each task in the test plan.
730
797
 
731
798
  **Critical Rules:**
732
799
  - Tests must be **syntactically valid** and **runnable**
@@ -1051,6 +1118,14 @@ After user approval:
1051
1118
  # Push branch
1052
1119
  git push -u origin "$branchName"
1053
1120
 
1121
+ # Warn if the PR will have no automated CI checks
1122
+ node -e "const fs = require('fs');
1123
+ const { detectCI } = require('./server/lib/scaffolding/ci-detector.js');
1124
+ const result = detectCI({ projectDir: process.cwd(), fs });
1125
+ if (result.platform === 'none') {
1126
+ console.warn('No CI configured. PR will not have automated checks. Run /tlc:ci to set up.');
1127
+ }" 2>/dev/null
1128
+
1054
1129
  # Create PR with phase summary
1055
1130
  gh pr create \
1056
1131
  --base "$mainBranch" \
@@ -1068,6 +1143,14 @@ gh pr create \
1068
1143
  {test runner summary}"
1069
1144
  ```
1070
1145
 
1146
+ **Merge strategy:** When merging PRs, ALWAYS use `--merge` (not `--squash`):
1147
+ ```bash
1148
+ gh pr merge <number> --merge
1149
+ ```
1150
+ - `--merge` preserves commit history and shows the correct PR title
1151
+ - `--squash` only when the user explicitly asks for it (messy WIP branches)
1152
+ - Sync PRs (dev → test, test → main) MUST use `--merge` — never squash a sync
1153
+
1071
1154
  #### Step 11-gh: GitHub: Link PR to Project
1072
1155
 
1073
1156
  If GitHub sync is enabled, after the PR is created: