agentic-sdlc-wizard 1.30.0 → 1.31.0
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +17 -0
- package/CLAUDE_CODE_SDLC_WIZARD.md +2 -2
- package/README.md +2 -2
- package/cli/init.js +70 -3
- package/hooks/_find-sdlc-root.sh +36 -0
- package/hooks/instructions-loaded-check.sh +15 -1
- package/hooks/sdlc-prompt-check.sh +15 -2
- package/package.json +1 -1
- package/skills/update/SKILL.md +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,23 @@ All notable changes to the SDLC Wizard.
|
|
|
4
4
|
|
|
5
5
|
> **Note:** This changelog is for humans to read. Don't manually apply these changes - just run the wizard ("Check for SDLC wizard updates") and it handles everything automatically.
|
|
6
6
|
|
|
7
|
+
## [1.31.0] - 2026-04-14
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- Ephemeral marketplace path detection in CLI `check` command (#174)
|
|
11
|
+
- Scans `~/.claude/settings.json` `extraKnownMarketplaces` for directory sources on ephemeral paths (`/tmp/`, `/private/tmp/`, `/var/folders/`)
|
|
12
|
+
- `EPHEMERAL` status (path exists but in ephemeral root) warns but doesn't fail check
|
|
13
|
+
- `DANGLING` status (path doesn't exist) errors with non-zero exit code
|
|
14
|
+
- Suggests moving to `~/.claude/plugins-local/<name>` for stable installs
|
|
15
|
+
- JSON output (`--json`) includes new `marketplace` field
|
|
16
|
+
- 10 new tests (51 total CLI tests)
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
- Hook false-positive "SETUP NOT COMPLETE" in non-SDLC directories (#173, PR #175)
|
|
20
|
+
- Three-way detection: both files (normal), one file (warn partial setup), neither (silent exit)
|
|
21
|
+
- Added `find_partial_sdlc_root` helper for partial-setup detection
|
|
22
|
+
- 2 new hook tests (60 total hook tests)
|
|
23
|
+
|
|
7
24
|
## [1.30.0] - 2026-04-12
|
|
8
25
|
|
|
9
26
|
### Added
|
|
@@ -2628,7 +2628,7 @@ If deployment fails or post-deploy verification catches issues:
|
|
|
2628
2628
|
|
|
2629
2629
|
**SDLC.md:**
|
|
2630
2630
|
```markdown
|
|
2631
|
-
<!-- SDLC Wizard Version: 1.
|
|
2631
|
+
<!-- SDLC Wizard Version: 1.31.0 -->
|
|
2632
2632
|
<!-- Setup Date: [DATE] -->
|
|
2633
2633
|
<!-- Completed Steps: step-0.1, step-0.2, step-0.4, step-1, step-2, step-3, step-4, step-5, step-6, step-7, step-8, step-9 -->
|
|
2634
2634
|
<!-- Git Workflow: [PRs or Solo] -->
|
|
@@ -3687,7 +3687,7 @@ Walk through updates? (y/n)
|
|
|
3687
3687
|
Store wizard state in `SDLC.md` as metadata comments (invisible to readers, parseable by Claude):
|
|
3688
3688
|
|
|
3689
3689
|
```markdown
|
|
3690
|
-
<!-- SDLC Wizard Version: 1.
|
|
3690
|
+
<!-- SDLC Wizard Version: 1.31.0 -->
|
|
3691
3691
|
<!-- Setup Date: 2026-01-24 -->
|
|
3692
3692
|
<!-- Completed Steps: step-0.1, step-0.2, step-1, step-2, step-3, step-4, step-5, step-6, step-7, step-8, step-9 -->
|
|
3693
3693
|
<!-- Git Workflow: PRs -->
|
package/README.md
CHANGED
|
@@ -87,7 +87,7 @@ Layer 4: STATISTICAL VALIDATION
|
|
|
87
87
|
SDP normalizes for model quality. CUSUM catches drift.
|
|
88
88
|
|
|
89
89
|
Layer 3: SCORING ENGINE
|
|
90
|
-
|
|
90
|
+
Multi-criteria scoring, 10/11 points. Claude evaluates Claude.
|
|
91
91
|
Before/after wizard A/B comparison in CI.
|
|
92
92
|
|
|
93
93
|
Layer 2: ENFORCEMENT
|
|
@@ -229,7 +229,7 @@ This isn't the only Claude Code SDLC tool. Here's an honest comparison:
|
|
|
229
229
|
| Document | What It Covers |
|
|
230
230
|
|----------|---------------|
|
|
231
231
|
| [ARCHITECTURE.md](ARCHITECTURE.md) | System design, 5-layer diagram, data flows, file structure |
|
|
232
|
-
| [CI_CD.md](CI_CD.md) | All
|
|
232
|
+
| [CI_CD.md](CI_CD.md) | All workflows, E2E scoring, tier system, SDP, integrity checks |
|
|
233
233
|
| [SDLC.md](SDLC.md) | Version tracking, enforcement rules, SDLC configuration |
|
|
234
234
|
| [TESTING.md](TESTING.md) | Testing philosophy, test diamond, TDD approach |
|
|
235
235
|
| [CHANGELOG.md](CHANGELOG.md) | Version history, what changed and when |
|
package/cli/init.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const crypto = require('crypto');
|
|
4
4
|
const fs = require('fs');
|
|
5
|
+
const os = require('os');
|
|
5
6
|
const path = require('path');
|
|
6
7
|
|
|
7
8
|
const RESET = '\x1b[0m';
|
|
@@ -285,23 +286,37 @@ function check(targetDir, { json = false } = {}) {
|
|
|
285
286
|
// Offline or npm unavailable — skip update check
|
|
286
287
|
}
|
|
287
288
|
|
|
288
|
-
const
|
|
289
|
+
const marketplace = checkMarketplacePaths();
|
|
290
|
+
const hasDrift = results.some((r) => r.status === 'MISSING' || r.status === 'DRIFT')
|
|
291
|
+
|| marketplace.some((m) => m.status === 'DANGLING');
|
|
289
292
|
|
|
290
293
|
if (json) {
|
|
291
|
-
console.log(JSON.stringify({ files: results, update: updateInfo }, null, 2));
|
|
294
|
+
console.log(JSON.stringify({ files: results, update: updateInfo, marketplace }, null, 2));
|
|
292
295
|
} else {
|
|
293
296
|
for (const r of results) {
|
|
294
297
|
const color = r.status === 'MATCH' ? GREEN : r.status === 'MISSING' ? RED : YELLOW;
|
|
295
298
|
console.log(` ${color}${r.status}${RESET} ${r.file}`);
|
|
296
299
|
if (r.details) console.log(` ${r.details}`);
|
|
297
300
|
}
|
|
301
|
+
for (const m of marketplace) {
|
|
302
|
+
const color = m.status === 'DANGLING' ? RED : YELLOW;
|
|
303
|
+
const heading = m.status === 'EPHEMERAL'
|
|
304
|
+
? `Marketplace '${m.name}' source path is ephemeral:`
|
|
305
|
+
: `Marketplace '${m.name}' source path does not exist:`;
|
|
306
|
+
console.log(`\n ${color}${m.status}${RESET} ${heading}`);
|
|
307
|
+
console.log(` ${m.path}`);
|
|
308
|
+
console.log(` ${m.details}`);
|
|
309
|
+
if (m.suggestion) {
|
|
310
|
+
console.log(` Recommended: move to ${m.suggestion}`);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
298
313
|
if (updateInfo) {
|
|
299
314
|
console.log(`\n ${YELLOW}UPDATE${RESET} v${updateInfo.current} -> v${updateInfo.latest}`);
|
|
300
315
|
console.log(' Run: npx agentic-sdlc-wizard init --force');
|
|
301
316
|
}
|
|
302
317
|
}
|
|
303
318
|
|
|
304
|
-
return { results, updateInfo, hasDrift };
|
|
319
|
+
return { results, updateInfo, hasDrift, marketplace };
|
|
305
320
|
}
|
|
306
321
|
|
|
307
322
|
function checkFile(srcPath, destPath, relativeDest, shouldBeExecutable) {
|
|
@@ -341,4 +356,56 @@ function checkGitignore(gitignorePath) {
|
|
|
341
356
|
return { file: '.gitignore', status: 'MATCH' };
|
|
342
357
|
}
|
|
343
358
|
|
|
359
|
+
const EPHEMERAL_ROOTS = /^(\/tmp\/|\/private\/tmp\/|\/var\/folders\/|\/private\/var\/folders\/)/;
|
|
360
|
+
|
|
361
|
+
function checkMarketplacePaths() {
|
|
362
|
+
const results = [];
|
|
363
|
+
const globalSettings = path.join(os.homedir(), '.claude', 'settings.json');
|
|
364
|
+
|
|
365
|
+
if (!fs.existsSync(globalSettings)) return results;
|
|
366
|
+
|
|
367
|
+
let data;
|
|
368
|
+
try {
|
|
369
|
+
data = JSON.parse(fs.readFileSync(globalSettings, 'utf8'));
|
|
370
|
+
} catch (_) {
|
|
371
|
+
return results;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
const marketplaces = data.extraKnownMarketplaces;
|
|
375
|
+
if (!marketplaces || typeof marketplaces !== 'object') return results;
|
|
376
|
+
|
|
377
|
+
for (const [name, entry] of Object.entries(marketplaces)) {
|
|
378
|
+
const source = entry && entry.source;
|
|
379
|
+
if (!source || source.source !== 'directory' || !source.path || typeof source.path !== 'string') continue;
|
|
380
|
+
|
|
381
|
+
const sourcePath = source.path;
|
|
382
|
+
const isEphemeral = EPHEMERAL_ROOTS.test(sourcePath);
|
|
383
|
+
const exists = fs.existsSync(sourcePath);
|
|
384
|
+
const basename = path.basename(sourcePath);
|
|
385
|
+
const suggestion = `~/.claude/plugins-local/${basename}`;
|
|
386
|
+
|
|
387
|
+
if (!exists) {
|
|
388
|
+
results.push({
|
|
389
|
+
name,
|
|
390
|
+
path: sourcePath,
|
|
391
|
+
status: 'DANGLING',
|
|
392
|
+
details: isEphemeral
|
|
393
|
+
? 'Ephemeral path has been reaped — plugin is broken'
|
|
394
|
+
: 'Path does not exist — plugin may be silently broken',
|
|
395
|
+
suggestion: isEphemeral ? suggestion : undefined,
|
|
396
|
+
});
|
|
397
|
+
} else if (isEphemeral) {
|
|
398
|
+
results.push({
|
|
399
|
+
name,
|
|
400
|
+
path: sourcePath,
|
|
401
|
+
status: 'EPHEMERAL',
|
|
402
|
+
details: 'macOS reaps this path periodically — plugin may break silently',
|
|
403
|
+
suggestion,
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
return results;
|
|
409
|
+
}
|
|
410
|
+
|
|
344
411
|
module.exports = { init, check, planOperations, GITIGNORE_ENTRIES };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Shared helper: walk up from CWD to find nearest SDLC.md + TESTING.md pair
|
|
3
|
+
# Sourced by sdlc-prompt-check.sh and instructions-loaded-check.sh
|
|
4
|
+
# Fixes #171: false-positive "SETUP NOT COMPLETE" in monorepos / nested projects
|
|
5
|
+
|
|
6
|
+
# find_sdlc_root — walks up from pwd, stops at $HOME (exclusive)
|
|
7
|
+
# Sets SDLC_ROOT to the found directory, or empty string if not found
|
|
8
|
+
find_sdlc_root() {
|
|
9
|
+
local check_dir
|
|
10
|
+
check_dir="$(pwd)"
|
|
11
|
+
SDLC_ROOT=""
|
|
12
|
+
while [ "$check_dir" != "/" ] && [ "$check_dir" != "$HOME" ] && [ -n "$check_dir" ]; do
|
|
13
|
+
if [ -f "$check_dir/SDLC.md" ] && [ -f "$check_dir/TESTING.md" ]; then
|
|
14
|
+
SDLC_ROOT="$check_dir"
|
|
15
|
+
return 0
|
|
16
|
+
fi
|
|
17
|
+
check_dir="$(dirname "$check_dir")"
|
|
18
|
+
done
|
|
19
|
+
return 1
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
# find_partial_sdlc_root — walks up looking for EITHER SDLC.md OR TESTING.md
|
|
23
|
+
# Used to detect partial setup (one file exists but not both) vs not-an-SDLC-project
|
|
24
|
+
find_partial_sdlc_root() {
|
|
25
|
+
local check_dir
|
|
26
|
+
check_dir="$(pwd)"
|
|
27
|
+
SDLC_ROOT=""
|
|
28
|
+
while [ "$check_dir" != "/" ] && [ "$check_dir" != "$HOME" ] && [ -n "$check_dir" ]; do
|
|
29
|
+
if [ -f "$check_dir/SDLC.md" ] || [ -f "$check_dir/TESTING.md" ]; then
|
|
30
|
+
SDLC_ROOT="$check_dir"
|
|
31
|
+
return 0
|
|
32
|
+
fi
|
|
33
|
+
check_dir="$(dirname "$check_dir")"
|
|
34
|
+
done
|
|
35
|
+
return 1
|
|
36
|
+
}
|
|
@@ -4,7 +4,21 @@
|
|
|
4
4
|
# Available since Claude Code v2.1.69
|
|
5
5
|
# Note: no set -e — this hook must always exit 0 to not block session start
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
# Walk up from CWD to find nearest SDLC.md + TESTING.md (#171: monorepo support)
|
|
8
|
+
HOOK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
9
|
+
source "$HOOK_DIR/_find-sdlc-root.sh"
|
|
10
|
+
|
|
11
|
+
# CWD walk-up finds nearest SDLC project (#173: silent exit for non-SDLC dirs)
|
|
12
|
+
if find_sdlc_root; then
|
|
13
|
+
PROJECT_DIR="$SDLC_ROOT"
|
|
14
|
+
elif find_partial_sdlc_root; then
|
|
15
|
+
# Partial setup — one file exists but not both. Warn about missing files
|
|
16
|
+
PROJECT_DIR="$SDLC_ROOT"
|
|
17
|
+
else
|
|
18
|
+
# Not an SDLC project at all — exit silently
|
|
19
|
+
exit 0
|
|
20
|
+
fi
|
|
21
|
+
|
|
8
22
|
MISSING=""
|
|
9
23
|
|
|
10
24
|
if [ ! -f "$PROJECT_DIR/SDLC.md" ]; then
|
|
@@ -2,8 +2,21 @@
|
|
|
2
2
|
# Light SDLC hook - baseline reminder every prompt (~100 tokens)
|
|
3
3
|
# Full guidance in skill: .claude/skills/sdlc/
|
|
4
4
|
|
|
5
|
-
#
|
|
6
|
-
|
|
5
|
+
# Walk up from CWD to find nearest SDLC.md + TESTING.md (#171: monorepo support)
|
|
6
|
+
HOOK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
7
|
+
source "$HOOK_DIR/_find-sdlc-root.sh"
|
|
8
|
+
|
|
9
|
+
# CWD walk-up finds nearest SDLC project (#173: silent exit for non-SDLC dirs)
|
|
10
|
+
if find_sdlc_root; then
|
|
11
|
+
PROJECT_DIR="$SDLC_ROOT"
|
|
12
|
+
elif find_partial_sdlc_root; then
|
|
13
|
+
# Partial setup — one file exists but not both. Warn about missing files
|
|
14
|
+
PROJECT_DIR="$SDLC_ROOT"
|
|
15
|
+
else
|
|
16
|
+
# Not an SDLC project at all — exit silently
|
|
17
|
+
exit 0
|
|
18
|
+
fi
|
|
19
|
+
|
|
7
20
|
if [ ! -s "$PROJECT_DIR/SDLC.md" ] || [ ! -s "$PROJECT_DIR/TESTING.md" ]; then
|
|
8
21
|
cat << 'SETUP'
|
|
9
22
|
SETUP NOT COMPLETE: SDLC.md and/or TESTING.md are missing.
|
package/package.json
CHANGED
package/skills/update/SKILL.md
CHANGED
|
@@ -46,9 +46,10 @@ Parse all CHANGELOG entries between the user's installed version and the latest.
|
|
|
46
46
|
|
|
47
47
|
```
|
|
48
48
|
Installed: 1.24.0
|
|
49
|
-
Latest: 1.
|
|
49
|
+
Latest: 1.31.0
|
|
50
50
|
|
|
51
51
|
What changed:
|
|
52
|
+
- [1.31.0] Hook false-positive fix for non-SDLC dirs, ephemeral marketplace path warning, ...
|
|
52
53
|
- [1.30.0] Firmware fixture, model A/B comparison workflow, CC degradation detection, ...
|
|
53
54
|
- [1.29.0] Node 24 compliance, autocompact in settings.json, effectiveness scoreboard, ...
|
|
54
55
|
- [1.28.0] Autocompact benchmarking methodology, canary fact mechanism, benchmark harness, ...
|