prizmkit 1.1.106 → 1.1.108

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 (85) hide show
  1. package/bin/create-prizmkit.js +4 -0
  2. package/bundled/VERSION.json +3 -3
  3. package/bundled/dev-pipeline/prizmkit_runtime/config.py +81 -14
  4. package/bundled/dev-pipeline/prizmkit_runtime/heartbeat.py +19 -8
  5. package/bundled/dev-pipeline/prizmkit_runtime/interoperability.py +0 -1
  6. package/bundled/dev-pipeline/prizmkit_runtime/launch_profiles.py +18 -0
  7. package/bundled/dev-pipeline/prizmkit_runtime/runner_bookkeeping.py +22 -2
  8. package/bundled/dev-pipeline/prizmkit_runtime/runner_classification.py +56 -5
  9. package/bundled/dev-pipeline/prizmkit_runtime/runner_models.py +0 -8
  10. package/bundled/dev-pipeline/prizmkit_runtime/runner_recovery.py +11 -1
  11. package/bundled/dev-pipeline/prizmkit_runtime/runners.py +298 -63
  12. package/bundled/dev-pipeline/prizmkit_runtime/sessions.py +243 -37
  13. package/bundled/dev-pipeline/scripts/continuation.py +0 -5
  14. package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +10 -82
  15. package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +7 -64
  16. package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +40 -63
  17. package/bundled/dev-pipeline/scripts/utils.py +123 -0
  18. package/bundled/dev-pipeline/templates/agent-prompts/critic-plan-challenge.md +4 -3
  19. package/bundled/dev-pipeline/templates/agent-prompts/reviewer-review.md +5 -6
  20. package/bundled/dev-pipeline/templates/bootstrap-prompt.md +1 -1
  21. package/bundled/dev-pipeline/templates/bootstrap-tier1.md +36 -35
  22. package/bundled/dev-pipeline/templates/bootstrap-tier2.md +53 -80
  23. package/bundled/dev-pipeline/templates/bootstrap-tier3.md +43 -78
  24. package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +5 -17
  25. package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +6 -18
  26. package/bundled/dev-pipeline/templates/sections/checkpoint-system.md +14 -48
  27. package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +7 -14
  28. package/bundled/dev-pipeline/templates/sections/feature-context.md +0 -4
  29. package/bundled/dev-pipeline/templates/sections/phase-browser-verification-auto.md +0 -7
  30. package/bundled/dev-pipeline/templates/sections/phase-browser-verification-opencli.md +0 -7
  31. package/bundled/dev-pipeline/templates/sections/phase-browser-verification.md +0 -7
  32. package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +0 -14
  33. package/bundled/dev-pipeline/templates/sections/phase-commit.md +0 -14
  34. package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-agent-suffix.md +0 -7
  35. package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-base.md +0 -2
  36. package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-lite-suffix.md +0 -7
  37. package/bundled/dev-pipeline/templates/sections/phase-critic-plan-full.md +6 -8
  38. package/bundled/dev-pipeline/templates/sections/phase-critic-plan.md +3 -7
  39. package/bundled/dev-pipeline/templates/sections/phase-implement-agent.md +4 -16
  40. package/bundled/dev-pipeline/templates/sections/phase-implement-full.md +4 -17
  41. package/bundled/dev-pipeline/templates/sections/phase-implement-lite.md +0 -7
  42. package/bundled/dev-pipeline/templates/sections/phase-plan-agent.md +2 -9
  43. package/bundled/dev-pipeline/templates/sections/phase-plan-lite.md +1 -8
  44. package/bundled/dev-pipeline/templates/sections/phase-prizmkit-test.md +15 -16
  45. package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +3 -10
  46. package/bundled/dev-pipeline/templates/sections/phase-review-full.md +3 -10
  47. package/bundled/dev-pipeline/templates/sections/phase-specify-plan-full.md +2 -9
  48. package/bundled/dev-pipeline/templates/sections/phase0-init.md +0 -7
  49. package/bundled/dev-pipeline/templates/sections/phase0-test-baseline.md +2 -15
  50. package/bundled/dev-pipeline/tests/conftest.py +0 -1
  51. package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +395 -21
  52. package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +50 -14
  53. package/bundled/dev-pipeline/tests/test_generate_refactor_prompt.py +154 -2
  54. package/bundled/dev-pipeline/tests/test_python_runner_parity.py +431 -3
  55. package/bundled/dev-pipeline/tests/test_unified_cli.py +857 -5
  56. package/bundled/skills/_metadata.json +4 -4
  57. package/bundled/skills/app-planner/SKILL.md +1 -1
  58. package/bundled/skills/app-planner/references/architecture-decisions.md +1 -1
  59. package/bundled/skills/bug-fix-workflow/SKILL.md +174 -128
  60. package/bundled/skills/bug-planner/SKILL.md +101 -15
  61. package/bundled/skills/bug-planner/references/severity-rules.md +20 -8
  62. package/bundled/skills/feature-planner/SKILL.md +87 -8
  63. package/bundled/skills/feature-planner/assets/planning-guide.md +34 -10
  64. package/bundled/skills/feature-workflow/SKILL.md +100 -81
  65. package/bundled/skills/{prizm-kit → prizmkit}/SKILL.md +1 -1
  66. package/bundled/skills/prizmkit-code-review/SKILL.md +12 -13
  67. package/bundled/skills/prizmkit-code-review/references/reviewer-agent-prompt.md +10 -10
  68. package/bundled/skills/refactor-planner/SKILL.md +88 -7
  69. package/bundled/skills/refactor-planner/references/fast-path.md +2 -1
  70. package/bundled/skills/refactor-planner/references/planning-phases.md +29 -11
  71. package/bundled/skills/refactor-workflow/SKILL.md +116 -57
  72. package/bundled/templates/project-memory-template.md +1 -1
  73. package/package.json +1 -1
  74. package/src/ai-cli-launch.js +194 -0
  75. package/src/config.js +26 -14
  76. package/src/index.js +11 -44
  77. package/src/platforms.js +10 -3
  78. package/src/prompts.js +60 -2
  79. package/src/scaffold.js +26 -14
  80. package/bundled/dev-pipeline/scripts/prizmkit-test-gate.py +0 -446
  81. package/bundled/dev-pipeline/templates/agent-prompts/dev-fix.md +0 -7
  82. package/bundled/dev-pipeline/templates/agent-prompts/dev-resume.md +0 -5
  83. package/bundled/dev-pipeline/templates/sections/log-size-awareness.md +0 -20
  84. package/bundled/dev-pipeline/tests/test_prizmkit_test_gate.py +0 -107
  85. package/bundled/skills/prizmkit-code-review/references/dev-agent-prompt.md +0 -30
