@avesta-hq/prevention 0.6.0-pre.21 → 0.6.0-pre.23

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.
@@ -16,4 +16,4 @@ If `success` is false: Display the `error` to the user and stop.
16
16
  Show the result to the user:
17
17
  - Project type
18
18
  - Whether it needs scaffolding (`needs_scaffold`)
19
- - Next step from `next_step` field: if "scaffold" → tell user to run `/avesta-scaffold`, if "vision" tell user to run `/avesta-vision`
19
+ - Next step: tell user to run `/avesta-vision` to define what they're building.
@@ -7,21 +7,18 @@ Call `avesta_dispatch(user_input="$ARGUMENTS", current_command="scaffold")`.
7
7
 
8
8
  If `gate_check.allowed` is false: Display the `error_message` to the user and stop.
9
9
 
10
- ## Feature name
11
-
12
- Use `AskUserQuestion` to ask: "What is the main thing your app does? This becomes your first feature folder (e.g. 'todo', 'identity', 'catalog'). Use a short, lowercase, singular noun."
13
-
14
- Wait for the answer. Store it as `feature_name`.
15
-
16
10
  ## Spawn
17
11
 
18
- Use the **Agent tool** with `subagent_type: "avesta-scaffolder"` and the following promptsubstituting actual values for `[project_type]` and `[feature_name]`:
12
+ Do NOT ask the user for a feature name. The scaffolder agent derives it automatically from `.avesta/docs/user-story-map/story-map.html` (rendered by `/avesta-shape` Step 6) first MVP story text, falling back to the product name from `<h1><em>` or `<title>`.
13
+
14
+ Use the **Agent tool** with `subagent_type: "avesta-scaffolder"` and the following prompt — substituting the actual value for `[project_type]`:
19
15
 
20
16
  ```
21
17
  IMPORTANT: Your FIRST action must be to call avesta_get_prompt("scaffolder") with context {project_type: "[project_type from dispatch]"} to load your full instructions. Then call avesta_load_skill for EVERY skill in skills_to_load before doing anything else. Read the checkpoint manifest via avesta_get_checkpoint_manifest() and resume from the next un-advanced checkpoint — do not re-ask questions whose answers were already captured.
22
18
 
19
+ When you call avesta_scaffold, omit the feature_name parameter — the tool resolves it from .avesta/docs/user-story-map/story-map.html and returns the resolved value in feature_name with feature_name_source. If the tool errors because the HTML is missing, surface the error and tell the user to run /avesta-shape to completion before scaffolding. Do NOT ask the user for a feature name and do NOT volunteer example names.
20
+
23
21
  User request: $ARGUMENTS
24
- Feature name: [feature_name]
25
22
  Dispatch result: [full dispatch response]
26
23
  ```
27
24
 
package/bin/lib/init.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
3
  const { COMMANDS_DIR, AGENTS_DIR, AVESTA_DIR, GITHUB_RELEASES_REPO, copyDir, downloadBinary, getVersion } = require('./utils');
4
- const { configureMcpServer, configureSessionStartHook, configureEnforcementHooks, configurePermissions, configureStatusLine, ensureClaudeMdSection } = require('./settings');
4
+ const { configureMcpServer, configureSessionStartHook, configureEnforcementHooks, configurePermissions, configureLocalPermissions, configureLocalFastMode, configureStatusLine, ensureClaudeMdSection } = require('./settings');
5
5
 
6
6
  function getInstalledVersion(targetDir) {
7
7
  try {
@@ -72,6 +72,8 @@ function init() {
72
72
  configureSessionStartHook(targetDir);
73
73
  configureEnforcementHooks(targetDir);
74
74
  configurePermissions(targetDir);
75
+ configureLocalPermissions(targetDir);
76
+ configureLocalFastMode(targetDir);
75
77
  configureStatusLine(targetDir);
76
78
  ensureClaudeMdSection(targetDir);
77
79
 
@@ -140,6 +142,8 @@ function update() {
140
142
  // Reconfigure hooks and permissions (picks up any new patterns)
141
143
  configureEnforcementHooks(targetDir);
142
144
  configurePermissions(targetDir);
145
+ configureLocalPermissions(targetDir);
146
+ configureLocalFastMode(targetDir);
143
147
 
144
148
  writeInstalledVersion(targetDir);
145
149
 
@@ -157,12 +157,59 @@ function configurePermissions(targetDir) {
157
157
  if (!settings.permissions) settings.permissions = {};
158
158
  if (!settings.permissions.allow) settings.permissions.allow = [];
159
159
 
160
- const rule = "mcp__prevention__*";
160
+ const rules = ["mcp__prevention__*", "mcp__prevention-content__*"];
161
+ for (const rule of rules) {
162
+ if (!settings.permissions.allow.includes(rule)) {
163
+ settings.permissions.allow.push(rule);
164
+ }
165
+ }
166
+
167
+ writeSettings(targetDir, settings);
168
+ }
169
+
170
+ function readLocalSettings(targetDir) {
171
+ const p = path.join(targetDir, ".claude", "settings.local.json");
172
+ if (!fs.existsSync(p)) return {};
173
+ try {
174
+ return JSON.parse(fs.readFileSync(p, "utf8"));
175
+ } catch {
176
+ return {};
177
+ }
178
+ }
179
+
180
+ function writeLocalSettings(targetDir, settings) {
181
+ const claudeDir = path.join(targetDir, ".claude");
182
+ if (!fs.existsSync(claudeDir)) {
183
+ fs.mkdirSync(claudeDir, { recursive: true });
184
+ }
185
+ fs.writeFileSync(
186
+ path.join(claudeDir, "settings.local.json"),
187
+ JSON.stringify(settings, null, 2) + "\n",
188
+ );
189
+ }
190
+
191
+ // Path-scoped permissions live in settings.local.json (machine-specific)
192
+ // so the absolute path doesn't get committed and break for other clones.
193
+ function configureLocalPermissions(targetDir) {
194
+ const settings = readLocalSettings(targetDir);
195
+ if (!settings.permissions) settings.permissions = {};
196
+ if (!settings.permissions.allow) settings.permissions.allow = [];
197
+
198
+ const rule = `Write(${path.resolve(targetDir, ".avesta")}/**)`;
161
199
  if (!settings.permissions.allow.includes(rule)) {
162
200
  settings.permissions.allow.push(rule);
163
201
  }
164
202
 
165
- writeSettings(targetDir, settings);
203
+ writeLocalSettings(targetDir, settings);
204
+ }
205
+
206
+ // Force fastMode off in this project. Prevention agents are tuned for
207
+ // the standard model; fast mode swaps to a smaller model and degrades
208
+ // gate-validation quality.
209
+ function configureLocalFastMode(targetDir) {
210
+ const settings = readLocalSettings(targetDir);
211
+ settings.fastMode = false;
212
+ writeLocalSettings(targetDir, settings);
166
213
  }
167
214
 
168
215
  function configureStatusLine(targetDir) {
@@ -295,6 +342,8 @@ module.exports = {
295
342
  configureSessionStartHook,
296
343
  configureEnforcementHooks,
297
344
  configurePermissions,
345
+ configureLocalPermissions,
346
+ configureLocalFastMode,
298
347
  configureStatusLine,
299
348
  configureMcpServer,
300
349
  ensureClaudeMdSection,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@avesta-hq/prevention",
3
- "version": "0.6.0-pre.21",
3
+ "version": "0.6.0-pre.23",
4
4
  "description": "XP/CD development agent commands for Claude Code - achieve Elite DORA metrics through disciplined TDD and Continuous Delivery practices",
5
5
  "keywords": [
6
6
  "claude-code",