prizmkit 1.0.15 → 1.0.16

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.15",
3
- "bundledAt": "2026-03-15T12:24:22.555Z",
4
- "bundledFrom": "8b809a8"
2
+ "frameworkVersion": "1.0.16",
3
+ "bundledAt": "2026-03-15T13:35:03.135Z",
4
+ "bundledFrom": "d609245"
5
5
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.0.15",
2
+ "version": "1.0.16",
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.",
@@ -39,44 +39,32 @@ BROWNFIELD WORKFLOW (existing project):
39
39
  4. Catalog dependencies (external packages)
40
40
  5. Count source files per directory
41
41
 
42
- **Step 2: State Assessment**
43
- 2a. Run dependency analysis:
44
- - Count outdated dependencies (if lockfile exists)
45
- - Note any known vulnerability patterns
46
-
47
- 2b. Scan for technical debt indicators:
48
- - Count TODO/FIXME/HACK/XXX comments
49
- - Identify large files (>500 lines)
50
- - Check for test directories and coverage config
51
-
52
- 2c. Generate `ASSESSMENT.md` in project root with findings
53
-
54
- **Step 3: Prizm Documentation Generation**
55
- 3a. Invoke prizmkit-prizm-docs `prizmkit.doc.init` algorithm:
42
+ **Step 2: Prizm Documentation Generation**
43
+ 2a. Invoke prizmkit-prizm-docs `prizmkit.doc.init` algorithm:
56
44
  - Create `.prizm-docs/` directory structure
57
45
  - Generate `root.prizm` (L0) with project meta and module index
58
46
  - Generate L1 docs for all discovered modules
59
47
  - Create `changelog.prizm`
60
48
  - Skip L2 (lazy generation)
61
49
 
62
- 3b. If project has existing `docs/AI_CONTEXT/`: suggest running `prizmkit.doc.migrate`
50
+ 2b. If project has existing `docs/AI_CONTEXT/`: suggest running `prizmkit.doc.migrate`
63
51
 
64
- **Step 4: PrizmKit Workspace Initialization**
65
- 4a. Create `.prizmkit/` directory:
52
+ **Step 3: PrizmKit Workspace Initialization**
53
+ 3a. Create `.prizmkit/` directory:
66
54
  - `.prizmkit/config.json` (adoption_mode, speckit_hooks_enabled, platform)
67
55
  - `.prizmkit/specs/` (empty)
68
56
 
69
- **Step 5: Hook & Settings Configuration (Platform-Specific)**
57
+ **Step 4: Hook & Settings Configuration (Platform-Specific)**
70
58
 
71
59
  **If platform is CodeBuddy (or both):**
72
- 5a-cb. Read or create `.codebuddy/settings.json`
73
- 5b-cb. Add UserPromptSubmit hook from `${SKILL_DIR}/../../../assets/hooks/prizm-commit-hook.json`
74
- 5c-cb. Preserve any existing hooks
60
+ 4a-cb. Read or create `.codebuddy/settings.json`
61
+ 4b-cb. Add UserPromptSubmit hook from `${SKILL_DIR}/../../../assets/hooks/prizm-commit-hook.json`
62
+ 4c-cb. Preserve any existing hooks
75
63
 
76
64
  **If platform is Claude Code (or both):**
77
- 5a-cl. Read or create `.claude/settings.json`
78
- 5b-cl. Add `permissions` and `allowedTools` entries if needed
79
- 5c-cl. Create `.claude/rules/prizm-documentation.md` with glob-scoped rules:
65
+ 4a-cl. Read or create `.claude/settings.json`
66
+ 4b-cl. Add `permissions` and `allowedTools` entries if needed
67
+ 4c-cl. Create `.claude/rules/prizm-documentation.md` with glob-scoped rules:
80
68
  ```yaml
81
69
  ---
82
70
  description: PrizmKit documentation rules
@@ -91,7 +79,7 @@ BROWNFIELD WORKFLOW (existing project):
91
79
  2. After changes, update affected `.prizm-docs/` files
92
80
  3. Follow Prizm doc format (KEY: value, not prose)
93
81
  ```