@@ -12,10 +12,12 @@ from generate_bugfix_prompt import (
12
12
  format_environment,
13
13
  process_conditional_blocks,
14
14
  render_template,
15
- load_log_size_section,
16
15
  )
17
16
  from continuation import append_continuation_handoff
18
17
 
18
+ REMOVED_MAX_LOG_ENV = "MAX_" + "LOG_SIZE"
19
+ REMOVED_MAX_LOG_HUMAN = REMOVED_MAX_LOG_ENV + "_HUMAN"
20
+
19
21
 
20
22
  # ---------------------------------------------------------------------------
21
23
  # find_bug
@@ -193,6 +195,14 @@ class TestExplicitProjectRoot:
193
195
  )
194
196
  assert not replacements["{{SESSION_STATUS_PATH}}"].startswith(str(execution_root.resolve()))
195
197
  assert replacements["{{DEV_SUBAGENT_PATH}}"].startswith(str(execution_root.resolve()))
198
+ assert replacements["{{SESSION_LOG_PATH}}"].endswith(
199
+ ".prizmkit/state/bugfix/B-001/sessions/session-1/logs/session.log"
200
+ )
201
+ assert "{{" + REMOVED_MAX_LOG_ENV + "}}" not in replacements
202
+ assert "{{" + REMOVED_MAX_LOG_HUMAN + "}}" not in replacements
203
+ assert "### Checkpoint Update Helper" in replacements["{{CHECKPOINT_SYSTEM}}"]
204
+ assert "python3 .prizmkit/dev-pipeline/scripts/update-checkpoint.py" in replacements["{{CHECKPOINT_SYSTEM}}"]
205
+ assert "pipeline progress mechanism" not in replacements["{{CHECKPOINT_SYSTEM}}"]
196
206
 
197
207
 
198
208
  # ---------------------------------------------------------------------------
@@ -218,23 +228,27 @@ class TestSharedHelpers:
218
228
  # ---------------------------------------------------------------------------
219
229
 
220
230
  class TestHeadlessRecoveryReframing:
