prizmkit 1.1.118 → 1.1.120

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 (70) hide show
  1. package/bin/create-prizmkit.js +1 -5
  2. package/bundled/VERSION.json +3 -3
  3. package/bundled/dev-pipeline/README.md +41 -38
  4. package/bundled/dev-pipeline/assets/skill-subagent-integration.md +76 -0
  5. package/bundled/dev-pipeline/prizmkit_runtime/config.py +2 -8
  6. package/bundled/dev-pipeline/prizmkit_runtime/gitops.py +2 -4
  7. package/bundled/dev-pipeline/prizmkit_runtime/interoperability.py +1 -1
  8. package/bundled/dev-pipeline/prizmkit_runtime/platform_detection.py +3 -3
  9. package/bundled/dev-pipeline/prizmkit_runtime/runner_bookkeeping.py +21 -11
  10. package/bundled/dev-pipeline/prizmkit_runtime/runners.py +45 -3
  11. package/bundled/dev-pipeline/prizmkit_runtime/sessions.py +28 -6
  12. package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +60 -102
  13. package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +1 -19
  14. package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +1 -19
  15. package/bundled/dev-pipeline/scripts/{init-dev-team.py → init-change-artifact.py} +6 -16
  16. package/bundled/dev-pipeline/scripts/parse-stream-progress.py +364 -76
  17. package/bundled/dev-pipeline/scripts/utils.py +1 -1
  18. package/bundled/dev-pipeline/templates/bootstrap-prompt.md +2 -2
  19. package/bundled/dev-pipeline/templates/bootstrap-tier3.md +7 -9
  20. package/bundled/dev-pipeline/templates/sections/bugfix-phase-review.md +2 -2
  21. package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +1 -1
  22. package/bundled/dev-pipeline/templates/sections/critical-paths-agent.md +0 -1
  23. package/bundled/dev-pipeline/templates/sections/critical-paths-full.md +0 -2
  24. package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +8 -1
  25. package/bundled/dev-pipeline/templates/sections/phase-implement-agent.md +6 -7
  26. package/bundled/dev-pipeline/templates/sections/phase-implement-full.md +6 -7
  27. package/bundled/dev-pipeline/templates/sections/phase-implement-lite.md +4 -2
  28. package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +2 -2
  29. package/bundled/dev-pipeline/templates/sections/phase-review-full.md +4 -2
  30. package/bundled/dev-pipeline/templates/sections/phase-specify-plan-full.md +20 -0
  31. package/bundled/dev-pipeline/templates/sections/refactor-phase-review.md +2 -2
  32. package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +204 -141
  33. package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +16 -10
  34. package/bundled/dev-pipeline/tests/test_generate_refactor_prompt.py +2 -13
  35. package/bundled/dev-pipeline/tests/test_python_runner_parity.py +13 -14
  36. package/bundled/dev-pipeline/tests/test_unified_cli.py +227 -7
  37. package/bundled/skills/_metadata.json +1 -1
  38. package/bundled/skills/app-planner/SKILL.md +2 -2
  39. package/bundled/skills/app-planner/references/architecture-decisions.md +1 -3
  40. package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +4 -2
  41. package/bundled/skills/bugfix-pipeline-launcher/references/configuration.md +40 -1
  42. package/bundled/skills/feature-pipeline-launcher/SKILL.md +4 -2
  43. package/bundled/skills/feature-pipeline-launcher/references/configuration.md +40 -1
  44. package/bundled/skills/prizmkit-code-review/SKILL.md +16 -14
  45. package/bundled/skills/prizmkit-code-review/references/reviewer-agent-prompt.md +9 -9
  46. package/bundled/skills/prizmkit-implement/SKILL.md +21 -1
  47. package/bundled/skills/prizmkit-implement/references/implementation-subagent-procedure.md +67 -0
  48. package/bundled/skills/refactor-pipeline-launcher/SKILL.md +4 -2
  49. package/bundled/skills/refactor-pipeline-launcher/references/configuration.md +40 -1
  50. package/package.json +1 -1
  51. package/src/clean.js +12 -8
  52. package/src/config.js +24 -42
  53. package/src/index.js +1 -10
  54. package/src/manifest.js +3 -9
  55. package/src/metadata.js +0 -26
  56. package/src/prompts.js +0 -13
  57. package/src/scaffold.js +76 -201
  58. package/src/upgrade.js +16 -33
  59. package/bundled/adapters/claude/agent-adapter.js +0 -96
  60. package/bundled/adapters/claude/team-adapter.js +0 -183
  61. package/bundled/adapters/codebuddy/agent-adapter.js +0 -42
  62. package/bundled/adapters/codebuddy/team-adapter.js +0 -46
  63. package/bundled/adapters/codex/agent-adapter.js +0 -38
  64. package/bundled/adapters/codex/team-adapter.js +0 -37
  65. package/bundled/agents/prizm-dev-team-dev.md +0 -123
  66. package/bundled/agents/prizm-dev-team-reviewer.md +0 -113
  67. package/bundled/dev-pipeline/assets/prizm-dev-team-integration.md +0 -65
  68. package/bundled/dev-pipeline/templates/bootstrap-tier1.md +0 -436
  69. package/bundled/dev-pipeline/templates/bootstrap-tier2.md +0 -510
  70. package/bundled/team/prizm-dev-team.json +0 -27