94
- 5d-cl. Create `.claude/rules/prizm-commit-workflow.md` with commit-scoped rules:
82
+ 4d-cl. Create `.claude/rules/prizm-commit-workflow.md` with commit-scoped rules:
95
83
  ```yaml
96
84
  ---
97
85
  description: PrizmKit commit workflow enforcement
@@ -105,33 +93,33 @@ BROWNFIELD WORKFLOW (existing project):
105
93
  4. Stage .prizm-docs/ changes
106
94
  5. Use /prizmkit-committer for the complete workflow
107
95
  ```
108
- 5e-cl. Preserve any existing Claude settings and rules
96
+ 4e-cl. Preserve any existing Claude settings and rules
109
97
 
110
- **Step 6: Project Memory Update (Platform-Specific)**
98
+ **Step 5: Project Memory Update (Platform-Specific)**
111
99
 
112
100
  **If platform is CodeBuddy (or both):**
113
- 6a-cb. Read existing `CODEBUDDY.md` (or create if missing)
114
- 6b-cb. Append PrizmKit section from `${SKILL_DIR}/../../../assets/codebuddy-md-template.md`
115
- 6c-cb. Do not duplicate if already present
101
+ 5a-cb. Read existing `CODEBUDDY.md` (or create if missing)
102
+ 5b-cb. Append PrizmKit section from `${SKILL_DIR}/../../../assets/codebuddy-md-template.md`
103
+ 5c-cb. Do not duplicate if already present
116
104
 
117
105
  **If platform is Claude Code (or both):**
118
- 6a-cl. Read existing `CLAUDE.md` (or create if missing)
119
- 6b-cl. Append PrizmKit section from `${SKILL_DIR}/../../../assets/claude-md-template.md`
120
- 6c-cl. Adjust command references to use `/command-name` format (not `prizmkit.xxx`)
121
- 6d-cl. Do not duplicate if already present
106
+ 5a-cl. Read existing `CLAUDE.md` (or create if missing)
107
+ 5b-cl. Append PrizmKit section from `${SKILL_DIR}/../../../assets/claude-md-template.md`
108
+ 5c-cl. Adjust command references to use `/command-name` format (not `prizmkit.xxx`)
109
+ 5d-cl. Do not duplicate if already present
122
110
 
123
- **Step 7: Report**
124
- Output summary: platform detected, tech stack detected, modules discovered, L1 docs generated, assessment highlights, platform-specific configuration applied, next recommended steps.
111
+ **Step 6: Report**
112
+ Output summary: platform detected, tech stack detected, modules discovered, L1 docs generated, platform-specific configuration applied, next recommended steps.
125
113
 
126
114
  Include platform-specific guidance:
127
115
  - CodeBuddy: "Use `prizmkit.specify` to start your first feature"
128
116
  - Claude Code: "Use `/prizmkit-specify` to start your first feature"
129
117
 
130
118
  GREENFIELD WORKFLOW (new project):
131
- - Skip Steps 1-2 (no code to scan)
132
- - Step 3: Create minimal `.prizm-docs/` with just `root.prizm` skeleton
133
- - Steps 4-6: Same as brownfield
134
- - Step 7: Recommend starting with specify for first feature (platform-appropriate command format)
119
+ - Skip Step 1 (no code to scan)
120
+ - Step 2: Create minimal `.prizm-docs/` with just `root.prizm` skeleton
121
+ - Steps 3-5: Same as brownfield
122
+ - Step 6: Recommend starting with specify for first feature (platform-appropriate command format)
135
123
 
136
124
  ### Gradual Adoption Path
137
125
  After init, PrizmKit operates in phases:
@@ -10,6 +10,17 @@
10
10
  }
11
11
  ]
12
12
  }
13
+ ],
14
+ "PostToolUse": [
15
+ {
16
+ "matcher": "Bash",
17
+ "hooks": [
18
+ {
19
+ "type": "command",
20
+ "command": "if echo \"$CLAUDE_TOOL_INPUT\" 2>/dev/null | grep -qE 'git (commit|merge|rebase)' 2>/dev/null; then DRIFT=$(sh .prizmkit/scripts/diff-prizm-docs.sh 2>/dev/null); if [ -n \"$DRIFT\" ]; then echo \"PRIZMKIT_DRIFT_DETECTED: prizm-docs structural differences found after git operation:\"; echo \"$DRIFT\"; echo \"Please update affected .prizm-docs/ files using /prizmkit-prizm-docs.\"; fi; fi"
21
+ }
22
+ ]
23
+ }
13
24
  ]
