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
@@ -1,414 +1,178 @@
1
- # /tlc:ci - CI/CD Integration
2
-
3
- Generate CI/CD pipeline configuration for your TLC project.
4
-
5
- ## Usage
6
-
7
- ```
8
- /tlc:ci [provider]
9
- ```
10
-
11
- Providers: `github`, `gitlab`, `bitbucket`, `azure`, `circle`
12
-
13
- If no provider specified, auto-detects from git remote.
14
-
15
- ## What This Does
16
-
17
- 1. Detects your CI/CD platform from git remote
18
- 2. Generates appropriate config file
19
- 3. Includes test-first validation
20
- 4. Adds regression test gates
21
-
22
- ## GitHub Actions
23
-
24
- Creates `.github/workflows/tlc.yml`:
25
-
26
- ```yaml
27
- name: TLC Pipeline
28
-
29
- on:
30
- push:
31
- branches: [main, develop]
32
- pull_request:
33
- branches: [main]
34
-
35
- jobs:
36
- test:
37
- runs-on: ubuntu-latest
38
- steps:
39
- - uses: actions/checkout@v4
40
-
41
- - name: Setup Node.js
42
- uses: actions/setup-node@v4
43
- with:
44
- node-version: '20'
45
- cache: 'npm'
46
-
47
- - name: Install dependencies
48
- run: npm ci
49
-
50
- - name: Run tests
51
- run: npm test
52
-
53
- - name: Upload coverage
54
- uses: codecov/codecov-action@v4
55
- if: always()
56
-
57
- lint:
58
- runs-on: ubuntu-latest
59
- steps:
60
- - uses: actions/checkout@v4
61
- - uses: actions/setup-node@v4
62
- with:
63
- node-version: '20'
64
- cache: 'npm'
65
- - run: npm ci
66
- - run: npm run lint
67
-
68
- regression:
69
- runs-on: ubuntu-latest
70
- needs: [test]
71
- if: github.event_name == 'pull_request'
72
- steps:
73
- - uses: actions/checkout@v4
74
- with:
75
- fetch-depth: 0
76
-
77
- - uses: actions/setup-node@v4
78
- with:
79
- node-version: '20'
80
- cache: 'npm'
81
-
82
- - run: npm ci
83
-
84
- - name: Check for untested code
85
- run: |
86
- # Get changed files
87
- CHANGED=$(git diff --name-only origin/main...HEAD | grep -E '\.(ts|js|tsx|jsx)$' | grep -v '\.test\.' || true)
88
-
89
- if [ -n "$CHANGED" ]; then
90
- echo "Changed source files:"
91
- echo "$CHANGED"
92
-
93
- # Check each has corresponding test
94
- for file in $CHANGED; do
95
- testfile="${file%.*}.test.${file##*.}"
96
- if [ ! -f "$testfile" ]; then
97
- echo "::warning file=$file::No test file found for $file"
98
- fi
99
- done
100
- fi
101
-
102
- - name: Run regression tests
103
- run: npm test -- --coverage
104
-
105
- - name: Coverage diff
106
- run: |
107
- # Compare coverage with base branch
108
- echo "Coverage report generated"
109
- ```
110
-
111
- ## GitLab CI
112
-
113
- Creates `.gitlab-ci.yml`:
114
-
115
- ```yaml
116
- stages:
117
- - test
118
- - regression
119
-
120
- default:
121
- image: node:20
122
- cache:
123
- paths:
124
- - node_modules/
125
-
126
- test:
127
- stage: test
128
- script:
129
- - npm ci
130
- - npm test
131
- coverage: '/Lines\s*:\s*(\d+\.?\d*)%/'
132
- artifacts:
133
- reports:
134
- coverage_report:
135
- coverage_format: cobertura
136
- path: coverage/cobertura-coverage.xml
137
-
138
- lint:
139
- stage: test
140
- script:
141
- - npm ci
142
- - npm run lint
143
- allow_failure: true
144
-
145
- regression:
146
- stage: regression
147
- only:
148
- - merge_requests
149
- script:
150
- - npm ci
151
- - |
152
- CHANGED=$(git diff --name-only $CI_MERGE_REQUEST_DIFF_BASE_SHA...HEAD | grep -E '\.(ts|js)$' | grep -v '\.test\.' || true)
153
- if [ -n "$CHANGED" ]; then
154
- echo "Checking tests for changed files..."
155
- for file in $CHANGED; do
156
- testfile="${file%.*}.test.${file##*.}"
157
- if [ ! -f "$testfile" ]; then
158
- echo "WARNING: No test file for $file"
159
- fi
160
- done
161
- fi
162
- - npm test -- --coverage
163
- ```
164
-
165
- ## Bitbucket Pipelines
166
-
167
- Creates `bitbucket-pipelines.yml`:
168
-
169
- ```yaml
170
- image: node:20
171
-
172
- definitions:
173
- caches:
174
- npm: ~/.npm
175
-
176
- pipelines:
177
- default:
178
- - step:
179
- name: Test
180
- caches:
181
- - npm
182
- script:
183
- - npm ci
184
- - npm test
185
-
186
- pull-requests:
187
- '**':
188
- - step:
189
- name: Test
190
- caches:
191
- - npm
192
- script:
193
- - npm ci
194
- - npm test
195
- - step:
196
- name: Regression Check
197
- caches:
198
- - npm
199
- script:
200
- - npm ci
201
- - npm test -- --coverage
202
- ```
203
-
204
- ## Azure Pipelines
205
-
206
- Creates `azure-pipelines.yml`:
207
-
208
- ```yaml
209
- trigger:
210
- - main
211
- - develop
212
-
213
- pool:
214
- vmImage: 'ubuntu-latest'
215
-
216
- stages:
217
- - stage: Test
218
- jobs:
219
- - job: Test
220
- steps:
221
- - task: NodeTool@0
222
- inputs:
223
- versionSpec: '20.x'
224
-
225
- - script: npm ci
226
- displayName: Install dependencies
227
-
228
- - script: npm test
229
- displayName: Run tests
230
-
231
- - task: PublishCodeCoverageResults@2
232
- inputs:
233
- summaryFileLocation: '$(System.DefaultWorkingDirectory)/coverage/cobertura-coverage.xml'
234
-
235
- - stage: Regression
236
- condition: eq(variables['Build.Reason'], 'PullRequest')
237
- jobs:
238
- - job: Regression
239
- steps:
240
- - task: NodeTool@0
241
- inputs:
242
- versionSpec: '20.x'
243
- - script: npm ci
244
- - script: npm test -- --coverage
245
- displayName: Regression tests
246
- ```
247
-
248
- ## CircleCI
249
-
250
- Creates `.circleci/config.yml`:
251
-
252
- ```yaml
253
- version: 2.1
254
-
255
- executors:
256
- node:
257
- docker:
258
- - image: cimg/node:20.0
259
-
260
- jobs:
261
- test:
262
- executor: node
263
- steps:
264
- - checkout
265
- - restore_cache:
266
- keys:
267
- - npm-{{ checksum "package-lock.json" }}
268
- - run: npm ci
269
- - save_cache:
270
- paths:
271
- - node_modules
272
- key: npm-{{ checksum "package-lock.json" }}
273
- - run: npm test
274
- - store_test_results:
275
- path: test-results
276
- - store_artifacts:
277
- path: coverage
278
-
279
- regression:
280
- executor: node
281
- steps:
282
- - checkout
283
- - restore_cache:
284
- keys:
285
- - npm-{{ checksum "package-lock.json" }}
286
- - run: npm ci
287
- - run:
288
- name: Check for untested code
289
- command: |
290
- CHANGED=$(git diff --name-only origin/main...HEAD | grep -E '\.(ts|js)$' | grep -v '\.test\.' || true)
291
- if [ -n "$CHANGED" ]; then
292
- echo "Changed files: $CHANGED"
293
- fi
294
- - run: npm test -- --coverage
295
-
296
- workflows:
297
- test-and-deploy:
298
- jobs:
299
- - test
300
- - regression:
301
- filters:
302
- branches:
303
- ignore: main
304
- ```
305
-
306
- ## Regression Test Features
307
-
308
- ### Automatic Detection
309
-
310
- The CI config includes regression checks that:
311
-
312
- 1. **Identify changed files** in the PR/MR
313
- 2. **Verify test coverage** for changed files
314
- 3. **Run full test suite** to catch regressions
315
- 4. **Report coverage diff** vs base branch
316
-
317
- ### Configuring Regression Behavior
318
-
319
- In `.tlc.json`:
320
-
321
- ```json
322
- {
323
- "ci": {
324
- "requireTestsForNewFiles": true,
325
- "coverageThreshold": 80,
326
- "failOnCoverageDecrease": true,
327
- "regressionOnPR": true
328
- }
329
- }
330
- ```
331
-
332
- ### Coverage Requirements
333
-
334
- Set minimum coverage in `package.json`:
335
-
336
- ```json
337
- {
338
- "jest": {
339
- "coverageThreshold": {
340
- "global": {
341
- "branches": 80,
342
- "functions": 80,
343
- "lines": 80,
344
- "statements": 80
345
- }
346
- }
347
- }
348
- }
349
- ```
350
-
351
- Or for mocha with nyc:
352
-
353
- ```json
354
- {
355
- "nyc": {
356
- "check-coverage": true,
357
- "lines": 80,
358
- "functions": 80,
359
- "branches": 80
360
- }
361
- }
362
- ```
363
-
364
- ## Import/Merge Regression
365
-
366
- When importing external code (`/tlc:import-project`), automatically run regression:
367
-
368
- ```
369
- > /tlc:import-project ../legacy-api
370
-
371
- Importing legacy-api...
372
-
373
- Found 47 source files without tests.
374
-
375
- Running regression tests on merge...
376
- ✓ 23 existing tests pass
377
- ⚠ 12 new files need tests
378
-
379
- Create tasks for missing tests? (Y/n)
380
- ```
381
-
382
- ## Example Session
383
-
384
- ```
385
- > /tlc:ci
386
-
387
- Detecting CI/CD platform...
388
- Remote: git@github.com:acme/myproject.git
389
- Platform: GitHub
390
-
391
- Generating .github/workflows/tlc.yml...
392
-
393
- Created CI pipeline with:
394
- ✓ Test job (runs on all pushes)
395
- ✓ Lint job (runs on all pushes)
396
- ✓ Regression job (runs on PRs)
397
- ✓ Coverage reporting (Codecov)
398
-
399
- Commit this file? (Y/n) y
400
-
401
- Committed: ci: add TLC GitHub Actions pipeline
402
-
403
- Next steps:
404
- 1. Push to GitHub
405
- 2. Add CODECOV_TOKEN secret (optional)
406
- 3. PRs will now require passing tests
407
- ```
408
-
409
- ## Notes
410
-
411
- - CI config respects `.tlc.json` settings
412
- - Coverage thresholds match project config
413
- - Regression checks are PR-only by default
414
- - Use `/tlc:ci --dry-run` to preview without creating files
1
+ # /tlc:ci - CI/CD Integration
2
+
3
+ Detect existing CI first, report what is already configured, then offer to scaffold only the missing pieces.
4
+
5
+ ## Usage
6
+
7
+ ```text
8
+ /tlc:ci [provider]
9
+ /tlc:ci [provider] --dry-run
10
+ ```
11
+
12
+ Providers: `github`, `gitlab`, `bitbucket`, `azure`, `circle`
13
+
14
+ - Keep the provider argument optional.
15
+ - If no provider is passed, prefer the detected CI platform.
16
+ - `--dry-run` previews findings and proposed scaffolding without writing files.
17
+
18
+ ## Detection-First Flow
19
+
20
+ 1. Detect existing CI with `server/lib/scaffolding/ci-detector.js`.
21
+ 2. Show what already exists.
22
+ 3. Show the gaps that were found.
23
+ 4. Offer to scaffold only the missing pieces with `server/lib/scaffolding/ci-scaffolder.js`.
24
+ 5. If `--dry-run` is set, stop after the preview and do not write anything.
25
+
26
+ ## Detection Step
27
+
28
+ Run the detector before asking about providers or generating files.
29
+
30
+ Use `server/lib/scaffolding/ci-detector.js` to inspect the project and return:
31
+
32
+ - `platform`: detected CI platform, or `none`
33
+ - `workflows`: existing workflow/config files with coverage of test, deploy, and coverage behavior
34
+ - `gaps`: missing capabilities such as `no-ci`, `missing-test-step`, `missing-deploy-step`, and `missing-coverage-upload`
35
+
36
+ Supported detected platforms today:
37
+
38
+ - `github-actions`
39
+ - `gitlab`
40
+ - `jenkins`
41
+ - `circleci`
42
+ - `none`
43
+
44
+ ## Output Requirements
45
+
46
+ Always show detection results before offering scaffolding.
47
+
48
+ Detection output should include:
49
+
50
+ - detected platform
51
+ - each existing workflow/config file path
52
+ - whether each file already includes test, deploy, and coverage behavior
53
+ - the gap list
54
+
55
+ Example:
56
+
57
+ ```text
58
+ > /tlc:ci
59
+
60
+ Detecting existing CI...
61
+
62
+ Found:
63
+ Platform: github-actions
64
+ Workflows:
65
+ - .github/workflows/test.yml
66
+ test: yes
67
+ deploy: no
68
+ coverage: yes
69
+ - .github/workflows/release.yml
70
+ test: no
71
+ deploy: yes
72
+ coverage: no
73
+
74
+ Gaps:
75
+ - missing-coverage-upload
76
+
77
+ Scaffold the missing pieces with GitHub Actions templates? (Y/n)
78
+ ```
79
+
80
+ If no CI exists:
81
+
82
+ ```text
83
+ > /tlc:ci
84
+
85
+ Detecting existing CI...
86
+
87
+ Found:
88
+ Platform: none
89
+ Workflows: none
90
+
91
+ Gaps:
92
+ - no-ci
93
+
94
+ Scaffold a new CI pipeline? (Y/n)
95
+ ```
96
+
97
+ ## Scaffolding Step
98
+
99
+ Only scaffold after detection results have been shown and the user accepts.
100
+
101
+ Use `server/lib/scaffolding/ci-scaffolder.js` to generate the missing pieces for the selected or detected provider.
102
+
103
+ Scaffolding rules:
104
+
105
+ - do not replace working CI configs unless the user explicitly approves it
106
+ - fill only the reported gaps when CI already exists
107
+ - create a full starter pipeline when `gaps` contains `no-ci`
108
+ - prefer the detected platform over a guessed provider
109
+ - if the user passes a provider explicitly, use that provider for the scaffold preview and confirmation prompt
110
+
111
+ ## Dry Run
112
+
113
+ `--dry-run` must run the same detection flow and the same scaffold planning logic, but without writing files.
114
+
115
+ Dry-run output should:
116
+
117
+ - show detected CI and gaps
118
+ - show which files would be created or updated
119
+ - show which missing capabilities would be added
120
+ - not write files
121
+ - not commit changes
122
+
123
+ Example:
124
+
125
+ ```text
126
+ > /tlc:ci github --dry-run
127
+
128
+ Detecting existing CI...
129
+
130
+ Found:
131
+ Platform: none
132
+ Workflows: none
133
+
134
+ Gaps:
135
+ - no-ci
136
+
137
+ Dry run:
138
+ Would create .github/workflows/tlc.yml
139
+ Would add:
140
+ - test job
141
+ - deploy job
142
+ - coverage upload
143
+
144
+ No files written.
145
+ ```
146
+
147
+ ## Provider Handling
148
+
149
+ - Keep `/tlc:ci [provider]` as the command shape.
150
+ - A provider argument overrides the scaffold target, but detection still runs first.
151
+ - If detection finds an existing platform and the provider differs, call that out before scaffolding.
152
+ - If no provider is passed, use the detected platform when one exists.
153
+ - If no provider is passed and detection returns `none`, prompt for a provider or infer from git remote if available.
154
+
155
+ ## Commit Behavior
156
+
157
+ If files were written and the user confirms, commit the result after scaffolding.
158
+
159
+ Suggested commit message:
160
+
161
+ ```text
162
+ ci: scaffold missing CI pieces
163
+ ```
164
+
165
+ If a brand-new pipeline was created, this is also acceptable:
166
+
167
+ ```text
168
+ ci: add TLC CI pipeline
169
+ ```
170
+
171
+ Do not commit on `--dry-run`.
172
+
173
+ ## Notes
174
+
175
+ - Detection is mandatory and happens before scaffolding.
176
+ - Gap reporting is mandatory even when CI already exists.
177
+ - Scaffolding is opt-in.
178
+ - `--dry-run` previews the exact changes without writing.
@@ -97,6 +97,40 @@ process.stdout.write(JSON.stringify(result));" 2>/dev/null
97
97
 