221
- def test_bugfix_log_size_section_is_passive_checkpoint_guidance(self):
222
- content = load_log_size_section(str(Path("dev-pipeline/scripts").resolve()))
223
-
224
- assert "passive checkpoint guidance" in content
225
- assert "Headless recovery must rely on durable checkpoints" in content
226
- assert "fresh continuation session" in content
227
- assert "optional interactive convenience only" in content
228
- assert "COMPACT_NEEDED" not in content
229
- assert "monitor-log" not in content
230
- assert "background monitoring subagent" not in content
231
- assert "Execute `/compact`" not in content
232
- assert "run `/compact`" not in content.lower()
231
+ def test_bugfix_source_has_no_deleted_log_size_injection(self):
232
+ deleted_section = "log-size-" + "awareness.md"
233
+ loader = "load_" + "log_size_section"
234
+ placeholder = "{{LOG_" + "SIZE_AWARENESS}}"
235
+ deleted_title = "Session " + "Checkpoint Awareness"
236
+ source = Path("dev-pipeline/scripts/generate-bugfix-prompt.py").read_text(encoding="utf-8")
237
+ template = Path("dev-pipeline/templates/bugfix-bootstrap-prompt.md").read_text(encoding="utf-8")
238
+
239
+ assert (Path("dev-pipeline/templates/sections") / deleted_section).exists() is False
240
+ for content in (source, template):
241
+ for forbidden in (deleted_section, loader, placeholder, deleted_title):
242
+ assert forbidden not in content
233
243
 
234
244
  def test_bugfix_template_does_not_spawn_monitor_or_require_compact(self):
235
245
  content = Path("dev-pipeline/templates/bugfix-bootstrap-prompt.md").read_text(encoding="utf-8")
236
246
 
237
247
  assert "Do not spawn persistent background subagents for headless recovery" in content
248
+ assert REMOVED_MAX_LOG_ENV not in content
249
+ assert REMOVED_MAX_LOG_HUMAN not in content
250
+ assert ("209" + "7152") not in content
251
+ assert ("2" + "MB") not in content
238
252
  assert "log-size monitor" not in content
239
253
  assert "monitor-log" not in content
240
254
  assert "COMPACT_NEEDED" not in content
@@ -263,6 +277,28 @@ class TestBugfixContinuationHandoff:
263
277
 
264
278
  assert prompt.startswith("BUGFIX PROMPT")
265
279
  assert "This is an automatic continuation after context overflow." in prompt
266
- assert "Do not attempt `/compact` as the recovery mechanism." in prompt
280
+ assert "Do not attempt `/compact` as the recovery mechanism." not in prompt
281
+ assert ("Log " + "monitor") not in prompt
282
+ assert ("log-" + "monitor") not in prompt
267
283
  assert (tmp_path / ".prizmkit/specs/B-007/continuation-summary.md").exists()
268
284
  assert (tmp_path / ".prizmkit/bugfix/B-007/continuation-summary.md").exists()
285
+
286
+
287
+ HEADLESS_FORBIDDEN_PROMPT_STRINGS = [
288
+ "### Interactive Claude Code Note",
289
+ "### Project Conventions",
290
+ "Scaffold / generated file awareness",
291
+ "### Resume Behavior",
292
+ "[NEEDS CLARIFICATION]",
293
+ "pause for interactive input",
294
+ "prizmkit-test-gate.py",
295
+ "/compact",
296
+ "Session " + "Checkpoint Awareness",
297
+ "{{LOG_" + "SIZE_AWARENESS}}",
298
+ ]
299
+
300
+
301
+ def test_template_source_is_clean_for_headless_prompt_contract():
302
+ content = Path("dev-pipeline/templates/bugfix-bootstrap-prompt.md").read_text(encoding="utf-8")
303
+ for forbidden in HEADLESS_FORBIDDEN_PROMPT_STRINGS:
304
+ assert forbidden not in content
@@ -1,9 +1,17 @@
1
1
  """Tests for generate-refactor-prompt.py continuation behavior."""
2
2
 
3
3
  from argparse import Namespace
4
+ from pathlib import Path
4
5
 
5
6
  from continuation import append_continuation_handoff
6
- from generate_refactor_prompt import generate_refactor_checkpoint, merge_refactor_checkpoint_state
7
+ from generate_refactor_prompt import (
8
+ build_replacements,
9
+ generate_refactor_checkpoint,
10
+ merge_refactor_checkpoint_state,
11
+ )
12
+
13
+ REMOVED_MAX_LOG_ENV = "MAX_" + "LOG_SIZE"
14
+ REMOVED_MAX_LOG_HUMAN = REMOVED_MAX_LOG_ENV + "_HUMAN"
7
15
 
