warp-os 1.1.2 → 1.2.1

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 (45) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/README.md +6 -4
  3. package/VERSION +1 -1
  4. package/agents/warp-annotate.md +394 -0
  5. package/agents/warp-browse.md +9 -1
  6. package/agents/warp-build-code.md +9 -1
  7. package/agents/warp-orchestrator.md +10 -1
  8. package/agents/warp-plan-architect.md +120 -1
  9. package/agents/warp-plan-brainstorm.md +93 -2
  10. package/agents/warp-plan-design.md +97 -4
  11. package/agents/warp-plan-onboarding.md +9 -1
  12. package/agents/warp-plan-optimize.md +9 -1
  13. package/agents/warp-plan-scope.md +67 -1
  14. package/agents/warp-plan-security.md +576 -35
  15. package/agents/warp-plan-testdesign.md +9 -1
  16. package/agents/warp-qa-debug.md +117 -1
  17. package/agents/warp-qa-test.md +167 -1
  18. package/agents/warp-release-update.md +290 -4
  19. package/agents/warp-setup.md +9 -1
  20. package/agents/warp-upgrade.md +21 -4
  21. package/bin/hooks/CLAUDE.md +24 -0
  22. package/bin/hooks/_warp_json.sh +4 -2
  23. package/bin/hooks/identity-briefing.sh +20 -13
  24. package/bin/hooks/validate-askuser.sh +41 -0
  25. package/bin/migrate-sessions.js +284 -173
  26. package/dist/warp-annotate/SKILL.md +404 -0
  27. package/dist/warp-browse/SKILL.md +9 -1
  28. package/dist/warp-build-code/SKILL.md +9 -1
  29. package/dist/warp-orchestrator/SKILL.md +10 -1
  30. package/dist/warp-plan-architect/SKILL.md +120 -1
  31. package/dist/warp-plan-brainstorm/SKILL.md +93 -2
  32. package/dist/warp-plan-design/SKILL.md +97 -4
  33. package/dist/warp-plan-onboarding/SKILL.md +9 -1
  34. package/dist/warp-plan-optimize/SKILL.md +9 -1
  35. package/dist/warp-plan-scope/SKILL.md +67 -1
  36. package/dist/warp-plan-security/SKILL.md +578 -35
  37. package/dist/warp-plan-testdesign/SKILL.md +9 -1
  38. package/dist/warp-qa-debug/SKILL.md +117 -1
  39. package/dist/warp-qa-test/SKILL.md +167 -1
  40. package/dist/warp-release-update/SKILL.md +290 -4
  41. package/dist/warp-setup/SKILL.md +9 -1
  42. package/dist/warp-upgrade/SKILL.md +21 -4
  43. package/package.json +2 -2
  44. package/shared/project-hooks.json +7 -0
  45. package/shared/tier1-engineering-constitution.md +9 -1
@@ -119,6 +119,8 @@ Shell commands use Unix syntax (Git Bash). Never use CMD (`dir`, `type`, `del`)
119
119
 
120
120
  ## AskUserQuestion
121
121
 
122
+ **Flow: analysis first, then decision tool.** Present your full reasoning, trade-offs, and recommendations as conversational text — the user wants to read your thinking. Then cap it with AskUserQuestion to formalize the decision. **If you're composing a message with multiple options or "which approach?" language, you MUST end it with AskUserQuestion.** Never present options in prose without the tool.
123
+
122
124
  **Contract:**
123
125
  1. **Re-ground:** Project name, branch, current task. (1-2 sentences.)
124
126
  2. **Simplify:** Plain English a smart 16-year-old could follow.
@@ -140,9 +142,15 @@ Shell commands use Unix syntax (Git Bash). Never use CMD (`dir`, `type`, `del`)
140
142
  Format: `"Option name — X/10 🟢"` (or 🟡 or 🔴). In the label, not the description.
141
143
  Rate: 🟢 9-10 complete, 🟡 6-8 adequate, 🔴 1-5 shortcuts.
142
144
 
145
+ **Pre-call checklist (verify before every AskUserQuestion invocation):**
146
+ - ☐ Completeness scores in every option label
147
+ - ☐ Recommended option listed first
148
+ - ☐ One decision per question (split if multiple)
149
+ - ☐ Analysis/reasoning already presented in message text above
150
+
143
151
  **Formatting:**
144
152
  - *Italics* for emphasis, not **bold** (bold for headers only).
145
- - After each answer: `✔ Decision {N} recorded [quicksave updated]`
153
+ - After each answer: `✔ Decision {N} recorded`
146
154
  - Previews under 8 lines. Full mockups go in conversation text before the question.
147
155
 
148
156
  ---
