prizmkit 1.0.9 → 1.0.11
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/heartbeat.sh +12 -2
- package/bundled/dev-pipeline/retry-feature.sh +7 -0
- package/bundled/dev-pipeline/run.sh +14 -0
- package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +1 -0
- package/bundled/dev-pipeline/scripts/update-feature-status.py +49 -5
- package/bundled/dev-pipeline/templates/bootstrap-prompt.md +12 -1
- package/package.json +1 -1
package/bundled/VERSION.json
CHANGED
|
@@ -166,8 +166,18 @@ detect_stream_json_support() {
|
|
|
166
166
|
local cli_cmd="$1"
|
|
167
167
|
USE_STREAM_JSON="false"
|
|
168
168
|
|
|
169
|
-
#
|
|
170
|
-
if "$cli_cmd"
|
|
169
|
+
# CodeBuddy (cbc) always supports stream-json
|
|
170
|
+
if [[ "$cli_cmd" == "cbc" ]]; then
|
|
171
|
+
USE_STREAM_JSON="true"
|
|
172
|
+
return 0
|
|
173
|
+
fi
|
|
174
|
+
|
|
175
|
+
# For other CLIs, try to detect support via --help output
|
|
176
|
+
# Use explicit file descriptor to avoid issues in background processes
|
|
177
|
+
local help_output
|
|
178
|
+
help_output=$("$cli_cmd" --help 2>&1) || true
|
|
179
|
+
|
|
180
|
+
if echo "$help_output" | grep -q "stream-json"; then
|
|
171
181
|
USE_STREAM_JSON="true"
|
|
172
182
|
fi
|
|
173
183
|
}
|
|
@@ -202,6 +202,13 @@ if [[ "$USE_STREAM_JSON" == "true" ]]; then
|
|
|
202
202
|
STREAM_JSON_FLAG="--output-format stream-json"
|
|
203
203
|
fi
|
|
204
204
|
|
|
205
|
+
# Mark feature as in-progress before spawning session
|
|
206
|
+
python3 "$SCRIPTS_DIR/update-feature-status.py" \
|
|
207
|
+
--feature-list "$FEATURE_LIST" \
|
|
208
|
+
--state-dir "$STATE_DIR" \
|
|
209
|
+
--feature-id "$FEATURE_ID" \
|
|
210
|
+
--action start >/dev/null 2>&1 || true
|
|
211
|
+
|
|
205
212
|
# Spawn AI CLI session
|
|
206
213
|
case "$CLI_CMD" in
|
|
207
214
|
*claude*)
|
|
@@ -516,6 +516,13 @@ sys.exit(1)
|
|
|
516
516
|
return 0
|
|
517
517
|
fi
|
|
518
518
|
|
|
519
|
+
# Mark feature as in-progress before spawning session
|
|
520
|
+
python3 "$SCRIPTS_DIR/update-feature-status.py" \
|
|
521
|
+
--feature-list "$feature_list" \
|
|
522
|
+
--state-dir "$STATE_DIR" \
|
|
523
|
+
--feature-id "$feature_id" \
|
|
524
|
+
--action start >/dev/null 2>&1 || true
|
|
525
|
+
|
|
519
526
|
# Spawn AI CLI Session
|
|
520
527
|
echo ""
|
|
521
528
|
echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
|
|
@@ -729,6 +736,13 @@ with open(os.path.join(state_dir, 'current-session.json'), 'w') as f:
|
|
|
729
736
|
json.dump(data, f, indent=2)
|
|
730
737
|
" "$feature_id" "$session_id" "$STATE_DIR"
|
|
731
738
|
|
|
739
|
+
# Mark feature as in-progress before spawning session
|
|
740
|
+
python3 "$SCRIPTS_DIR/update-feature-status.py" \
|
|
741
|
+
--feature-list "$feature_list" \
|
|
742
|
+
--state-dir "$STATE_DIR" \
|
|
743
|
+
--feature-id "$feature_id" \
|
|
744
|
+
--action start >/dev/null 2>&1 || true
|
|
745
|
+
|
|
732
746
|
# Spawn session and wait
|
|
733
747
|
log_info "Spawning AI CLI session: $session_id"
|
|
734
748
|
_SPAWN_RESULT=""
|
|
@@ -428,6 +428,7 @@ def build_replacements(args, feature, features, global_context, script_dir):
|
|
|
428
428
|
"{{RUN_ID}}": args.run_id,
|
|
429
429
|
"{{SESSION_ID}}": args.session_id,
|
|
430
430
|
"{{FEATURE_ID}}": args.feature_id,
|
|
431
|
+
"{{FEATURE_LIST_PATH}}": os.path.abspath(args.feature_list),
|
|
431
432
|
"{{FEATURE_TITLE}}": feature.get("title", ""),
|
|
432
433
|
"{{RETRY_COUNT}}": str(args.retry_count),
|
|
433
434
|
"{{MAX_RETRIES}}": str(DEFAULT_MAX_RETRIES),
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""Core state machine for updating feature status in the dev-pipeline.
|
|
3
3
|
|
|
4
|
-
Handles
|
|
4
|
+
Handles eight actions:
|
|
5
5
|
- get_next: Find the next feature to process based on priority and dependencies
|
|
6
|
+
- start: Mark a feature as in_progress when a session starts
|
|
6
7
|
- update: Update a feature's status based on session outcome
|
|
7
8
|
- status: Print a formatted overview of all features
|
|
8
9
|
- pause: Save pipeline state for graceful shutdown
|
|
@@ -13,7 +14,7 @@ Handles seven actions:
|
|
|
13
14
|
Usage:
|
|
14
15
|
python3 update-feature-status.py \
|
|
15
16
|
--feature-list <path> --state-dir <path> \
|
|
16
|
-
--action <get_next|update|status|pause|reset|clean|complete> \
|
|
17
|
+
--action <get_next|start|update|status|pause|reset|clean|complete> \
|
|
17
18
|
[--feature-id <id>] [--session-status <status>] \
|
|
18
19
|
[--session-id <id>] [--max-retries <n>]
|
|
19
20
|
"""
|
|
@@ -63,13 +64,13 @@ def parse_args():
|
|
|
63
64
|
parser.add_argument(
|
|
64
65
|
"--action",
|
|
65
66
|
required=True,
|
|
66
|
-
choices=["get_next", "update", "status", "pause", "reset", "clean", "complete"],
|
|
67
|
+
choices=["get_next", "start", "update", "status", "pause", "reset", "clean", "complete"],
|
|
67
68
|
help="Action to perform",
|
|
68
69
|
)
|
|
69
70
|
parser.add_argument(
|
|
70
71
|
"--feature-id",
|
|
71
72
|
default=None,
|
|
72
|
-
help="Feature ID (required for
|
|
73
|
+
help="Feature ID (required for start/reset/clean/complete/update actions)",
|
|
73
74
|
)
|
|
74
75
|
parser.add_argument(
|
|
75
76
|
"--session-status",
|
|
@@ -767,6 +768,47 @@ def action_status(feature_list_data, state_dir):
|
|
|
767
768
|
print("╚" + "═" * BOX_WIDTH + "╝")
|
|
768
769
|
|
|
769
770
|
|
|
771
|
+
# ---------------------------------------------------------------------------
|
|
772
|
+
# Action: start
|
|
773
|
+
# ---------------------------------------------------------------------------
|
|
774
|
+
|
|
775
|
+
def action_start(args, feature_list_path, state_dir):
|
|
776
|
+
"""Mark a feature as in_progress at session start.
|
|
777
|
+
|
|
778
|
+
This keeps feature-list.json/state status in sync during execution,
|
|
779
|
+
instead of only updating after session end.
|
|
780
|
+
"""
|
|
781
|
+
feature_id = args.feature_id
|
|
782
|
+
if not feature_id:
|
|
783
|
+
error_out("--feature-id is required for 'start' action")
|
|
784
|
+
return
|
|
785
|
+
|
|
786
|
+
fs = load_feature_status(state_dir, feature_id)
|
|
787
|
+
old_status = fs.get("status", "pending")
|
|
788
|
+
|
|
789
|
+
fs["status"] = "in_progress"
|
|
790
|
+
fs["updated_at"] = now_iso()
|
|
791
|
+
|
|
792
|
+
err = save_feature_status(state_dir, feature_id, fs)
|
|
793
|
+
if err:
|
|
794
|
+
error_out("Failed to save feature status: {}".format(err))
|
|
795
|
+
return
|
|
796
|
+
|
|
797
|
+
err = update_feature_in_list(feature_list_path, feature_id, "in_progress")
|
|
798
|
+
if err:
|
|
799
|
+
error_out("Failed to update feature-list.json: {}".format(err))
|
|
800
|
+
return
|
|
801
|
+
|
|
802
|
+
result = {
|
|
803
|
+
"action": "start",
|
|
804
|
+
"feature_id": feature_id,
|
|
805
|
+
"old_status": old_status,
|
|
806
|
+
"new_status": "in_progress",
|
|
807
|
+
"updated_at": fs["updated_at"],
|
|
808
|
+
}
|
|
809
|
+
print(json.dumps(result, indent=2, ensure_ascii=False))
|
|
810
|
+
|
|
811
|
+
|
|
770
812
|
# ---------------------------------------------------------------------------
|
|
771
813
|
# Action: reset
|
|
772
814
|
# ---------------------------------------------------------------------------
|
|
@@ -964,7 +1006,7 @@ def main():
|
|
|
964
1006
|
error_out("--feature-id is required for 'update' action")
|
|
965
1007
|
if not args.session_status:
|
|
966
1008
|
error_out("--session-status is required for 'update' action")
|
|
967
|
-
if args.action in ("reset", "clean", "complete"):
|
|
1009
|
+
if args.action in ("start", "reset", "clean", "complete"):
|
|
968
1010
|
if not args.feature_id:
|
|
969
1011
|
error_out("--feature-id is required for '{}' action".format(args.action))
|
|
970
1012
|
if args.action == "clean":
|
|
@@ -981,6 +1023,8 @@ def main():
|
|
|
981
1023
|
# Dispatch action
|
|
982
1024
|
if args.action == "get_next":
|
|
983
1025
|
action_get_next(feature_list_data, args.state_dir)
|
|
1026
|
+
elif args.action == "start":
|
|
1027
|
+
action_start(args, args.feature_list, args.state_dir)
|
|
984
1028
|
elif args.action == "update":
|
|
985
1029
|
action_update(args, args.feature_list, args.state_dir)
|
|
986
1030
|
elif args.action == "status":
|
|
@@ -191,7 +191,17 @@ This is a **resume** from Phase {{RESUME_PHASE}}. After completing the team setu
|
|
|
191
191
|
|
|
192
192
|
**7a.** Run `prizmkit.summarize` (invoke the prizmkit-summarize skill) → archive to REGISTRY.md
|
|
193
193
|
|
|
194
|
-
**7b.**
|
|
194
|
+
**7b.** BEFORE commit, mark current feature as completed in feature-list:
|
|
195
|
+
```bash
|
|
196
|
+
python3 {{VALIDATOR_SCRIPTS_DIR}}/update-feature-status.py \
|
|
197
|
+
--feature-list "{{FEATURE_LIST_PATH}}" \
|
|
198
|
+
--state-dir "{{PROJECT_ROOT}}/dev-pipeline/state" \
|
|
199
|
+
--feature-id "{{FEATURE_ID}}" \
|
|
200
|
+
--session-id "{{SESSION_ID}}" \
|
|
201
|
+
--action complete
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
**7c.** Run `prizmkit.committer` (invoke the prizmkit-committer skill) → `feat({{FEATURE_ID}}): {{FEATURE_TITLE}}`, do NOT push
|
|
195
205
|
|
|
196
206
|
### Step 3: Report Session Status
|
|
197
207
|
|
|
@@ -248,6 +258,7 @@ TeamDelete
|
|
|
248
258
|
| Reviewer Agent Def | {{REVIEWER_SUBAGENT_PATH}} |
|
|
249
259
|
| Session Status Output | {{SESSION_STATUS_PATH}} |
|
|
250
260
|
| Project Root | {{PROJECT_ROOT}} |
|
|
261
|
+
| Feature List Path | {{FEATURE_LIST_PATH}} |
|
|
251
262
|
|
|
252
263
|
## Reminders
|
|
253
264
|
|