prizmkit 1.0.45 → 1.0.66

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 (67) hide show
  1. package/bundled/VERSION.json +3 -3
  2. package/bundled/adapters/claude/agent-adapter.js +2 -1
  3. package/bundled/adapters/claude/command-adapter.js +3 -3
  4. package/bundled/agents/prizm-dev-team-dev.md +1 -1
  5. package/bundled/dev-pipeline/README.md +6 -8
  6. package/bundled/dev-pipeline/assets/prizm-dev-team-integration.md +24 -19
  7. package/bundled/dev-pipeline/launch-bugfix-daemon.sh +2 -2
  8. package/bundled/dev-pipeline/launch-daemon.sh +2 -2
  9. package/bundled/dev-pipeline/lib/branch.sh +76 -0
  10. package/bundled/dev-pipeline/run-bugfix.sh +58 -149
  11. package/bundled/dev-pipeline/run.sh +60 -153
  12. package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +17 -4
  13. package/bundled/dev-pipeline/scripts/parse-stream-progress.py +2 -2
  14. package/bundled/dev-pipeline/templates/bootstrap-tier1.md +16 -27
  15. package/bundled/dev-pipeline/templates/bootstrap-tier2.md +20 -32
  16. package/bundled/dev-pipeline/templates/bootstrap-tier3.md +32 -53
  17. package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +29 -41
  18. package/bundled/dev-pipeline/templates/session-status-schema.json +1 -1
  19. package/bundled/dev-pipeline/tests/conftest.py +19 -126
  20. package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +207 -0
  21. package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +128 -141
  22. package/bundled/dev-pipeline/tests/test_utils.py +51 -110
  23. package/bundled/rules/prizm/prizm-commit-workflow.md +3 -3
  24. package/bundled/skills/_metadata.json +15 -16
  25. package/bundled/skills/app-planner/SKILL.md +8 -7
  26. package/bundled/skills/bug-fix-workflow/SKILL.md +171 -0
  27. package/bundled/skills/bug-planner/SKILL.md +25 -33
  28. package/bundled/skills/bug-planner/scripts/validate-bug-list.py +156 -0
  29. package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +5 -7
  30. package/bundled/skills/dev-pipeline-launcher/SKILL.md +4 -6
  31. package/bundled/skills/feature-workflow/SKILL.md +25 -42
  32. package/bundled/skills/prizm-kit/SKILL.md +61 -23
  33. package/bundled/skills/prizm-kit/assets/{claude-md-template.md → project-memory-template.md} +3 -3
  34. package/bundled/skills/prizmkit-analyze/SKILL.md +44 -33
  35. package/bundled/skills/prizmkit-clarify/SKILL.md +40 -30
  36. package/bundled/skills/prizmkit-code-review/SKILL.md +58 -45
  37. package/bundled/skills/prizmkit-committer/SKILL.md +30 -68
  38. package/bundled/skills/prizmkit-implement/SKILL.md +60 -28
  39. package/bundled/skills/prizmkit-init/SKILL.md +57 -66
  40. package/bundled/skills/prizmkit-plan/SKILL.md +60 -23
  41. package/bundled/skills/prizmkit-prizm-docs/SKILL.md +74 -19
  42. package/bundled/skills/prizmkit-prizm-docs/assets/PRIZM-SPEC.md +23 -23
  43. package/bundled/skills/prizmkit-retrospective/SKILL.md +142 -65
  44. package/bundled/skills/prizmkit-retrospective/assets/retrospective-template.md +13 -0
  45. package/bundled/skills/prizmkit-specify/SKILL.md +69 -15
  46. package/bundled/skills/refactor-workflow/SKILL.md +116 -52
  47. package/bundled/team/prizm-dev-team.json +2 -2
  48. package/package.json +1 -1
  49. package/src/scaffold.js +4 -4
  50. package/bundled/dev-pipeline/lib/worktree.sh +0 -164
  51. package/bundled/dev-pipeline/tests/__init__.py +0 -0
  52. package/bundled/dev-pipeline/tests/test_check_session.py +0 -131
  53. package/bundled/dev-pipeline/tests/test_cleanup_logs.py +0 -119
  54. package/bundled/dev-pipeline/tests/test_detect_stuck.py +0 -207
  55. package/bundled/dev-pipeline/tests/test_generate_prompt.py +0 -190
  56. package/bundled/dev-pipeline/tests/test_init_bugfix_pipeline.py +0 -153
  57. package/bundled/dev-pipeline/tests/test_init_pipeline.py +0 -241
  58. package/bundled/dev-pipeline/tests/test_update_bug_status.py +0 -142
  59. package/bundled/dev-pipeline/tests/test_update_feature_status.py +0 -338
  60. package/bundled/dev-pipeline/tests/test_worktree.py +0 -236
  61. package/bundled/dev-pipeline/tests/test_worktree_integration.py +0 -796
  62. package/bundled/skills/prizm-kit/assets/codebuddy-md-template.md +0 -35
  63. package/bundled/skills/prizm-kit/assets/hooks/prizm-commit-hook.json +0 -15
  64. package/bundled/skills/prizmkit-summarize/SKILL.md +0 -51
  65. package/bundled/skills/prizmkit-summarize/assets/registry-template.md +0 -18
  66. package/bundled/templates/hooks/commit-intent-claude.json +0 -26
  67. /package/bundled/templates/hooks/{commit-intent-codebuddy.json → commit-intent.json} +0 -0
