prizmkit 1.0.92 → 1.0.94
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/branch.sh +22 -8
- package/bundled/dev-pipeline/retry-bug.sh +1 -0
- package/bundled/dev-pipeline/retry-feature.sh +1 -0
- package/bundled/dev-pipeline/run-bugfix.sh +1 -0
- package/bundled/dev-pipeline/run.sh +30 -56
- package/bundled/dev-pipeline/scripts/init-bugfix-pipeline.py +1 -1
- package/bundled/dev-pipeline/scripts/init-pipeline.py +1 -1
- package/bundled/skills/_metadata.json +1 -1
- package/package.json +1 -1
package/bundled/VERSION.json
CHANGED
|
@@ -81,9 +81,10 @@ branch_return() {
|
|
|
81
81
|
# Merges dev_branch into original_branch, then optionally pushes.
|
|
82
82
|
# Steps:
|
|
83
83
|
# 1. Checkout original_branch
|
|
84
|
-
# 2.
|
|
85
|
-
# 3.
|
|
86
|
-
# 4.
|
|
84
|
+
# 2. Rebase dev_branch onto original_branch (handles diverged main)
|
|
85
|
+
# 3. Fast-forward merge original_branch to rebased dev tip
|
|
86
|
+
# 4. Push to remote if auto_push == "1"
|
|
87
|
+
# 5. Delete dev_branch (local only, it's been merged)
|
|
87
88
|
#
|
|
88
89
|
# Returns 0 on success, 1 on failure.
|
|
89
90
|
branch_merge() {
|
|
@@ -100,15 +101,28 @@ branch_merge() {
|
|
|
100
101
|
git -C "$project_root" add -A 2>/dev/null || true
|
|
101
102
|
git -C "$project_root" commit --no-verify -m "chore: include pipeline state artifacts" 2>/dev/null || true
|
|
102
103
|
fi
|
|
104
|
+
|
|
105
|
+
# Step 2: Rebase dev branch onto original to make it fast-forwardable.
|
|
106
|
+
# This handles the case where original_branch has diverged
|
|
107
|
+
# (e.g. commits were made on main while the pipeline was running).
|
|
108
|
+
# "git rebase A B" is equivalent to: git checkout B && git rebase A
|
|
109
|
+
log_info "Merging $dev_branch into $original_branch..."
|
|
110
|
+
if ! git -C "$project_root" rebase "$original_branch" "$dev_branch" 2>&1; then
|
|
111
|
+
log_error "Rebase of $dev_branch onto $original_branch failed — resolve manually:"
|
|
112
|
+
log_error " git rebase --abort # then resolve conflicts and retry"
|
|
113
|
+
git -C "$project_root" rebase --abort 2>/dev/null || true
|
|
114
|
+
git -C "$project_root" checkout "$dev_branch" 2>/dev/null || true
|
|
115
|
+
return 1
|
|
116
|
+
fi
|
|
117
|
+
# After the rebase we are on dev_branch — checkout original for the fast-forward
|
|
103
118
|
if ! git -C "$project_root" checkout "$original_branch" 2>/dev/null; then
|
|
104
119
|
log_error "Failed to checkout $original_branch for merge"
|
|
105
120
|
return 1
|
|
106
121
|
fi
|
|
107
122
|
|
|
108
|
-
# Step
|
|
109
|
-
log_info "Merging $dev_branch into $original_branch..."
|
|
123
|
+
# Step 3: Fast-forward original_branch to the rebased dev tip
|
|
110
124
|
if ! git -C "$project_root" merge --ff-only "$dev_branch" 2>&1; then
|
|
111
|
-
log_error "Merge failed
|
|
125
|
+
log_error "Merge failed after rebase — this should not happen, resolve manually:"
|
|
112
126
|
log_error " git checkout $original_branch && git rebase $dev_branch"
|
|
113
127
|
git -C "$project_root" checkout "$dev_branch" 2>/dev/null || true
|
|
114
128
|
return 1
|
|
@@ -116,7 +130,7 @@ branch_merge() {
|
|
|
116
130
|
|
|
117
131
|
log_success "Merged $dev_branch into $original_branch"
|
|
118
132
|
|
|
119
|
-
# Step
|
|
133
|
+
# Step 4: Push if AUTO_PUSH enabled
|
|
120
134
|
if [[ "$auto_push" == "1" ]]; then
|
|
121
135
|
log_info "Pushing $original_branch to remote..."
|
|
122
136
|
if git -C "$project_root" push 2>/dev/null; then
|
|
@@ -126,7 +140,7 @@ branch_merge() {
|
|
|
126
140
|
fi
|
|
127
141
|
fi
|
|
128
142
|
|
|
129
|
-
# Step
|
|
143
|
+
# Step 5: Delete merged dev branch
|
|
130
144
|
git -C "$project_root" branch -d "$dev_branch" 2>/dev/null && \
|
|
131
145
|
log_info "Deleted merged branch: $dev_branch" || true
|
|
132
146
|
|
|
@@ -328,6 +328,7 @@ if [[ -f "$SESSION_LOG" ]]; then
|
|
|
328
328
|
FINAL_SIZE=$(wc -c < "$SESSION_LOG" 2>/dev/null | tr -d ' ')
|
|
329
329
|
log_info "Session log: $FINAL_LINES lines, $((FINAL_SIZE / 1024))KB"
|
|
330
330
|
fi
|
|
331
|
+
log_info "exit_code=$EXIT_CODE"
|
|
331
332
|
|
|
332
333
|
# ── Determine session outcome from observable signals ──────────────
|
|
333
334
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
@@ -337,6 +337,7 @@ if [[ -f "$SESSION_LOG" ]]; then
|
|
|
337
337
|
FINAL_SIZE=$(wc -c < "$SESSION_LOG" 2>/dev/null | tr -d ' ')
|
|
338
338
|
log_info "Session log: $FINAL_LINES lines, $((FINAL_SIZE / 1024))KB"
|
|
339
339
|
fi
|
|
340
|
+
log_info "exit_code=$EXIT_CODE"
|
|
340
341
|
|
|
341
342
|
# ── Determine session outcome from observable signals ──────────────
|
|
342
343
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
@@ -163,6 +163,7 @@ spawn_and_wait_session() {
|
|
|
163
163
|
local final_lines=$(wc -l < "$session_log" 2>/dev/null | tr -d ' ')
|
|
164
164
|
log_info "Session log: $final_lines lines, $((final_size / 1024))KB"
|
|
165
165
|
fi
|
|
166
|
+
log_info "exit_code=$exit_code"
|
|
166
167
|
|
|
167
168
|
# ── Determine session outcome from observable signals ──────────────
|
|
168
169
|
local session_status
|
|
@@ -28,7 +28,7 @@ set -euo pipefail
|
|
|
28
28
|
# LOG_RETENTION_DAYS Delete logs older than N days (default: 14)
|
|
29
29
|
# LOG_MAX_TOTAL_MB Keep total logs under N MB via oldest-first cleanup (default: 1024)
|
|
30
30
|
# PIPELINE_MODE Override mode for all features: lite|standard|full|self-evolve (used by daemon)
|
|
31
|
-
# DEV_BRANCH Custom dev branch name (default: auto-generated dev/
|
|
31
|
+
# DEV_BRANCH Custom dev branch name (default: auto-generated dev/{feature_id}-YYYYMMDDHHmm)
|
|
32
32
|
# AUTO_PUSH Auto-push to remote after successful feature (default: 0). Set to 1 to enable.
|
|
33
33
|
# ============================================================
|
|
34
34
|
|
|
@@ -183,6 +183,7 @@ spawn_and_wait_session() {
|
|
|
183
183
|
local final_lines=$(wc -l < "$session_log" 2>/dev/null | tr -d ' ')
|
|
184
184
|
log_info "Session log: $final_lines lines, $((final_size / 1024))KB"
|
|
185
185
|
fi
|
|
186
|
+
log_info "exit_code=$exit_code"
|
|
186
187
|
|
|
187
188
|
# ── Determine session outcome from observable signals ──────────────
|
|
188
189
|
# No dependency on session-status.json — uses exit code, git commits,
|
|
@@ -272,39 +273,6 @@ sys.exit(1)
|
|
|
272
273
|
feature_slug=""
|
|
273
274
|
}
|
|
274
275
|
|
|
275
|
-
if [[ -n "$feature_slug" ]]; then
|
|
276
|
-
local project_root_for_summary
|
|
277
|
-
project_root_for_summary="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
278
|
-
local summary_path="$project_root_for_summary/.prizmkit/specs/${feature_slug}/session-summary.json"
|
|
279
|
-
mkdir -p "$(dirname "$summary_path")"
|
|
280
|
-
local session_start_time
|
|
281
|
-
session_start_time=$(python3 -c "
|
|
282
|
-
import json, sys, os
|
|
283
|
-
p = os.path.join(sys.argv[1], 'current-session.json')
|
|
284
|
-
if os.path.isfile(p):
|
|
285
|
-
with open(p) as f: print(json.load(f).get('started_at', ''))
|
|
286
|
-
else: print('')
|
|
287
|
-
" "$STATE_DIR" 2>/dev/null) || session_start_time=""
|
|
288
|
-
local exec_tier
|
|
289
|
-
exec_tier=$(python3 -c "
|
|
290
|
-
import json, sys, os
|
|
291
|
-
p = sys.argv[1]
|
|
292
|
-
if os.path.isfile(p):
|
|
293
|
-
with open(p) as f: print(json.load(f).get('exec_tier', ''))
|
|
294
|
-
else: print('')
|
|
295
|
-
" "$session_dir/session-status.json" 2>/dev/null) || exec_tier=""
|
|
296
|
-
cat > "$summary_path" <<SUMMARY
|
|
297
|
-
{
|
|
298
|
-
"feature_id": "$feature_id",
|
|
299
|
-
"session_id": "$session_id",
|
|
300
|
-
"status": "$session_status",
|
|
301
|
-
"started_at": "$session_start_time",
|
|
302
|
-
"completed_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
|
303
|
-
"tier": "$exec_tier"
|
|
304
|
-
}
|
|
305
|
-
SUMMARY
|
|
306
|
-
fi
|
|
307
|
-
|
|
308
276
|
# Validate key artifacts exist after successful session
|
|
309
277
|
if [[ "$session_status" == "success" && -n "$feature_slug" ]]; then
|
|
310
278
|
local project_root_for_artifacts
|
|
@@ -744,7 +712,7 @@ sys.exit(1)
|
|
|
744
712
|
_source_branch=$(git -C "$_proj_root" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")
|
|
745
713
|
_ORIGINAL_BRANCH="$_source_branch"
|
|
746
714
|
|
|
747
|
-
local _branch_name="${DEV_BRANCH:-dev/${feature_id}-$(date +%
|
|
715
|
+
local _branch_name="${DEV_BRANCH:-dev/${feature_id}-$(date +%Y%m%d%H%M)}"
|
|
748
716
|
if branch_create "$_proj_root" "$_branch_name" "$_source_branch"; then
|
|
749
717
|
_DEV_BRANCH_NAME="$_branch_name"
|
|
750
718
|
else
|
|
@@ -895,23 +863,13 @@ main() {
|
|
|
895
863
|
echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
|
|
896
864
|
echo ""
|
|
897
865
|
|
|
898
|
-
# Branch lifecycle:
|
|
866
|
+
# Branch lifecycle: each feature gets its own dev branch (created per-iteration below)
|
|
899
867
|
local _proj_root
|
|
900
868
|
_proj_root="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
901
869
|
local _source_branch
|
|
902
870
|
_source_branch=$(git -C "$_proj_root" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")
|
|
903
871
|
_ORIGINAL_BRANCH="$_source_branch"
|
|
904
872
|
|
|
905
|
-
local run_id_for_branch
|
|
906
|
-
run_id_for_branch=$(jq -r '.run_id' "$STATE_DIR/pipeline.json" 2>/dev/null || echo "$$")
|
|
907
|
-
local _branch_name="${DEV_BRANCH:-dev/pipeline-${run_id_for_branch}}"
|
|
908
|
-
if branch_create "$_proj_root" "$_branch_name" "$_source_branch"; then
|
|
909
|
-
_DEV_BRANCH_NAME="$_branch_name"
|
|
910
|
-
log_info "Dev branch: $_branch_name"
|
|
911
|
-
else
|
|
912
|
-
log_warn "Failed to create dev branch; running on current branch: $_source_branch"
|
|
913
|
-
fi
|
|
914
|
-
|
|
915
873
|
# Main processing loop
|
|
916
874
|
local session_count=0
|
|
917
875
|
|
|
@@ -952,16 +910,6 @@ for f in data.get('stuck_features', []):
|
|
|
952
910
|
log_success " Total sessions: $session_count"
|
|
953
911
|
log_success "════════════════════════════════════════════════════"
|
|
954
912
|
rm -f "$STATE_DIR/current-session.json"
|
|
955
|
-
|
|
956
|
-
# Merge dev branch back to original
|
|
957
|
-
if [[ -n "$_DEV_BRANCH_NAME" ]]; then
|
|
958
|
-
if branch_merge "$_proj_root" "$_DEV_BRANCH_NAME" "$_ORIGINAL_BRANCH" "$AUTO_PUSH"; then
|
|
959
|
-
_DEV_BRANCH_NAME=""
|
|
960
|
-
else
|
|
961
|
-
log_warn "Auto-merge failed — dev branch preserved: $_DEV_BRANCH_NAME"
|
|
962
|
-
log_warn "Merge manually: git checkout $_ORIGINAL_BRANCH && git rebase $_DEV_BRANCH_NAME"
|
|
963
|
-
fi
|
|
964
|
-
fi
|
|
965
913
|
break
|
|
966
914
|
fi
|
|
967
915
|
|
|
@@ -989,6 +937,16 @@ for f in data.get('stuck_features', []):
|
|
|
989
937
|
fi
|
|
990
938
|
echo -e "${BOLD}────────────────────────────────────────────────────${NC}"
|
|
991
939
|
|
|
940
|
+
# Create per-feature dev branch
|
|
941
|
+
local _feature_branch="${DEV_BRANCH:-dev/${feature_id}-$(date +%Y%m%d%H%M)}"
|
|
942
|
+
if branch_create "$_proj_root" "$_feature_branch" "$_ORIGINAL_BRANCH"; then
|
|
943
|
+
_DEV_BRANCH_NAME="$_feature_branch"
|
|
944
|
+
log_info "Dev branch: $_feature_branch"
|
|
945
|
+
else
|
|
946
|
+
log_warn "Failed to create dev branch; running on current branch: $_ORIGINAL_BRANCH"
|
|
947
|
+
_DEV_BRANCH_NAME=""
|
|
948
|
+
fi
|
|
949
|
+
|
|
992
950
|
# Generate session ID and bootstrap prompt
|
|
993
951
|
local session_id run_id
|
|
994
952
|
run_id=$(jq -r '.run_id' "$STATE_DIR/pipeline.json")
|
|
@@ -1071,6 +1029,22 @@ os.replace(tmp, target)
|
|
|
1071
1029
|
"$bootstrap_prompt" "$session_dir" "$MAX_RETRIES" "$feature_model"
|
|
1072
1030
|
local session_status="$_SPAWN_RESULT"
|
|
1073
1031
|
|
|
1032
|
+
# Merge per-feature dev branch back to original on success
|
|
1033
|
+
if [[ "$session_status" == "success" && -n "$_DEV_BRANCH_NAME" ]]; then
|
|
1034
|
+
if branch_merge "$_proj_root" "$_DEV_BRANCH_NAME" "$_ORIGINAL_BRANCH" "$AUTO_PUSH"; then
|
|
1035
|
+
_DEV_BRANCH_NAME=""
|
|
1036
|
+
else
|
|
1037
|
+
log_warn "Auto-merge failed — dev branch preserved: $_DEV_BRANCH_NAME"
|
|
1038
|
+
log_warn "Merge manually: git checkout $_ORIGINAL_BRANCH && git rebase $_DEV_BRANCH_NAME"
|
|
1039
|
+
_DEV_BRANCH_NAME=""
|
|
1040
|
+
fi
|
|
1041
|
+
elif [[ -n "$_DEV_BRANCH_NAME" ]]; then
|
|
1042
|
+
# Session failed — return to original branch, preserve dev branch for inspection
|
|
1043
|
+
git -C "$_proj_root" checkout "$_ORIGINAL_BRANCH" 2>/dev/null || true
|
|
1044
|
+
log_warn "Session failed — dev branch preserved for inspection: $_DEV_BRANCH_NAME"
|
|
1045
|
+
_DEV_BRANCH_NAME=""
|
|
1046
|
+
fi
|
|
1047
|
+
|
|
1074
1048
|
session_count=$((session_count + 1))
|
|
1075
1049
|
|
|
1076
1050
|
# Brief pause before next iteration
|
|
@@ -195,7 +195,7 @@ def create_state_directory(state_dir, bug_list_path, bugs):
|
|
|
195
195
|
bugs_dir = os.path.join(abs_state_dir, "bugs")
|
|
196
196
|
|
|
197
197
|
now = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
198
|
-
run_id = "bugfix-run-" + datetime.now(timezone.utc).strftime("%Y%m%d
|
|
198
|
+
run_id = "bugfix-run-" + datetime.now(timezone.utc).strftime("%Y%m%d%H%M")
|
|
199
199
|
|
|
200
200
|
# Create top-level state directory
|
|
201
201
|
os.makedirs(abs_state_dir, exist_ok=True)
|
|
@@ -231,7 +231,7 @@ def create_state_directory(state_dir, feature_list_path, features):
|
|
|
231
231
|
features_dir = os.path.join(abs_state_dir, "features")
|
|
232
232
|
|
|
233
233
|
now = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
234
|
-
run_id = "run-" + datetime.now(timezone.utc).strftime("%Y%m%d
|
|
234
|
+
run_id = "run-" + datetime.now(timezone.utc).strftime("%Y%m%d%H%M")
|
|
235
235
|
|
|
236
236
|
# Create top-level state directory
|
|
237
237
|
os.makedirs(abs_state_dir, exist_ok=True)
|