14
25
  }
15
26
  }
@@ -10,6 +10,17 @@
10
10
  }
11
11
  ]
12
12
  }
13
+ ],
14
+ "PostToolUse": [
15
+ {
16
+ "matcher": "Bash",
17
+ "hooks": [
18
+ {
19
+ "type": "command",
20
+ "command": "TOOL_INPUT=\"${CLAUDE_TOOL_INPUT:-${CODEBUDDY_TOOL_INPUT:-}}\"; if echo \"$TOOL_INPUT\" | grep -qE 'git (commit|merge|rebase)' 2>/dev/null; then DRIFT=$(sh .prizmkit/scripts/diff-prizm-docs.sh 2>/dev/null); if [ -n \"$DRIFT\" ]; then echo \"PRIZMKIT_DRIFT_DETECTED: prizm-docs structural differences found:\"; echo \"$DRIFT\"; echo \"Please update affected .prizm-docs/ files.\"; fi; fi"
21
+ }
22
+ ]
23
+ }
13
24
  ]
14
25
  }
15
26
  }
@@ -0,0 +1,158 @@
1
+ #!/bin/sh
2
+ # PrizmKit: diff-prizm-docs.sh
3
+ # Outputs structural differences between .prizm-docs/ and source code.
4
+ # Silent (exit 0) if no differences or if .prizm-docs doesn't exist.
5
+ # POSIX sh only — no arrays, no bashisms.
6
+
7
+ set -e
8
+
9
+ ROOT_PRIZM=".prizm-docs/root.prizm"
10
+
11
+ # 1. Exit silently if no root.prizm
12
+ [ -f "$ROOT_PRIZM" ] || exit 0
13
+
14
+ # 2. Detect language from LANG: field
15
+ LANG_VAL=$(grep '^LANG:' "$ROOT_PRIZM" | head -1 | sed 's/^LANG:[[:space:]]*//' | tr '[:upper:]' '[:lower:]')
16
+
17
+ case "$LANG_VAL" in
18
+ go)
19
+ FILE_PATTERN="*.go"
20
+ ;;
21
+ javascript|typescript|javascript/typescript|typescript/javascript)
22
+ FILE_PATTERN="*.ts *.tsx *.js *.jsx"
23
+ ;;
24
+ python)
25
+ FILE_PATTERN="*.py"
26
+ ;;
27
+ rust)
28
+ FILE_PATTERN="*.rs"
29
+ ;;
30
+ *)
31
+ FILE_PATTERN=""
32
+ ;;
33
+ esac
34
+
35
+ # Helper: count source files in a directory (maxdepth 1) by language
36
+ count_source_files() {
37
+ _dir="$1"
38
+ [ -d "$_dir" ] || { echo 0; return; }
39
+ if [ -z "$FILE_PATTERN" ]; then
40
+ # All non-hidden files
41
+ find "$_dir" -maxdepth 1 -type f ! -name '.*' 2>/dev/null | wc -l | tr -d ' '
42
+ else
43
+ _count=0
44
+ for _pat in $FILE_PATTERN; do
45
+ _c=$(find "$_dir" -maxdepth 1 -type f -name "$_pat" 2>/dev/null | wc -l | tr -d ' ')
46
+ _count=$((_count + _c))
47
+ done
48
+ echo "$_count"
49
+ fi
50
+ }
51
+
52
+ # 3. Parse MODULE_INDEX from root.prizm
53
+ # Extract lines between MODULE_INDEX: and next ALL-CAPS header or EOF
54
+ # Each module line: "- src/auth: ..." -> source path is text before first ":" after "- "
55
+ REGISTERED_PATHS=""
56
+ _in_index=0
57
+ while IFS= read -r line; do
58
+ case "$line" in
59
+ MODULE_INDEX:*)
60
+ _in_index=1
61
+ continue
62
+ ;;
63
+ esac
64
+ if [ "$_in_index" -eq 1 ]; then
65
+ # Check for next ALL-CAPS section header (word followed by colon, all uppercase letters)
66
+ _header=$(echo "$line" | grep '^[A-Z_][A-Z_]*:' || true)
67
+ if [ -n "$_header" ]; then
68
+ break
69
+ fi
70
+ # Extract source path from "- src/auth: ..."
71
+ case "$line" in
72
+ "- "*)
73
+ _path=$(echo "$line" | sed 's/^- //' | sed 's/:.*//')
74
+ if [ -n "$_path" ]; then
75
+ REGISTERED_PATHS="${REGISTERED_PATHS}${_path}
76
+ "
77
+ fi
78
+ ;;
79
+ esac
80
+ fi
81
+ done < "$ROOT_PRIZM"
82
+
83
+ # 4. Check each registered module for drift
84
+ echo "$REGISTERED_PATHS" | while IFS= read -r source_path; do
85
+ [ -z "$source_path" ] && continue
86
+
87
+ # Derive L1 prizm file path
88
+ l1_file=".prizm-docs/${source_path}.prizm"
89
+
90
+ if [ ! -f "$l1_file" ]; then
91
+ continue
92
+ fi
93
+
94
+ # Read declared FILES: count
95
+ declared=$(grep '^FILES:' "$l1_file" | head -1 | awk '{print $2}')
96
+ [ -z "$declared" ] && continue
97
+
98
+ # Count actual source files
99
+ actual=$(count_source_files "$source_path")
100
+
101
+ if [ "$actual" -gt 0 ] && [ "$declared" != "$actual" ]; then
102
+ echo "MODULE_DRIFT: $source_path | declared FILES: $declared | actual: $actual"
103
+ fi
104
+ done
105
+
106
+ # 5. Find orphan docs
107
+ find .prizm-docs -name '*.prizm' 2>/dev/null | while IFS= read -r prizm_file; do
108
+ _basename=$(basename "$prizm_file")
109
+ case "$_basename" in
110
+ root.prizm|changelog.prizm|changelog-archive.prizm)
111
+ continue
112
+ ;;
113
+ esac
114
+
115
+ # Derive source path: remove .prizm-docs/ prefix and .prizm suffix
116
+ source_path=$(echo "$prizm_file" | sed 's|^\.prizm-docs/||' | sed 's|\.prizm$||')
117
+
118
+ if [ ! -d "$source_path" ]; then
119
+ echo "ORPHAN_DOC: $prizm_file | source dir missing"
120
+ fi
121
+ done
122
+
123
+ # 6. Find unregistered directories
124
+ find . -mindepth 1 -maxdepth 3 -type d \
125
+ ! -path '*/.*' \
126
+ ! -path '*/node_modules/*' ! -path './node_modules' \
127
+ ! -path '*/vendor/*' ! -path './vendor' \
128
+ ! -path '*/dist/*' ! -path './dist' \
129
+ ! -path '*/build/*' ! -path './build' \
130
+ ! -path '*/__pycache__/*' ! -path './__pycache__' \
131
+ ! -path '*/target/*' ! -path './target' \
132
+ ! -path '*/tests/*' ! -path './tests' \
133
+ ! -path '*/__tests__/*' ! -path './__tests__' \
134
+ ! -path '*/.prizm-docs/*' ! -path './.prizm-docs' \
135
+ ! -path '*/.claude/*' ! -path './.claude' \
136
+ ! -path '*/.codebuddy/*' ! -path './.codebuddy' \
137
+ ! -path '*/dev-pipeline/*' ! -path './dev-pipeline' \
138
+ ! -path '*/coverage/*' ! -path './coverage' \
139
+ ! -path '*/.nyc_output/*' ! -path './.nyc_output' \
140
+ ! -path '*/out/*' ! -path './out' \
141
+ ! -path '*/tmp/*' ! -path './tmp' \
142
+ 2>/dev/null | while IFS= read -r candidate; do
143
+ # Normalize: remove leading ./
144
+ candidate_clean=$(echo "$candidate" | sed 's|^\./||')
145
+
146
+ # Count source files
147
+ file_count=$(count_source_files "$candidate_clean")
148
+
149
+ if [ "$file_count" -ge 3 ]; then
150
+ # Check if registered in MODULE_INDEX
151
+ _match=$(echo "$REGISTERED_PATHS" | grep -Fx "$candidate_clean" || true)
152
+ if [ -z "$_match" ]; then
153
+ echo "UNREGISTERED: $candidate_clean | $file_count source files | not in MODULE_INDEX"
154
+ fi
155
+ fi
156
+ done
157
+
158
+ exit 0
@@ -6,7 +6,8 @@ PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null) || exit 0
6
6
  # Only run in prizm projects
