@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
|
|
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
|
-
|
|
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
|
|
package/bin/lib/settings.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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.
|
|
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",
|