prizmkit 1.0.3 → 1.0.5
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.
- package/bin/create-prizmkit.js +7 -1
- package/bundled/VERSION.json +3 -3
- package/bundled/adapters/claude/agent-adapter.js +1 -10
- package/bundled/adapters/claude/command-adapter.js +5 -1
- package/bundled/adapters/claude/paths.js +1 -2
- package/bundled/adapters/shared/constants.js +13 -0
- package/bundled/adapters/shared/frontmatter.js +3 -0
- package/bundled/dev-pipeline/launch-daemon.sh +22 -23
- package/bundled/dev-pipeline/run.sh +16 -13
- package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +2 -15
- package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +3 -17
- package/bundled/dev-pipeline/scripts/init-dev-team.py +11 -11
- package/bundled/dev-pipeline/scripts/update-bug-status.py +8 -67
- package/bundled/dev-pipeline/scripts/update-feature-status.py +8 -83
- package/bundled/dev-pipeline/scripts/utils.py +85 -0
- package/bundled/skills/_metadata.json +19 -3
- package/bundled/skills/feature-workflow/SKILL.md +317 -0
- package/bundled/skills/prizm-kit/SKILL.md +5 -3
- package/bundled/skills/prizm-kit/assets/hooks/prizm-commit-hook.json +2 -2
- package/bundled/skills/prizmkit-bug-fix-workflow/SKILL.md +1 -1
- package/bundled/skills/prizmkit-committer/SKILL.md +21 -3
- package/bundled/skills/prizmkit-prizm-docs/assets/PRIZM-SPEC.md +1 -1
- package/bundled/skills/refactor-workflow/SKILL.md +340 -0
- package/bundled/templates/hooks/commit-intent-claude.json +16 -0
- package/bundled/templates/hooks/commit-intent-codebuddy.json +16 -0
- package/package.json +2 -3
- package/src/detect-platform.js +10 -2
- package/src/scaffold.js +38 -70
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "refactor-workflow"
|
|
3
|
+
tier: 1
|
|
4
|
+
description: "[Tier 1] End-to-end refactor workflow: analyze → plan → tasks → implement → review → commit. 6-phase behavior-preserving pipeline with scope guard and mandatory test gates. (project)"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# PrizmKit Refactor Workflow
|
|
8
|
+
|
|
9
|
+
End-to-end orchestration skill for code refactoring and optimization. Chains existing PrizmKit skills (tech-debt-tracker, plan, tasks, implement, code-review, committer) into a 6-phase behavior-preserving pipeline with scope guard enforcement.
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
prizmkit.refactor <目标模块或描述>
|
|
15
|
+
→ Phase 1: Analyze → refactor-analysis.md
|
|
16
|
+
→ Phase 2: Plan → plan.md
|
|
17
|
+
→ Phase 3: Tasks → tasks.md
|
|
18
|
+
→ Phase 4: Implement → (code)
|
|
19
|
+
→ Phase 5: Review → (review report)
|
|
20
|
+
→ Phase 6: Commit → git commit
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Pipeline Phases
|
|
24
|
+
|
|
25
|
+
| Phase | Name | Skill Used | Artifact |
|
|
26
|
+
|-------|------|-----------|----------|
|
|
27
|
+
| 1 | Analyze 代码分析 | `prizmkit.tech-debt-tracker` + code reading | → `refactor-analysis.md` |
|
|
28
|
+
| 2 | Plan 重构方案 | `prizmkit.plan` | → `plan.md` |
|
|
29
|
+
| 3 | Tasks 任务拆解 | `prizmkit.tasks` | → `tasks.md` |
|
|
30
|
+
| 4 | Implement 实现 | `prizmkit.implement` | (code changes) |
|
|
31
|
+
| 5 | Code Review | `prizmkit.code-review` | (review report) |
|
|
32
|
+
| 6 | Commit | `prizmkit.committer` | git commit |
|
|
33
|
+
|
|
34
|
+
### Key Principles
|
|
35
|
+
|
|
36
|
+
- **Behavior preservation**: Refactoring MUST NOT change observable behavior
|
|
37
|
+
- **Acceptance criteria** = "behavior unchanged + structure improved"
|
|
38
|
+
- **No REGISTRY entry**: Refactoring does not go into REGISTRY.md
|
|
39
|
+
- **No spec.md**: Refactoring has no user stories
|
|
40
|
+
- **Mandatory test gates**: Full test suite after every task, not just checkpoints
|
|
41
|
+
- **Scope guard**: New behavior detected → STOP and suggest feature-workflow
|
|
42
|
+
|
|
43
|
+
### Artifacts
|
|
44
|
+
|
|
45
|
+
Refactor artifacts stored at `.prizmkit/refactor/<refactor-slug>/`:
|
|
46
|
+
- **`refactor-analysis.md`** — Code analysis (Phase 1)
|
|
47
|
+
- **`plan.md`** — Refactoring plan (Phase 2)
|
|
48
|
+
- **`tasks.md`** — Task breakdown (Phase 3)
|
|
49
|
+
|
|
50
|
+
## Commands
|
|
51
|
+
|
|
52
|
+
### prizmkit.refactor \<目标模块或描述\>
|
|
53
|
+
|
|
54
|
+
Execute the full refactor pipeline for a module or code area.
|
|
55
|
+
|
|
56
|
+
**INPUT**: Target description. Can be:
|
|
57
|
+
- Module or file path (e.g., "src/auth/")
|
|
58
|
+
- Natural language description (e.g., "重构认证模块,提取公共逻辑")
|
|
59
|
+
- Specific refactoring goal (e.g., "extract payment processing into separate service")
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Phase 1: Analyze — 代码分析
|
|
64
|
+
|
|
65
|
+
**Goal**: Assess current code state, identify refactoring targets, establish baseline.
|
|
66
|
+
|
|
67
|
+
**STEPS:**
|
|
68
|
+
|
|
69
|
+
1. **Read target code**: Thoroughly read and understand the target module/files:
|
|
70
|
+
- Code structure and architecture
|
|
71
|
+
- Dependencies (incoming and outgoing)
|
|
72
|
+
- Current test coverage
|
|
73
|
+
- Known tech debt (from `.prizm-docs/` TRAPS)
|
|
74
|
+
|
|
75
|
+
2. **Invoke `prizmkit.tech-debt-tracker`** on target area:
|
|
76
|
+
- Receive: debt items, complexity metrics, code smell patterns
|
|
77
|
+
- Identify highest-impact refactoring opportunities
|
|
78
|
+
|
|
79
|
+
3. **Establish baseline**:
|
|
80
|
+
- Run full test suite — record pass/fail counts
|
|
81
|
+
- Note any pre-existing test failures (isolate from refactor impact)
|
|
82
|
+
- Document current behavior contracts (public API, interfaces)
|
|
83
|
+
|
|
84
|
+
4. **Generate `refactor-analysis.md`** at `.prizmkit/refactor/<refactor-slug>/refactor-analysis.md`:
|
|
85
|
+
|
|
86
|
+
Required sections:
|
|
87
|
+
- **Current State**: module overview, file inventory, dependency graph, complexity metrics
|
|
88
|
+
- **Refactoring Goals**: what structural improvements are targeted, why (debt items, complexity, maintainability)
|
|
89
|
+
- **Risk Assessment**: what could break, cross-module impact, data migration needs
|
|
90
|
+
- **Baseline Tests**: test suite status (total, passing, failing), coverage estimate, behavior contracts to preserve
|
|
91
|
+
- **Scope Boundary**: what IS in scope, what is explicitly OUT of scope
|
|
92
|
+
|
|
93
|
+
**CHECKPOINT CP-RW-1**: `refactor-analysis.md` exists with baseline test results.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Phase 2: Plan — 重构方案
|
|
98
|
+
|
|
99
|
+
**Goal**: Generate technical refactoring plan that preserves behavior.
|
|
100
|
+
|
|
101
|
+
**STEPS:**
|
|
102
|
+
|
|
103
|
+
1. **Read context**: refactor-analysis.md, `.prizm-docs/` (PATTERNS, RULES, TRAPS)
|
|
104
|
+
|
|
105
|
+
2. **Invoke `prizmkit.plan`** with refactor-analysis.md as input (in place of spec.md):
|
|
106
|
+
- Plan MUST specify: what changes, what stays the same, how behavior is preserved
|
|
107
|
+
- Artifact path: `.prizmkit/refactor/<refactor-slug>/plan.md`
|
|
108
|
+
|
|
109
|
+
3. **Verify plan constraints**:
|
|
110
|
+
- No new user-facing behavior (scope guard)
|
|
111
|
+
- All public API contracts preserved
|
|
112
|
+
- Test strategy: how to verify behavior unchanged at each step
|
|
113
|
+
- Rollback strategy: how to revert if behavior breaks
|
|
114
|
+
|
|
115
|
+
**CHECKPOINT CP-RW-2**: `plan.md` exists with behavior preservation strategy.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Phase 3: Tasks — 任务拆解
|
|
120
|
+
|
|
121
|
+
**Goal**: Break refactoring plan into safe, atomic, testable tasks.
|
|
122
|
+
|
|
123
|
+
**STEPS:**
|
|
124
|
+
|
|
125
|
+
1. **Invoke `prizmkit.tasks`** with plan.md:
|
|
126
|
+
- Each task MUST be independently testable
|
|
127
|
+
- Each task MUST preserve all tests (green → green)
|
|
128
|
+
- Artifact path: `.prizmkit/refactor/<refactor-slug>/tasks.md`
|
|
129
|
+
|
|
130
|
+
2. **Verify task safety**:
|
|
131
|
+
- Every task ends with "run full test suite"
|
|
132
|
+
- No task introduces temporary test failures
|
|
133
|
+
- Tasks are ordered to minimize risk (safe renames first, structural changes later)
|
|
134
|
+
|
|
135
|
+
**CHECKPOINT CP-RW-3**: `tasks.md` exists with test gates on every task.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Phase 4: Implement — 实现
|
|
140
|
+
|
|
141
|
+
**Goal**: Execute refactoring tasks with mandatory test verification after each task.
|
|
142
|
+
|
|
143
|
+
**STEPS:**
|
|
144
|
+
|
|
145
|
+
1. **For EACH task in tasks.md**:
|
|
146
|
+
a. Implement the refactoring change
|
|
147
|
+
b. **Run FULL test suite** (not just affected tests)
|
|
148
|
+
c. Verify: all previously-passing tests still pass
|
|
149
|
+
d. If any test fails → STOP, revert task, investigate
|
|
150
|
+
|
|
151
|
+
2. **Scope Guard** (checked after each task):
|
|
152
|
+
- If implementation reveals need for new behavior → **STOP**
|
|
153
|
+
- Output: "Scope guard triggered: <description of new behavior needed>"
|
|
154
|
+
- Recommend: "Switch to `prizmkit.feature` for this change"
|
|
155
|
+
- Do NOT proceed with behavior changes in refactor pipeline
|
|
156
|
+
|
|
157
|
+
3. **Progress tracking**:
|
|
158
|
+
- Mark tasks complete in tasks.md as they finish
|
|
159
|
+
- Record test results after each task
|
|
160
|
+
|
|
161
|
+
**CHECKPOINT CP-RW-4**: All tasks complete, full test suite green.
|
|
162
|
+
|
|
163
|
+
**KEY RULES:**
|
|
164
|
+
- NEVER skip the test gate between tasks
|
|
165
|
+
- NEVER allow temporary test failures ("we'll fix it in the next task")
|
|
166
|
+
- If a task cannot be completed without breaking tests → split it into smaller tasks
|
|
167
|
+
- Max 3 attempts per task before escalating to user
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Phase 5: Code Review — 代码审查
|
|
172
|
+
|
|
173
|
+
**Goal**: Verify refactoring quality and behavior preservation.
|
|
174
|
+
|
|
175
|
+
**STEPS:**
|
|
176
|
+
|
|
177
|
+
1. **Invoke `prizmkit.code-review`** (scoped to changed files):
|
|
178
|
+
- Review dimensions for refactoring:
|
|
179
|
+
- **Behavior preservation**: Does observable behavior remain identical?
|
|
180
|
+
- **Structural improvement**: Is the code measurably better? (complexity, coupling, readability)
|
|
181
|
+
- **Test integrity**: Are all tests still meaningful and passing?
|
|
182
|
+
- **Code quality**: Does refactored code follow project conventions?
|
|
183
|
+
- Verdict: PASS / PASS_WITH_WARNINGS / NEEDS_FIXES
|
|
184
|
+
|
|
185
|
+
2. **Run full test suite one final time**: All tests MUST pass
|
|
186
|
+
|
|
187
|
+
3. **Handle review results**:
|
|
188
|
+
- **PASS / PASS_WITH_WARNINGS**: Proceed to Phase 6
|
|
189
|
+
- **NEEDS_FIXES**: Return to Phase 4 (max 2 review rounds)
|
|
190
|
+
|
|
191
|
+
**CHECKPOINT CP-RW-5**: Code review passes, all tests green.
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Phase 6: Commit — 提交
|
|
196
|
+
|
|
197
|
+
**Goal**: Commit with refactor convention.
|
|
198
|
+
|
|
199
|
+
**STEPS:**
|
|
200
|
+
|
|
201
|
+
1. **Invoke `prizmkit.committer`**:
|
|
202
|
+
- Commit message: `refactor(<scope>): <description>`
|
|
203
|
+
- Include all refactored code + any test updates
|
|
204
|
+
- Do NOT push
|
|
205
|
+
- Do NOT invoke `prizmkit.summarize` (no REGISTRY entry for refactoring)
|
|
206
|
+
|
|
207
|
+
2. **Update `.prizm-docs/`** if needed:
|
|
208
|
+
- Updated module structure documentation
|
|
209
|
+
- New PATTERNS discovered
|
|
210
|
+
- Resolved TRAPS (remove if debt is paid)
|
|
211
|
+
|
|
212
|
+
**CHECKPOINT CP-RW-6**: Commit recorded with `refactor()` prefix.
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Fast Path — 快速路径
|
|
217
|
+
|
|
218
|
+
For single-file refactoring (rename, extract method, <30 lines changed):
|
|
219
|
+
|
|
220
|
+
```
|
|
221
|
+
Phase 1 (Analyze) → Phase 4 (Implement) → Phase 5 (Review) → Phase 6 (Commit)
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Skip Phase 2 (Plan) and Phase 3 (Tasks).
|
|
225
|
+
|
|
226
|
+
**CRITERIA** (ALL must be true):
|
|
227
|
+
- Single file change
|
|
228
|
+
- Estimated change < 30 lines
|
|
229
|
+
- Well-known refactoring pattern (rename, extract method/class, inline, move)
|
|
230
|
+
- No cross-module impact
|
|
231
|
+
- No dependency changes
|
|
232
|
+
|
|
233
|
+
**Fast Path still requires:**
|
|
234
|
+
- refactor-analysis.md (lightweight version with baseline)
|
|
235
|
+
- Full test suite run after implementation
|
|
236
|
+
- Code review
|
|
237
|
+
- `refactor(<scope>):` commit convention
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## Resume — 中断恢复
|
|
242
|
+
|
|
243
|
+
The pipeline supports resuming from the last completed phase by detecting existing artifacts.
|
|
244
|
+
|
|
245
|
+
**Detection logic**: Check `.prizmkit/refactor/<slug>/` for:
|
|
246
|
+
|
|
247
|
+
| Artifact Found | Resume From |
|
|
248
|
+
|---------------|------------|
|
|
249
|
+
| (nothing) | Phase 1: Analyze |
|
|
250
|
+
| `refactor-analysis.md` only | Phase 2: Plan |
|
|
251
|
+
| `refactor-analysis.md` + `plan.md` | Phase 3: Tasks |
|
|
252
|
+
| All 3 docs | Phase 4: Implement |
|
|
253
|
+
| All 3 docs + code changes exist | Phase 5: Review |
|
|
254
|
+
| All 3 docs + review passed | Phase 6: Commit |
|
|
255
|
+
|
|
256
|
+
**Resume command**: `prizmkit.refactor <slug>` — if `<slug>` matches an existing `.prizmkit/refactor/<slug>/` directory, resume instead of starting fresh.
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## Scope Guard — 范围守卫
|
|
261
|
+
|
|
262
|
+
The scope guard is a critical safety mechanism that prevents behavior changes from sneaking into refactoring.
|
|
263
|
+
|
|
264
|
+
**Triggers:**
|
|
265
|
+
- New public API method or endpoint added
|
|
266
|
+
- New user-facing feature or UI element
|
|
267
|
+
- Changed return values or response formats
|
|
268
|
+
- New configuration options
|
|
269
|
+
- Modified business logic (not just restructured)
|
|
270
|
+
|
|
271
|
+
**When triggered:**
|
|
272
|
+
1. STOP current task immediately
|
|
273
|
+
2. Output clear message: "⚠️ Scope Guard: This change introduces new behavior"
|
|
274
|
+
3. Describe what new behavior was detected
|
|
275
|
+
4. Recommend: "Create a feature request and use `prizmkit.feature` instead"
|
|
276
|
+
5. Offer to continue refactoring WITHOUT the behavior change
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Error Handling
|
|
281
|
+
|
|
282
|
+
| Scenario | Action |
|
|
283
|
+
|----------|--------|
|
|
284
|
+
| Cannot identify target module | Ask user for clarification |
|
|
285
|
+
| No tests exist for target module | WARN user, recommend writing tests first |
|
|
286
|
+
| Baseline tests already failing | Isolate failures, document, proceed with caution |
|
|
287
|
+
| Test fails after a refactoring task | Revert task, investigate, retry or split |
|
|
288
|
+
| Scope guard triggered | STOP, recommend feature-workflow |
|
|
289
|
+
| Implementation fails after 3 rounds | Escalate to user with analysis |
|
|
290
|
+
| Review fails after 2 rounds | Escalate with review findings |
|
|
291
|
+
| Refactoring creates circular dependency | STOP, revise plan |
|
|
292
|
+
| Performance regression detected | STOP, investigate, revise approach |
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## Relationship to Other Skills
|
|
297
|
+
|
|
298
|
+
| Skill | Role in Refactor Workflow |
|
|
299
|
+
|-------|--------------------------|
|
|
300
|
+
| `prizmkit-tech-debt-tracker` | Phase 1: identify debt and complexity |
|
|
301
|
+
| `prizmkit-plan` | Phase 2: refactoring plan generation |
|
|
302
|
+
| `prizmkit-tasks` | Phase 3: task breakdown |
|
|
303
|
+
| `prizmkit-implement` | Phase 4: execute refactoring tasks |
|
|
304
|
+
| `prizmkit-code-review` | Phase 5: review quality and behavior preservation |
|
|
305
|
+
| `prizmkit-committer` | Phase 6: commit with `refactor()` convention |
|
|
306
|
+
| `feature-workflow` | Handoff target when scope guard triggers |
|
|
307
|
+
| `prizmkit-specify` | NOT used (no user stories for refactoring) |
|
|
308
|
+
| `prizmkit-analyze` | NOT used (no spec ↔ plan consistency needed) |
|
|
309
|
+
| `prizmkit-summarize` | NOT used (no REGISTRY entry for refactoring) |
|
|
310
|
+
| `prizmkit-retrospective` | Optional: post-refactor lessons learned |
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## Comparison with Feature and Bug Fix Pipelines
|
|
315
|
+
|
|
316
|
+
| Dimension | Feature Workflow | Refactor Workflow | Bug Fix Pipeline |
|
|
317
|
+
|-----------|-----------------|-------------------|-----------------|
|
|
318
|
+
| Input | Requirement description | Module/code target | Bug description |
|
|
319
|
+
| Pipeline Phases | 7 (Fast: 5) | 6 (Fast: 4) | 5 (Fast: 3) |
|
|
320
|
+
| Phase 1 | Specify (spec.md) | Analyze (refactor-analysis.md) | Triage (fix-plan.md) |
|
|
321
|
+
| Artifact Path | `.prizmkit/specs/<slug>/` | `.prizmkit/refactor/<slug>/` | `.prizmkit/bugfix/<id>/` |
|
|
322
|
+
| Commit Prefix | `feat(<scope>):` | `refactor(<scope>):` | `fix(<scope>):` |
|
|
323
|
+
| REGISTRY Update | ✅ | ❌ | ❌ |
|
|
324
|
+
| Test Strategy | TDD per task | Full suite after EVERY task | Reproduction test |
|
|
325
|
+
| Scope Guard | N/A | ✅ (enforced) | N/A |
|
|
326
|
+
| Behavior Change | ✅ Expected | ❌ Forbidden | ✅ Fix behavior |
|
|
327
|
+
|
|
328
|
+
## Path References
|
|
329
|
+
|
|
330
|
+
All internal asset paths MUST use `${SKILL_DIR}` placeholder for cross-IDE compatibility.
|
|
331
|
+
|
|
332
|
+
## Output
|
|
333
|
+
|
|
334
|
+
- `refactor-analysis.md` (Phase 1 artifact)
|
|
335
|
+
- `plan.md` (Phase 2 artifact)
|
|
336
|
+
- `tasks.md` (Phase 3 artifact)
|
|
337
|
+
- Refactored implementation code (Phase 4)
|
|
338
|
+
- Code review report (Phase 5, conversation only)
|
|
339
|
+
- Git commit with `refactor(<scope>):` prefix (Phase 6)
|
|
340
|
+
- Updated `.prizm-docs/` (if applicable)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"UserPromptSubmit": [
|
|
4
|
+
{
|
|
5
|
+
"matcher": "\\b(commit|Commit|push|Push|finish|Finish|ship|Ship|merge|Merge|pull request|Pull Request|pr|PR)\\b|提交|推送|收尾|完成任务|合并|发版|发布",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "prompt",
|
|
9
|
+
"prompt": "You are a commit-intent detector for PrizmKit. Analyze the user prompt and determine if the user intends to COMMIT, PUSH, FINISH, SHIP, MERGE, or create a PULL REQUEST.\n\nUser prompt: $ARGUMENTS\n\nIF commit intent detected, respond with:\n{\"ok\": true, \"reason\": \"PRIZMKIT_DOC_UPDATE_REQUIRED: Before committing, you MUST update .prizm-docs/ per Prizm auto-update protocol. Steps: 1) Run git diff --cached --name-status. 2) Map changed files to modules via root.prizm MODULE_INDEX. 3) Read and update affected .prizm files (only changed sections). 4) Append to changelog.prizm. 5) Stage .prizm files with git add .prizm-docs/. 6) Then proceed with commit using prizmkit-committer workflow. RULES: Never rewrite entire .prizm files. Never add prose. Only update affected sections.\"}\n\nIF no commit intent, respond with:\n{\"ok\": true}\n\nRespond with JSON only. No explanation.",
|
|
10
|
+
"timeout": 300
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"UserPromptSubmit": [
|
|
4
|
+
{
|
|
5
|
+
"matcher": "(?i)\\b(commit|push|finish|ship|merge|pull request|pr)\\b|提交|推送|收尾|完成任务|合并|发版|发布",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "prompt",
|
|
9
|
+
"prompt": "You are a commit-intent detector for PrizmKit. Analyze the user prompt and determine if the user intends to COMMIT, PUSH, FINISH, SHIP, MERGE, or create a PULL REQUEST.\n\nUser prompt: $ARGUMENTS\n\nIF commit intent detected, respond with:\n{\"ok\": true, \"reason\": \"PRIZMKIT_DOC_UPDATE_REQUIRED: Before committing, you MUST update .prizm-docs/ per Prizm auto-update protocol. Steps: 1) Run git diff --cached --name-status. 2) Map changed files to modules via root.prizm MODULE_INDEX. 3) Read and update affected .prizm files (only changed sections). 4) Append to changelog.prizm. 5) Stage .prizm files with git add .prizm-docs/. 6) Then proceed with commit using prizmkit-committer workflow. RULES: Never rewrite entire .prizm files. Never add prose. Only update affected sections.\"}\n\nIF no commit intent, respond with:\n{\"ok\": true}\n\nRespond with JSON only. No explanation.",
|
|
10
|
+
"timeout": 300
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prizmkit",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "Create a new PrizmKit-powered project with clean initialization — no framework dev files, just what you need.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -21,8 +21,7 @@
|
|
|
21
21
|
"@inquirer/prompts": "^7.0.0",
|
|
22
22
|
"chalk": "^5.3.0",
|
|
23
23
|
"commander": "^12.1.0",
|
|
24
|
-
"fs-extra": "^11.2.0"
|
|
25
|
-
"yaml": "^2.6.0"
|
|
24
|
+
"fs-extra": "^11.2.0"
|
|
26
25
|
},
|
|
27
26
|
"engines": {
|
|
28
27
|
"node": ">=18.0.0"
|
package/src/detect-platform.js
CHANGED
|
@@ -3,14 +3,22 @@
|
|
|
3
3
|
* 检测系统中已安装的 AI CLI 工具。
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { execFileSync } from 'child_process';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 允许检测的命令白名单
|
|
10
|
+
*/
|
|
11
|
+
const ALLOWED_COMMANDS = ['cbc', 'claude'];
|
|
7
12
|
|
|
8
13
|
/**
|
|
9
14
|
* 检查命令是否存在于 PATH 中
|
|
10
15
|
*/
|
|
11
16
|
function commandExists(cmd) {
|
|
17
|
+
if (!ALLOWED_COMMANDS.includes(cmd)) {
|
|
18
|
+
throw new Error(`Unknown command: ${cmd}`);
|
|
19
|
+
}
|
|
12
20
|
try {
|
|
13
|
-
|
|
21
|
+
execFileSync('which', [cmd], { stdio: 'ignore' });
|
|
14
22
|
return true;
|
|
15
23
|
} catch {
|
|
16
24
|
return false;
|
package/src/scaffold.js
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 纯净安装核心逻辑
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* - 自动生成 .gitignore
|
|
4
|
+
* 全部使用 Copy 模式(不使用 symlink),项目完全独立于框架仓库。
|
|
5
|
+
* 通过 adapters 转换 core/ 资源为平台特定格式。
|
|
6
|
+
* 不安装框架开发文件(docs、tests、scripts 等)。
|
|
7
|
+
* 自动生成 .gitignore。
|
|
9
8
|
*/
|
|
10
9
|
|
|
11
10
|
import chalk from 'chalk';
|
|
12
11
|
import fs from 'fs-extra';
|
|
13
12
|
import path from 'path';
|
|
14
|
-
import { fileURLToPath } from 'url';
|
|
15
13
|
import {
|
|
16
14
|
loadMetadata,
|
|
17
15
|
getSkillsDir,
|
|
@@ -24,8 +22,6 @@ import {
|
|
|
24
22
|
} from './metadata.js';
|
|
25
23
|
import { generateGitignore } from './gitignore-template.js';
|
|
26
24
|
|
|
27
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
28
|
-
|
|
29
25
|
// ============================================================
|
|
30
26
|
// Adapter 动态加载
|
|
31
27
|
// ============================================================
|
|
@@ -73,6 +69,13 @@ async function installSkills(platform, skills, projectRoot, dryRun) {
|
|
|
73
69
|
const skillsDir = getSkillsDir();
|
|
74
70
|
const { parseFrontmatter, buildMarkdown } = await loadSharedFrontmatter();
|
|
75
71
|
|
|
72
|
+
// Load Claude command adapter for skill conversion
|
|
73
|
+
let convertSkillToCommand;
|
|
74
|
+
if (platform === 'claude') {
|
|
75
|
+
const commandAdapter = await loadAdapter('claude', 'command-adapter.js');
|
|
76
|
+
convertSkillToCommand = commandAdapter.convertSkillToCommand;
|
|
77
|
+
}
|
|
78
|
+
|
|
76
79
|
for (const skillName of skills) {
|
|
77
80
|
const corePath = path.join(skillsDir, skillName);
|
|
78
81
|
if (!await fs.pathExists(corePath)) continue;
|
|
@@ -111,17 +114,7 @@ async function installSkills(platform, skills, projectRoot, dryRun) {
|
|
|
111
114
|
|
|
112
115
|
} else if (platform === 'claude') {
|
|
113
116
|
const content = await fs.readFile(skillMdPath, 'utf8');
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
// Claude Code 格式转换
|
|
117
|
-
const claudeFm = {
|
|
118
|
-
description: String(frontmatter.description || `PrizmKit ${skillName}`)
|
|
119
|
-
.replace(/prizmkit\.(\w+)/g, (_, sub) => `/prizmkit-${sub.replace(/_/g, '-')}`),
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
let convertedBody = body
|
|
123
|
-
.replace(/\$\{SKILL_DIR\}/g, `.claude/commands/${skillName}`)
|
|
124
|
-
.replace(/prizmkit\.(\w+)/g, (_, sub) => `/prizmkit-${sub.replace(/_/g, '-')}`);
|
|
117
|
+
const converted = convertSkillToCommand(content, skillName);
|
|
125
118
|
|
|
126
119
|
const hasAssets = await fs.pathExists(path.join(corePath, 'assets'));
|
|
127
120
|
const hasScripts = await fs.pathExists(path.join(corePath, 'scripts'));
|
|
@@ -135,7 +128,7 @@ async function installSkills(platform, skills, projectRoot, dryRun) {
|
|
|
135
128
|
await fs.ensureDir(targetDir);
|
|
136
129
|
await fs.writeFile(
|
|
137
130
|
path.join(targetDir, `${skillName}.md`),
|
|
138
|
-
|
|
131
|
+
converted
|
|
139
132
|
);
|
|
140
133
|
for (const subdir of ['assets', 'scripts']) {
|
|
141
134
|
const srcSubdir = path.join(corePath, subdir);
|
|
@@ -153,7 +146,7 @@ async function installSkills(platform, skills, projectRoot, dryRun) {
|
|
|
153
146
|
await fs.ensureDir(targetDir);
|
|
154
147
|
await fs.writeFile(
|
|
155
148
|
path.join(targetDir, `${skillName}.md`),
|
|
156
|
-
|
|
149
|
+
converted
|
|
157
150
|
);
|
|
158
151
|
console.log(chalk.green(` ✓ .claude/commands/${skillName}.md`));
|
|
159
152
|
}
|
|
@@ -166,17 +159,14 @@ async function installSkills(platform, skills, projectRoot, dryRun) {
|
|
|
166
159
|
*/
|
|
167
160
|
async function installAgents(platform, projectRoot, dryRun) {
|
|
168
161
|
const agentsDir = getAgentsDir();
|
|
169
|
-
const { parseFrontmatter, buildMarkdown } = await loadSharedFrontmatter();
|
|
170
162
|
const agentFiles = (await fs.readdir(agentsDir)).filter(f => f.endsWith('.md'));
|
|
171
163
|
|
|
172
|
-
// Claude
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
'
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
'SendMessage': 'SendMessage',
|
|
179
|
-
};
|
|
164
|
+
// Load Claude agent adapter
|
|
165
|
+
let convertAgentFn;
|
|
166
|
+
if (platform === 'claude') {
|
|
167
|
+
const agentAdapter = await loadAdapter('claude', 'agent-adapter.js');
|
|
168
|
+
convertAgentFn = agentAdapter.convertAgent;
|
|
169
|
+
}
|
|
180
170
|
|
|
181
171
|
for (const file of agentFiles) {
|
|
182
172
|
const content = await fs.readFile(path.join(agentsDir, file), 'utf8');
|
|
@@ -192,26 +182,7 @@ async function installAgents(platform, projectRoot, dryRun) {
|
|
|
192
182
|
console.log(chalk.green(` ✓ .codebuddy/agents/${file}`));
|
|
193
183
|
|
|
194
184
|
} else if (platform === 'claude') {
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
// 工具映射
|
|
198
|
-
let tools = [];
|
|
199
|
-
if (frontmatter.tools) {
|
|
200
|
-
const rawTools = frontmatter.tools.split(',').map(t => t.trim());
|
|
201
|
-
const mapped = rawTools.map(t => TOOL_MAPPING[t] || t).filter(Boolean);
|
|
202
|
-
tools = [...new Set(mapped)];
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// 转换 body 中的命令引用
|
|
206
|
-
let convertedBody = body
|
|
207
|
-
.replace(/prizmkit\.(\w+)/g, (_, sub) => `/prizmkit-${sub.replace(/_/g, '-')}`);
|
|
208
|
-
|
|
209
|
-
const claudeFm = {
|
|
210
|
-
name: frontmatter.name,
|
|
211
|
-
description: frontmatter.description,
|
|
212
|
-
tools: tools,
|
|
213
|
-
model: 'inherit',
|
|
214
|
-
};
|
|
185
|
+
const converted = convertAgentFn(content, { model: 'inherit' });
|
|
215
186
|
|
|
216
187
|
const targetDir = path.join(projectRoot, '.claude', 'agents');
|
|
217
188
|
if (dryRun) {
|
|
@@ -219,7 +190,7 @@ async function installAgents(platform, projectRoot, dryRun) {
|
|
|
219
190
|
continue;
|
|
220
191
|
}
|
|
221
192
|
await fs.ensureDir(targetDir);
|
|
222
|
-
await fs.writeFile(path.join(targetDir, file),
|
|
193
|
+
await fs.writeFile(path.join(targetDir, file), converted);
|
|
223
194
|
console.log(chalk.green(` ✓ .claude/agents/${file}`));
|
|
224
195
|
}
|
|
225
196
|
}
|
|
@@ -331,23 +302,11 @@ async function installSettings(platform, projectRoot, options, dryRun) {
|
|
|
331
302
|
|
|
332
303
|
await fs.ensureDir(path.dirname(settingsPath));
|
|
333
304
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
{
|
|
338
|
-
matcher: '(?i)\\b(commit|push|finish|ship|merge|pull request|pr)\\b|提交|推送|收尾|完成任务|合并|发版|发布',
|
|
339
|
-
hooks: [
|
|
340
|
-
{
|
|
341
|
-
type: 'prompt',
|
|
342
|
-
prompt: 'You are a commit-intent detector for PrizmKit. Analyze the user prompt and determine if the user intends to COMMIT, PUSH, FINISH, SHIP, MERGE, or create a PULL REQUEST.\n\nUser prompt: $ARGUMENTS\n\nIF commit intent detected, respond with:\n{"ok": true, "reason": "PRIZMKIT_DOC_UPDATE_REQUIRED: Before committing, you MUST update .prizm-docs/ per Prizm auto-update protocol. Steps: 1) Run git diff --cached --name-status. 2) Map changed files to modules via root.prizm MODULE_INDEX. 3) Read and update affected .prizm files (only changed sections). 4) Append to changelog.prizm. 5) Stage .prizm files with git add .prizm-docs/. 6) Then proceed with commit using prizmkit-committer workflow. RULES: Never rewrite entire .prizm files. Never add prose. Only update affected sections."}\n\nIF no commit intent, respond with:\n{"ok": true}\n\nRespond with JSON only. No explanation.',
|
|
343
|
-
},
|
|
344
|
-
],
|
|
345
|
-
},
|
|
346
|
-
],
|
|
347
|
-
},
|
|
348
|
-
};
|
|
305
|
+
// Read hook definition from unified template
|
|
306
|
+
const templatesDir = getTemplatesDir();
|
|
307
|
+
const hookTemplate = await fs.readJSON(path.join(templatesDir, 'hooks', 'commit-intent-codebuddy.json'));
|
|
349
308
|
|
|
350
|
-
await fs.writeFile(settingsPath, JSON.stringify(
|
|
309
|
+
await fs.writeFile(settingsPath, JSON.stringify(hookTemplate, null, 2));
|
|
351
310
|
console.log(chalk.green(` ✓ .codebuddy/settings.json`));
|
|
352
311
|
|
|
353
312
|
} else if (platform === 'claude') {
|
|
@@ -361,19 +320,28 @@ async function installSettings(platform, projectRoot, options, dryRun) {
|
|
|
361
320
|
|
|
362
321
|
await fs.ensureDir(claudeDir);
|
|
363
322
|
|
|
323
|
+
// Read hook definition from unified template
|
|
324
|
+
const templatesDir = getTemplatesDir();
|
|
325
|
+
const hookTemplate = await fs.readJSON(path.join(templatesDir, 'hooks', 'commit-intent-claude.json'));
|
|
326
|
+
|
|
364
327
|
// Settings
|
|
365
328
|
const permissions = [
|
|
366
|
-
'Bash(python3
|
|
367
|
-
'Bash(git *)',
|
|
329
|
+
'Bash(python3 dev-pipeline/scripts/*)',
|
|
330
|
+
'Bash(git add *)',
|
|
331
|
+
'Bash(git commit *)',
|
|
332
|
+
'Bash(git diff *)',
|
|
333
|
+
'Bash(git status)',
|
|
334
|
+
'Bash(git log *)',
|
|
368
335
|
'Bash(jq *)',
|
|
369
336
|
];
|
|
370
337
|
if (options.pipeline) {
|
|
371
|
-
permissions.push('Bash(./dev-pipeline
|
|
338
|
+
permissions.push('Bash(./dev-pipeline/run.sh *)', 'Bash(./dev-pipeline/launch-daemon.sh *)');
|
|
372
339
|
}
|
|
373
340
|
|
|
374
341
|
const settings = {
|
|
375
342
|
permissions: { allow: permissions },
|
|
376
343
|
hooks: {
|
|
344
|
+
...hookTemplate.hooks,
|
|
377
345
|
SessionStart: [
|
|
378
346
|
{
|
|
379
347
|
matcher: 'startup',
|