@@ -1,5 +1,5 @@
1
1
  {
2
- "frameworkVersion": "1.0.45",
3
- "bundledAt": "2026-03-18T12:24:34.664Z",
4
- "bundledFrom": "6127c1a"
2
+ "frameworkVersion": "1.0.66",
3
+ "bundledAt": "2026-03-19T12:01:20.770Z",
4
+ "bundledFrom": "913a1b3"
5
5
  }
@@ -65,7 +65,8 @@ export function convertAgent(agentContent, options = {}) {
65
65
  'run `/$1` command'
66
66
  );
67
67
 
68
- // Replace prizmkit.xxx shorthand with /prizmkit-xxx
68
+ // Legacy fallback: replace any remaining prizmkit.xxx shorthand with /prizmkit-xxx
69
+ // Core files now use /prizmkit-xxx natively, but this catches any stragglers
69
70
  convertedBody = convertedBody.replace(
70
71
  /prizmkit\.(\w+)/g,
71
72
  (match, sub) => `/prizmkit-${sub.replace(/_/g, '-')}`
@@ -56,7 +56,6 @@ export function convertSkillToCommand(skillContent, skillName) {
56
56
  const { frontmatter, body } = parseFrontmatter(skillContent);
57
57
 
58
58
  // Claude Code command frontmatter only uses description
59
- // Also convert prizmkit.xxx references in the description field
60
59
  let desc = frontmatter.description || `PrizmKit ${skillName} command`;
61
60
  desc = desc.replace(/prizmkit\.(\w+)/g, (_m, sub) => `/${toClaudePrizmkitCommand(sub)}`);
62
61
 
@@ -74,13 +73,14 @@ export function convertSkillToCommand(skillContent, skillName) {
74
73
  `.claude/command-assets/${skillName}`
75
74
  );
76
75
 
77
- // Replace "invoke the X skill" or "prizmkit.X" patterns with /X slash command
76
+ // Replace "invoke the X skill" or "/prizmkit-X" patterns with /X slash command (legacy fallback)
78
77
  convertedBody = convertedBody.replace(
79
78
  /invoke\s+(?:the\s+)?[`"]?(\w[\w-]*)[`"]?\s+skill/gi,
80
79
  'run the `/$1` command'
81
80
  );
82
81
 
83
- // Replace prizmkit.xxx with /prizmkit-xxx for Claude Code
82
+ // Legacy fallback: replace any remaining prizmkit.xxx with /prizmkit-xxx for Claude Code
83
+ // Core files now use /prizmkit-xxx natively, but this catches any stragglers
84
84
  convertedBody = convertedBody.replace(
85
85
  /prizmkit\.(\w+)/g,
86
86
  (_match, sub) => {
@@ -47,7 +47,7 @@ skills: prizmkit-implement, prizmkit-prizm-docs
47
47
  - 不进行集成测试(Reviewer 的职责)
48
48
  - **不执行任何 git 操作**(git commit / git add / git reset / git push 均禁止 — 由 Orchestrator 通过 /prizmkit-committer 统一提交)
49
49
  - 不修改 `.prizmkit/specs/` 中除 `plan.md`(标记 Tasks section [x])以外的任何文件
50
- - 不为 bug 修复创建新的文档条目;bug 修复是现有功能的完善,应更新原始功能的文档而非在 REGISTRY.md 中创建新条目
50
+ - 不为 bug 修复创建新的文档条目;bug 修复是现有功能的完善,应更新原始功能的文档
51
51
  - 不使用 TaskCreate/TaskUpdate 创建或修改 Orchestrator 层的任务(Task 工具仅用于内部进度追踪,且任务 ID 在各 agent 子会话中互不共享)
52
52
 
53
53
  ### 行为规则
@@ -85,7 +85,7 @@ When a feature is stuck (e.g. retry count exceeded, bad artifacts), use `reset-f
85
85
 
86
86
  What gets cleaned with `--clean`:
87
87
  - `state/features/F-XXX/sessions/` — all session logs and prompts
88
- - `.prizmkit/specs/{feature-slug}/` — spec.md, plan.md, tasks.md, contracts/
88
+ - `.prizmkit/specs/{feature-slug}/` — spec.md, plan.md (with Tasks section), contracts/
89
89
 
90
90
  What is always reset (with or without `--clean`):
91
91
  - `status.json` — status → pending, retry_count → 0
@@ -221,7 +221,7 @@ run.sh main loop
221
221
  ├─ AI CLI session # cbc --print -y < prompt (CodeBuddy)
222
222
  │ │ # claude --print -p "$(cat prompt)" --yes (Claude Code)
223
223
  │ └─ prizm-dev-team # Multi-agent team implements the feature
224
- │ ├─ Orchestrator # Main agent: init, plan, schedule, summarize, commit
224
+ │ ├─ Orchestrator # Main agent: init, plan, schedule, retrospective, commit
225
225
  │ ├─ Dev x N # Implementation with TDD
226
226
  │ └─ Reviewer # Analyze + code review
227
227
 
@@ -247,7 +247,7 @@ Each AI CLI session drives the prizm-dev-team through these phases. **All phases
247
247
  | 5 | Implement | Dev x N | `prizmkit-implement` | Code + tests, plan.md Tasks marked `[x]` |
248
248
  | 6 | Review | Reviewer | `prizmkit-code-review` | Integration tests, review report |
249
249
  | 7 | Fix Loop | Dev | — | Max 3 rounds of fixes |
250
- | 8 | Summarize & Commit | Orchestrator | `prizmkit-summarize`, `prizmkit-committer`, `prizmkit-retrospective` | REGISTRY.md, git commit, .prizm-docs/ updated |
250
+ | 8 | Retrospective & Commit | Orchestrator | `prizmkit-retrospective`, `prizmkit-committer` | .prizm-docs/ synced + enriched, git commit |
251
251
 
252
252
  ### Feature Dependency Resolution
253
253
 
@@ -383,15 +383,13 @@ Each feature generates artifacts in a dedicated subdirectory under `.prizmkit/sp
383
383
  .prizmkit/
384
384
  ├── config.json # PrizmKit configuration
385
385
  └── specs/
386
- ├── REGISTRY.md # Feature registry (Phase 9 appends here)
387
386
  ├── 001-project-infrastructure-setup/
388
387
  │ ├── spec.md # Phase 1: Feature specification
389
388
  │ ├── checklists/
390
389
  │ │ └── requirements.md # Phase 1: Spec quality checklist
391
390
  │ ├── plan.md # Phase 2: Implementation plan
392
391
  │ ├── data-model.md # Phase 2: Data model (if applicable)
393
- ├── contracts/ # Phase 2: API contracts (if applicable)
394
- │ └── tasks.md # Phase 3: Task breakdown
392
+ └── contracts/ # Phase 2: API contracts (if applicable)
395
393
  ├── 002-core-encryption-vault/
396
394
  │ └── ...
397
395
  └── ...
@@ -438,7 +436,7 @@ The AI CLI session exited without producing a `session-status.json`. This typica
438
436
 
439
437
  ### .prizmkit/specs/ is empty after feature completion
440
438
 
441
- The session skipped the PrizmKit artifact generation phases (spec.md, plan.md, tasks.md). This can happen if:
439
+ The session skipped the PrizmKit artifact generation phases (spec.md, plan.md). This can happen if:
442
440
 
443
441
  1. **Agent definitions not found**: Check that agent definition files exist
444
442
  - CodeBuddy: `.codebuddy/agents/prizm-dev-team-*.md`
@@ -574,7 +572,7 @@ dev-pipeline/bugfix-state/ # Runtime state (gitignored)
574
572
  | Ordering | Dependencies DAG → priority | N/A (single refactor per session) | Severity → priority (no dependencies) |
575
573
  | Phases | 10-phase (specify → plan → tasks → implement → review) | 6-phase (analyze → plan → tasks → implement → review → commit) | 5-phase (triage → reproduce → fix → verify → commit) |
576
574
  | Agents | Orchestrator + Dev + Reviewer | Dev + Reviewer only | Dev + Reviewer only |
577
- | Artifacts | spec.md, plan.md, tasks.md, REGISTRY.md | refactor-analysis.md, plan.md, tasks.md | fix-plan.md, fix-report.md only |
575
+ | Artifacts | spec.md, plan.md (with Tasks section) | refactor-analysis.md, plan.md (with Tasks section) | fix-plan.md, fix-report.md only |
578
576
  | Commit prefix | `feat(<scope>):` | `refactor(<scope>):` | `fix(<scope>):` |
579
577
  | Scope Guard | N/A | ✅ (behavior change → STOP) | N/A |
580
578
  | Test Strategy | TDD per task | Full suite after EVERY task | Reproduction test |
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## Overview
4
4
 
5
- dev-pipeline drives the prizm-dev-team multi-agent team through an outer shell loop. Each iteration spawns a new CodeBuddy CLI session with a bootstrap prompt that instructs the agent to create and orchestrate the team for one feature.
5
+ dev-pipeline drives the prizm-dev-team multi-agent team through an outer shell loop. Each iteration spawns a new AI CLI session with a bootstrap prompt that instructs the agent to create and orchestrate the team for one feature.
6
6
 
7
7
  ## Architecture
8
8
 
@@ -16,11 +16,11 @@ dev-pipeline (outer loop)
16
16
  └── [per session] AI CLI
17
17
 
18
18
  ├── Phase 0: Init (Orchestrator)
19
- ├── Phase 1-2: Context snapshot + Plan & Tasks (Orchestrator)
20
- ├── Phase 3-4: Analyze (Reviewer agent)
21
- ├── Phase 5: Implement (Dev agent)
22
- ├── Phase 6: Review (Reviewer agent)
23
- └── Phase 7: Summarize & Commit (Orchestrator)
19
+ ├── Phase 1-2: Context snapshot + Specify + Plan (Orchestrator)
20
+ ├── Phase 3: Analyze (Reviewer agent) [tier2] / Phase 4: Analyze [tier3]
21
+ ├── Phase 4: Implement (Dev agent) [tier2] / Phase 5: Implement [tier3]
22
+ ├── Phase 4.5/6: Review (Reviewer agent)
23
+ └── Phase 5/7: Retrospective & Commit (Orchestrator)
24
24
 
25
25
  └── Write session-status.json → exit
26
26
  ```
@@ -34,17 +34,24 @@ dev-pipeline (outer loop)
34
34
 
35
35
  Note: The Orchestrator role is handled by the main agent (session orchestrator) directly — no separate agent definition needed.
36
36
 
37
- ## Validator Scripts
37
+ ## Pipeline Scripts
38
38
 
39
39
  Located at `dev-pipeline/scripts/`:
40
40
 
41
- | Script | Checkpoint | Purpose |
42
- |--------|-----------|---------|
43
- | `init-dev-team.py` | CP-0 | Initialize `.dev-team/` + `.prizmkit/` directories |
44
- | `validate-json-schema.py` | CP-1,2,3 | Validate JSON artifacts against schemas |
45
- | `validate-dag.py` | CP-3 | Verify dependency graph has no cycles |
46
- | `validate-report-format.py` | CP-6,7 | Check Markdown reports have required sections |
47
- | `check-contract-integrity.py` | CP-3,6,7 | SHA-256 hash verification for contracts |
41
+ | Script | Purpose |
42
+ |--------|---------|
43
+ | `init-dev-team.py` | Initialize `.dev-team/` + `.prizmkit/` directories |
44
+ | `init-pipeline.py` | Initialize pipeline state directories and config |
45
+ | `init-bugfix-pipeline.py` | Initialize bugfix pipeline state |
46
+ | `generate-bootstrap-prompt.py` | Render tier-specific bootstrap prompt with feature context |
47
+ | `generate-bugfix-prompt.py` | Render bugfix bootstrap prompt with bug context |
48
+ | `update-feature-status.py` | Update feature status in feature-list.json after session |
49
+ | `update-bug-status.py` | Update bug status in bug-fix-list.json after session |
50
+ | `check-session-status.py` | Read and validate session-status.json output |
51
+ | `detect-stuck.py` | Detect stuck/hung pipeline sessions via heartbeat |
52
+ | `parse-stream-progress.py` | Parse AI CLI output stream for progress tracking |
53
+ | `cleanup-logs.py` | Clean up old pipeline logs and state files |
54
+ | `utils.py` | Shared utility functions for pipeline scripts |
48
55
 
49
56
  ## Artifact Mapping
50
57
 
@@ -54,9 +61,8 @@ Located at `dev-pipeline/scripts/`:
54
61
  |-------|------|---------|
55
62
  | 1 | `specs/spec.md` | Feature specification (WHAT/WHY) |
56
63
  | 2 | `plans/plan.md` | Technical plan (architecture, API, tests) |
57
- | 3 | `tasks/tasks.md` | Executable task list with `[ ]` / `[x]` |
64
+ | 3 | `tasks/tasks.md` | Executable task list with `[ ]` / `[x]` (legacy — now part of plan.md Tasks section) |
58
65
  | 4 | `analysis/analyze-report.md` | Consistency analysis |
59
- | 9 | `specs/REGISTRY.md` | Completed features archive |
60
66
 
61
67
  ### Dev-Team Artifacts (.dev-team/)
62
68
 
@@ -78,7 +84,7 @@ Located at `dev-pipeline/scripts/`:
78
84
  The bootstrap prompt instructs the agent to:
79
85
  - Execute phases directly as the session orchestrator
80
86
  - Spawn Dev and Reviewer agents as subagents for implementation and review phases
81
- - The orchestrator handles context building, planning, summarize, and commit phases directly
87
+ - The orchestrator handles context building, planning, retrospective, and commit phases directly
82
88
 
83
89
  ### 2. Pipeline Execution
84
90
 
@@ -103,8 +109,7 @@ The agent MUST write `session-status.json` before exiting:
103
109
  "resume_from_phase": null,
104
110
  "artifacts": {
105
111
  "spec_path": ".prizmkit/specs/spec.md",
106
- "plan_path": ".prizmkit/plans/plan.md",
107
- "tasks_path": ".prizmkit/tasks/tasks.md"
112
+ "plan_path": ".prizmkit/plans/plan.md"
108
113
  },
109
114
  "timestamp": "2026-03-04T11:30:00Z"
110
115
  }
@@ -436,8 +436,8 @@ Environment Variables (pass via --env):
436
436
  SESSION_TIMEOUT Session timeout in seconds (default: 0 = no limit)
437
437
  VERBOSE Set to 1 for verbose AI CLI output
438
438
  HEARTBEAT_INTERVAL Heartbeat log interval in seconds (default: 30)
439
- USE_WORKTREE Enable git worktree isolation per session (default: 1, set 0 to disable)
440
- AUTO_PUSH Auto-push to remote after successful worktree merge (default: 0, set 1 to enable)
439
+ DEV_BRANCH Custom dev branch name (default: auto-generated)
440
+ AUTO_PUSH Auto-push to remote after successful bug fix (default: 0, set 1 to enable)
441
441
  HELP
442
442
  }
443
443
 
@@ -576,8 +576,8 @@ Environment Variables (pass via --env):
576
576
  SESSION_TIMEOUT Session timeout in seconds (default: 0 = no limit)
577
577
  VERBOSE Set to 1 for verbose AI CLI output
578
578
  HEARTBEAT_INTERVAL Heartbeat log interval in seconds (default: 30)
579
- USE_WORKTREE Enable git worktree isolation per session (default: 1, set 0 to disable)
580
- AUTO_PUSH Auto-push to remote after successful worktree merge (default: 0, set 1 to enable)
579
+ DEV_BRANCH Custom dev branch name (default: auto-generated)
580
+ AUTO_PUSH Auto-push to remote after successful feature (default: 0, set 1 to enable)
581
581
  HELP
582
582
  }
583
583
 
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env bash
2
+ # ============================================================
3
+ # dev-pipeline/lib/branch.sh - Git Branch Lifecycle Library
4
+ #
5
+ # Shared by run.sh and run-bugfix.sh for branch-based serial
6
+ # development. Each pipeline run creates a dev branch and all
7
+ # features/bugs commit directly on it in sequence.
8
+ #
9
+ # Functions:
10
+ # branch_create — Create and checkout a new branch
11
+ # branch_return — Checkout back to original branch
12
+ #
13
+ # Environment:
14
+ # DEV_BRANCH — Optional custom branch name override
15
+ # AUTO_PUSH — Set to 1 to auto-push after successful feature
16
+ # ============================================================
17
+
18
+ # branch_create <project_root> <branch_name> <source_branch>
19
+ #
20
+ # Creates a new branch from source_branch and checks it out.
21
+ # If the branch already exists, checks it out instead.
22
+ #
23
+ # Returns 0 on success, 1 on failure.
24
+ branch_create() {
25
+ local project_root="$1"
26
+ local branch_name="$2"
27
+ local source_branch="$3"
28
+
29
+ # Check if branch already exists
30
+ if git -C "$project_root" rev-parse --verify "$branch_name" >/dev/null 2>&1; then
31
+ log_info "Branch already exists: $branch_name — checking out"
32
+ if ! git -C "$project_root" checkout "$branch_name" 2>/dev/null; then
33
+ log_error "Failed to checkout existing branch: $branch_name"
34
+ return 1
35
+ fi
36
+ return 0
37
+ fi
38
+
39
+ # Create and checkout new branch
40
+ if ! git -C "$project_root" checkout -b "$branch_name" "$source_branch" 2>/dev/null; then
41
+ log_error "Failed to create branch: $branch_name from $source_branch"
42
+ return 1
43
+ fi
44
+
45
+ log_info "Created and checked out branch: $branch_name (from $source_branch)"
46
+ return 0
47
+ }
48
+
49
+ # branch_return <project_root> <original_branch>
50
+ #
51
+ # Checks out the original branch after pipeline completes.
52
+ # Safe to call even if already on the original branch.
53
+ #
54
+ # Returns 0 on success, 1 on failure.
55
+ branch_return() {
56
+ local project_root="$1"
57
+ local original_branch="$2"
58
+
59
+ local current_branch
60
+ current_branch=$(git -C "$project_root" rev-parse --abbrev-ref HEAD 2>/dev/null) || {
61
+ log_error "Failed to determine current branch"
62
+ return 1
63
+ }
64
+
65
+ if [[ "$current_branch" == "$original_branch" ]]; then
66
+ return 0
67
+ fi
68
+
69
+ if ! git -C "$project_root" checkout "$original_branch" 2>/dev/null; then
70
+ log_error "Failed to checkout original branch: $original_branch"
71
+ return 1
72
+ fi
73
+
74
+ log_info "Returned to branch: $original_branch"
75
+ return 0
76
+ }
@@ -25,8 +25,8 @@ set -euo pipefail
25
25
  # LOG_CLEANUP_ENABLED Run periodic log cleanup (default: 1)
26
26
  # LOG_RETENTION_DAYS Delete logs older than N days (default: 14)
27
27
  # LOG_MAX_TOTAL_MB Keep total logs under N MB via oldest-first cleanup (default: 1024)
28
- # USE_WORKTREE Enable git worktree isolation per session (default: 1). Set to 0 to disable.
29
- # AUTO_PUSH Auto-push to remote after successful worktree merge (default: 0). Set to 1 to enable.
28
+ # DEV_BRANCH Custom dev branch name (default: auto-generated bugfix/pipeline-{run_id})
29
+ # AUTO_PUSH Auto-push to remote after successful bug fix (default: 0). Set to 1 to enable.
30
30
  # ============================================================
31
31
 
32
32
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
@@ -42,7 +42,7 @@ LOG_CLEANUP_ENABLED=${LOG_CLEANUP_ENABLED:-1}
42
42
  LOG_RETENTION_DAYS=${LOG_RETENTION_DAYS:-14}
43
43
  LOG_MAX_TOTAL_MB=${LOG_MAX_TOTAL_MB:-1024}
44
44
  VERBOSE=${VERBOSE:-0}
45
- USE_WORKTREE=${USE_WORKTREE:-1}
45
+ DEV_BRANCH=${DEV_BRANCH:-""}
46
46
  AUTO_PUSH=${AUTO_PUSH:-0}
47
47
 
48
48
  # Source shared common helpers (CLI/platform detection + logs + deps)
@@ -52,8 +52,8 @@ prizm_detect_cli_and_platform
52
52
  # Source shared heartbeat library
53
53
  source "$SCRIPT_DIR/lib/heartbeat.sh"
54
54
 
55
- # Source shared worktree library
56
- source "$SCRIPT_DIR/lib/worktree.sh"
55
+ # Source shared branch library
56
+ source "$SCRIPT_DIR/lib/branch.sh"
57
57
 
58
58
  # Detect stream-json support
59
59
  detect_stream_json_support "$CLI_CMD"
@@ -61,9 +61,9 @@ detect_stream_json_support "$CLI_CMD"
61
61
  # Bug list path (set in main, used by cleanup trap)
62
62
  BUG_LIST=""
63
63
 
64
- # Active worktree tracking (for cleanup on interrupt)
65
- _ACTIVE_WORKTREE_PATH=""
66
- _ACTIVE_WORKTREE_BRANCH=""
64
+ # Branch tracking (for cleanup on interrupt)
65
+ _ORIGINAL_BRANCH=""
66
+ _DEV_BRANCH_NAME=""
67
67
 
68
68
  # ============================================================
69
69
  # Shared: Spawn AI CLI session and wait for result
@@ -76,7 +76,6 @@ spawn_and_wait_session() {
76
76
  local bootstrap_prompt="$4"
77
77
  local session_dir="$5"
78
78
  local max_retries="$6"
79
- local worktree_path="${7:-}"
80
79
 
81
80
  local session_log="$session_dir/logs/session.log"
82
81
  local progress_json="$session_dir/logs/progress.json"
@@ -100,14 +99,6 @@ spawn_and_wait_session() {
100
99
  # within an existing Claude Code session (e.g. via launch-bugfix-daemon.sh).
101
100
  unset CLAUDECODE 2>/dev/null || true
102
101
 
103
- # If worktree path is provided, cd into it for the AI CLI session
104
- local _saved_pwd=""
105
- if [[ -n "$worktree_path" && -d "$worktree_path" ]]; then
106
- _saved_pwd="$(pwd)"
107
- cd "$worktree_path"
108
- log_info "Running AI CLI in worktree: $worktree_path"
109
- fi
110
-
111
102
  case "$CLI_CMD" in
112
103
  *claude*)
113
104
  # Claude Code: prompt via -p, --dangerously-skip-permissions for auto-accept
@@ -133,11 +124,6 @@ spawn_and_wait_session() {
133
124
  esac
134
125
  local cli_pid=$!
135
126
 
136
- # Restore original directory if we changed it
137
- if [[ -n "$_saved_pwd" ]]; then
138
- cd "$_saved_pwd"
139
- fi
140
-
141
127
  # Start progress parser (no-op if stream-json not supported)
142
128
  start_progress_parser "$session_log" "$progress_json" "$SCRIPTS_DIR"
143
129
  local parser_pid="${_PARSER_PID:-}"
@@ -231,13 +217,10 @@ cleanup() {
231
217
  # Kill all child processes (claude-internal, heartbeat, progress parser, etc.)
232
218
  kill 0 2>/dev/null || true
233
219
 
234
- # Clean up active worktree if any
235
- if [[ -n "$_ACTIVE_WORKTREE_PATH" ]]; then
236
- local _project_root
237
- _project_root="$(cd "$SCRIPT_DIR/.." && pwd)"
238
- worktree_cleanup "$_project_root" "$_ACTIVE_WORKTREE_PATH" "$_ACTIVE_WORKTREE_BRANCH"
239
- _ACTIVE_WORKTREE_PATH=""
240
- _ACTIVE_WORKTREE_BRANCH=""
220
+ # Log current branch info for recovery
221
+ if [[ -n "$_DEV_BRANCH_NAME" ]]; then
222
+ log_info "Development was on branch: $_DEV_BRANCH_NAME"
223
+ log_info "Original branch was: $_ORIGINAL_BRANCH"
241
224
  fi
242
225
 
243
226
  if [[ -n "$BUG_LIST" && -f "$BUG_LIST" ]]; then
@@ -420,13 +403,9 @@ sys.exit(1)
420
403
  echo ""
421
404
  log_warn "Interrupted. Killing session..."
422
405
  kill 0 2>/dev/null || true
423
- # Clean up active worktree if any
424
- if [[ -n "$_ACTIVE_WORKTREE_PATH" ]]; then
425
- local _proj_root
426
- _proj_root="$(cd "$SCRIPT_DIR/.." && pwd)"
427
- worktree_cleanup "$_proj_root" "$_ACTIVE_WORKTREE_PATH" "$_ACTIVE_WORKTREE_BRANCH"
428
- _ACTIVE_WORKTREE_PATH=""
429
- _ACTIVE_WORKTREE_BRANCH=""
406
+ # Log current branch info
407
+ if [[ -n "$_DEV_BRANCH_NAME" ]]; then
408
+ log_info "Development was on branch: $_DEV_BRANCH_NAME"
430
409
  fi
431
410
  log_info "Session log: $session_dir/logs/session.log"
432
411
  exit 130
@@ -435,63 +414,31 @@ sys.exit(1)
435
414
 
436
415
  _SPAWN_RESULT=""
437
416
 
438
- # Worktree lifecycle: create worktree before session if enabled
439
- local _wt_path="" _wt_branch=""
440
- if [[ "$USE_WORKTREE" == "1" ]]; then
441
- local _proj_root
442
- _proj_root="$(cd "$SCRIPT_DIR/.." && pwd)"
443
- local _wt_base="$STATE_DIR/worktrees"
444
- local _source_branch
445
- _source_branch=$(git -C "$_proj_root" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")
446
-
447
- # Prune stale worktrees before creating new one
448
- worktree_prune_stale "$_proj_root"
449
-
450
- _WORKTREE_PATH=""
451
- _WORKTREE_BRANCH=""
452
- if worktree_create "$_proj_root" "$_wt_base" "$session_id" "$_source_branch"; then
453
- _wt_path="$_WORKTREE_PATH"
454
- _wt_branch="$_WORKTREE_BRANCH"
455
- _ACTIVE_WORKTREE_PATH="$_wt_path"
456
- _ACTIVE_WORKTREE_BRANCH="$_wt_branch"
457
- else
458
- log_warn "Failed to create worktree; running session in main working tree"
459
- fi
417
+ # Branch lifecycle: create and checkout bugfix branch
418
+ local _proj_root
419
+ _proj_root="$(cd "$SCRIPT_DIR/.." && pwd)"
420
+ local _source_branch
421
+ _source_branch=$(git -C "$_proj_root" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")
422
+ _ORIGINAL_BRANCH="$_source_branch"
423
+
424
+ local _branch_name="${DEV_BRANCH:-bugfix/${bug_id}-$(date +%s)}"
425
+ if branch_create "$_proj_root" "$_branch_name" "$_source_branch"; then
426
+ _DEV_BRANCH_NAME="$_branch_name"
427
+ else
428
+ log_warn "Failed to create branch; running session on current branch"
460
429
  fi
461
430
 
462
431
  spawn_and_wait_session \
463
432
  "$bug_id" "$bug_list" "$session_id" \
464
- "$bootstrap_prompt" "$session_dir" 999 "$_wt_path"
433
+ "$bootstrap_prompt" "$session_dir" 999
465
434
  local session_status="$_SPAWN_RESULT"
466
435
 
467
- # Worktree lifecycle: merge and cleanup after session
468
- if [[ -n "$_wt_path" && -n "$_wt_branch" ]]; then
436
+ # Auto-push after successful session
437
+ if [[ "$session_status" == "success" && "$AUTO_PUSH" == "1" ]]; then
469
438
  local _proj_root
470
439
  _proj_root="$(cd "$SCRIPT_DIR/.." && pwd)"
471
- local _target_branch
472
- _target_branch=$(git -C "$_proj_root" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")
473
-
474
- if [[ "$session_status" == "success" ]]; then
475
- _MERGE_RESULT=""
476
- worktree_merge "$_proj_root" "$_wt_branch" "$_target_branch" "$bug_id" "$session_id" || true
477
- if [[ "$_MERGE_RESULT" == "success" ]]; then
478
- if [[ "$AUTO_PUSH" == "1" ]]; then
479
- log_info "AUTO_PUSH enabled; pushing to remote..."
480
- git -C "$_proj_root" push 2>/dev/null || log_warn "Auto-push failed"
481
- fi
482
- worktree_cleanup "$_proj_root" "$_wt_path" "$_wt_branch"
483
- elif [[ "$_MERGE_RESULT" == "conflict" ]]; then
484
- session_status="merge_conflict"
485
- _SPAWN_RESULT="merge_conflict"
486
- log_warn "Worktree branch preserved for manual conflict resolution: $_wt_branch"
487
- else
488
- worktree_cleanup "$_proj_root" "$_wt_path" "$_wt_branch"
489
- fi
490
- else
491
- worktree_cleanup "$_proj_root" "$_wt_path" "$_wt_branch"
492
- fi
493
- _ACTIVE_WORKTREE_PATH=""
494
- _ACTIVE_WORKTREE_BRANCH=""
440
+ log_info "AUTO_PUSH enabled; pushing to remote..."
441
+ git -C "$_proj_root" push -u origin "$_DEV_BRANCH_NAME" 2>/dev/null || log_warn "Auto-push failed"
495
442
  fi
496
443
 
497
444
  echo ""
@@ -529,13 +476,6 @@ main() {
529
476
  check_dependencies
530
477
  run_log_cleanup
531
478
 
532
- # Prune stale worktree references at startup
533
- if [[ "$USE_WORKTREE" == "1" ]]; then
534
- local _prune_root
535
- _prune_root="$(cd "$SCRIPT_DIR/.." && pwd)"
536
- worktree_prune_stale "$_prune_root"
537
- fi
538
-
539
479
  # Initialize pipeline state if needed
540
480
  if [[ ! -f "$STATE_DIR/pipeline.json" ]]; then
541
481
  log_info "Initializing bugfix pipeline state..."
@@ -576,6 +516,23 @@ main() {
576
516
  echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
577
517
  echo ""
578
518
 
519
+ # Branch lifecycle: create bugfix branch for this pipeline run
520
+ local _proj_root
521
+ _proj_root="$(cd "$SCRIPT_DIR/.." && pwd)"
522
+ local _source_branch
523
+ _source_branch=$(git -C "$_proj_root" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")
524
+ _ORIGINAL_BRANCH="$_source_branch"
525
+
526
+ local run_id_for_branch
527
+ run_id_for_branch=$(jq -r '.run_id' "$STATE_DIR/pipeline.json" 2>/dev/null || echo "$$")
528
+ local _branch_name="${DEV_BRANCH:-bugfix/pipeline-${run_id_for_branch}}"
529
+ if branch_create "$_proj_root" "$_branch_name" "$_source_branch"; then
530
+ _DEV_BRANCH_NAME="$_branch_name"
531
+ log_info "Dev branch: $_branch_name"
532
+ else
533
+ log_warn "Failed to create bugfix branch; running on current branch: $_source_branch"
534
+ fi
535
+
579
536
  local session_count=0
580
537
 
581
538
  while true; do
@@ -592,6 +549,10 @@ main() {
592
549
  log_success "════════════════════════════════════════════════════"
593
550
  log_success " All bugs processed! Bug fix pipeline finished."
594
551
  log_success " Total sessions: $session_count"
552
+ if [[ -n "$_DEV_BRANCH_NAME" ]]; then
553
+ log_success " Dev branch: $_DEV_BRANCH_NAME"
554
+ log_success " Merge with: git checkout $_ORIGINAL_BRANCH && git merge $_DEV_BRANCH_NAME"
555
+ fi
595
556
  log_success "════════════════════════════════════════════════════"
596
557
  rm -f "$STATE_DIR/current-session.json"
597
558
  break
@@ -662,68 +623,16 @@ os.replace(tmp, target)
662
623
  log_info "Spawning AI CLI session: $session_id"
663
624
  _SPAWN_RESULT=""
664
625
 
665
- # Worktree lifecycle: create worktree before session if enabled
666
- local _wt_path="" _wt_branch=""
667
- if [[ "$USE_WORKTREE" == "1" ]]; then
668
- local _proj_root
669
- _proj_root="$(cd "$SCRIPT_DIR/.." && pwd)"
670
- local _wt_base="$STATE_DIR/worktrees"
671
- local _source_branch
672
- _source_branch=$(git -C "$_proj_root" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")
673
-
674
- _WORKTREE_PATH=""
675
- _WORKTREE_BRANCH=""
676
- if worktree_create "$_proj_root" "$_wt_base" "$session_id" "$_source_branch"; then
677
- _wt_path="$_WORKTREE_PATH"
678
- _wt_branch="$_WORKTREE_BRANCH"
679
- _ACTIVE_WORKTREE_PATH="$_wt_path"
680
- _ACTIVE_WORKTREE_BRANCH="$_wt_branch"
681
- else
682
- log_warn "Failed to create worktree; running session in main working tree"
683
- fi
684
- fi
685
-
686
626
  spawn_and_wait_session \
687
627
  "$bug_id" "$bug_list" "$session_id" \
688
- "$bootstrap_prompt" "$session_dir" "$MAX_RETRIES" "$_wt_path"
628
+ "$bootstrap_prompt" "$session_dir" "$MAX_RETRIES"
689
629
 
690
- # Worktree lifecycle: merge and cleanup after session
691
- if [[ -n "$_wt_path" && -n "$_wt_branch" ]]; then
630
+ # Auto-push after successful session
631
+ if [[ "$_SPAWN_RESULT" == "success" && "$AUTO_PUSH" == "1" ]]; then
692
632
  local _proj_root
693
633
  _proj_root="$(cd "$SCRIPT_DIR/.." && pwd)"
694
- local _target_branch
695
- _target_branch=$(git -C "$_proj_root" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")
696
- local _session_status="$_SPAWN_RESULT"
697
-
698
- if [[ "$_session_status" == "success" ]]; then
699
- _MERGE_RESULT=""
700
- worktree_merge "$_proj_root" "$_wt_branch" "$_target_branch" "$bug_id" "$session_id" || true
701
- if [[ "$_MERGE_RESULT" == "success" ]]; then
702
- if [[ "$AUTO_PUSH" == "1" ]]; then
703
- log_info "AUTO_PUSH enabled; pushing to remote..."
704
- git -C "$_proj_root" push 2>/dev/null || log_warn "Auto-push failed"
705
- fi
706
- worktree_cleanup "$_proj_root" "$_wt_path" "$_wt_branch"
707
- elif [[ "$_MERGE_RESULT" == "conflict" ]]; then
708
- _SPAWN_RESULT="merge_conflict"
709
- log_warn "Worktree branch preserved for manual conflict resolution: $_wt_branch"
710
- # Update bug status to merge_conflict
711
- python3 "$SCRIPTS_DIR/update-bug-status.py" \
712
- --bug-list "$bug_list" \
713
- --state-dir "$STATE_DIR" \
714
- --bug-id "$bug_id" \
715
- --session-status "merge_conflict" \
716
- --session-id "$session_id" \
717
- --max-retries "$MAX_RETRIES" \
718
- --action update >/dev/null 2>&1 || true
719
- else
720
- worktree_cleanup "$_proj_root" "$_wt_path" "$_wt_branch"
721
- fi
722
- else
723
- worktree_cleanup "$_proj_root" "$_wt_path" "$_wt_branch"
724
- fi
725
- _ACTIVE_WORKTREE_PATH=""
726
- _ACTIVE_WORKTREE_BRANCH=""
634
+ log_info "AUTO_PUSH enabled; pushing to remote..."
635
+ git -C "$_proj_root" push 2>/dev/null || log_warn "Auto-push failed"
727
636
  fi
728
637
 
729
638
  session_count=$((session_count + 1))