@@ -301,12 +309,29 @@ npx turbo run test 2>&1 | tail -30
301
309
  TEST SUITE STATUS:
302
310
  Total tests: [N]
303
311
  Passing: [N]
304
- Failing: [N] (MUST be 0 to proceed)
312
+ Failing: [N]
305
313
  Skipped: [N] (each must have documented reason in build-log)
306
314
  Runtime: [X]s
307
315
  ```
308
316
 
309
- **HARD GATE: If any test fails, stop. Do not ship with failing tests. Fix the test or the code, then re-run.**
317
+ If any tests fail, triage before blocking. Not all failures are equal failures you introduced are blockers, pre-existing failures are decisions.
318
+
319
+ ```bash
320
+ # Identify pre-existing failures by checking the test against the base branch
321
+ git stash && npx turbo run test 2>&1 | tail -30 # run tests on base state
322
+ git stash pop
323
+ ```
324
+
325
+ ```
326
+ TEST FAILURE TRIAGE:
327
+ In-branch failures (introduced by this diff): [N] — MUST fix before ship
328
+ Pre-existing failures (existed before this work): [N] — Handle each:
329
+ - Fix now, OR
330
+ - Add to TODOS.md with rationale, OR
331
+ - Document as known issue in PR body
332
+ ```
333
+
334
+ **HARD GATE: In-branch failures (failures introduced by your diff) MUST be fixed before shipping. Pre-existing failures must be handled — fix, defer to TODOS.md with rationale, or document as known issue in the PR body — but each must have an explicit decision, not silent acceptance.**
310
335
 
311
336
  ### 1C. Security Recency Check
312
337
 
@@ -346,6 +371,69 @@ QA READINESS:
346
371
 
347
372
  **HARD GATE: If QA readiness is NO-GO, stop. Return to /warp-qa-test or /warp-qa-debug. If CONDITIONAL, present the remaining issues to the user and get explicit approval to proceed.**
348
373
 
374
+ ### 1E. Verification Gate
375
+
376
+ If ANY code was changed after the initial test run in Phase 1B (e.g., fixing diff review findings, addressing review comments, last-minute polish), re-run the full test suite before proceeding to commit.
377
+
378
+ The Iron Law: "Should work now" is not evidence. Run it. "I'm confident the fix is correct" — confidence is not a test result.
379
+
380
+ ```
381
+ VERIFICATION GATE:
382
+ Code changed after initial test run: [yes | no]
383
+ If yes:
384
+ Files modified: [list]
385
+ Reason: [review fix | polish | bug fix | other]
386
+ Re-run result: [N] passing, [N] failing
387
+ Gate: [PASS — all green | FAIL — fix and re-run]
388
+ ```
389
+
390
+ This gate re-triggers whenever code changes. There is no limit to how many times it runs. The only exit is a clean test suite with zero changes after the last run.
391
+
392
+ ### 1F. Plan Completion Audit
393
+
394
+ Read scope.md acceptance criteria and compare against what was actually built. Every AC gets an explicit status.
395
+
396
+ ```bash
397
+ # Read scope acceptance criteria
398
+ cat .warp/reports/planning/scope.md 2>/dev/null | head -100
399
+ ```
400
+
401
+ ```
402
+ PLAN COMPLETION AUDIT:
403
+ Acceptance Criteria from scope.md:
404
+ 1. [AC description] — DONE (evidence: [test name, file, or behavior])
405
+ 2. [AC description] — NOT DONE (reason: [why] + user approved to ship without)
406
+ 3. [AC description] — PARTIAL (what's done, what's missing)
407
+ ...
408
+
409
+ Summary: [N] DONE / [N] NOT DONE / [N] PARTIAL out of [N] total
410
+ ```
411
+
412
+ **HARD GATE: User must explicitly approve shipping without any NOT DONE or PARTIAL items.** Present each incomplete AC and ask: "Ship without this? [Y/n]". If the user says no, return to build.
413
+
414
+ ### 1G. Distribution Pipeline Check
415
+
416
+ If the architecture introduces a new standalone artifact (CLI binary, npm package, library, Docker image), check whether a release/publish workflow exists.
417
+
418
+ ```bash
419
+ # Check for publish workflows
420
+ ls -la .github/workflows/*publish* .github/workflows/*release* 2>/dev/null
421
+ cat package.json 2>/dev/null | grep -E '"(name|publishConfig|bin|main|module|exports)"' || true
422
+ ls -la Dockerfile* docker-compose* 2>/dev/null
423
+ ```
424
+
425
+ ```
426
+ DISTRIBUTION CHECK:
427
+ Publishable artifacts detected: [list or "none"]
428
+ For each artifact:
429
+ Artifact: [name]
430
+ Registry: [npm | PyPI | crates.io | Docker Hub | etc.]
431
+ Publish workflow exists: [yes — path | no — FLAG]
432
+ Version in package file matches VERSION: [yes | no — FLAG]
433
+ ```
434
+
435
+ If a publishable artifact has no release workflow, flag it: "No publish workflow detected for {artifact}. Create one before shipping, or document why manual publish is acceptable."
436
+
349
437
  ---
350
438
 
351
439
  ## PHASE 2: Diff Review
@@ -468,6 +556,25 @@ DIFF REVIEW SUMMARY:
468
556
 
469
557
  ### 3A. Version Bump
470
558
 
559
+ Before bumping, run an idempotency check. This makes `/warp-release-update` safe to re-run after a partial failure (e.g., version was bumped but push failed, or PR was created but tests were re-run).
560
+
561
+ ```bash
562
+ # Check current version state
563
+ cat VERSION 2>/dev/null || echo "no VERSION file"
564
+ git log --oneline -1 -- VERSION
565
+ git rev-list --count @{u}..HEAD 2>/dev/null || echo "no upstream"
566
+ gh pr list --head "$(git branch --show-current)" --json number,url --jq '.[0]' 2>/dev/null || echo "no PR"
567
+ ```
568
+
569
+ ```
570
+ IDEMPOTENCY CHECK:
571
+ Version already bumped: [yes — skip bump | no — proceed]
572
+ Branch already pushed: [yes — skip push | no — proceed]
573
+ PR already exists: [yes — update body | no — create new]
574
+ ```
575
+
576
+ If version is already bumped (VERSION file shows the target version), skip the bump and proceed to changelog verification. If branch is already pushed, skip push in Phase 4C. If a PR already exists, update the PR body in Phase 5 instead of creating a new one (`gh pr edit` instead of `gh pr create`).
577
+
471
578
  Determine the appropriate version bump:
472
579
 
473
580
  ```
@@ -545,6 +652,27 @@ STAGING REVIEW:
545
652
 
546
653
  ### 4B. Commit
547
654
 
655
+ Analyze the diff and consider whether it should be split into logical, independently-valid commits. Each commit should pass tests on its own and be ordered by dependency:
656
+
657
+ ```
658
+ COMMIT SPLIT ANALYSIS:
659
+ Total files changed: [N]
660
+ Suggested split:
661
+ 1. [type]: [description] — [N] files (infrastructure / config)
662
+ 2. [type]: [description] — [N] files (models / data layer)
663
+ 3. [type]: [description] — [N] files (business logic / services)
664
+ 4. [type]: [description] — [N] files (UI / components)
665
+ 5. [type]: [description] — [N] files (tests)
666
+ 6. [type]: [description] — [N] files (docs / VERSION)
667
+
668
+ Recommended: [split into N commits | single commit is fine]
669
+ Rationale: [why — e.g., "all changes are tightly coupled" or "infra + feature + tests are independent concerns"]
670
+ ```
671
+
672
+ Dependency order for split commits: infrastructure → models → business logic → UI → tests → docs → VERSION. Each commit in the sequence should pass the test suite independently, making `git bisect` useful when tracking down regressions.
673
+
674
+ If the user prefers a single commit, that is fine — but always offer the split for non-trivial diffs (5+ files or 3+ logical concerns).
675
+
548
676
  Create a meaningful commit (or verify commits are already clean from the polish phase):
549
677
 
550
678
  ```bash
@@ -834,7 +962,31 @@ API DOCS UPDATE CHECK:
834
962
  ☐ Error codes updated
835
963
  ```
836
964
 
837
- ### 7E. Documentation Commit
965
+ ### 7E. TODOS.md Auto-Update
966
+
967
+ After shipping, scan the diff against TODOS.md to keep the backlog honest.
968
+
969
+ ```bash
970
+ # Read current TODOS
971
+ cat TODOS.md 2>/dev/null || echo "no TODOS.md"
972
+ ```
973
+
974
+ ```
975
+ TODOS.MD UPDATE:
976
+ Completed items detected from diff: [N]
977
+ - [item description] — completed by [commit/file evidence]
978
+ - [item description] — completed by [commit/file evidence]
979
+ Action: [check boxes | move to Completed section | leave as-is if none]
980
+
981
+ New TODO-worthy work created by this diff: [N]
982
+ - [description] — [why this is a TODO, not a bug]
983
+ - [description]
984
+ Action: [add to TODOS.md | skip if none]
985
+ ```
986
+
987
+ Mark completed items (check the box or move to a Completed section, matching the project's TODOS.md format). Add new items only if the diff genuinely creates deferred work — do not manufacture TODOs.
988
+
989
+ ### 7F. Documentation Commit
838
990
 
839
991
  If any documentation was updated:
840
992
 
@@ -1121,6 +1273,28 @@ git log --format="%cd" --date=short --since="7 days ago" | sort | uniq -c
1121
1273
 
1122
1274
  Collect: commit history, files changed, hotspots (most-modified files), test file changes, new/deleted files.
1123
1275
 
1276
+ **Work Session Detection:** Detect coding sessions using a 45-minute gap threshold between consecutive commits. Two commits within 45 minutes of each other belong to the same session. A gap larger than 45 minutes starts a new session.
1277
+
1278
+ ```bash
1279
+ # Get commit timestamps for session detection
1280
+ git log --format="%H %ai" --since="7 days ago" | sort -k2,3
1281
+ ```
1282
+
1283
+ Classify each session:
1284
+ - **Deep** (>2 hours): sustained focus work, likely feature development or complex debugging
1285
+ - **Medium** (30 min — 2 hours): standard work sessions
1286
+ - **Micro** (<30 min): quick fixes, one-off commits, config changes
1287
+
1288
+ ```
1289
+ WORK SESSIONS:
1290
+ Total sessions: [N]
1291
+ Deep (>2hr): [N] sessions, [N] total hours
1292
+ Medium (30min-2hr): [N] sessions, [N] total hours
1293
+ Micro (<30min): [N] sessions
1294
+ Total active hours: [N]
1295
+ LOC per active hour: [N] (lines added + removed / active hours)
1296
+ ```
1297
+
1124
1298
  ### R2. Work Pattern Analysis
1125
1299
 
1126
1300
  **Commit pacing:** Distributed across the week (healthy) vs. burst-and-crash (warning). Flag 3+ day gaps or all commits on 1-2 days.
@@ -1129,6 +1303,63 @@ Collect: commit history, files changed, hotspots (most-modified files), test fil
1129
1303
 
1130
1304
  **Scope adherence:** Compare work done to TODOS.md priorities. Note emergent work (normal), scope creep (worth naming), distraction (address).
1131
1305
 
1306
+ **Hourly Commit Histogram:** Produce an ASCII bar chart of commits by hour of day. Identify peak hours, dead zones, and bimodal patterns (e.g., morning burst + late night session).
1307
+
1308
+ ```bash
1309
+ # Commits by hour
1310
+ git log --format="%H %ai" --since="7 days ago" | awk '{split($3,t,":"); print t[1]}' | sort | uniq -c | sort -k2 -n
1311
+ ```
1312
+
1313
+ ```
1314
+ COMMIT HISTOGRAM (by hour):
1315
+ 00 |
1316
+ 01 |
1317
+ ...
1318
+ 09 | ████████ (8)
1319
+ 10 | ████████████ (12)
1320
+ 11 | ██████ (6)
1321
+ 12 | ██ (2)
1322
+ ...
1323
+ 21 | ██████████ (10)
1324
+ 22 | ████████████████ (16)
1325
+ 23 | ████ (4)
1326
+
1327
+ Peak hours: [list — e.g., 10:00, 22:00]
1328
+ Dead zones: [list — e.g., 00:00-08:00, 12:00-14:00]
1329
+ Pattern: [single peak | bimodal | distributed | nocturnal]
1330
+ ```
1331
+
1332
+ **Streak Tracking:** Count consecutive days with at least 1 commit. A streak is broken by a calendar day with zero commits.
1333
+
1334
+ ```bash
1335
+ # Commits per day (all time for streak, period for current)
1336
+ git log --format="%cd" --date=short | sort -u
1337
+ ```
1338
+
1339
+ ```
1340
+ STREAK:
1341
+ Current streak: [N] days (since [date])
1342
+ Longest streak: [N] days ([start date] — [end date])
1343
+ Days active this period: [N] / [N] total days
1344
+ Activity rate: [N]%
1345
+ ```
1346
+
1347
+ **TODOS/Backlog Health:** Read TODOS.md and assess backlog health for the retro period.
1348
+
1349
+ ```bash
1350
+ cat TODOS.md 2>/dev/null || echo "no TODOS.md"
1351
+ ```
1352
+
1353
+ ```
1354
+ BACKLOG HEALTH:
1355
+ Total open items: [N]
1356
+ P1 (critical/urgent) items: [N]
1357
+ Items added this period: [N]
1358
+ Items completed this period: [N]
1359
+ Net change: [+N | -N | 0] (positive = backlog growing)
1360
+ Health: [healthy (shrinking or stable) | warning (growing) | critical (P1 count > 3)]
1361
+ ```
1362
+
1132
1363
  ### R3. Code Quality Metrics
1133
1364
 
1134
1365
  ```bash
@@ -1168,6 +1399,61 @@ RETROSPECTIVE: {period}
1168
1399
  Actions: {3-5 assigned items}
1169
1400
  ```
1170
1401
 
1402
+ **JSON Snapshot Persistence:** Save retro metrics as JSON to `.warp/reports/releasing/retro-history.json` for trend comparison across retros. Append to the array — do not overwrite previous entries.
1403
+
1404
+ ```bash
1405
+ # Read existing history (or initialize)
1406
+ cat .warp/reports/releasing/retro-history.json 2>/dev/null || echo "[]"
1407
+ ```
1408
+
1409
+ Append a snapshot with this shape:
1410
+
1411
+ ```json
1412
+ {
1413
+ "date": "YYYY-MM-DD",
1414
+ "period": "YYYY-MM-DD to YYYY-MM-DD",
1415
+ "commits": N,
1416
+ "loc_added": N,
1417
+ "loc_removed": N,
1418
+ "files_changed": N,
1419
+ "test_count": N,
1420
+ "test_coverage_pct": N,
1421
+ "quality_score": N,
1422
+ "sessions": { "deep": N, "medium": N, "micro": N },
1423
+ "active_hours": N,
1424
+ "streak_current": N,
1425
+ "streak_longest": N,
1426
+ "backlog_open": N,
1427
+ "backlog_p1": N,
1428
+ "actions_completed": N,
1429
+ "actions_total": N
1430
+ }
1431
+ ```
1432
+
1433
+ **Compare Mode:** If prior retro data exists in `retro-history.json`, show period-over-period deltas for key metrics. Use arrows to indicate direction.
1434
+
1435
+ ```
1436
+ TREND COMPARISON (vs. previous retro):
1437
+ Commits: [N] [↑ +3 | ↓ -2 | → same]
1438
+ LOC (net): [N] [↑ | ↓ | →]
1439
+ Test count: [N] [↑ | ↓ | →]
1440
+ Coverage: [N]% [↑ | ↓ | →]
1441
+ Quality score: [N]/10 [↑ | ↓ | →]
1442
+ Active hours: [N] [↑ | ↓ | →]
1443
+ Streak: [N]d [↑ | ↓ | →]
1444
+ Backlog (open): [N] [↑ growing | ↓ shrinking | → stable]
1445
+
1446
+ Overall trajectory: [improving | stable | declining | mixed]
1447
+ ```
1448
+
1449
+ If no prior data exists, skip the comparison and note: "First retro — no prior data for comparison. Trends will appear after the next retro."
1450
+
1451
+ **Tweetable Summary:** Produce a single-line summary suitable for a status update, team standup, or personal log.
1452
+
1453
+ ```
1454
+ TWEETABLE: Week of {date}: {N} commits, {N} LOC, {N}% tests, {N} files | Streak: {N}d | Quality: {N}/10
1455
+ ```
1456
+
1171
1457
  ---
1172
1458
 
1173
1459
  ## PUSH GATE
@@ -119,6 +119,8 @@ Shell commands use Unix syntax (Git Bash). Never use CMD (`dir`, `type`, `del`)
119
119
 
120
120
  ## AskUserQuestion
121
121
 
122
+ **Flow: analysis first, then decision tool.** Present your full reasoning, trade-offs, and recommendations as conversational text — the user wants to read your thinking. Then cap it with AskUserQuestion to formalize the decision. **If you're composing a message with multiple options or "which approach?" language, you MUST end it with AskUserQuestion.** Never present options in prose without the tool.
123
+
122
124
  **Contract:**
123
125
  1. **Re-ground:** Project name, branch, current task. (1-2 sentences.)
124
126
  2. **Simplify:** Plain English a smart 16-year-old could follow.
@@ -140,9 +142,15 @@ Shell commands use Unix syntax (Git Bash). Never use CMD (`dir`, `type`, `del`)
140
142
  Format: `"Option name — X/10 🟢"` (or 🟡 or 🔴). In the label, not the description.
141
143
  Rate: 🟢 9-10 complete, 🟡 6-8 adequate, 🔴 1-5 shortcuts.
142
144
 
145
+ **Pre-call checklist (verify before every AskUserQuestion invocation):**
146
+ - ☐ Completeness scores in every option label
147
+ - ☐ Recommended option listed first
148
+ - ☐ One decision per question (split if multiple)
149
+ - ☐ Analysis/reasoning already presented in message text above
150
+
143
151
  **Formatting:**
144
152
  - *Italics* for emphasis, not **bold** (bold for headers only).
145
- - After each answer: `✔ Decision {N} recorded [quicksave updated]`
153
+ - After each answer: `✔ Decision {N} recorded`
146
154
  - Previews under 8 lines. Full mockups go in conversation text before the question.
147
155
 
148
156
  ---
@@ -119,6 +119,8 @@ Shell commands use Unix syntax (Git Bash). Never use CMD (`dir`, `type`, `del`)
119
119
 
120
120
  ## AskUserQuestion
121
121
 
122
+ **Flow: analysis first, then decision tool.** Present your full reasoning, trade-offs, and recommendations as conversational text — the user wants to read your thinking. Then cap it with AskUserQuestion to formalize the decision. **If you're composing a message with multiple options or "which approach?" language, you MUST end it with AskUserQuestion.** Never present options in prose without the tool.
123
+
122
124
  **Contract:**
123
125
  1. **Re-ground:** Project name, branch, current task. (1-2 sentences.)
124
126
  2. **Simplify:** Plain English a smart 16-year-old could follow.
@@ -140,9 +142,15 @@ Shell commands use Unix syntax (Git Bash). Never use CMD (`dir`, `type`, `del`)
140
142
  Format: `"Option name — X/10 🟢"` (or 🟡 or 🔴). In the label, not the description.
141
143
  Rate: 🟢 9-10 complete, 🟡 6-8 adequate, 🔴 1-5 shortcuts.
142
144
 
145
+ **Pre-call checklist (verify before every AskUserQuestion invocation):**
146
+ - ☐ Completeness scores in every option label
147
+ - ☐ Recommended option listed first
148
+ - ☐ One decision per question (split if multiple)
149
+ - ☐ Analysis/reasoning already presented in message text above
150
+
143
151
  **Formatting:**
144
152
  - *Italics* for emphasis, not **bold** (bold for headers only).
145
- - After each answer: `✔ Decision {N} recorded [quicksave updated]`
153
+ - After each answer: `✔ Decision {N} recorded`
146
154
  - Previews under 8 lines. Full mockups go in conversation text before the question.
147
155
 
148
156
  ---
@@ -311,11 +319,20 @@ WARP │ UPGRADE
311
319
  Hooks: patched ✓
312
320
  claude-mem: installed ✓
313
321
  Stale: {N items cleaned / none}
314
- Restart: required
322
+ Restart: {context-aware — see below}
315
323
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
316
324
  ```
317
325
 
318
- **Always remind:** "Restart Claude Code to pick up the new skills and hooks."
326
+ ### Restart guidance (context-aware)
327
+
328
+ Skills are discovered dynamically — new skills are available immediately after install, no restart needed. Hooks fire on session lifecycle events (SessionStart, Stop, PreToolUse) — if hook *scripts* changed in this upgrade, a restart picks up the new behavior.
329
+
330
+ Determine restart need:
331
+ - **Hooks changed** (new hooks added, existing hooks modified) → `Restart: recommended (hooks updated)`
332
+ - **Only skills/agents changed** → `Restart: not needed — new skills available now`
333
+ - **Already current** (same version) → `Restart: not needed`
334
+
335
+ When hooks changed, say: "Restart Claude Code to pick up updated hooks." When they didn't, say: "No restart needed — new skills are available now."
319
336
 
320
337
  ---
321
338
 
@@ -327,7 +344,7 @@ WARP │ UPGRADE
327
344
  - Check for and offer to clean stale artifacts
328
345
  - Verify claude-mem is installed
329
346
  - Show changelog summary
330
- - Remind user to restart Claude Code
347
+ - Give context-aware restart guidance (hooks changed → recommend restart; skills only → no restart needed)
331
348
 
332
349
  **MUST NOT:**
333
350
  - Use git clone/pull to upgrade (npm handles distribution now)
@@ -0,0 +1,24 @@
1
+ # Hooks
2
+
3
+ Warp hook scripts for Claude Code's hook system. Each script handles a specific lifecycle event.
4
+
5
+ ## Hook scripts
6
+
7
+ - **identity-foundation.sh** — SessionStart. Injects the Warp engineering foundation identity. Runs on all session sources.
8
+ - **identity-briefing.sh** — SessionStart. Injects pipeline state, branch, P1 priorities via `additionalContext` JSON. Dual-path artifact lookup: checks `.warp/reports/planning/` then `.warp/pipeline/`.
9
+ - **consistency-check.sh** — Stop. Validates CLAUDE.md and TODOS.md consistency on session end. Warns only (stdout), cannot block.
10
+ - **validate-askuser.sh** — PreToolUse on AskUserQuestion. L1 deterministic gate that blocks calls if option labels lack completeness scores (`X/10` + emoji). Exit 2 = block.
11
+
12
+ ## Shared utilities
13
+
14
+ - **_warp_json.sh** — JSON field extraction without jq. Source this in every hook. Provides `_warp_read_input`, `_warp_field`, `_warp_field_raw`, `_warp_escape_json`.
15
+ - **_warp_html.sh** — Markdown-to-HTML conversion with Warp styling. Used by orchestrator for artifact preview.
16
+
17
+ ## Conventions
18
+
19
+ - All scripts use `set -euo pipefail`. Every `grep` in a pipeline must have `|| true` to survive no-match (exit 1 + pipefail = crash).
20
+ - Source `_warp_json.sh` and call `_warp_read_input` before extracting fields.
21
+ - Exit codes: `0` = allow/success, `2` = block with message (PreToolUse only). Never exit 1 (treated as error, not block).
22
+ - SessionStart hooks output JSON: `{"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"..."}}`. Escape newlines via `_warp_escape_json`.
23
+ - Stop hooks can only warn via stdout. They cannot block session end.
24
+ - Keep hooks fast (< 100ms). No network calls, no heavy computation.
@@ -22,6 +22,7 @@ _warp_read_input() {
22
22
  # Extract a JSON string field: "key": "value" → value
23
23
  # Handles optional whitespace around the colon.
24
24
  # Returns empty string if field not found.
25
+ # Safe under set -eo pipefail (grep no-match → empty, not crash).
25
26
  _warp_field() {
26
27
  local key="$1"
27
28
  if [ -z "$_WARP_HOOK_INPUT" ]; then
@@ -31,11 +32,12 @@ _warp_field() {
31
32
  echo "$_WARP_HOOK_INPUT" | \
32
33
  grep -o "\"$key\"[[:space:]]*:[[:space:]]*\"[^\"]*\"" | \
33
34
  head -1 | \
34
- sed "s/\"$key\"[[:space:]]*:[[:space:]]*\"//;s/\"$//"
35
+ sed "s/\"$key\"[[:space:]]*:[[:space:]]*\"//;s/\"$//" || true
35
36
  }
36
37
 
37
38
  # Extract a non-string JSON field: "key": true → true, "key": 42 → 42
38
39
  # For booleans, numbers, null. Returns empty string if not found.
40
+ # Safe under set -eo pipefail (grep no-match → empty, not crash).
39
41
  _warp_field_raw() {
40
42
  local key="$1"
41
43
  if [ -z "$_WARP_HOOK_INPUT" ]; then
@@ -46,7 +48,7 @@ _warp_field_raw() {
46
48
  grep -o "\"$key\"[[:space:]]*:[[:space:]]*[^,}\"][^,}]*" | \
47
49
  head -1 | \
48
50
  sed "s/\"$key\"[[:space:]]*:[[:space:]]*//" | \
49
- tr -d '[:space:]'
51
+ tr -d '[:space:]' || true
50
52
  }