@@ -34,8 +34,6 @@ program
34
34
  .option('--platform <platform>', 'Target platform: codebuddy, claude, codex, or all')
35
35
  .option('--runtime <runtime>', 'Runtime assets: python or auto; unix/windows are accepted as legacy aliases for python')
36
36
  .option('--skills <suite>', 'Skill suite: core, minimal, or recommended:<type> (frontend/backend/fullstack/library)', 'core')
37
- .option('--team', 'Enable multi-agent team mode (default: true)')
38
- .option('--no-team', 'Disable multi-agent team mode')
39
37
  .option('--pipeline', 'Install dev-pipeline (default: true)')
40
38
  .option('--no-pipeline', 'Disable dev-pipeline')
41
39
  .option('--playwright-cli', 'Install playwright-cli browser tool (default: true)')
@@ -64,7 +62,7 @@ program
64
62
  .command('uninstall [directory]')
65
63
  .description('Remove PrizmKit files from an existing project')
66
64
  .option('--dry-run', 'Show what would be removed without deleting')
67
- .option('--global-team', 'Also remove ~/.codebuddy/teams/prizm-dev-team')
65
+ .option('--global-team', 'Also remove legacy global CodeBuddy team config')
68
66
  .action(async (directory = '.', options) => {
69
67
  try {
70
68
  await runClean(directory, options);
@@ -99,8 +97,6 @@ program
99
97
  .option('--ai-cli <command>', 'AI CLI executable command (e.g. cbc, claude, codex)')
100
98
  .option('--headless-prompt-arg <arg>', 'Prompt injection argv token for a custom AI CLI (e.g. -p or -i)')
101
99
  .option('--headless-extra-args <args>', 'Additional headless argv tokens for a custom AI CLI')
102
- .option('--team', 'Enable multi-agent team mode')
103
- .option('--no-team', 'Disable multi-agent team mode')
104
100
  .option('--pipeline', 'Enable dev-pipeline')
105
101
  .option('--no-pipeline', 'Disable dev-pipeline')
106
102
  .option('--non-interactive', 'Skip interactive prompts')
@@ -1,5 +1,5 @@
1
1
  {
2
- "frameworkVersion": "1.1.118",
3
- "bundledAt": "2026-07-09T14:31:05.918Z",
4
- "bundledFrom": "932cf65"
2
+ "frameworkVersion": "1.1.120",
3
+ "bundledAt": "2026-07-10T01:27:14.094Z",
4
+ "bundledFrom": "3d5e4ff"
5
5
  }
@@ -1,6 +1,6 @@
1
1
  # dev-pipeline
2
2
 
3
- Autonomous development pipeline that drives the `prizm-dev-team` multi-agent team through iterative AI CLI sessions, implementing a complete app feature-by-feature from a `.prizmkit/plans/feature-list.json` specification. Includes a parallel bug-fix pipeline for `.prizmkit/plans/bug-fix-list.json`.
3
+ Autonomous development pipeline that drives iterative AI CLI sessions through PrizmKit skills, implementing feature, bugfix, and refactor work from `.prizmkit/plans/*.json` specifications.
4
4
 
5
5
  ## Prerequisites
6
6
 
@@ -258,12 +258,12 @@ python3 scripts/init-bugfix-pipeline.py \
258
258
 
259
259
  ---
260
260
 
261
- ### `scripts/init-dev-team.py` — Initialize PrizmKit Directories
261
+ ### `scripts/init-change-artifact.py` — Initialize PrizmKit Directories
262
262
 
263
- Creates per-feature directory structure for PrizmKit agent artifacts.
263
+ Creates per-feature directory structure for PrizmKit change artifacts.
264
264
 
265
265
  ```bash
266
- python3 scripts/init-dev-team.py \
266
+ python3 scripts/init-change-artifact.py \
267
267
  --project-root <path> \
268
268
  [--feature-id <id>] \
269
269
  [--feature-slug <slug>]
@@ -275,7 +275,7 @@ python3 scripts/init-dev-team.py \
275
275
 
276
276
  ### `scripts/generate-bootstrap-prompt.py` — Generate Feature Session Prompt
277
277
 
278
- Renders a session-specific bootstrap prompt from a tier template and .prizmkit/plans/feature-list.json.
278
+ Renders a session-specific bootstrap prompt from modular `templates/sections/` content and `.prizmkit/plans/feature-list.json`.
279
279
 
280
280
  ```bash
281
281
  python3 scripts/generate-bootstrap-prompt.py \
@@ -291,13 +291,15 @@ python3 scripts/generate-bootstrap-prompt.py \
291
291
  [--mode lite|standard|full]
292
292
  ```
293
293
 
294
- **Template auto-selection by complexity:**
294
+ **Prompt assembly:**
295
295
 
296
- | `estimated_complexity` | Pipeline Mode | Template |
297
- |------------------------|--------------|----------|
298
- | `low` | lite | `bootstrap-tier1.md` (single agent) |
299
- | `medium` | standard | `bootstrap-tier2.md` (dual agent) |
300
- | `high` / `critical` | full | `bootstrap-tier3.md` (full team) |
296
+ | Condition | Prompt Source | Behavior |
297
+ |-----------|---------------|----------|
298
+ | `templates/sections/` exists and no `--template` | Modular sections | Uses the full/tier3-equivalent guidance for every `estimated_complexity` value |
299
+ | Custom `--template <path>` supplied | Caller template | Renders the explicit template with legacy placeholder/conditional support |
300
+ | Sections unavailable and no custom template | `bootstrap-tier3.md`, then `bootstrap-prompt.md` | Monolithic compatibility fallback; never defaults to retired reduced-tier templates |
301
+
302
+ `estimated_complexity` remains in feature metadata and rendered Session Context for planning summaries and compatibility, but it no longer chooses a reduced prompt template.
301
303
 
302
304
  **Output (JSON to stdout):**
303
305
 
@@ -307,10 +309,10 @@ python3 scripts/generate-bootstrap-prompt.py \
307
309
 
308
310
  The `model` field is extracted from the feature's `"model"` field in .prizmkit/plans/feature-list.json (empty string if not specified). Used by `cli.py feature` to set `--model` on the AI CLI.
309
311
 
310
- **Conditional blocks resolved:**
312
+ **Conditional blocks resolved for explicit legacy templates:**
311
313
  - `{{IF_RESUME}}` / `{{IF_FRESH_START}}` — Resume vs fresh start
312
314
  - `{{IF_INIT_NEEDED}}` / `{{IF_INIT_DONE}}` — PrizmKit init status
313
- - `{{IF_MODE_LITE}}` / `{{IF_MODE_STANDARD}}` / `{{IF_MODE_FULL}}` — Pipeline mode blocks
315
+ - `{{IF_MODE_LITE}}` / `{{IF_MODE_STANDARD}}` / `{{IF_MODE_FULL}}` — Compatibility mode blocks
314
316
 
315
317
  ---
316
318
 
@@ -686,17 +688,19 @@ cli.py feature run command
686
688
  +- loop -> next feature
687
689
  ```
688
690
 
689
- ### Tiered Execution (per feature session)
691
+ ### Unified Feature Prompt Execution
692
+
693
+ Feature bootstrap prompts use the same full/tier3-equivalent modular section composition for every feature task. Complexity metadata is still retained for planning, summaries, dependency/status compatibility, and rendered Session Context, but it no longer reduces prompt guidance.
690
694
 
691
- The bootstrap prompt adapts based on feature complexity:
695
+ | Feature metadata | Normal prompt source | Execution guidance |
696
+ |------------------|----------------------|--------------------|
697
+ | `estimated_complexity: low` | `templates/sections/` full composition | Main orchestrator builds context, plans, implements directly, runs review/test/browser/commit gates |
698
+ | `estimated_complexity: medium` | `templates/sections/` full composition | Same full guidance |
699
+ | `estimated_complexity: high` / `critical` | `templates/sections/` full composition | Same full guidance |
692
700
 
693
- | Tier | Template | Agents | Use Case |
694
- |------|----------|--------|----------|
695
- | Tier 1 (lite) | `bootstrap-tier1.md` | Single agent handles everything | Low complexity features |
696
- | Tier 2 (standard) | `bootstrap-tier2.md` | Orchestrator implements directly + Reviewer gate | Medium/high complexity |
697
- | Tier 3 (full) | `bootstrap-tier3.md` | Orchestrator implements directly + strongest planning, testing, and Reviewer gates | High/critical complexity |
701
+ Monolithic compatibility fallback uses `bootstrap-tier3.md` before `bootstrap-prompt.md` only when sections are unavailable and no custom `--template` was supplied.
698
702
 
699
- **Self-evolve mode:** Uses Tier 3 template with additional framework guardrails for developing the PrizmKit framework itself.
703
+ **Self-evolve mode:** Uses the same full feature prompt guidance with additional framework guardrails supplied by the feature context.
700
704
 
701
705
  ### Feature Dependency Resolution
702
706
 
@@ -718,7 +722,7 @@ Features are executed in dependency order via DAG:
718
722
  ### Heartbeat Output
719
723
 
720
724
  ```
721
- > [HEARTBEAT] 1m30s elapsed | log: 245KB (+12480B) | Creating team prizm-dev-team-F-001...
725
+ > [HEARTBEAT] 1m30s elapsed | log: 245KB (+12480B) | Creating feature change artifacts...
722
726
  > [HEARTBEAT] 2m0s elapsed | log: 389KB (+147456B) | Generating spec.md for feature...
723
727
  @ [HEARTBEAT] 2m30s elapsed | log: 389KB (+0B) | (waiting for AI response)
724
728
  ```
@@ -863,7 +867,7 @@ cli.py bugfix run command
863
867
  | +-- utils.py # Shared Python utilities (JSON I/O, logging)
864
868
  | +-- init-pipeline.py # Validate .prizmkit/plans/feature-list.json + create .prizmkit/state/features/
865
869
  | +-- init-bugfix-pipeline.py # Validate .prizmkit/plans/bug-fix-list.json + create .prizmkit/state/bugfix/
866
- | +-- init-dev-team.py # Create .prizmkit/specs/{slug}/ directories
870
+ | +-- init-change-artifact.py # Create .prizmkit/specs/{slug}/ directories
867
871
  | +-- generate-bootstrap-prompt.py # Render feature session prompt from template
868
872
  | +-- generate-bugfix-prompt.py # Render bugfix session prompt from template
869
873
  | +-- check-session-status.py # Parse session-status.json outcome
@@ -873,18 +877,17 @@ cli.py bugfix run command
873
877
  | +-- parse-stream-progress.py # Real-time stream-json progress parser
874
878
  |
875
879
  +-- templates/
876
- | +-- bootstrap-tier1.md # Tier 1 prompt template (single agent, lite)
877
- | +-- bootstrap-tier2.md # Tier 2 prompt template (dual agent, standard)
878
- | +-- bootstrap-tier3.md # Tier 3 prompt template (full team, full)
879
- | +-- bootstrap-prompt.md # Legacy monolithic template (fallback)
880
- | +-- bugfix-bootstrap-prompt.md # Bug-fix session prompt template
881
- | +-- feature-list-schema.json # JSON schema for .prizmkit/plans/feature-list.json
882
- | +-- bug-fix-list-schema.json # JSON schema for .prizmkit/plans/bug-fix-list.json
883
- | +-- session-status-schema.json # JSON schema for session-status.json
880
+ | +-- sections/ # Modular feature prompt sections (normal full guidance path)
881
+ | +-- bootstrap-tier3.md # Legacy monolithic full prompt fallback
882
+ | +-- bootstrap-prompt.md # Last-resort monolithic fallback
883
+ | +-- bugfix-bootstrap-prompt.md # Bug-fix session prompt template
884
+ | +-- feature-list-schema.json # JSON schema for .prizmkit/plans/feature-list.json
885
+ | +-- bug-fix-list-schema.json # JSON schema for .prizmkit/plans/bug-fix-list.json
886
+ | +-- session-status-schema.json # JSON schema for session-status.json
884
887
  |
885
888
  +-- assets/
886
889
  | +-- feature-list-example.json # Example feature list
887
- | +-- prizm-dev-team-integration.md # Pipeline + prizm-dev-team integration docs
890
+ | +-- skill-subagent-integration.md # Pipeline + skill-owned subagent integration docs
888
891
  |
889
892
  +-- tests/
890
893
  | +-- conftest.py # Pytest configuration
@@ -909,14 +912,14 @@ cli.py bugfix run command
909
912
 
910
913
  ---
911
914
 
912
- ## Agent and Team Configuration
915
+ ## Skill-Owned Subagent References
913
916
 
914
- | Platform | Agent Definitions | Team Config |
915
- |----------|------------------|-------------|
916
- | Claude Code | `.claude/agents/prizm-dev-team-*.md` | `.claude/team-info.json` |
917
- | CodeBuddy | `.codebuddy/agents/prizm-dev-team-*.md` | `~/.codebuddy/teams/prizm-dev-team/config.json` |
917
+ | Skill | Reference | Purpose |
918
+ |-------|-----------|---------|
919
+ | `/prizmkit-implement` | skill-local implementation-subagent procedure | Optional narrow implementation delegation in the active checkout |
920
+ | `/prizmkit-code-review` | skill-local reviewer prompt | Required independent reviewer loop in the active checkout |
918
921
 
919
- Agent files include Dev and Reviewer definitions used by prompt flows. `prizm-dev-team-dev.md` remains available for targeted specialized handoffs, but top-level feature implementation is performed directly by the main orchestrator with `/prizmkit-implement`. Paths are auto-resolved by prompt generators.
922
+ Platform-installed named agents and team topology are not part of the current runtime model. Prompt flows call skills, and the skills own any inline subagent prompts plus active-checkout/no-worktree constraints.
920
923
 
921
924
  ---
922
925
 
@@ -0,0 +1,76 @@
1
+ # Skill Subagent Integration Guide
2
+
3
+ ## Overview
4
+
5
+ `dev-pipeline` drives feature, bugfix, and refactor sessions through the unified Python outer loop. Each iteration spawns a new AI CLI session with a bootstrap prompt that makes the main session orchestrator responsible for planning, implementation, review coordination, testing, retrospective, and commit.
6
+
7
+ Implementation and review behavior is owned by skills:
8
+ - `/prizmkit-implement` executes plan tasks directly and may use its local implementation-subagent reference for narrow active-checkout delegation.
9
+ - `/prizmkit-code-review` owns its internal inline reviewer subagent review loop through its local reviewer prompt reference.
10
+
11
+ ## Architecture
12
+
13
+ ```text
14
+ dev-pipeline (outer loop)
15
+ |
16
+ +-- cli.py feature/bugfix/refactor Python runtime CLI — picks next item, spawns CLI
17
+ +-- scripts/ Python state and prompt management scripts
18
+ +-- templates/ Session prompt templates and sections
19
+ |
20
+ +-- [per session] AI CLI
21
+ |
22
+ +-- Context snapshot + specify + plan (orchestrator)
23
+ +-- Local plan/spec review loop inside prizmkit-plan
24
+ +-- Implement through /prizmkit-implement
25
+ +-- Code review through /prizmkit-code-review inline reviewer loop
26
+ +-- Scoped test gate and browser attempt
27
+ +-- Retrospective & commit (orchestrator)
28
+ ```
29
+
30
+ ## Skill-Owned References
31
+
32
+ | Skill | Reference | Purpose |
33
+ |-------|-----------|---------|
34
+ | `/prizmkit-implement` | skill-local `references/implementation-subagent-procedure.md` | Optional narrow implementation delegation contract |
35
+ | `/prizmkit-code-review` | skill-local `references/reviewer-agent-prompt.md` | Required independent reviewer-loop prompt |
36
+
37
+ The orchestrator role is handled by the main agent directly — no separate platform agent definition or team topology is installed.
38
+
39
+ ## Active Checkout Contract
40
+
41
+ Any skill-level implementation or review subagent must run in the expected active git top-level. The prompt contract forbids git worktrees, tool-created worktree isolation, copied repository checkouts, remote isolated checkouts, branch switching, and operating outside the expected active checkout.
42
+
43
+ Pipeline runner-owned linked worktrees are an outer runtime option. They do not authorize skill-level subagents to create or enter their own worktrees.
44
+
45
+ ## Pipeline Scripts
46
+
47
+ Located at `.prizmkit/dev-pipeline/scripts/`:
48
+
49
+ | Script | Purpose |
50
+ |--------|---------|
51
+ | `init-pipeline.py` | Initialize feature pipeline state |
52
+ | `init-bugfix-pipeline.py` | Initialize bugfix pipeline state |
53
+ | `init-refactor-pipeline.py` | Initialize refactor pipeline state |
54
+ | `init-change-artifact.py` | Initialize feature change-artifact directories |
55
+ | `generate-bootstrap-prompt.py` | Render feature bootstrap prompt with feature context |
56
+ | `generate-bugfix-prompt.py` | Render bugfix bootstrap prompt with bug context |
57
+ | `generate-refactor-prompt.py` | Render refactor bootstrap prompt with refactor context |
58
+ | `update-feature-status.py` | Update feature status after session |
59
+ | `update-bug-status.py` | Update bug status after session |
60
+ | `update-refactor-status.py` | Update refactor status after session |
61
+ | `check-session-status.py` | Read and validate session-status output |
62
+ | `detect-stuck.py` | Detect stuck or stale pipeline sessions |
63
+ | `parse-stream-progress.py` | Parse AI CLI output stream for progress tracking |
64
+ | `utils.py` | Shared utility functions for pipeline scripts |
65
+
66
+ ## Session Lifecycle
67
+
68
+ 1. Runtime selects the next eligible item from the plan list.
69
+ 2. Prompt generator renders a session prompt and checkpoint file.
70
+ 3. AI CLI session executes the generated prompt in the active project checkout or runner-owned worktree.
71
+ 4. Session writes status and completion artifacts.
72
+ 5. Runtime updates plan-list status and propagates completion notes.
73
+
74
+ ## Failure Recovery
75
+
76
+ The generated checkpoint file is the recovery truth. Continuation prompts resume from the first pending or in-progress checkpoint step and prefer synthesized artifacts over full log rereads.
@@ -269,10 +269,7 @@ def _installed_platform_cli(
269
269
  paths: RuntimePaths,
270
270
  env: Mapping[str, str],
271
271
  ) -> tuple[str | None, str | None]:
272
- if (
273
- (paths.project_root / ".codex" / "agents" / "prizm-dev-team-dev.toml").is_file()
274
- or (paths.project_root / ".agents" / "skills" / "prizmkit" / "SKILL.md").is_file()
275
- ):
272
+ if (paths.project_root / ".agents" / "skills" / "prizmkit" / "SKILL.md").is_file():
276
273
  resolved = _resolve_cli_name("codex", env)
277
274
  if resolved:
278
275
  return resolved, "installed-platform:codex"
@@ -280,10 +277,7 @@ def _installed_platform_cli(
280
277
  resolved = _resolve_cli_name("claude", env)
281
278
  if resolved:
282
279
  return resolved, "installed-platform:claude"
283
- if (
284
- (paths.project_root / ".codebuddy" / "agents" / "prizm-dev-team-dev.md").is_file()
285
- or (paths.project_root / ".codebuddy" / "skills" / "prizmkit" / "SKILL.md").is_file()
286
- ):
280
+ if (paths.project_root / ".codebuddy" / "skills" / "prizmkit" / "SKILL.md").is_file():
287
281
  resolved = _resolve_cli_name("cbc", env)
288
282
  if resolved:
289
283
  return resolved, "installed-platform:codebuddy"
@@ -33,10 +33,8 @@ HIDDEN_TOOL_WORKTREE_EXCLUDES = (
33
33
  ":(top,exclude).prizmkit/manifest.json",
34
34
  ":(top,exclude).prizmkit/state",
35
35
  ":(top,exclude,glob).prizmkit/state/**",
36
- ":(top,exclude).prizmkit/dev-pipeline/scripts",
37
- ":(top,exclude,glob).prizmkit/dev-pipeline/scripts/**",
38
- ":(top,exclude).prizmkit/dev-pipeline/prizmkit_runtime",
39
- ":(top,exclude,glob).prizmkit/dev-pipeline/prizmkit_runtime/**",
36
+ ":(top,exclude).prizmkit/dev-pipeline",
37
+ ":(top,exclude,glob).prizmkit/dev-pipeline/**",
40
38
  )
41
39
 
42
40
  PIPELINE_FALLBACK_GIT_NAME = "PrizmKit Pipeline"
@@ -19,7 +19,7 @@ UTILITY_ENTRYPOINTS = {
19
19
  "generate-recovery-prompt": "scripts/generate-recovery-prompt.py",
20
20
  "generate-refactor-prompt": "scripts/generate-refactor-prompt.py",
21
21
  "init-bugfix-pipeline": "scripts/init-bugfix-pipeline.py",
22
- "init-dev-team": "scripts/init-dev-team.py",
22
+ "init-change-artifact": "scripts/init-change-artifact.py",
23
23
  "init-pipeline": "scripts/init-pipeline.py",
24
24
  "init-refactor-pipeline": "scripts/init-refactor-pipeline.py",
25
25
  "parse-stream-progress": "scripts/parse-stream-progress.py",
@@ -41,9 +41,9 @@ class SkillResolution:
41
41
 
42
42
 
43
43
  _PLATFORM_MARKERS = {
44
- "claude": (".claude/agents", ".claude/commands", ".claude/skills"),
45
- "codex": (".codex/agents", ".agents/skills"),
46
- "codebuddy": (".codebuddy/agents", ".codebuddy/skills"),
44
+ "claude": (".claude/commands", ".claude/skills"),
45
+ "codex": (".agents/skills",),
46
+ "codebuddy": (".codebuddy/skills",),
47
47
  }
48
48
 
49
49
 
@@ -46,18 +46,27 @@ def _visible_status_result(project_root: Path) -> GitCommandResult:
46
46
  return run_git_command(project_root, ("status", "--porcelain", "--", ".", *HIDDEN_TOOL_WORKTREE_EXCLUDES))
47
47
 
48
48
 
49
+ def _paths_from_status(stdout: str) -> tuple[str, ...]:
50
+ changed: list[str] = []
51
+ seen: set[str] = set()
52
+ for line in stdout.splitlines():
53
+ if len(line) < 4:
54
+ continue
55
+ path = line[3:].strip()
56
+ paths = path.split(" -> ", 1) if " -> " in path else [path]
57
+ for candidate in paths:
58
+ candidate = candidate.strip()
59
+ if candidate and candidate not in seen:
60
+ changed.append(candidate)
61
+ seen.add(candidate)
62
+ return tuple(changed)
63
+
64
+
49
65
  def _changed_paths_in(project_root: Path, paths: Sequence[str]) -> tuple[str, ...]:
50
66
  result = run_git_command(project_root, ("status", "--porcelain", "--", *paths))
51
67
  if result.return_code != 0:
52
68
  return ()
53
- changed: list[str] = []
54
- for line in result.stdout.splitlines():
55
- path = line[3:].strip()
56
- if " -> " in path:
57
- path = path.split(" -> ", 1)[1].strip()
58
- if path:
59
- changed.append(path)
60
- return tuple(changed)
69
+ return _paths_from_status(result.stdout)
61
70
 
62
71
 
63
72
  def commit_bookkeeping_changes(
@@ -80,14 +89,15 @@ def commit_preflight_ready_changes(project_root: Path, item_id: str) -> Bookkeep
80
89
  visible_status = _visible_status_result(project_root)
81
90
  if visible_status.return_code != 0:
82
91
  return BookkeepingResult(attempted=True, committed=False, result=visible_status)
83
- if not visible_status.stdout.strip():
92
+ paths = _paths_from_status(visible_status.stdout)
93
+ if not paths:
84
94
  return BookkeepingResult(attempted=False, committed=False)
85
- add_result = run_git_command(project_root, ("add", "-A", "--", ".", *HIDDEN_TOOL_WORKTREE_EXCLUDES))
95
+ add_result = run_git_command(project_root, ("add", "-A", "-f", "--", *paths))
86
96
  if add_result.return_code != 0:
87
97
  return BookkeepingResult(attempted=True, committed=False, result=add_result)
88
98
  result = run_git_command(
89
99
  project_root,
90
- ("commit", "--no-verify", "-m", f"chore: ready for {item_id}", "--", ".", *HIDDEN_TOOL_WORKTREE_EXCLUDES),
100
+ ("commit", "--no-verify", "-m", f"chore: ready for {item_id}", "--", *paths),
91
101
  )
92
102
  if result.return_code != 0:
93
103
  return BookkeepingResult(attempted=True, committed=False, result=result)
@@ -5,6 +5,7 @@ from __future__ import annotations
5
5
  import json
6
6
  import sys
7
7
  import time
8
+ from collections.abc import Mapping
8
9
  from pathlib import Path
9
10
 
10
11
  from .commands import CommandResult # type: ignore # imported only at runtime by commands.py
@@ -336,6 +337,32 @@ def _progress_data(path: Path) -> dict[str, object]:
336
337
  return data if isinstance(data, dict) else {}
337
338
 
338
339
 
340
+ def _subagent_state_summary(progress: Mapping[str, object]) -> str:
341
+ states = progress.get("subagent_states")
342
+ if not isinstance(states, list):
343
+ return ""
344
+ parts = []
345
+ for item in states:
346
+ if not isinstance(item, Mapping):
347
+ continue
348
+ status = str(item.get("status") or "unknown")
349
+ count = int(item.get("count") or 0)
350
+ if count:
351
+ parts.append(f"{status}={count}")
352
+ return ", ".join(parts)
353
+
354
+
355
+ def _child_log_activity_summary(progress: Mapping[str, object]) -> str:
356
+ child_bytes = int(progress.get("child_total_bytes") or 0)
357
+ child_files = progress.get("child_session_files")
358
+ child_file_count = len(child_files) if isinstance(child_files, list) else 0
359
+ if not child_bytes and not child_file_count:
360
+ return ""
361
+ if child_file_count:
362
+ return f"{_bytes_text(child_bytes)} across {child_file_count} files"
363
+ return _bytes_text(child_bytes)
364
+
365
+
339
366
  def _emit_prompt_summary(prompt: PromptGenerationResult, session_id: str) -> None:
340
367
  if prompt.pipeline_mode:
341
368
  _emit_info(f"Pipeline mode: {_pipeline_mode_label(prompt.pipeline_mode)}")
@@ -359,9 +386,24 @@ def _emit_session_summary(session_result, session_paths: SessionPaths, classific
359
386
  _emit_info(f"exit_code={getattr(session_result, 'exit_code', None)}")
360
387
  _emit_info(f"Session result: {classification.session_status}")
361
388
  progress = _progress_data(session_paths.progress_json)
362
- subagent_calls = int(progress.get("subagent_spawn_count") or 0)
363
- if subagent_calls:
364
- _emit_info(f"Subagent calls detected in session: {subagent_calls}")
389
+ subagent_stats = progress.get("subagent_statistics")
390
+ if isinstance(subagent_stats, Mapping):
391
+ spawned = int(subagent_stats.get("spawned") or 0)
392
+ active = int(subagent_stats.get("active") or 0)
393
+ providers = subagent_stats.get("providers")
394
+ provider_text = ",".join(str(provider) for provider in providers) if isinstance(providers, list) else ""
395
+ else:
396
+ spawned = int(progress.get("subagent_spawn_count") or 0)
397
+ active = int(progress.get("active_subagent_count") or 0)
398
+ provider_text = str(progress.get("subagent_provider") or "")
399
+ state_summary = _subagent_state_summary(progress)
400
+ if spawned or active or state_summary:
401
+ suffix = f" ({provider_text}; source=session.log)" if provider_text else " (source=session.log)"
402
+ state_text = f", states: {state_summary}" if state_summary else ""
403
+ _emit_info(f"Subagents: spawned={spawned}, active={active}{state_text}{suffix}")
404
+ child_summary = _child_log_activity_summary(progress)
405
+ if child_summary:
406
+ _emit_info(f"Child log activity: {child_summary} (heartbeat liveness only)")
365
407
  if classification.session_status == "success":
366
408
  _emit_info("CHECKPOINT: All workflow steps completed")
367
409
 
@@ -402,6 +402,10 @@ def _progress_refresh_key(data: Mapping[str, object]) -> tuple[object, ...]:
402
402
  int(data.get("total_tool_calls") or 0),
403
403
  int(data.get("active_subagent_count") or 0),
404
404
  int(data.get("subagent_spawn_count") or 0),
405
+ str(data.get("subagent_stats_source") or ""),
406
+ str(data.get("subagent_provider") or ""),
407
+ json.dumps(data.get("subagent_states") or [], sort_keys=True, default=str),
408
+ json.dumps(data.get("subagent_observed_ids") or [], sort_keys=True, default=str),
405
409
  str(data.get("child_activity_signature") or ""),
406
410
  int(data.get("child_total_bytes") or 0),
407
411
  str(data.get("fatal_error_code") or ""),
@@ -549,12 +553,30 @@ def _compact_progress_line(
549
553
  f"log: {_format_bytes(log_size)}",
550
554
  ]
551
555
  child_bytes = int(data.get("child_total_bytes") or 0)
552
- subagents = int(data.get("subagent_spawn_count") or 0)
553
- if child_bytes or subagents:
554
- child = _format_bytes(child_bytes)
555
- if subagents:
556
- child = f"{child}/{subagents}"
557
- parts.append(f"child: {child}")
556
+ child_files = data.get("child_session_files")
557
+ child_file_count = len(child_files) if isinstance(child_files, list) else 0
558
+ spawned = int(data.get("subagent_spawn_count") or 0)
559
+ active = int(data.get("active_subagent_count") or 0)
560
+ subagent_states = data.get("subagent_states")
561
+ if spawned or active or subagent_states:
562
+ state_bits = []
563
+ if isinstance(subagent_states, list):
564
+ for item in subagent_states:
565
+ if not isinstance(item, Mapping):
566
+ continue
567
+ status = str(item.get("status") or "unknown")
568
+ count = int(item.get("count") or 0)
569
+ if count:
570
+ state_bits.append(f"{status}={count}")
571
+ subagent_text = f"spawned={spawned} active={active}"
572
+ if state_bits:
573
+ subagent_text = f"{subagent_text} states:{','.join(state_bits)}"
574
+ parts.append(f"subagents: {subagent_text}")
575
+ if child_bytes or child_file_count:
576
+ child_text = _format_bytes(child_bytes)
577
+ if child_file_count:
578
+ child_text = f"{child_text}/{child_file_count} files"
579
+ parts.append(f"child logs: {child_text}")
558
580
  phase = _checkpoint_phase_label(checkpoint_path)
559
581
  if phase:
560
582
  parts.append(f"phase: {phase}")