prizmkit 1.0.13 → 1.0.14

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.
Files changed (77) hide show
  1. package/bin/create-prizmkit.js +4 -1
  2. package/bundled/VERSION.json +3 -3
  3. package/bundled/adapters/claude/command-adapter.js +35 -4
  4. package/bundled/adapters/claude/rules-adapter.js +6 -58
  5. package/bundled/adapters/claude/team-adapter.js +2 -2
  6. package/bundled/adapters/codebuddy/agent-adapter.js +0 -1
  7. package/bundled/adapters/codebuddy/rules-adapter.js +30 -0
  8. package/bundled/adapters/shared/frontmatter.js +3 -1
  9. package/bundled/dev-pipeline/README.md +13 -3
  10. package/bundled/dev-pipeline/launch-bugfix-daemon.sh +10 -0
  11. package/bundled/dev-pipeline/launch-daemon.sh +18 -4
  12. package/bundled/dev-pipeline/lib/common.sh +105 -0
  13. package/bundled/dev-pipeline/run-bugfix.sh +57 -57
  14. package/bundled/dev-pipeline/run.sh +75 -59
  15. package/bundled/dev-pipeline/scripts/check-session-status.py +47 -2
  16. package/bundled/dev-pipeline/scripts/cleanup-logs.py +192 -0
  17. package/bundled/dev-pipeline/scripts/detect-stuck.py +15 -3
  18. package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +32 -27
  19. package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +23 -23
  20. package/bundled/dev-pipeline/scripts/update-feature-status.py +50 -2
  21. package/bundled/dev-pipeline/scripts/utils.py +22 -0
  22. package/bundled/dev-pipeline/templates/bootstrap-tier1.md +18 -1
  23. package/bundled/dev-pipeline/templates/bootstrap-tier2.md +19 -1
  24. package/bundled/dev-pipeline/templates/bootstrap-tier3.md +18 -2
  25. package/bundled/dev-pipeline/templates/session-status-schema.json +7 -1
  26. package/bundled/dev-pipeline/tests/__init__.py +0 -0
  27. package/bundled/dev-pipeline/tests/conftest.py +133 -0
  28. package/bundled/dev-pipeline/tests/test_check_session.py +127 -0
  29. package/bundled/dev-pipeline/tests/test_cleanup_logs.py +119 -0
  30. package/bundled/dev-pipeline/tests/test_detect_stuck.py +207 -0
  31. package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +181 -0
  32. package/bundled/dev-pipeline/tests/test_generate_prompt.py +190 -0
  33. package/bundled/dev-pipeline/tests/test_init_bugfix_pipeline.py +153 -0
  34. package/bundled/dev-pipeline/tests/test_init_pipeline.py +241 -0
  35. package/bundled/dev-pipeline/tests/test_update_bug_status.py +142 -0
  36. package/bundled/dev-pipeline/tests/test_update_feature_status.py +277 -0
  37. package/bundled/dev-pipeline/tests/test_utils.py +141 -0
  38. package/bundled/rules/USAGE.md +153 -0
  39. package/bundled/rules/_rules-metadata.json +43 -0
  40. package/bundled/rules/general/prefer-linux-commands.md +9 -0
  41. package/bundled/rules/prizm/prizm-commit-workflow.md +10 -0
  42. package/bundled/rules/prizm/prizm-documentation.md +19 -0
  43. package/bundled/rules/prizm/prizm-progressive-loading.md +11 -0
  44. package/bundled/skills/_metadata.json +130 -67
  45. package/bundled/skills/app-planner/SKILL.md +252 -499
  46. package/bundled/skills/app-planner/assets/evaluation-guide.md +44 -0
  47. package/bundled/skills/app-planner/scripts/validate-and-generate.py +143 -4
  48. package/bundled/skills/bug-planner/SKILL.md +58 -13
  49. package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +5 -7
  50. package/bundled/skills/dev-pipeline-launcher/SKILL.md +16 -7
  51. package/bundled/skills/feature-workflow/SKILL.md +175 -234
  52. package/bundled/skills/prizm-kit/SKILL.md +17 -31
  53. package/bundled/skills/{prizmkit-adr-manager → prizmkit-tool-adr-manager}/SKILL.md +6 -7
  54. package/bundled/skills/{prizmkit-api-doc-generator → prizmkit-tool-api-doc-generator}/SKILL.md +4 -5
  55. package/bundled/skills/{prizmkit-bug-reproducer → prizmkit-tool-bug-reproducer}/SKILL.md +4 -5
  56. package/bundled/skills/{prizmkit-ci-cd-generator → prizmkit-tool-ci-cd-generator}/SKILL.md +4 -5
  57. package/bundled/skills/{prizmkit-db-migration → prizmkit-tool-db-migration}/SKILL.md +4 -5
  58. package/bundled/skills/{prizmkit-dependency-health → prizmkit-tool-dependency-health}/SKILL.md +3 -4
  59. package/bundled/skills/{prizmkit-deployment-strategy → prizmkit-tool-deployment-strategy}/SKILL.md +4 -5
  60. package/bundled/skills/{prizmkit-error-triage → prizmkit-tool-error-triage}/SKILL.md +4 -5
  61. package/bundled/skills/{prizmkit-log-analyzer → prizmkit-tool-log-analyzer}/SKILL.md +4 -5
  62. package/bundled/skills/{prizmkit-monitoring-setup → prizmkit-tool-monitoring-setup}/SKILL.md +4 -5
  63. package/bundled/skills/{prizmkit-onboarding-generator → prizmkit-tool-onboarding-generator}/SKILL.md +4 -5
  64. package/bundled/skills/{prizmkit-perf-profiler → prizmkit-tool-perf-profiler}/SKILL.md +4 -5
  65. package/bundled/skills/{prizmkit-security-audit → prizmkit-tool-security-audit}/SKILL.md +3 -4
  66. package/bundled/skills/{prizmkit-tech-debt-tracker → prizmkit-tool-tech-debt-tracker}/SKILL.md +3 -4
  67. package/bundled/skills/refactor-skill/SKILL.md +371 -0
  68. package/bundled/skills/refactor-workflow/SKILL.md +17 -119
  69. package/package.json +1 -1
  70. package/src/external-skills.js +71 -0
  71. package/src/index.js +62 -4
  72. package/src/metadata.js +36 -0
  73. package/src/scaffold.js +136 -32
  74. package/bundled/skills/prizmkit-bug-fix-workflow/SKILL.md +0 -356
  75. package/bundled/templates/claude-md-template.md +0 -38
  76. package/bundled/templates/codebuddy-md-template.md +0 -35
  77. /package/bundled/skills/{prizmkit-adr-manager → prizmkit-tool-adr-manager}/assets/adr-template.md +0 -0
