prizmkit 1.0.115 → 1.0.118
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/bundled/VERSION.json +3 -3
- package/bundled/dev-pipeline/lib/common.sh +27 -0
- package/bundled/dev-pipeline/retry-bug.sh +2 -3
- package/bundled/dev-pipeline/retry-feature.sh +2 -3
- package/bundled/dev-pipeline/run-bugfix.sh +1 -0
- package/bundled/dev-pipeline/run.sh +1 -0
- package/bundled/dev-pipeline/templates/bootstrap-tier1.md +4 -1
- package/bundled/dev-pipeline/templates/bootstrap-tier2.md +4 -1
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +4 -1
- package/bundled/skills/_metadata.json +1 -1
- package/bundled/skills/app-planner/SKILL.md +5 -0
- package/bundled/skills/app-planner/assets/planning-guide.md +52 -4
- package/bundled/skills/app-planner/scripts/validate-and-generate.py +20 -0
- package/bundled/skills/prizmkit-init/SKILL.md +11 -0
- package/package.json +1 -1
package/bundled/VERSION.json
CHANGED
|
@@ -106,3 +106,30 @@ prizm_check_common_dependencies() {
|
|
|
106
106
|
log_warn "Continuing anyway (will fail when spawning sessions)..."
|
|
107
107
|
fi
|
|
108
108
|
}
|
|
109
|
+
|
|
110
|
+
# Ensure git is installed and the current directory is a git repository.
|
|
111
|
+
# If git is missing, print install instructions and exit.
|
|
112
|
+
# If not inside a git repo, run git init + initial commit automatically.
|
|
113
|
+
prizm_ensure_git_repo() {
|
|
114
|
+
if ! command -v git &>/dev/null; then
|
|
115
|
+
log_error "git is required but not installed."
|
|
116
|
+
log_error "Install git:"
|
|
117
|
+
log_error " macOS: brew install git or xcode-select --install"
|
|
118
|
+
log_error " Ubuntu: sudo apt-get install git"
|
|
119
|
+
log_error " Windows: https://git-scm.com/download/win"
|
|
120
|
+
exit 1
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
if ! git rev-parse --is-inside-work-tree &>/dev/null 2>&1; then
|
|
124
|
+
log_warn "Current directory is not a git repository."
|
|
125
|
+
log_info "Initializing git repository..."
|
|
126
|
+
git init -b main
|
|
127
|
+
# Create initial commit so branches and diffs work
|
|
128
|
+
git add -A
|
|
129
|
+
git commit --no-verify -m "chore: initial commit (auto-created by dev-pipeline)" || {
|
|
130
|
+
# If nothing to commit (empty project), create an empty initial commit
|
|
131
|
+
git commit --no-verify --allow-empty -m "chore: initial commit (auto-created by dev-pipeline)"
|
|
132
|
+
}
|
|
133
|
+
log_success "Git repository initialized with initial commit."
|
|
134
|
+
fi
|
|
135
|
+
}
|
|
@@ -164,6 +164,7 @@ sys.exit(1)
|
|
|
164
164
|
# ============================================================
|
|
165
165
|
|
|
166
166
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
167
|
+
ORIGINAL_BRANCH=$(git -C "$PROJECT_ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")
|
|
167
168
|
|
|
168
169
|
log_info "Cleaning $BUG_ID artifacts for full restart..."
|
|
169
170
|
python3 "$SCRIPTS_DIR/update-bug-status.py" \
|
|
@@ -329,9 +330,7 @@ log_info "exit_code=$EXIT_CODE"
|
|
|
329
330
|
|
|
330
331
|
# ── Determine session outcome from observable signals ──────────────
|
|
331
332
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
332
|
-
DEFAULT_BRANCH
|
|
333
|
-
| sed 's@^refs/remotes/origin/@@') \
|
|
334
|
-
|| DEFAULT_BRANCH=$(git -C "$PROJECT_ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null | grep -E '^(main|master)$' || echo "main")
|
|
333
|
+
DEFAULT_BRANCH="$ORIGINAL_BRANCH"
|
|
335
334
|
|
|
336
335
|
if [[ $EXIT_CODE -eq 124 ]]; then
|
|
337
336
|
log_warn "Session timed out after ${SESSION_TIMEOUT}s"
|
|
@@ -149,6 +149,7 @@ sys.exit(1)
|
|
|
149
149
|
# ============================================================
|
|
150
150
|
|
|
151
151
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
152
|
+
ORIGINAL_BRANCH=$(git -C "$PROJECT_ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")
|
|
152
153
|
FEATURE_SLUG=$(FEATURE_ID="$FEATURE_ID" FEATURE_TITLE="$FEATURE_TITLE" python3 -c "
|
|
153
154
|
import os, re
|
|
154
155
|
fid = os.environ['FEATURE_ID'].replace('F-', '').replace('f-', '').zfill(3)
|
|
@@ -338,9 +339,7 @@ log_info "exit_code=$EXIT_CODE"
|
|
|
338
339
|
|
|
339
340
|
# ── Determine session outcome from observable signals ──────────────
|
|
340
341
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
341
|
-
DEFAULT_BRANCH
|
|
342
|
-
| sed 's@^refs/remotes/origin/@@') \
|
|
343
|
-
|| DEFAULT_BRANCH=$(git -C "$PROJECT_ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null | grep -E '^(main|master)$' || echo "main")
|
|
342
|
+
DEFAULT_BRANCH="$ORIGINAL_BRANCH"
|
|
344
343
|
|
|
345
344
|
if [[ $EXIT_CODE -eq 124 ]]; then
|
|
346
345
|
log_warn "Session timed out after ${SESSION_TIMEOUT}s"
|
|
@@ -91,7 +91,10 @@ If MISSING — build it now:
|
|
|
91
91
|
2. Scan `src/` for files related to this feature; read each one
|
|
92
92
|
3. Write `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md`:
|
|
93
93
|
- **Section 1 — Feature Brief**: feature description + acceptance criteria (copy from above)
|
|
94
|
-
- **Section 2 — Project Structure**:
|
|
94
|
+
- **Section 2 — Project Structure**: run the following to get a visual directory tree, then paste output:
|
|
95
|
+
```bash
|
|
96
|
+
find . -maxdepth 2 -type d -not -path '*/node_modules/*' -not -path '*/.git/*' -not -path '*/dist/*' -not -path '*/build/*' -not -path '*/__pycache__/*' -not -path '*/vendor/*' | sed -e 's;[^/]*/;|____;g;s;____|; |;g'
|
|
97
|
+
```
|
|
95
98
|
- **Section 3 — Prizm Context**: content of root.prizm and relevant L1/L2 docs
|
|
96
99
|
- **Section 4 — Existing Source Files**: **full verbatim content** of each related file in fenced code blocks (with `### path/to/file` heading and line count). Include ALL files needed for implementation and review — downstream phases read this section instead of re-reading individual source files
|
|
97
100
|
- **Section 5 — Existing Tests**: full content of related test files as code block
|
|
@@ -102,7 +102,10 @@ If MISSING — build it now:
|
|
|
102
102
|
2. Scan `src/` for files related to this feature; read each one
|
|
103
103
|
3. Write `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md`:
|
|
104
104
|
- **Section 1 — Feature Brief**: feature description + acceptance criteria (copy from above)
|
|
105
|
-
- **Section 2 — Project Structure**:
|
|
105
|
+
- **Section 2 — Project Structure**: run the following to get a visual directory tree, then paste output:
|
|
106
|
+
```bash
|
|
107
|
+
find . -maxdepth 2 -type d -not -path '*/node_modules/*' -not -path '*/.git/*' -not -path '*/dist/*' -not -path '*/build/*' -not -path '*/__pycache__/*' -not -path '*/vendor/*' | sed -e 's;[^/]*/;|____;g;s;____|; |;g'
|
|
108
|
+
```
|
|
106
109
|
- **Section 3 — Prizm Context**: full content of root.prizm and relevant L1/L2 docs
|
|
107
110
|
- **Section 4 — File Manifest**: For each file relevant to this feature, list: file path, why it's needed (modify/reference/test), key interface signatures (function names + params + return types). Do NOT include full file content — agents read files on-demand. Format:
|
|
108
111
|
### Files to Modify
|
|
@@ -180,7 +180,10 @@ If `EXISTING_CODE` is non-empty: your spec/plan/tasks must reflect this existing
|
|
|
180
180
|
2. Scan `src/` for files related to this feature; read each one
|
|
181
181
|
3. Write `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md`:
|
|
182
182
|
- **Section 1 — Feature Brief**: feature description + acceptance criteria (copy from above)
|
|
183
|
-
- **Section 2 — Project Structure**:
|
|
183
|
+
- **Section 2 — Project Structure**: run the following to get a visual directory tree, then paste output:
|
|
184
|
+
```bash
|
|
185
|
+
find . -maxdepth 2 -type d -not -path '*/node_modules/*' -not -path '*/.git/*' -not -path '*/dist/*' -not -path '*/build/*' -not -path '*/__pycache__/*' -not -path '*/vendor/*' | sed -e 's;[^/]*/;|____;g;s;____|; |;g'
|
|
186
|
+
```
|
|
184
187
|
- **Section 3 — Prizm Context**: full content of root.prizm and relevant L1/L2 docs
|
|
185
188
|
- **Section 4 — File Manifest**: For each file relevant to this feature, list: file path, why it's needed (modify/reference/test), key interface signatures (function names + params + return types). Do NOT include full file content — agents read files on-demand. Format:
|
|
186
189
|
### Files to Modify
|
|
@@ -49,6 +49,10 @@ Before questions, check optional context files (never block if absent):
|
|
|
49
49
|
- `.prizm-docs/root.prizm` (architecture/project context)
|
|
50
50
|
- `.prizmkit/config.json` (existing stack preferences and detected tech stack)
|
|
51
51
|
- existing `feature-list.json` (required for incremental mode)
|
|
52
|
+
- If `.prizm-docs/root.prizm` is absent and the project has existing source code, scan the directory structure to understand the codebase layout:
|
|
53
|
+
```bash
|
|
54
|
+
find . -maxdepth 2 -type d -not -path '*/node_modules/*' -not -path '*/.git/*' -not -path '*/dist/*' -not -path '*/build/*' -not -path '*/__pycache__/*' -not -path '*/vendor/*' | sed -e 's;[^/]*/;|____;g;s;____|; |;g'
|
|
55
|
+
```
|
|
52
56
|
|
|
53
57
|
**Tech stack auto-population from config.json:**
|
|
54
58
|
- If `.prizmkit/config.json` contains a `tech_stack` object, use it to pre-fill `global_context` fields in the generated `feature-list.json`.
|
|
@@ -227,6 +231,7 @@ AI: "Ready to proceed to dev-pipeline."
|
|
|
227
231
|
- new items default `status: "pending"`
|
|
228
232
|
- English feature titles for stable slug generation
|
|
229
233
|
- `model` field is optional — omitting it means the pipeline uses $MODEL env or CLI default
|
|
234
|
+
- **descriptions must be implementation-ready** — minimum 15 words (error), recommended 30/50/80 words for low/medium/high complexity (warning). See `planning-guide.md` §4 for what to include.
|
|
230
235
|
|
|
231
236
|
## Next-Step Execution Policy (after planning)
|
|
232
237
|
|
|
@@ -174,7 +174,55 @@ F-010: Admin Dashboard (deps: F-006, F-007)
|
|
|
174
174
|
|
|
175
175
|
---
|
|
176
176
|
|
|
177
|
-
## 4.
|
|
177
|
+
## 4. Feature Description Writing Guide
|
|
178
|
+
|
|
179
|
+
Feature descriptions are the **primary input** for autonomous pipeline sessions. A thin description forces the AI to guess — producing worse code. Invest in rich descriptions upfront.
|
|
180
|
+
|
|
181
|
+
### Minimum Word Counts
|
|
182
|
+
|
|
183
|
+
| Complexity | Minimum Words | Warning Threshold |
|
|
184
|
+
|------------|---------------|-------------------|
|
|
185
|
+
| low | 15 | 30 |
|
|
186
|
+
| medium | 15 | 50 |
|
|
187
|
+
| high | 15 | 80 |
|
|
188
|
+
|
|
189
|
+
Below 15 words is a validation error. Below the threshold triggers a warning.
|
|
190
|
+
|
|
191
|
+
### What to Include
|
|
192
|
+
|
|
193
|
+
Every description should cover these aspects (adapt per feature type):
|
|
194
|
+
|
|
195
|
+
1. **What to build** — concrete deliverables (API endpoints, UI pages/components, CLI commands, data models)
|
|
196
|
+
2. **Key behaviors** — business rules, validation, state transitions, workflows
|
|
197
|
+
3. **Integration points** — which existing modules, services, or APIs it connects to
|
|
198
|
+
4. **Data model** — entities, relationships, key fields, storage approach (when applicable)
|
|
199
|
+
5. **Error/edge cases** — failure modes, empty states, limits, unauthorized access
|
|
200
|
+
|
|
201
|
+
### Good vs Bad Examples
|
|
202
|
+
|
|
203
|
+
**Bad** (17 words — too thin):
|
|
204
|
+
```
|
|
205
|
+
"Build user authentication with login and registration. Support email/password and social login options."
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**Good** (78 words — implementation-ready):
|
|
209
|
+
```
|
|
210
|
+
"Implement user authentication with email/password registration and login. Create a User model with fields: id, email (unique), password_hash, display_name, created_at, last_login. Build POST /api/auth/register (validate email format, enforce 8+ char password, check uniqueness, hash with bcrypt, return JWT), POST /api/auth/login (verify credentials, issue JWT with 7-day expiry), and GET /api/auth/me (return current user from JWT). Add auth middleware that validates JWT on protected routes. Handle errors: duplicate email (409), invalid credentials (401), expired token (401)."
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**Bad** (12 words):
|
|
214
|
+
```
|
|
215
|
+
"Create the main dashboard page showing project overview and recent activity."
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**Good** (65 words):
|
|
219
|
+
```
|
|
220
|
+
"Build a dashboard page at /dashboard as the post-login landing screen. Display: (1) summary cards showing total projects count, active tasks count, and recent activity count; (2) a recent activity feed listing the last 10 actions across all projects with timestamps; (3) a quick-access project list showing the 5 most recently updated projects. Fetch data via GET /api/dashboard/summary. Show loading skeleton on initial load, empty state when user has no projects."
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## 5. Acceptance Criteria Writing Guide
|
|
178
226
|
|
|
179
227
|
Acceptance criteria define what "done" means for a feature. They should be specific, testable, and unambiguous.
|
|
180
228
|
|
|
@@ -215,7 +263,7 @@ Then [expected outcome]
|
|
|
215
263
|
|
|
216
264
|
---
|
|
217
265
|
|
|
218
|
-
##
|
|
266
|
+
## 6. Complexity Estimation Guide
|
|
219
267
|
|
|
220
268
|
| Complexity | Characteristics | Typical Scope |
|
|
221
269
|
|------------|----------------|---------------|
|
|
@@ -242,7 +290,7 @@ Consider splitting a feature if it exhibits any of the following:
|
|
|
242
290
|
|
|
243
291
|
---
|
|
244
292
|
|
|
245
|
-
##
|
|
293
|
+
## 7. Dependency Graph Rules
|
|
246
294
|
|
|
247
295
|
These rules ensure the feature dependency graph is valid and buildable.
|
|
248
296
|
|
|
@@ -270,7 +318,7 @@ These rules ensure the feature dependency graph is valid and buildable.
|
|
|
270
318
|
|
|
271
319
|
---
|
|
272
320
|
|
|
273
|
-
##
|
|
321
|
+
## 8. Session Granularity Decision Rules
|
|
274
322
|
|
|
275
323
|
Session granularity determines whether a feature is implemented in a single coding session or split across multiple sub-feature sessions.
|
|
276
324
|
|
|
@@ -229,6 +229,26 @@ def validate_feature_list(data, planning_mode="new"):
|
|
|
229
229
|
if not isinstance(val, str) or not val.strip():
|
|
230
230
|
errors.append("{}: {} must be a non-empty string".format(label, key))
|
|
231
231
|
|
|
232
|
+
# -- Description depth check --
|
|
233
|
+
desc = feat.get("description", "")
|
|
234
|
+
if isinstance(desc, str) and desc.strip():
|
|
235
|
+
word_count = len(desc.split())
|
|
236
|
+
complexity = feat.get("estimated_complexity", "medium")
|
|
237
|
+
min_words = {"low": 30, "medium": 50, "high": 80}.get(complexity, 50)
|
|
238
|
+
if word_count < 15:
|
|
239
|
+
errors.append(
|
|
240
|
+
"{}: description too short ({} words, minimum 15). "
|
|
241
|
+
"Include: what to build, key behaviors, integration points, "
|
|
242
|
+
"and data model overview.".format(label, word_count)
|
|
243
|
+
)
|
|
244
|
+
elif word_count < min_words:
|
|
245
|
+
warnings.append(
|
|
246
|
+
"{}: description only {} words (recommend {}+ for {} complexity). "
|
|
247
|
+
"Richer descriptions produce better pipeline results.".format(
|
|
248
|
+
label, word_count, min_words, complexity
|
|
249
|
+
)
|
|
250
|
+
)
|
|
251
|
+
|
|
232
252
|
# -- Priority --
|
|
233
253
|
priority = feat.get("priority")
|
|
234
254
|
if isinstance(priority, int) and priority > 0:
|
|
@@ -49,6 +49,17 @@ BROWNFIELD WORKFLOW (existing project):
|
|
|
49
49
|
- SUB-MODULES: directories INSIDE a top-level module (e.g. `src/routes/`, `src/models/`)
|
|
50
50
|
- A sub-module maps to `.prizm-docs/<M>/<S>.prizm`, never to `.prizm-docs/<S>.prizm` — flattening would create ambiguous paths when two modules have identically-named sub-modules
|
|
51
51
|
- Exclude: `.git/`, `node_modules/`, `vendor/`, `build/`, `dist/`, `__pycache__/`, `target/`, `bin/`, `.claude/`, `.codebuddy/`, `.prizmkit/`, `.prizm-docs/`, `dev-pipeline/`
|
|
52
|
+
- **Scan command** — run this to get a 2-level directory tree (excludes noise directories):
|
|
53
|
+
```bash
|
|
54
|
+
find . -maxdepth 2 -type d \
|
|
55
|
+
-not -path '*/node_modules/*' -not -path '*/.git/*' \
|
|
56
|
+
-not -path '*/dist/*' -not -path '*/build/*' \
|
|
57
|
+
-not -path '*/__pycache__/*' -not -path '*/vendor/*' \
|
|
58
|
+
-not -path '*/.claude/*' -not -path '*/.codebuddy/*' \
|
|
59
|
+
-not -path '*/.prizmkit/*' -not -path '*/.prizm-docs/*' \
|
|
60
|
+
-not -path '*/dev-pipeline/*' -not -path '*/target/*' \
|
|
61
|
+
| sed -e 's;[^/]*/;|____;g;s;____|; |;g'
|
|
62
|
+
```
|
|
52
63
|
3. Identify entry points by language convention
|
|
53
64
|
4. Catalog dependencies (external packages)
|
|
54
65
|
5. Count source files per directory
|