8
16
 
9
17
  class TestRefactorContinuationHandoff:
@@ -26,7 +34,9 @@ class TestRefactorContinuationHandoff:
26
34
 
27
35
  assert prompt.startswith("REFACTOR PROMPT")
28
36
  assert "This is a fresh headless AI CLI session for the same task." in prompt
29
- assert "Do not attempt `/compact` as the recovery mechanism." in prompt
37
+ assert "Do not attempt `/compact` as the recovery mechanism." not in prompt
38
+ assert ("Log " + "monitor") not in prompt
39
+ assert ("log-" + "monitor") not in prompt
30
40
  assert (tmp_path / ".prizmkit/specs/R-007/continuation-summary.md").exists()
31
41
  assert (tmp_path / ".prizmkit/refactor/R-007/continuation-summary.md").exists()
32
42
 
@@ -41,3 +51,145 @@ class TestRefactorCheckpointMerge:
41
51
 
42
52
  assert merged["steps"][0]["status"] == "skipped"
43
53
  assert merged["steps"][1]["status"] == "pending"
54
+
55
+
56
+ class TestExplicitProjectRoot:
57
+ def test_build_replacements_infers_project_root_from_refactor_list(self, tmp_path, monkeypatch):
58
+ monkeypatch.delenv("PRIZMKIT_PLATFORM", raising=False)
59
+ project = tmp_path / "project"
60
+ plan_path = project / ".prizmkit" / "plans" / "refactor-list.json"
61
+ plan_path.parent.mkdir(parents=True)
62
+ (project / ".prizmkit" / "config.json").write_text(
63
+ '{"platform":"claude","ai_cli":"claude"}', encoding="utf-8"
64
+ )
65
+ args = Namespace(
66
+ refactor_list=str(plan_path),
67
+ refactor_id="R-001",
68
+ session_id="session-1",
69
+ run_id="run-1",
70
+ retry_count="0",
71
+ resume_phase="null",
72
+ state_dir=str(project / ".prizmkit" / "state" / "refactor"),
73
+ output=str(project / "out.md"),
74
+ template=None,
75
+ mode=None,
76
+ critic=None,
77
+ )
78
+ refactor = {"id": "R-001", "title": "Restructure", "description": "d"}
79
+
80
+ replacements = build_replacements(
81
+ args, refactor, [refactor], {}, str(Path("dev-pipeline/scripts").resolve())
82
+ )
83
+
84
+ assert replacements["{{PROJECT_ROOT}}"] == str(project.resolve())
85
+ assert replacements["{{REVIEWER_SUBAGENT_PATH}}"].endswith(
86
+ ".claude/agents/prizm-dev-team-reviewer.md"
87
+ )
88
+ assert replacements["{{REVIEWER_SUBAGENT_PATH}}"].startswith(str(project.resolve()))
89
+ assert replacements["{{SESSION_STATUS_PATH}}"] == str(
90
+ project / ".prizmkit" / "state" / "refactor" / "R-001" /
91
+ "sessions" / "session-1" / "session-status.json"
92
+ )
93
+
94
+ def test_build_replacements_uses_cli_project_root_for_rendered_paths(self, tmp_path, monkeypatch):
95
+ monkeypatch.setenv("PRIZMKIT_PLATFORM", "claude")
96
+ execution_root = tmp_path / "worktree"
97
+ main_checkout = tmp_path / "main"
98
+ execution_root.mkdir()
99
+ main_checkout.mkdir()
100
+ args = Namespace(
101
+ refactor_list=str(main_checkout / ".prizmkit" / "plans" / "refactor-list.json"),
102
+ refactor_id="R-001",
103
+ session_id="session-1",
104
+ run_id="run-1",
105
+ retry_count="0",
106
+ resume_phase="null",
107
+ state_dir=str(main_checkout / ".prizmkit" / "state" / "refactor"),
108
+ output=str(main_checkout / ".prizmkit" / "state" / "refactor" / "R-001" / "sessions" / "session-1" / "bootstrap-prompt.md"),
109
+ template=None,
110
+ mode=None,
111
+ critic=None,
112
+ project_root=str(execution_root),
113
+ )
114
+ refactor = {"id": "R-001", "title": "Worktree Refactor", "description": "d"}
115
+
116
+ replacements = build_replacements(
117
+ args,
118
+ refactor,
119
+ [refactor],
120
+ {},
121
+ str(main_checkout / "dev-pipeline" / "scripts"),
122
+ )
123
+
124
+ assert replacements["{{PROJECT_ROOT}}"] == str(execution_root.resolve())
125
+ assert replacements["{{SESSION_STATUS_PATH}}"] == str(
126
+ main_checkout / ".prizmkit" / "state" / "refactor" / "R-001" /
127
+ "sessions" / "session-1" / "session-status.json"
128
+ )
129
+ assert not replacements["{{SESSION_STATUS_PATH}}"].startswith(str(execution_root.resolve()))
130
+ assert replacements["{{DEV_SUBAGENT_PATH}}"].startswith(str(execution_root.resolve()))
131
+ assert "### Checkpoint Update Helper" in replacements["{{CHECKPOINT_SYSTEM}}"]
132
+ assert "python3 .prizmkit/dev-pipeline/scripts/update-checkpoint.py" in replacements["{{CHECKPOINT_SYSTEM}}"]
133
+ assert "pipeline progress mechanism" not in replacements["{{CHECKPOINT_SYSTEM}}"]
134
+
135
+
136
+ class TestRefactorPromptMaxLogRemoval:
137
+ def test_refactor_source_has_no_deleted_log_size_injection(self):
138
+ deleted_section = "log-size-" + "awareness.md"
139
+ loader = "load_" + "log_size_section"
140
+ placeholder = "{{LOG_" + "SIZE_AWARENESS}}"
141
+ deleted_title = "Session " + "Checkpoint Awareness"
142
+ source = Path("dev-pipeline/scripts/generate-refactor-prompt.py").read_text(encoding="utf-8")
143
+ template = Path("dev-pipeline/templates/refactor-bootstrap-prompt.md").read_text(encoding="utf-8")
144
+
145
+ assert (Path("dev-pipeline/templates/sections") / deleted_section).exists() is False
146
+ for content in (source, template):
147
+ for forbidden in (deleted_section, loader, placeholder, deleted_title):
148
+ assert forbidden not in content
149
+
150
+ def test_refactor_replacements_keep_session_log_without_max_log_placeholders(self, monkeypatch):
151
+ monkeypatch.setenv("PRIZMKIT_PLATFORM", "claude")
152
+ args = Namespace(
153
+ refactor_id="R-001",
154
+ session_id="session-1",
155
+ run_id="run-1",
156
+ retry_count="0",
157
+ resume_phase="null",
158
+ state_dir=None,
159
+ output="out.md",
160
+ template=None,
161
+ mode=None,
162
+ critic=None,
163
+ )
164
+ refactor = {"id": "R-001", "title": "Restructure", "description": "d"}
165
+
166
+ replacements = build_replacements(
167
+ args, refactor, [refactor], {}, str(Path("dev-pipeline/scripts").resolve())
168
+ )
169
+
170
+ assert replacements["{{SESSION_LOG_PATH}}"].endswith(
171
+ ".prizmkit/state/refactor/R-001/sessions/session-1/logs/session.log"
172
+ )
173
+ assert "{{" + REMOVED_MAX_LOG_ENV + "}}" not in replacements
174
+ assert "{{" + REMOVED_MAX_LOG_HUMAN + "}}" not in replacements
175
+ assert "{{LOG_" + "SIZE_AWARENESS}}" not in replacements
176
+
177
+
178
+ HEADLESS_FORBIDDEN_PROMPT_STRINGS = [
179
+ "### Interactive Claude Code Note",
180
+ "### Project Conventions",
181
+ "Scaffold / generated file awareness",
182
+ "### Resume Behavior",
183
+ "[NEEDS CLARIFICATION]",
184
+ "pause for interactive input",
185
+ "prizmkit-test-gate.py",
186
+ "/compact",
187
+ "Session " + "Checkpoint Awareness",
188
+ "{{LOG_" + "SIZE_AWARENESS}}",
189
+ ]
190
+
191
+
192
+ def test_template_source_is_clean_for_headless_prompt_contract():
193
+ content = Path("dev-pipeline/templates/refactor-bootstrap-prompt.md").read_text(encoding="utf-8")
194
+ for forbidden in HEADLESS_FORBIDDEN_PROMPT_STRINGS:
195
+ assert forbidden not in content