7
7
  [ -f "$PROJECT_ROOT/.prizm-docs/root.prizm" ] || exit 0
8
8
 
9
- VALIDATE_SCRIPT="$PROJECT_ROOT/dev-pipeline/scripts/validate-prizm-docs.sh"
9
+ VALIDATE_SCRIPT="$PROJECT_ROOT/.prizmkit/scripts/validate-prizm-docs.sh"
10
+ [ -f "$VALIDATE_SCRIPT" ] || VALIDATE_SCRIPT="$PROJECT_ROOT/dev-pipeline/scripts/validate-prizm-docs.sh"
10
11
 
11
12
  if [ -f "$VALIDATE_SCRIPT" ]; then
12
13
  sh "$VALIDATE_SCRIPT" --staged
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prizmkit",
3
- "version": "1.0.15",
3
+ "version": "1.0.16",
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/scaffold.js CHANGED
@@ -472,25 +472,34 @@ async function installGitHook(projectRoot, dryRun) {
472
472
  }
473
473
 
474
474
  /**
475
- * 安装 validate-prizm-docs.sh dev-pipeline/scripts/
475
+ * 安装 PrizmKit 脚本到 .prizmkit/scripts/(始终安装)
476
476
  */
477
- async function installValidateScript(projectRoot, dryRun) {
478
- const sourcePath = path.join(getTemplatesDir(), 'hooks', 'validate-prizm-docs.sh');
479
- if (!fs.existsSync(sourcePath)) return;
477
+ async function installPrizmkitScripts(projectRoot, dryRun) {
478
+ const scriptsDir = path.join(projectRoot, '.prizmkit', 'scripts');
479
+ const templateHooksDir = path.join(getTemplatesDir(), 'hooks');
480
480
 
481
- const targetDir = path.join(projectRoot, 'dev-pipeline', 'scripts');
482
- const targetPath = path.join(targetDir, 'validate-prizm-docs.sh');
481
+ const scripts = [
482
+ 'validate-prizm-docs.sh',
483
+ 'diff-prizm-docs.sh',
484
+ ];
483
485
 
484
486
  if (dryRun) {
485
- console.log(chalk.gray(' [dry-run] dev-pipeline/scripts/validate-prizm-docs.sh'));
487
+ for (const s of scripts) {
488
+ console.log(chalk.gray(` [dry-run] .prizmkit/scripts/${s}`));
489
+ }
486
490
  return;
487
491
  }
488
492
 
489
- await fs.ensureDir(targetDir);
490
- await fs.copy(sourcePath, targetPath);
491
- fs.chmodSync(targetPath, 0o755);
493
+ await fs.ensureDir(scriptsDir);
492
494
 
493
- console.log(chalk.green(' ✓ dev-pipeline/scripts/validate-prizm-docs.sh'));
495
+ for (const s of scripts) {
496
+ const src = path.join(templateHooksDir, s);
497
+ if (!fs.existsSync(src)) continue;
498
+ const tgt = path.join(scriptsDir, s);
499
+ await fs.copy(src, tgt);
500
+ fs.chmodSync(tgt, 0o755);
501
+ console.log(chalk.green(` ✓ .prizmkit/scripts/${s}`));
502
+ }
494
503
  }
495
504
 
496
505
  /**
@@ -711,11 +720,9 @@ export async function scaffold(config) {
711
720
  console.log(chalk.blue(' Git Hook:'));
712
721
  await installGitHook(projectRoot, dryRun);
713
722
 
714
- // 11. Validate script (only if pipeline enabled)
715
- if (pipeline) {
716
- console.log(chalk.blue(' 验证脚本:'));
717
- await installValidateScript(projectRoot, dryRun);
718
- }
723
+ // 11. PrizmKit scripts (always installed)
724
+ console.log(chalk.blue(' PrizmKit 脚本:'));
725
+ await installPrizmkitScripts(projectRoot, dryRun);
719
726
 
720
727
  // === 完成 ===
721
728
  console.log('');