51
53
 
52
54
  # Escape a string for safe embedding inside a JSON string value.
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env bash
2
2
  # identity-briefing.sh — Inject pipeline state + priorities into Claude's context
3
- # Fires on SessionStart (all sources). Bounded to ~100-200 tokens.
3
+ # Fires on SessionStart (all sources including compact). Bounded to ~100-200 tokens.
4
4
  # Outputs partial briefing if some files are missing (graceful degradation).
5
+ # Must survive set -eo pipefail — every pipeline has || true or || echo fallback.
5
6
  set -euo pipefail
6
7
 
7
8
  SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
@@ -19,28 +20,28 @@ RULE="━━━━━━━━━━━━━━━━━━━━━━━━
19
20
 
20
21
  # Branch and git state
21
22
  BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
22
- UNCOMMITTED=$(git status --porcelain 2>/dev/null | wc -l | tr -d '[:space:]')
23
+ UNCOMMITTED=$(git status --porcelain 2>/dev/null | wc -l | tr -d '[:space:]' || echo "0")
23
24
  if [ "$UNCOMMITTED" = "0" ]; then
24
25
  GIT_STATE="clean"
25
26
  else
26
27
  GIT_STATE="${UNCOMMITTED} files"
27
28
  fi
28
29
 
29
- # Pipeline state
30
+ # Pipeline state — check new path (.warp/reports/planning/) then fall back to old (.warp/pipeline/)
30
31
  PIPELINE=""