98
98
  **Override:** Pass `--model <name>` to route this specific run to a different model.
99
99
 
100
+ After `resolveRouting` returns, immediately write `.tlc/.coverage-routing-active` with the active provider name from `models[0]` before doing any other coverage work. Remove `.tlc/.coverage-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 coverage 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 coverage analysis instead of scanning the repo inline.
113
+ 2. Gather the project's test framework, source layout, and any existing coverage context before dispatching the analysis.
114
+ 3. Package a prompt that asks the routed provider to map source files to tests, identify critical untested paths, and produce a prioritized coverage report or backlog.
115
+ 4. Dispatch 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.
116
+ 5. Verify the routed result before accepting it:
117
+ - Confirm it reflects the actual repository structure and test conventions.
118
+ - Confirm critical-path classifications are justified by the code, not by generic labels alone.
119
+ - Reject shallow reports that do not distinguish between tested, untested, and high-risk areas.
120
+ 6. If the routed analysis is incomplete or weak, dispatch a narrower follow-up for the missing directories, modules, or backlog output.
121
+ 7. Handle failures explicitly:
122
+ - 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.
123
+ - If retry still fails, stop and report the exact failure to the user. Do not silently fall back to Claude inline execution.
124
+ - If the provider produces a poor backlog or inaccurate mapping, reject it and rerun with explicit repository evidence.
125
+ 8. When finished, display the routed coverage result, persist any captured memory, remove `.tlc/.coverage-routing-active`, and stop. Do **not** execute Inline Mode afterward.
126
+
127
+ ## INLINE MODE
128
+
129
+ Use this mode only when `models[0]` **IS** `claude`.
130
+
131
+ The existing coverage instructions below are the Inline Mode instructions and should be followed unchanged.
132
+
133
+
100
134
  ## When to Use
101
135
 
102
136
  - After `/tlc:init` to add tests to existing code
@@ -381,12 +381,25 @@ app.post('/api/deploy', requireRole(['admin', 'engineer']));
381
381
  app.get('/api/status', requireRole(['admin', 'engineer', 'qa', 'po']));
382
382
  ```
383
383
 
384
- ## Deployment
385
-
386
- ### Push to Deploy
387
-
388
- ```
389
- > /tlc:deploy push
384
+ ## Deployment
385
+
386
+ ### Migration Snapshot
387
+
388
+ Check for migration files in the current diff:
389
+ ```bash
390
+ MIGRATION_FILES=$(git diff --name-only main...HEAD | grep -E "prisma/migrations|drizzle/|migrations/.*\.(ts|js|sql)|alembic/versions" | grep -v "\.test\.")
391
+ ```
392
+
393
+ If `MIGRATION_FILES` is not empty:
394
+ 1. Detect DB connection from `.env` or config
395
+ 2. Take snapshot: run `server/lib/scaffolding/snapshot-manager.js takeSnapshot()`
396
+ 3. Report: `DB snapshot taken: .tlc/snapshots/{filename}. Run /tlc:restore to rollback if needed.`
397
+ 4. If snapshot fails (DB not running): warn but continue build
398
+
399
+ ### Push to Deploy
400
+
401
+ ```
402
+ > /tlc:deploy push
390
403
 
391
404
  Deploying branch: feat-auth
392
405