@@ -0,0 +1,141 @@
1
+ """Tests for utils.py."""
2
+
3
+ import json
4
+ import os
5
+ import pytest
6
+
7
+ from utils import load_json_file, write_json_file, pad_right, _build_progress_bar
8
+
9
+
10
+ class TestLoadJsonFile:
11
+ def test_valid_json(self, tmp_path):
12
+ p = tmp_path / "valid.json"
13
+ p.write_text('{"key": "value"}', encoding="utf-8")
14
+ data, err = load_json_file(str(p))
15
+ assert err is None
16
+ assert data == {"key": "value"}
17
+
18
+ def test_invalid_json(self, tmp_path):
19
+ p = tmp_path / "invalid.json"
20
+ p.write_text("{not valid json", encoding="utf-8")
21
+ data, err = load_json_file(str(p))
22
+ assert data is None
23
+ assert "Invalid JSON" in err
24
+
25
+ def test_missing_file(self, tmp_path):
26
+ data, err = load_json_file(str(tmp_path / "missing.json"))
27
+ assert data is None
28
+ assert "File not found" in err
29
+
30
+ def test_empty_file(self, tmp_path):
31
+ p = tmp_path / "empty.json"
32
+ p.write_text("", encoding="utf-8")
33
+ data, err = load_json_file(str(p))
34
+ assert data is None
35
+ assert "Invalid JSON" in err
36
+
37
+ def test_unicode_content(self, tmp_path):
38
+ p = tmp_path / "unicode.json"
39
+ p.write_text('{"name": "hello"}', encoding="utf-8")
40
+ data, err = load_json_file(str(p))
41
+ assert err is None
42
+ assert data["name"] == "hello"
43
+
44
+ def test_nested_json(self, tmp_path):
45
+ nested = {"a": {"b": [1, 2, 3]}}
46
+ p = tmp_path / "nested.json"
47
+ p.write_text(json.dumps(nested), encoding="utf-8")
48
+ data, err = load_json_file(str(p))
49
+ assert err is None
50
+ assert data == nested
51
+
52
+
53
+ class TestWriteJsonFile:
54
+ def test_write_and_read_back(self, tmp_path):
55
+ p = str(tmp_path / "output.json")
56
+ data = {"hello": "world", "num": 42}
57
+ err = write_json_file(p, data)
58
+ assert err is None
59
+ read_data, read_err = load_json_file(p)
60
+ assert read_err is None
61
+ assert read_data == data
62
+
63
+ def test_creates_parent_directories(self, tmp_path):
64
+ p = str(tmp_path / "a" / "b" / "c" / "output.json")
65
+ err = write_json_file(p, {"nested": True})
66
+ assert err is None
67
+ assert os.path.isfile(p)
68
+
69
+ def test_overwrites_existing(self, tmp_path):
70
+ p = str(tmp_path / "overwrite.json")
71
+ write_json_file(p, {"v": 1})
72
+ write_json_file(p, {"v": 2})
73
+ data, _ = load_json_file(p)
74
+ assert data["v"] == 2
75
+
76
+ def test_unicode_data(self, tmp_path):
77
+ p = str(tmp_path / "unicode.json")
78
+ err = write_json_file(p, {"name": "hello"})
79
+ assert err is None
80
+ data, _ = load_json_file(p)
81
+ assert data["name"] == "hello"
82
+
83
+
84
+ class TestPadRight:
85
+ def test_shorter_than_width(self):
86
+ result = pad_right("abc", 10)
87
+ assert len(result) == 10
88
+ assert result == "abc "
89
+
90
+ def test_exact_width(self):
91
+ result = pad_right("abcde", 5)
92
+ assert result == "abcde"
93
+
94
+ def test_longer_than_width(self):
95
+ result = pad_right("abcdefgh", 5)
96
+ assert result == "abcdefgh"
97
+
98
+ def test_empty_string(self):
99
+ result = pad_right("", 5)
100
+ assert result == " "
101
+
102
+ def test_ansi_codes_ignored(self):
103
+ # ANSI escape should not count toward visible length
104
+ text = "\033[92mHi\033[0m" # visible "Hi" = 2 chars
105
+ result = pad_right(text, 5)
106
+ # visible width is 2, so 3 spaces of padding
107
+ assert result.endswith(" ")
108
+
109
+ def test_zero_width(self):
110
+ result = pad_right("abc", 0)
111
+ assert result == "abc"
112
+
113
+
114
+ class TestBuildProgressBar:
115
+ def test_zero_percent(self):
116
+ bar = _build_progress_bar(0)
117
+ assert "0%" in bar
118
+ assert "\u2591" in bar # empty blocks
119
+ assert "\u2588" not in bar # no filled blocks
120
+
121
+ def test_fifty_percent(self):
122
+ bar = _build_progress_bar(50, width=20)
123
+ assert "50%" in bar
124
+ assert bar.count("\u2588") == 10
125
+ assert bar.count("\u2591") == 10
126
+
127
+ def test_hundred_percent(self):
128
+ bar = _build_progress_bar(100, width=20)
129
+ assert "100%" in bar
130
+ assert bar.count("\u2588") == 20
131
+ assert bar.count("\u2591") == 0
132
+
133
+ def test_custom_width(self):
134
+ bar = _build_progress_bar(50, width=10)
135
+ assert bar.count("\u2588") == 5
136
+ assert bar.count("\u2591") == 5
137
+
138
+ def test_partial_percent(self):
139
+ bar = _build_progress_bar(33, width=10)
140
+ assert bar.count("\u2588") == 3
141
+ assert bar.count("\u2591") == 7
@@ -0,0 +1,153 @@
1
+ # Rules 使用说明
2
+
3
+ ## 目录结构
4
+
5
+ ```
6
+ core/rules/
7
+ ├── _rules-metadata.json # 规则元数据 + preset 定义
8
+ ├── prizm/ # PrizmKit 专属规则
9
+ │ ├── prizm-documentation.md
10
+ │ ├── prizm-commit-workflow.md
11
+ │ └── prizm-progressive-loading.md
12
+ └── general/ # 通用 AI 行为规则
13
+ └── prefer-linux-commands.md
14
+ ```
15
+
16
+ ## 现有规则
17
+
18
+ ### PrizmKit 专属规则(`prizm/`)
19
+
20
+ | 文件 | 说明 |
21
+ |------|------|
22
+ | `prizm-documentation.md` | 修改源文件时同步更新 `.prizm-docs/` |
23
+ | `prizm-commit-workflow.md` | 提交前更新文档,遵循 Conventional Commits |
24
+ | `prizm-progressive-loading.md` | 按需渐进加载 `.prizm-docs/`,禁止一次性全量读取 |
25
+
26
+ ### 通用规则(`general/`)
27
+
28
+ | 文件 | 说明 |
29
+ |------|------|
30
+ | `prefer-linux-commands.md` | 优先使用 Linux/Unix 命令,避免平台特定语法 |
31
+
32
+ ---
33
+
34
+ ## 安装预设(Presets)
35
+
36
+ 安装时通过 `--rules` 选项选择预设,在 `_rules-metadata.json` 的 `presets` 字段定义:
37
+
38
+ | Preset | 包含规则 |
39
+ |--------|---------|
40
+ | `recommended`(默认) | 全部 4 条规则 |
41
+ | `minimal` | prizm-progressive-loading + prefer-linux-commands |
42
+ | `none` | 不安装任何规则 |
43
+
44
+ 安装命令:
45
+ ```bash
46
+ npx prizmkit install . --rules recommended
47
+ npx prizmkit install . --rules minimal
48
+ npx prizmkit install . --rules none
49
+ ```
50
+
51
+ ---
52
+
53
+ ## 安装后的文件位置
54
+
55
+ | 平台 | 安装目录 | 格式 |
56
+ |------|---------|------|
57
+ | Claude Code | `.claude/rules/<name>.md` | Markdown + YAML frontmatter |
58
+ | CodeBuddy | `.codebuddy/rules/<name>.mdc` | `.mdc` 格式(自动转换) |
59
+
60
+ 规则名使用 `category/filename` 路径格式(如 `prizm/prizm-documentation`),安装时取最后一段作为文件名(`prizm-documentation.md`)。
61
+
62
+ ---
63
+
64
+ ## 添加新规则
65
+
66
+ ### 1. 创建规则文件
67
+
68
+ 在对应子目录创建 `.md` 文件:
69
+
70
+ ```bash
71
+ # PrizmKit 专属规则
72
+ core/rules/prizm/my-new-rule.md
73
+
74
+ # 通用规则
75
+ core/rules/general/my-new-rule.md
76
+ ```
77
+
78
+ 规则文件格式:
79
+ ```markdown
80
+ ---
81
+ description: "简短描述这条规则的作用"
82
+ ---
83
+
84
+ 规则正文,直接用自然语言描述 AI 应该遵守的行为。
85
+ ```
86
+
87
+ 如需限定文件类型(仅对特定文件触发),添加 `globs` 字段:
88
+ ```markdown
89
+ ---
90
+ description: "仅对 TypeScript 文件生效的规则"
91
+ globs:
92
+ - "**/*.ts"
93
+ - "**/*.tsx"
94
+ ---
95
+ ```
96
+
97
+ ### 2. 在 `_rules-metadata.json` 注册
98
+
99
+ 打开 `core/rules/_rules-metadata.json`,在 `rules` 对象中添加条目:
100
+
101
+ ```json
102
+ {
103
+ "rules": {
104
+ "prizm/my-new-rule": {
105
+ "description": "一句话说明规则用途",
106
+ "tags": ["prizm", "custom"]
107
+ }
108
+ }
109
+ }
110
+ ```
111
+
112
+ 规则名格式:`<category>/<filename>`(不含 `.md` 后缀)。
113
+
114
+ ### 3. 添加到 Preset(可选)
115
+
116
+ 如果希望新规则默认随 `recommended` 安装,在 `presets.recommended.rules` 数组中追加:
117
+
118
+ ```json
119
+ {
120
+ "presets": {
121
+ "recommended": {
122
+ "rules": [
123
+ "prizm/prizm-documentation",
124
+ "prizm/prizm-commit-workflow",
125
+ "prizm/prizm-progressive-loading",
126
+ "general/prefer-linux-commands",
127
+ "prizm/my-new-rule"
128
+ ]
129
+ }
130
+ }
131
+ }
132
+ ```
133
+
134
+ 也可以只添加到特定 preset,或不加入任何 preset(规则存在但不默认安装)。
135
+
136
+ ### 4. 重新打包
137
+
138
+ 修改 `core/rules/` 后,若需更新 npm 包的 `bundled/` 内容:
139
+
140
+ ```bash
141
+ npm run bundle
142
+ ```
143
+
144
+ ---
145
+
146
+ ## CodeBuddy `.mdc` 格式转换说明
147
+
148
+ 安装到 CodeBuddy 时,`.md` 文件会由 `adapters/codebuddy/rules-adapter.js` 自动转换为 `.mdc` 格式:
149
+
150
+ - 原始 `description` 字段保留
151
+ - 自动添加 `alwaysApply: true`、`enabled: true`、`updatedAt` 字段
152
+ - `globs` 字段(如有)保持不变
153
+ - 规则正文内容不变
@@ -0,0 +1,43 @@
1
+ {
2
+ "version": "1.0.0",
3
+ "rules": {
4
+ "prizm/prizm-documentation": {
5
+ "description": "PrizmKit documentation update protocol",
6
+ "tags": ["prizm", "docs"]
7
+ },
8
+ "prizm/prizm-commit-workflow": {
9
+ "description": "Conventional commits + prizm-docs update before commit",
10
+ "tags": ["prizm", "git"]
11
+ },
12
+ "prizm/prizm-progressive-loading": {
13
+ "description": "Progressive .prizm-docs context loading protocol",
14
+ "tags": ["prizm", "context"]
15
+ },
16
+ "general/prefer-linux-commands": {
17
+ "description": "Prefer Linux/Unix shell commands",
18
+ "tags": ["general", "shell"]
19
+ }
20
+ },
21
+ "presets": {
22
+ "recommended": {
23
+ "description": "All PrizmKit rules + general rules (recommended)",
24
+ "rules": [
25
+ "prizm/prizm-documentation",
26
+ "prizm/prizm-commit-workflow",
27
+ "prizm/prizm-progressive-loading",
28
+ "general/prefer-linux-commands"
29
+ ]
30
+ },
31
+ "minimal": {
32
+ "description": "Minimal: progressive loading + general rules only",
33
+ "rules": [
34
+ "prizm/prizm-progressive-loading",
35
+ "general/prefer-linux-commands"
36
+ ]
37
+ },
38
+ "none": {
39
+ "description": "No rules installed",
40
+ "rules": []
41
+ }
42
+ }
43
+ }
@@ -0,0 +1,9 @@
1
+ ---
2
+ description: "Prefer Linux/Unix commands for shell operations"
3
+ ---
4
+
5
+ When writing or suggesting shell commands:
6
+ 1. Prefer standard Linux/Unix commands (ls, grep, find, cat, sed, awk, etc.)
7
+ 2. Avoid PowerShell, Windows CMD, or macOS-specific commands unless the target is explicitly Windows
8
+ 3. Use POSIX-compliant syntax when possible for cross-platform compatibility
9
+ 4. For file operations, prefer: cp, mv, rm, mkdir, chmod over GUI or platform-specific tools
@@ -0,0 +1,10 @@
1
+ ---
2
+ description: "PrizmKit commit workflow rules"
3
+ ---
4
+
5
+ Before any git commit in this project:
6
+ 1. Update `.prizm-docs/` for affected modules
7
+ 2. Use Conventional Commits format: type(scope): description
8
+ 3. Bug fixes use `fix()` prefix, not `feat()`
9
+ 4. Do NOT create REGISTRY.md entries for bug fixes
10
+ 5. Use `/prizmkit-committer` command for the complete commit workflow
@@ -0,0 +1,19 @@
1
+ ---
2
+ description: "PrizmKit documentation rules"
3
+ globs:
4
+ - "**/*.ts"
5
+ - "**/*.tsx"
6
+ - "**/*.js"
7
+ - "**/*.jsx"
8
+ - "**/*.py"
9
+ - "**/*.go"
10
+ - "**/*.rs"
11
+ - "**/*.java"
12
+ ---
13
+
14
+ When modifying source files in this project:
15
+ 1. Check if `.prizm-docs/root.prizm` exists
16
+ 2. If it does, read it before making changes to understand project structure
17
+ 3. After making changes, update affected `.prizm-docs/` files
18
+ 4. Follow the Prizm doc format (KEY: value, not prose)
19
+ 5. Size limits: L0 = 4KB, L1 = 3KB, L2 = 5KB
@@ -0,0 +1,11 @@
1
+ ---
2
+ description: "PrizmKit progressive context loading protocol"
3
+ ---
4
+
5
+ This project uses PrizmKit's progressive loading protocol:
6
+ - ON SESSION START: Read `.prizm-docs/root.prizm` (L0 — project map)
7
+ - ON TASK: Read L1 (`.prizm-docs/<module>.prizm`) for relevant modules
8
+ - ON FILE EDIT: Read L2 (`.prizm-docs/<module>/<submodule>.prizm`) before modifying
9
+ - NEVER load all .prizm docs at once
10
+ - Arrow notation (->) in .prizm files indicates load pointers
11
+ - DECISIONS and CHANGELOG in .prizm files are append-only