31
32
  for artifact in brainstorm onboarding scope architecture design testspec security README; do
32
- f=".warp/pipeline/${artifact}.md"
33
- if [ -f "$f" ]; then
33
+ if [ -f ".warp/reports/planning/${artifact}.md" ] || [ -f ".warp/pipeline/${artifact}.md" ]; then
34
34
  PIPELINE="${PIPELINE} ✓${artifact}"
35
35
  else
36
36
  PIPELINE="${PIPELINE} ○${artifact}"
37
37
  fi
38
38
  done
39
39
 
40
- # Mode detection
41
- if [ -f ".warp/pipeline/README.md" ]; then
40
+ # Mode detection — check new path then old
41
+ if [ -f ".warp/reports/roadmap/README.md" ] || [ -f ".warp/pipeline/README.md" ]; then
42
42
  WARP_MODE="pipeline"
43
- elif [ -d ".warp/pipeline" ] && ls .warp/pipeline/*.md >/dev/null 2>&1; then
43
+ elif ([ -d ".warp/reports/planning" ] && ls .warp/reports/planning/*.md >/dev/null 2>&1) || \
44
+ ([ -d ".warp/pipeline" ] && ls .warp/pipeline/*.md >/dev/null 2>&1); then
44
45
  WARP_MODE="pipeline-partial"
45
46
  else
46
47
  WARP_MODE="no-pipeline"
@@ -53,11 +54,17 @@ if [ -n "$PIPELINE" ]; then
53
54
  BRIEFING="${BRIEFING}"$'\n'" Pipeline:${PIPELINE}"
54
55
  fi
55
56
 
56
- # Phase/cycle progress from roadmap
57
- if [ -f ".warp/pipeline/README.md" ]; then
58
- CHECKED=$(grep -c '^\- \[x\]' .warp/pipeline/README.md 2>/dev/null || echo "0")
59
- TOTAL=$(grep -c '^\- \[' .warp/pipeline/README.md 2>/dev/null || echo "0")
60
- NEXT=$(grep -m1 '^\- \[ \]' .warp/pipeline/README.md 2>/dev/null | sed 's/^- \[ \] //' | head -c 60 || true)
57
+ # Phase/cycle progress from roadmap — check new path then old
58
+ ROADMAP=""
59
+ if [ -f ".warp/reports/roadmap/README.md" ]; then
60
+ ROADMAP=".warp/reports/roadmap/README.md"
61
+ elif [ -f ".warp/pipeline/README.md" ]; then
62
+ ROADMAP=".warp/pipeline/README.md"
63
+ fi
64
+ if [ -n "$ROADMAP" ]; then
65
+ CHECKED=$(grep -c '^\- \[x\]' "$ROADMAP" 2>/dev/null || echo "0")
66
+ TOTAL=$(grep -c '^\- \[' "$ROADMAP" 2>/dev/null || echo "0")
67
+ NEXT=$(grep -m1 '^\- \[ \]' "$ROADMAP" 2>/dev/null | sed 's/^- \[ \] //' | head -c 60 || true)
61
68
  if [ "$TOTAL" != "0" ]; then
62
69
  BRIEFING="${BRIEFING}"$'\n'"Cycles: ${CHECKED}/${TOTAL} complete"
63
70
  if [ -n "$NEXT" ]; then
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env bash
2
+ # validate-askuser.sh — PreToolUse gate for AskUserQuestion
3
+ # Blocks the call if any option label is missing completeness scores.
4
+ # Pattern required: "X/10" followed by 🟢, 🟡, or 🔴 somewhere in the label.
5
+ #
6
+ # L1 enforcement — deterministic regex, zero AI judgment.
7
+ # Exit 0 = allow, exit 2 = block with message.
8
+ set -euo pipefail
9
+
10
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
11
+ source "$SCRIPT_DIR/_warp_json.sh"
12
+ _warp_read_input
13
+
14
+ # Extract all label values from the tool input.
15
+ # Labels appear as "label": "Option name — 8/10 🟡" in the JSON.
16
+ LABELS=$(echo "$_WARP_HOOK_INPUT" | grep -o '"label"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/"label"[[:space:]]*:[[:space:]]*"//;s/"$//' || true)
17
+
18
+ if [ -z "$LABELS" ]; then
19
+ # No labels found — might be malformed, let it through
20
+ exit 0
21
+ fi
22
+
23
+ # Check each label for the completeness pattern: digit(s)/10 + emoji
24
+ MISSING=""
25
+ while IFS= read -r label; do
26
+ # Match: one or more digits, /10, then anywhere in the label one of the three emojis
27
+ if ! echo "$label" | grep -qE '[0-9]+/10'; then
28
+ MISSING="${MISSING}\n - \"${label}\""
29
+ fi
30
+ done <<< "$LABELS"
31
+
32
+ if [ -n "$MISSING" ]; then
33
+ echo "BLOCKED: Completeness scores missing from option labels." >&2
34
+ echo "Every AskUserQuestion option label MUST include 'X/10' + 🟢🟡🔴." >&2
35
+ echo "Labels missing scores:${MISSING}" >&2
36
+ echo "" >&2
37
+ echo "Format: \"Option name — X/10 🟢\" (🟢 9-10, 🟡 6-8, 🔴 1-5)" >&2
38
+ exit 2
39
+ fi
40
+
41
+ exit 0