prizmkit 1.0.135 → 1.0.137

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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "frameworkVersion": "1.0.135",
3
- "bundledAt": "2026-03-28T13:09:04.448Z",
4
- "bundledFrom": "661d63b"
2
+ "frameworkVersion": "1.0.137",
3
+ "bundledAt": "2026-03-28T13:49:17.127Z",
4
+ "bundledFrom": "1cfc8e2"
5
5
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.0.135",
2
+ "version": "1.0.137",
3
3
  "skills": {
4
4
  "prizm-kit": {
5
5
  "description": "Full-lifecycle dev toolkit. Covers spec-driven development, Prizm context docs, code quality, debugging, deployment, and knowledge management.",
@@ -153,6 +153,7 @@ Execute the selected scenario workflow in conversation mode with mandatory check
153
153
  3. propose feature set with dependencies
154
154
  4. refine descriptions and acceptance criteria
155
155
  4.1 **per-feature clarification** — for each feature, if the description, acceptance criteria, or scope is vague or could be interpreted multiple ways, ask the user to clarify before finalizing. Continue until every feature has unambiguous, implementation-ready details.
156
+ 4.2 **browser interaction evaluation** (mandatory for fullstack/frontend projects) — see §Browser Interaction Planning below. For each feature with UI-related acceptance criteria, you MUST ask the user whether to add `browser_interaction`. Do NOT skip or defer this step.
156
157
  5. verify DAG/order/priorities
157
158
  6. build or append `feature-list.json`
158
159
  7. ask whether to enable adversarial critic review for high/critical features
@@ -169,6 +170,7 @@ Checkpoints catch cascading errors early — skipping one means the next phase b
169
170
  | **CP-AP-1** | Vision Summary | Goal/users/differentiators confirmed by user | 1-2 |
170
171
  | **CP-AP-2** | Feature Proposals | Feature set with titles+deps identified (pre-validation) | 3-5 |
171
172
  | **CP-AP-3** | DAG Validity | No cycles, dependencies resolved (validation dry-run) | 6 |
173
+ | **CP-AP-3.2** | Browser Interaction Evaluated | For each feature with UI acceptance criteria: user was asked about browser verification | 4 |
172
174
  | **CP-AP-3.5** | Critic Decision | User decided on critic review for high/critical features | 7 |
173
175
  | **CP-AP-4** | `feature-list.json` Generated | Schema validates, all required keys present | 6-7 |
174
176
  | **CP-AP-5** | Final Validation Pass | Python script returns `"valid": true` with zero errors | 8 |
@@ -222,13 +224,34 @@ AI: "Ready to proceed to dev-pipeline."
222
224
 
223
225
  ## Browser Interaction Planning
224
226
 
225
- For features with user-visible UI (pages, forms, modals), optionally add `browser_interaction` for automated playwright-cli verification in the pipeline.
227
+ For fullstack/frontend projects, evaluate each feature for automated browser verification via `browser_interaction`. This is a **mandatory evaluation step** (Phase 4.2), not an optional suggestion.
226
228
 
227
- **Suggest when**: web frontend + user-visible UI + acceptance criteria reference visual/interactive behavior.
228
- **Do NOT suggest for**: backend-only, config/setup, or non-UI features.
229
+ ### Auto-Detection Rule
229
230
 
230
- During Phase 4, ask qualifying features: "Want to add browser verification? (Y/n)"
231
- If yes → read `references/browser-interaction.md` for the `browser_interaction` object format and field rules.
231
+ A feature **qualifies** for browser interaction evaluation when ALL of these are true:
232
+ 1. `global_context.frontend_framework` exists (project has a frontend)
233
+ 2. The feature's `acceptance_criteria` contain UI-related keywords: click, button, modal, page, form, display, navigate, tab, input, opens, shows, renders, visible, redirect, download, upload, preview, select, toggle, dropdown, popup, toast, menu
234
+
235
+ A feature is **exempt** when ANY of these are true:
236
+ - It is backend-only (API endpoints, database migrations, no UI criteria)
237
+ - It is config/setup/infrastructure
238
+ - It has `status: "completed"` (already implemented)
239
+
240
+ ### Mandatory Prompt (Phase 4.2)
241
+
242
+ For EACH qualifying feature, you MUST ask:
243
+
244
+ > "Feature {F-XXX} has UI behavior in its acceptance criteria. Add browser verification so the pipeline can auto-check it after implementation? (Y/n)"
245
+
246
+ - If **yes** → read `references/browser-interaction.md` for the `browser_interaction` object format and field rules. Generate the field for this feature.
247
+ - If **no** → record the decision and move on. No field is added.
248
+ - If **user says no to all** → skip remaining features (batch decline). Record that user declined browser verification globally.
249
+
250
+ **You must NOT skip this prompt for qualifying features.** The checkpoint CP-AP-3.2 verifies this step was completed.
251
+
252
+ ### When NOT to evaluate
253
+
254
+ **Do NOT prompt for**: backend-only features, config/setup features, or non-UI features. These are automatically exempt — no user prompt needed.
232
255
 
233
256
  ## Output Rules
234
257
 
@@ -41,6 +41,14 @@ VALID_PLANNING_MODES = {"new", "incremental"}
41
41
  FEATURE_ID_RE = re.compile(r"^F-\d{3}(-[A-Z])?$")
42
42
  SUB_FEATURE_ID_RE = re.compile(r"^F-\d{3}-[A-Z]$")
43
43
 
44
+ # Keywords in acceptance criteria that indicate UI/browser interaction behavior.
45
+ UI_KEYWORDS_RE = re.compile(
46
+ r"\b(click|button|modal|page|form|display|navigate|tab|input|opens|shows|"
47
+ r"renders|visible|redirect|download|upload|preview|select|toggle|dropdown|"
48
+ r"popup|toast|menu)\b",
49
+ re.IGNORECASE,
50
+ )
51
+
44
52
  # ---------------------------------------------------------------------------
45
53
  # Helpers
46
54
  # ---------------------------------------------------------------------------
@@ -333,6 +341,23 @@ def validate_feature_list(data, planning_mode="new"):
333
341
  errors.append(
334
342
  "{}: 'critic_count' must be 1 or 3, got {}".format(label, critic_count)
335
343
  )
344
+
345
+ # -- Browser interaction check (warning for frontend features) --
346
+ has_frontend = bool(
347
+ data.get("global_context", {}).get("frontend_framework")
348
+ )
349
+ if has_frontend and feat.get("status") != "completed":
350
+ criteria = feat.get("acceptance_criteria", [])
351
+ criteria_text = " ".join(
352
+ c for c in criteria if isinstance(c, str)
353
+ )
354
+ if UI_KEYWORDS_RE.search(criteria_text):
355
+ if feat.get("browser_interaction") is None:
356
+ warnings.append(
357
+ "{}: has UI acceptance criteria but no browser_interaction "
358
+ "field. Consider adding browser verification.".format(label)
359
+ )
360
+
336
361
  if isinstance(subs, list):
337
362
  for sidx, sub in enumerate(subs):
338
363
  sub_label = "{}->sub_features[{}]".format(label, sidx)
@@ -9,16 +9,11 @@ Launch the autonomous bug fix pipeline from within an AI CLI conversation. Suppo
9
9
 
10
10
  ### Execution Mode
11
11
 
12
- **Default: Foreground mode** via `dev-pipeline/run-bugfix.sh run` this provides visible output and direct error feedback. Use `launch-bugfix-daemon.sh` only when the user explicitly requests background execution.
12
+ Three execution modes are available. The user chooses one before configuring other options:
13
13
 
14
- Foreground `run-bugfix.sh` is preferred because:
15
- - Immediate visibility of errors and progress
16
- - No orphaned processes if something goes wrong
17
- - Session summary artifacts are written reliably
18
-
19
- Use daemon mode (`launch-bugfix-daemon.sh`) only when:
20
- - User explicitly requests background/detached execution
21
- - Pipeline must survive AI CLI session closure
14
+ 1. **Foreground** (recommended) — `dev-pipeline/run-bugfix.sh run`. Visible output, direct error feedback, no orphaned processes.
15
+ 2. **Background daemon** — `dev-pipeline/launch-bugfix-daemon.sh`. Runs fully detached, survives AI CLI session closure.
16
+ 3. **Manual** Display the assembled command(s) only. Do not execute anything. User runs them on their own.
22
17
 
23
18
  **Background mode documentation**: When the user chooses background/daemon mode, record the choice and PID in `.prizmkit/bugfix-pipeline-run.log` (append-only) with timestamp, so the decision is traceable:
24
19
  ```
@@ -111,19 +106,25 @@ Detect user intent from their message, then follow the corresponding workflow:
111
106
  --action status 2>/dev/null
112
107
  ```
113
108
 
114
- 4. **Present all runtime options**: Show the user a complete options summary before launching. Present each option with its default, so the user can confirm or override.
109
+ 4. **Ask execution mode** (first user decision):
110
+
111
+ Present the three modes and ask the user to choose:
112
+ - **(1) Foreground** (recommended) — pipeline runs in the current session via `run-bugfix.sh run`. Visible output and direct error feedback.
113
+ - **(2) Background daemon** — pipeline runs fully detached via `launch-bugfix-daemon.sh`. Survives AI CLI session closure.
114
+ - **(3) Manual** — display the final assembled commands only. Do not execute anything. User runs them on their own.
115
115
 
116
- **Runtime Options:**
116
+ 5. **Present configuration options**: After execution mode is chosen, show the remaining options with defaults. Ask the user to confirm or override.
117
+
118
+ **Configuration Options:**
117
119
 
118
120
  | Option | Default | Description |
119
121
  |--------|---------|-------------|
120
- | **Execution mode** | Foreground | (1) Foreground — visible output (2) Background daemon — survives session closure (3) Manual — show commands only |
121
122
  | **Verbose logging** | On | Detailed AI session logs including tool calls and subagent activity |
122
123
  | **Max retries** | 3 | Max retry attempts per failed bug |
123
124
  | **Session timeout** | None | Per-bug timeout in seconds (e.g. `3600` = 1 hour) |
124
125
  | **Bug filter** | All | Run specific bugs: `B-001:B-005` (range), `B-001,B-003` (list), or mixed `B-001,B-005:B-010` |
125
126
 
126
- Default to Foreground + Verbose On if user doesn't specify.
127
+ Default Verbose On.
127
128
 
128
129
  **Environment variable mapping** (for natural language → env var translation):
129
130
 
@@ -136,19 +137,18 @@ Detect user intent from their message, then follow the corresponding workflow:
136
137
 
137
138
  Example presentation to user:
138
139
  ```
139
- Bugfix pipeline will process N bugs with these settings:
140
- - Execution: Foreground (recommended)
140
+ Bugfix pipeline will process N bugs in Foreground mode:
141
141
  - Verbose: On (subagent detection enabled)
142
142
  - Max retries: 3
143
143
  - Timeout: none
144
144
  - Bugs: all (by severity order)
145
145
 
146
- Want to change any options, or launch with these defaults?
146
+ Want to change any options, or proceed with these defaults?
147
147
  ```
148
148
 
149
- **Execution mode details:**
149
+ 6. **Show final command**: Assemble the complete command from execution mode + confirmed configuration, and present it to the user.
150
150
 
151
- **Foreground (recommended)**: Pipeline runs in the current session via `run-bugfix.sh run`. Provides visible output and direct error feedback.
151
+ **Foreground command:**
152
152
  ```bash
153
153
  VERBOSE=1 dev-pipeline/run-bugfix.sh run bug-fix-list.json
154
154
  ```
@@ -158,7 +158,7 @@ Detect user intent from their message, then follow the corresponding workflow:
158
158
  dev-pipeline/run-bugfix.sh run bug-fix-list.json
159
159
  ```
160
160
 
161
- **Background daemon**: Pipeline runs fully detached via `launch-bugfix-daemon.sh`. Survives session closure. Use only when user explicitly requests background execution.
161
+ **Background daemon command:**
162
162
  ```bash
163
163
  dev-pipeline/launch-bugfix-daemon.sh start bug-fix-list.json --env "VERBOSE=1"
164
164
  ```
@@ -168,9 +168,9 @@ Detect user intent from their message, then follow the corresponding workflow:
168
168
  --env "VERBOSE=1 MAX_RETRIES=5"
169
169
  ```
170
170
 
171
- **Manual — show commands**: Display the exact commands the user can run themselves. Print commands and stop. Do not execute anything.
171
+ **Manual mode**: Print the assembled command(s) and **stop here**. Do not execute anything. Do not proceed to step 7.
172
172
  ```
173
- # To run in foreground (recommended):
173
+ # To run in foreground:
174
174
  VERBOSE=1 dev-pipeline/run-bugfix.sh run bug-fix-list.json
175
175
 
176
176
  # To run in background (detached):
@@ -180,11 +180,13 @@ Detect user intent from their message, then follow the corresponding workflow:
180
180
  dev-pipeline/run-bugfix.sh status bug-fix-list.json
181
181
  ```
182
182
 
183
- 5. **Ask user to confirm**: "Ready to launch the bugfix pipeline with the above settings?"
183
+ 7. **Confirm and launch** (Foreground and Background only Manual mode ends at step 6):
184
+
185
+ Ask: "Ready to launch the bugfix pipeline with the above command?"
184
186
 
185
- 6. **Launch** with the assembled command from step 4.
187
+ After user confirms, execute the command from step 6.
186
188
 
187
- 7. **Post-launch** (depends on execution mode):
189
+ 8. **Post-launch** (depends on execution mode):
188
190
 
189
191
  **If foreground**: Pipeline runs to completion in the terminal. After it finishes:
190
192
  - Summarize results: total bugs, fixed, failed, skipped
@@ -9,16 +9,11 @@ Launch the autonomous development pipeline from within an AI CLI conversation. T
9
9
 
10
10
  ### Execution Mode
11
11
 
12
- **Default: Foreground mode** via `dev-pipeline/run.sh run` — this provides visible output and direct error feedback. Use `launch-daemon.sh` only when the user explicitly requests background execution (e.g., "run in background", "detached mode").
12
+ Three execution modes are available. The user chooses one before configuring other options:
13
13
 
14
- Foreground `run.sh` is preferred because:
15
- - Immediate visibility of errors and progress
16
- - No orphaned processes if something goes wrong
17
- - Session summary artifacts are written reliably
18
-
19
- Use daemon mode (`launch-daemon.sh`) only when:
20
- - User explicitly requests background/detached execution
21
- - Pipeline must survive AI CLI session closure
14
+ 1. **Foreground** (recommended) — `dev-pipeline/run.sh run`. Visible output, direct error feedback, no orphaned processes.
15
+ 2. **Background daemon** — `dev-pipeline/launch-daemon.sh`. Runs fully detached, survives AI CLI session closure.
16
+ 3. **Manual** Display the assembled command(s) only. Do not execute anything. User runs them on their own.
22
17
 
23
18
  ### When to Use
24
19
 
@@ -108,13 +103,19 @@ Detect user intent from their message, then follow the corresponding workflow:
108
103
  --action status 2>/dev/null
109
104
  ```
110
105
 
111
- 4. **Present all runtime options**: Show the user a complete options summary before launching. Present each option with its default, so the user can confirm or override.
106
+ 4. **Ask execution mode** (first user decision):
107
+
108
+ Present the three modes and ask the user to choose:
109
+ - **(1) Foreground** (recommended) — pipeline runs in the current session via `run.sh run`. Visible output and direct error feedback.
110
+ - **(2) Background daemon** — pipeline runs fully detached via `launch-daemon.sh`. Survives AI CLI session closure.
111
+ - **(3) Manual** — display the final assembled commands only. Do not execute anything. User runs them on their own.
112
112
 
113
- **Runtime Options:**
113
+ 5. **Present configuration options**: After execution mode is chosen, show the remaining options with defaults. Ask the user to confirm or override.
114
+
115
+ **Configuration Options:**
114
116
 
115
117
  | Option | Default | Description |
116
118
  |--------|---------|-------------|
117
- | **Execution mode** | Foreground | (1) Foreground — visible output (2) Background daemon — survives session closure (3) Manual — show commands only |
118
119
  | **Critic review** | Off | Adversarial review after planning & implementation. Increases time ~5-10 min/feature |
119
120
  | **Verbose logging** | On | Detailed AI session logs including tool calls and subagent activity |
120
121
  | **Max retries** | 3 | Max retry attempts per failed feature |
@@ -122,7 +123,7 @@ Detect user intent from their message, then follow the corresponding workflow:
122
123
  | **Feature filter** | All | Run specific features: `F-001:F-005` (range), `F-001,F-003` (list), or mixed `F-001,F-005:F-010` |
123
124
  | **Browser verify** | Auto | Run playwright-cli verification for features with `browser_interaction`. Auto = run if playwright-cli installed and features have the field |
124
125
 
125
- Default to Foreground + Verbose On if user doesn't specify. Default Critic to Off unless features have `estimated_complexity: "high"` or above.
126
+ Default Verbose On. Default Critic to Off unless features have `estimated_complexity: "high"` or above.
126
127
 
127
128
  **Environment variable mapping** (for natural language → env var translation):
128
129
 
@@ -138,20 +139,19 @@ Detect user intent from their message, then follow the corresponding workflow:
138
139
 
139
140
  Example presentation to user:
140
141
  ```
141
- Pipeline will process N features with these settings:
142
- - Execution: Foreground (recommended)
142
+ Pipeline will process N features in Foreground mode:
143
143
  - Critic: Off
144
144
  - Verbose: On (subagent detection enabled)
145
145
  - Max retries: 3
146
146
  - Timeout: none
147
147
  - Features: all
148
148
 
149
- Want to change any options, or launch with these defaults?
149
+ Want to change any options, or proceed with these defaults?
150
150
  ```
151
151
 
152
- **Execution mode details:**
152
+ 6. **Show final command**: Assemble the complete command from execution mode + confirmed configuration, and present it to the user.
153
153
 
154
- **Foreground (recommended)**: Pipeline runs in the current session via `run.sh run`. Provides visible output and direct error feedback.
154
+ **Foreground command:**
155
155
  ```bash
156
156
  VERBOSE=1 dev-pipeline/run.sh run feature-list.json
157
157
  ```
@@ -161,7 +161,7 @@ Detect user intent from their message, then follow the corresponding workflow:
161
161
  dev-pipeline/run.sh run feature-list.json --features F-001:F-005
162
162
  ```
163
163
 
164
- **Background daemon**: Pipeline runs fully detached via `launch-daemon.sh`. Survives session closure. Use only when user explicitly requests background execution.
164
+ **Background daemon command:**
165
165
  ```bash
166
166
  dev-pipeline/launch-daemon.sh start feature-list.json --env "VERBOSE=1"
167
167
  ```
@@ -171,9 +171,9 @@ Detect user intent from their message, then follow the corresponding workflow:
171
171
  --env "VERBOSE=1 ENABLE_CRITIC=true MAX_RETRIES=5"
172
172
  ```
173
173
 
174
- **Manual — show commands**: Display the exact commands the user can run themselves. Print commands and stop. Do not execute anything.
174
+ **Manual mode**: Print the assembled command(s) and **stop here**. Do not execute anything. Do not proceed to step 7.
175
175
  ```
176
- # To run in foreground (recommended):
176
+ # To run in foreground:
177
177
  VERBOSE=1 dev-pipeline/run.sh run feature-list.json
178
178
 
179
179
  # To run in background (detached):
@@ -183,11 +183,13 @@ Detect user intent from their message, then follow the corresponding workflow:
183
183
  dev-pipeline/run.sh status feature-list.json
184
184
  ```
185
185
 
186
- 5. **Ask user to confirm**: "Ready to launch the pipeline with the above settings?"
186
+ 7. **Confirm and launch** (Foreground and Background only Manual mode ends at step 6):
187
+
188
+ Ask: "Ready to launch the pipeline with the above command?"
187
189
 
188
- 6. **Launch** with the assembled command from step 4.
190
+ After user confirms, execute the command from step 6.
189
191
 
190
- 7. **Post-launch** (depends on execution mode):
192
+ 8. **Post-launch** (depends on execution mode):
191
193
 
192
194
  **If foreground**: Pipeline runs to completion in the terminal. After it finishes:
193
195
  - Summarize results: total features, succeeded, failed, skipped
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prizmkit",
3
- "version": "1.0.135",
3
+ "version": "1.0.137",
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": {
package/src/manifest.js CHANGED
@@ -55,6 +55,7 @@ export async function writeManifest(projectRoot, data) {
55
55
  * @param {boolean} params.team - whether team config was installed
56
56
  * @param {string} [params.aiCli] - AI CLI command
57
57
  * @param {string} [params.rulesPreset] - rules preset name
58
+ * @param {string[]} [params.extras] - installed extras (e.g. ['playwright-cli'])
58
59
  * @returns {Object} manifest
59
60
  */
60
61
  export function buildManifest({
@@ -68,6 +69,7 @@ export function buildManifest({
68
69
  team,
69
70
  aiCli,
70
71
  rulesPreset,
72
+ extras,
71
73
  }) {
72
74
  const now = new Date().toISOString();
73
75
  return {
@@ -87,6 +89,7 @@ export function buildManifest({
87
89
  agents: [...agents],
88
90
  rules: [...rules],
89
91
  pipeline: pipeline ? [...pipeline] : [],
92
+ extras: extras ? [...extras] : [],
90
93
  other: [platform === 'claude' ? 'CLAUDE.md' : platform === 'codebuddy' ? 'CODEBUDDY.md' : 'CLAUDE.md'],
91
94
  },
92
95
  };
package/src/scaffold.js CHANGED
@@ -676,6 +676,7 @@ export async function installPipeline(projectRoot, dryRun, { forceOverwrite = fa
676
676
  */
677
677
  export async function installGitignore(projectRoot, options, dryRun) {
678
678
  const targetPath = path.join(projectRoot, '.gitignore');
679
+ const templateContent = generateGitignore({ pipeline: options.pipeline });
679
680
 
680
681
  if (dryRun) {
681
682
  console.log(chalk.gray(` [dry-run] .gitignore`));
@@ -683,12 +684,22 @@ export async function installGitignore(projectRoot, options, dryRun) {
683
684
  }
684
685
 
685
686
  if (await fs.pathExists(targetPath)) {
686
- console.log(chalk.yellow(` ⚠ .gitignore 已存在,跳过`));
687
- return;
687
+ // 合并模式:追加缺失条目
688
+ const existing = await fs.readFile(targetPath, 'utf-8');
689
+ const existingLines = new Set(existing.split('\n').map(l => l.trim()));
690
+ const templateLines = templateContent.split('\n').map(l => l.trim()).filter(Boolean);
691
+ const missing = templateLines.filter(line => !existingLines.has(line) && !line.startsWith('#'));
692
+
693
+ if (missing.length > 0) {
694
+ const separator = existing.endsWith('\n') ? '' : '\n';
695
+ await fs.appendFile(targetPath, separator + '\n# PrizmKit\n' + missing.join('\n') + '\n');
696
+ console.log(chalk.green(` ✓ .gitignore (added ${missing.length} entries)`));
697
+ } else {
698
+ console.log(chalk.green(' ✓ .gitignore (up-to-date)'));
699
+ }
688
700
  } else {
689
- const content = generateGitignore({ pipeline: options.pipeline });
690
- await fs.writeFile(targetPath, content);
691
- console.log(chalk.green(` ✓ .gitignore`));
701
+ await fs.writeFile(targetPath, templateContent);
702
+ console.log(chalk.green(' ✓ .gitignore'));
692
703
  }
693
704
  }
694
705
 
@@ -733,6 +744,21 @@ export async function installPlaywrightCli(projectRoot, dryRun) {
733
744
  }
734
745
  }
735
746
 
747
+ // ============================================================
748
+ // Extras 注册表
749
+ // ============================================================
750
+
751
+ /**
752
+ * 外部工具注册表。upgrade.js 遍历此表来安装/更新外部工具。
753
+ * 新增工具只需:1) 写 installXxx 函数 2) 加一行到此表
754
+ */
755
+ export const EXTRAS_REGISTRY = {
756
+ 'playwright-cli': {
757
+ label: '浏览器交互工具',
758
+ install: installPlaywrightCli,
759
+ },
760
+ };
761
+
736
762
  // ============================================================
737
763
  // 主安装函数
738
764
  // ============================================================
@@ -846,9 +872,11 @@ export async function scaffold(config) {
846
872
  }
847
873
  }
848
874
 
849
- // 10. Playwright CLI (optional)
875
+ // 10. Extras (external tools via registry)
876
+ const activeExtras = [];
850
877
  if (playwrightCli) {
851
- console.log(chalk.blue(' 浏览器交互工具:'));
878
+ activeExtras.push('playwright-cli');
879
+ console.log(chalk.blue(` ${EXTRAS_REGISTRY['playwright-cli'].label}:`));
852
880
  await installPlaywrightCli(projectRoot, dryRun);
853
881
  console.log('');
854
882
  }
@@ -894,6 +922,7 @@ export async function scaffold(config) {
894
922
  team,
895
923
  aiCli,
896
924
  rulesPreset: rulesPresetName,
925
+ extras: activeExtras,
897
926
  });
898
927
  await writeManifest(projectRoot, manifest);
899
928
  console.log(chalk.green(' ✓ .prizmkit/manifest.json'));
package/src/upgrade.js CHANGED
@@ -30,6 +30,7 @@ import {
30
30
  installGitignore,
31
31
  installProjectMemory,
32
32
  resolvePipelineFileList,
33
+ EXTRAS_REGISTRY,
33
34
  } from './scaffold.js';
34
35
 
35
36
  const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -244,6 +245,13 @@ export async function runUpgrade(directory, options = {}) {
244
245
  // Resolve pipeline file list from source (for manifest diff)
245
246
  const newPipelineFiles = pipeline ? resolvePipelineFileList() : [];
246
247
 
248
+ // Resolve extras: merge old manifest extras + default extras for old manifests without the field
249
+ const extrasToInstall = [...new Set([
250
+ ...(oldManifest?.files?.extras || []),
251
+ // Old manifests without extras field: default to all registered extras
252
+ ...(!oldManifest?.files?.extras ? Object.keys(EXTRAS_REGISTRY) : []),
253
+ ])].filter(name => EXTRAS_REGISTRY[name]); // only keep extras that still exist in registry
254
+
247
255
  // 4. Build new manifest and compute diff
248
256
  const newManifest = buildManifest({
249
257
  version: pkg.version,
@@ -256,6 +264,7 @@ export async function runUpgrade(directory, options = {}) {
256
264
  team,
257
265
  aiCli,
258
266
  rulesPreset,
267
+ extras: extrasToInstall,
259
268
  });
260
269
 
261
270
  // Preserve original installedAt
@@ -360,6 +369,17 @@ export async function runUpgrade(directory, options = {}) {
360
369
  console.log('');
361
370
  }
362
371
 
372
+ // Extras (external tools via registry)
373
+ if (extrasToInstall.length > 0) {
374
+ for (const extraName of extrasToInstall) {
375
+ const entry = EXTRAS_REGISTRY[extraName];
376
+ if (!entry) continue;
377
+ console.log(chalk.blue(` ${entry.label}:`));
378
+ await entry.install(projectRoot, dryRun);
379
+ console.log('');
380
+ }
381
+ }
382
+
363
383
  // Git hook
364
384
  console.log(chalk.blue(' Git Hook:'));
365
385
  await installGitHook(projectRoot, dryRun);