prizmkit 1.1.97 → 1.1.99
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/README.md +5 -5
- package/bundled/dev-pipeline/launch-bugfix-daemon.sh +1 -1
- package/bundled/dev-pipeline/launch-feature-daemon.sh +1 -1
- package/bundled/dev-pipeline/launch-refactor-daemon.sh +1 -1
- package/bundled/dev-pipeline/reset-bug.sh +2 -2
- package/bundled/dev-pipeline/reset-feature.sh +2 -2
- package/bundled/dev-pipeline/reset-refactor.sh +2 -2
- package/bundled/dev-pipeline/run-bugfix.sh +5 -5
- package/bundled/dev-pipeline/run-feature.sh +4 -4
- package/bundled/dev-pipeline/run-refactor.sh +5 -5
- package/bundled/dev-pipeline/scripts/detect-stuck.py +5 -5
- package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +2 -5
- package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +6 -7
- package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +6 -7
- package/bundled/dev-pipeline/scripts/init-bugfix-pipeline.py +1 -1
- package/bundled/dev-pipeline/scripts/init-pipeline.py +1 -1
- package/bundled/dev-pipeline/scripts/init-refactor-pipeline.py +1 -1
- package/bundled/dev-pipeline/scripts/update-bug-status.py +6 -7
- package/bundled/dev-pipeline/scripts/update-feature-status.py +7 -12
- package/bundled/dev-pipeline/scripts/update-refactor-status.py +6 -7
- package/bundled/dev-pipeline/tests/test_auto_skip.py +8 -8
- package/bundled/dev-pipeline-windows/lib/pipeline.ps1 +2 -2
- package/bundled/dev-pipeline-windows/scripts/detect-stuck.py +5 -5
- package/bundled/dev-pipeline-windows/scripts/generate-bootstrap-prompt.py +2 -5
- package/bundled/dev-pipeline-windows/scripts/generate-bugfix-prompt.py +6 -7
- package/bundled/dev-pipeline-windows/scripts/generate-refactor-prompt.py +6 -7
- package/bundled/dev-pipeline-windows/scripts/init-bugfix-pipeline.py +1 -1
- package/bundled/dev-pipeline-windows/scripts/init-pipeline.py +1 -1
- package/bundled/dev-pipeline-windows/scripts/init-refactor-pipeline.py +1 -1
- package/bundled/dev-pipeline-windows/scripts/update-bug-status.py +6 -7
- package/bundled/dev-pipeline-windows/scripts/update-feature-status.py +7 -12
- package/bundled/dev-pipeline-windows/scripts/update-refactor-status.py +6 -7
- package/bundled/skills/_metadata.json +1 -1
- package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +2 -2
- package/bundled/skills/feature-pipeline-launcher/SKILL.md +2 -2
- package/bundled/skills/recovery-workflow/SKILL.md +2 -2
- package/bundled/skills/recovery-workflow/evals/evals.json +2 -2
- package/bundled/skills/refactor-pipeline-launcher/SKILL.md +2 -2
- package/bundled/skills-windows/bugfix-pipeline-launcher/SKILL.md +2 -2
- package/bundled/skills-windows/feature-pipeline-launcher/SKILL.md +2 -2
- package/bundled/skills-windows/recovery-workflow/SKILL.md +2 -2
- package/bundled/skills-windows/recovery-workflow/evals/evals.json +2 -2
- package/bundled/skills-windows/refactor-pipeline-launcher/SKILL.md +2 -2
- package/package.json +1 -1
package/bundled/VERSION.json
CHANGED
|
@@ -713,13 +713,13 @@ Features are executed in dependency order via DAG:
|
|
|
713
713
|
|
|
714
714
|
```bash
|
|
715
715
|
# Live tail current session
|
|
716
|
-
tail -f .prizmkit/state/features/
|
|
716
|
+
tail -f .prizmkit/state/features/F-*/sessions/*/logs/session.log
|
|
717
717
|
|
|
718
718
|
# Specific feature
|
|
719
|
-
tail -f .prizmkit/state/features/
|
|
719
|
+
tail -f .prizmkit/state/features/F-003/sessions/*/logs/session.log
|
|
720
720
|
|
|
721
721
|
# Review completed session
|
|
722
|
-
cat .prizmkit/state/features/
|
|
722
|
+
cat .prizmkit/state/features/F-003/sessions/F-003-*/logs/session.log | less
|
|
723
723
|
```
|
|
724
724
|
|
|
725
725
|
### Pause & Resume
|
|
@@ -735,7 +735,7 @@ cat .prizmkit/state/features/features/F-003/sessions/F-003-*/logs/session.log |
|
|
|
735
735
|
./.prizmkit/dev-pipeline/run-feature.sh status .prizmkit/plans/feature-list.json
|
|
736
736
|
|
|
737
737
|
# Review session logs
|
|
738
|
-
cat .prizmkit/state/features/
|
|
738
|
+
cat .prizmkit/state/features/F-XXX/sessions/*/logs/session.log
|
|
739
739
|
|
|
740
740
|
# Option A: Fix manually and mark complete
|
|
741
741
|
python3 .prizmkit/dev-pipeline/scripts/update-feature-status.py \
|
|
@@ -802,7 +802,7 @@ run-bugfix.sh main loop
|
|
|
802
802
|
```
|
|
803
803
|
.prizmkit/state/bugfix/ # Runtime state (gitignored)
|
|
804
804
|
+-- pipeline.json
|
|
805
|
-
+--
|
|
805
|
+
+-- B-XXX/
|
|
806
806
|
+-- status.json
|
|
807
807
|
+-- sessions/B-XXX-YYYYMMDDHHMMSS/
|
|
808
808
|
+-- bootstrap-prompt.md
|
|
@@ -384,7 +384,7 @@ total = len(bugs)
|
|
|
384
384
|
counts = {'completed': 0, 'in_progress': 0, 'failed': 0, 'pending': 0, 'needs_info': 0, 'skipped': 0}
|
|
385
385
|
for bug in bugs:
|
|
386
386
|
bid = bug.get('id', '')
|
|
387
|
-
sp = os.path.join('$STATE_DIR',
|
|
387
|
+
sp = os.path.join('$STATE_DIR', bid, 'status.json')
|
|
388
388
|
if os.path.isfile(sp):
|
|
389
389
|
fs = json.load(open(sp))
|
|
390
390
|
st = fs.get('status', 'pending')
|
|
@@ -487,7 +487,7 @@ total = len(features)
|
|
|
487
487
|
counts = {'completed': 0, 'in_progress': 0, 'failed': 0, 'pending': 0, 'skipped': 0, 'auto_skipped': 0}
|
|
488
488
|
for feat in features:
|
|
489
489
|
fid = feat.get('id', '')
|
|
490
|
-
sp = os.path.join(state_dir,
|
|
490
|
+
sp = os.path.join(state_dir, fid, 'status.json')
|
|
491
491
|
if os.path.isfile(sp):
|
|
492
492
|
fs = load_json(sp)
|
|
493
493
|
st = fs.get('status', 'pending')
|
|
@@ -384,7 +384,7 @@ total = len(items)
|
|
|
384
384
|
counts = {'completed': 0, 'in_progress': 0, 'failed': 0, 'pending': 0, 'skipped': 0, 'auto_skipped': 0}
|
|
385
385
|
for item in items:
|
|
386
386
|
rid = item.get('id', '')
|
|
387
|
-
sp = os.path.join('$STATE_DIR',
|
|
387
|
+
sp = os.path.join('$STATE_DIR', rid, 'status.json')
|
|
388
388
|
if os.path.isfile(sp):
|
|
389
389
|
fs = json.load(open(sp))
|
|
390
390
|
st = fs.get('status', 'pending')
|
|
@@ -243,7 +243,7 @@ sys.exit(1)
|
|
|
243
243
|
echo -e "${BOLD} Reset: $CUR_BUG_ID — $BUG_TITLE${NC}"
|
|
244
244
|
echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
|
|
245
245
|
|
|
246
|
-
STATUS_FILE="$STATE_DIR
|
|
246
|
+
STATUS_FILE="$STATE_DIR/$CUR_BUG_ID/status.json"
|
|
247
247
|
# Read status from bug-fix-list.json (single source of truth)
|
|
248
248
|
CURRENT_STATUS=$(python3 -c "
|
|
249
249
|
import json, sys
|
|
@@ -270,7 +270,7 @@ print('?')
|
|
|
270
270
|
log_info "PrizmKit artifacts: $BUGFIX_COUNT files in .prizmkit/bugfix/$CUR_BUG_ID/"
|
|
271
271
|
fi
|
|
272
272
|
|
|
273
|
-
SESSIONS_DIR="$STATE_DIR
|
|
273
|
+
SESSIONS_DIR="$STATE_DIR/$CUR_BUG_ID/sessions"
|
|
274
274
|
SESSIONS_COUNT=0
|
|
275
275
|
if [[ -d "$SESSIONS_DIR" ]]; then
|
|
276
276
|
SESSIONS_COUNT=$(find "$SESSIONS_DIR" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l | tr -d ' ')
|
|
@@ -252,7 +252,7 @@ sys.exit(1)
|
|
|
252
252
|
echo -e "${BOLD} Reset: $CUR_FEATURE_ID — $FEATURE_TITLE${NC}"
|
|
253
253
|
echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
|
|
254
254
|
|
|
255
|
-
STATUS_FILE="$STATE_DIR
|
|
255
|
+
STATUS_FILE="$STATE_DIR/$CUR_FEATURE_ID/status.json"
|
|
256
256
|
# Read status from feature-list.json (single source of truth)
|
|
257
257
|
CURRENT_STATUS=$(python3 -c "
|
|
258
258
|
import json, sys
|
|
@@ -279,7 +279,7 @@ print('?')
|
|
|
279
279
|
log_info "PrizmKit artifacts: $SPECS_COUNT files in .prizmkit/specs/$FEATURE_SLUG/"
|
|
280
280
|
fi
|
|
281
281
|
|
|
282
|
-
SESSIONS_DIR="$STATE_DIR
|
|
282
|
+
SESSIONS_DIR="$STATE_DIR/$CUR_FEATURE_ID/sessions"
|
|
283
283
|
SESSIONS_COUNT=0
|
|
284
284
|
if [[ -d "$SESSIONS_DIR" ]]; then
|
|
285
285
|
SESSIONS_COUNT=$(find "$SESSIONS_DIR" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l | tr -d ' ')
|
|
@@ -241,7 +241,7 @@ sys.exit(1)
|
|
|
241
241
|
echo -e "${BOLD} Reset: $CUR_REFACTOR_ID — $REFACTOR_TITLE${NC}"
|
|
242
242
|
echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
|
|
243
243
|
|
|
244
|
-
STATUS_FILE="$STATE_DIR
|
|
244
|
+
STATUS_FILE="$STATE_DIR/$CUR_REFACTOR_ID/status.json"
|
|
245
245
|
# Read status from refactor-list.json (single source of truth)
|
|
246
246
|
CURRENT_STATUS=$(python3 -c "
|
|
247
247
|
import json, sys
|
|
@@ -268,7 +268,7 @@ print('?')
|
|
|
268
268
|
log_info "PrizmKit artifacts: $SPECS_COUNT files in .prizmkit/specs/$REFACTOR_SLUG/"
|
|
269
269
|
fi
|
|
270
270
|
|
|
271
|
-
SESSIONS_DIR="$STATE_DIR
|
|
271
|
+
SESSIONS_DIR="$STATE_DIR/$CUR_REFACTOR_ID/sessions"
|
|
272
272
|
SESSIONS_COUNT=0
|
|
273
273
|
if [[ -d "$SESSIONS_DIR" ]]; then
|
|
274
274
|
SESSIONS_COUNT=$(find "$SESSIONS_DIR" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l | tr -d ' ')
|
|
@@ -519,7 +519,7 @@ sys.exit(1)
|
|
|
519
519
|
log_info "Removed $dev_team_dir"
|
|
520
520
|
fi
|
|
521
521
|
|
|
522
|
-
local bug_state_dir="$STATE_DIR
|
|
522
|
+
local bug_state_dir="$STATE_DIR/$bug_id"
|
|
523
523
|
if [[ -d "$bug_state_dir" ]]; then
|
|
524
524
|
rm -rf "$bug_state_dir"
|
|
525
525
|
log_info "Removed $bug_state_dir"
|
|
@@ -544,7 +544,7 @@ sys.exit(1)
|
|
|
544
544
|
local run_id session_id session_dir bootstrap_prompt
|
|
545
545
|
run_id=$(jq -r '.run_id' "$STATE_DIR/pipeline.json")
|
|
546
546
|
session_id="${bug_id}-$(date +%Y%m%d%H%M%S)"
|
|
547
|
-
session_dir="$STATE_DIR
|
|
547
|
+
session_dir="$STATE_DIR/$bug_id/sessions/$session_id"
|
|
548
548
|
mkdir -p "$session_dir/logs"
|
|
549
549
|
|
|
550
550
|
bootstrap_prompt="$session_dir/bootstrap-prompt.md"
|
|
@@ -553,7 +553,7 @@ sys.exit(1)
|
|
|
553
553
|
local retry_count
|
|
554
554
|
retry_count=$(python3 -c "
|
|
555
555
|
import json, os
|
|
556
|
-
status_path = os.path.join('$STATE_DIR', '
|
|
556
|
+
status_path = os.path.join('$STATE_DIR', '$bug_id', 'status.json')
|
|
557
557
|
if os.path.isfile(status_path):
|
|
558
558
|
with open(status_path) as f:
|
|
559
559
|
d = json.load(f)
|
|
@@ -564,7 +564,7 @@ else:
|
|
|
564
564
|
local resume_phase
|
|
565
565
|
resume_phase=$(python3 -c "
|
|
566
566
|
import json, os
|
|
567
|
-
status_path = os.path.join('$STATE_DIR', '
|
|
567
|
+
status_path = os.path.join('$STATE_DIR', '$bug_id', 'status.json')
|
|
568
568
|
if os.path.isfile(status_path):
|
|
569
569
|
with open(status_path) as f:
|
|
570
570
|
d = json.load(f)
|
|
@@ -1056,7 +1056,7 @@ DEPLOY_PROMPT_EOF
|
|
|
1056
1056
|
run_id=$(jq -r '.run_id' "$STATE_DIR/pipeline.json")
|
|
1057
1057
|
session_id="${bug_id}-$(date +%Y%m%d%H%M%S)"
|
|
1058
1058
|
|
|
1059
|
-
local session_dir="$STATE_DIR
|
|
1059
|
+
local session_dir="$STATE_DIR/$bug_id/sessions/$session_id"
|
|
1060
1060
|
mkdir -p "$session_dir/logs"
|
|
1061
1061
|
|
|
1062
1062
|
local bootstrap_prompt="$session_dir/bootstrap-prompt.md"
|
|
@@ -698,7 +698,7 @@ sys.exit(1)
|
|
|
698
698
|
log_info "Removed $dev_team_dir"
|
|
699
699
|
fi
|
|
700
700
|
|
|
701
|
-
local feature_state_dir="$STATE_DIR
|
|
701
|
+
local feature_state_dir="$STATE_DIR/$feature_id"
|
|
702
702
|
if [[ -d "$feature_state_dir" ]]; then
|
|
703
703
|
rm -rf "$feature_state_dir"
|
|
704
704
|
log_info "Removed $feature_state_dir"
|
|
@@ -724,7 +724,7 @@ sys.exit(1)
|
|
|
724
724
|
local run_id session_id session_dir bootstrap_prompt
|
|
725
725
|
run_id=$(jq -r '.run_id' "$STATE_DIR/pipeline.json")
|
|
726
726
|
session_id="${feature_id}-$(date +%Y%m%d%H%M%S)"
|
|
727
|
-
session_dir="$STATE_DIR
|
|
727
|
+
session_dir="$STATE_DIR/$feature_id/sessions/$session_id"
|
|
728
728
|
mkdir -p "$session_dir/logs"
|
|
729
729
|
|
|
730
730
|
bootstrap_prompt="$session_dir/bootstrap-prompt.md"
|
|
@@ -733,7 +733,7 @@ sys.exit(1)
|
|
|
733
733
|
local retry_count
|
|
734
734
|
retry_count=$(python3 -c "
|
|
735
735
|
import json, os
|
|
736
|
-
status_path = os.path.join('$STATE_DIR', '
|
|
736
|
+
status_path = os.path.join('$STATE_DIR', '$feature_id', 'status.json')
|
|
737
737
|
if os.path.isfile(status_path):
|
|
738
738
|
with open(status_path) as f:
|
|
739
739
|
d = json.load(f)
|
|
@@ -1275,7 +1275,7 @@ DEPLOY_PROMPT_EOF
|
|
|
1275
1275
|
run_id=$(jq -r '.run_id' "$STATE_DIR/pipeline.json")
|
|
1276
1276
|
session_id="${feature_id}-$(date +%Y%m%d%H%M%S)"
|
|
1277
1277
|
|
|
1278
|
-
local session_dir="$STATE_DIR
|
|
1278
|
+
local session_dir="$STATE_DIR/$feature_id/sessions/$session_id"
|
|
1279
1279
|
mkdir -p "$session_dir/logs"
|
|
1280
1280
|
|
|
1281
1281
|
local bootstrap_prompt="$session_dir/bootstrap-prompt.md"
|
|
@@ -544,7 +544,7 @@ sys.exit(1)
|
|
|
544
544
|
log_info "Removed $dev_team_dir"
|
|
545
545
|
fi
|
|
546
546
|
|
|
547
|
-
local refactor_state_dir="$STATE_DIR
|
|
547
|
+
local refactor_state_dir="$STATE_DIR/$refactor_id"
|
|
548
548
|
if [[ -d "$refactor_state_dir" ]]; then
|
|
549
549
|
rm -rf "$refactor_state_dir"
|
|
550
550
|
log_info "Removed $refactor_state_dir"
|
|
@@ -569,7 +569,7 @@ sys.exit(1)
|
|
|
569
569
|
local run_id session_id session_dir bootstrap_prompt
|
|
570
570
|
run_id=$(jq -r '.run_id' "$STATE_DIR/pipeline.json")
|
|
571
571
|
session_id="${refactor_id}-$(date +%Y%m%d%H%M%S)"
|
|
572
|
-
session_dir="$STATE_DIR
|
|
572
|
+
session_dir="$STATE_DIR/$refactor_id/sessions/$session_id"
|
|
573
573
|
mkdir -p "$session_dir/logs"
|
|
574
574
|
|
|
575
575
|
bootstrap_prompt="$session_dir/bootstrap-prompt.md"
|
|
@@ -578,7 +578,7 @@ sys.exit(1)
|
|
|
578
578
|
local retry_count
|
|
579
579
|
retry_count=$(python3 -c "
|
|
580
580
|
import json, os
|
|
581
|
-
status_path = os.path.join('$STATE_DIR', '
|
|
581
|
+
status_path = os.path.join('$STATE_DIR', '$refactor_id', 'status.json')
|
|
582
582
|
if os.path.isfile(status_path):
|
|
583
583
|
with open(status_path) as f:
|
|
584
584
|
d = json.load(f)
|
|
@@ -589,7 +589,7 @@ else:
|
|
|
589
589
|
local resume_phase
|
|
590
590
|
resume_phase=$(python3 -c "
|
|
591
591
|
import json, os
|
|
592
|
-
status_path = os.path.join('$STATE_DIR', '
|
|
592
|
+
status_path = os.path.join('$STATE_DIR', '$refactor_id', 'status.json')
|
|
593
593
|
if os.path.isfile(status_path):
|
|
594
594
|
with open(status_path) as f:
|
|
595
595
|
d = json.load(f)
|
|
@@ -1089,7 +1089,7 @@ DEPLOY_PROMPT_EOF
|
|
|
1089
1089
|
run_id=$(jq -r '.run_id' "$STATE_DIR/pipeline.json")
|
|
1090
1090
|
session_id="${refactor_id}-$(date +%Y%m%d%H%M%S)"
|
|
1091
1091
|
|
|
1092
|
-
local session_dir="$STATE_DIR
|
|
1092
|
+
local session_dir="$STATE_DIR/$refactor_id/sessions/$session_id"
|
|
1093
1093
|
mkdir -p "$session_dir/logs"
|
|
1094
1094
|
|
|
1095
1095
|
local bootstrap_prompt="$session_dir/bootstrap-prompt.md"
|
|
@@ -113,8 +113,8 @@ def load_json(path):
|
|
|
113
113
|
|
|
114
114
|
|
|
115
115
|
def discover_item_ids(state_dir, subdir):
|
|
116
|
-
"""Return a sorted list of item IDs found
|
|
117
|
-
items_dir = os.path.join(state_dir, subdir)
|
|
116
|
+
"""Return a sorted list of item IDs found directly under the typed state dir."""
|
|
117
|
+
items_dir = os.path.join(state_dir, subdir) if subdir else state_dir
|
|
118
118
|
if not os.path.isdir(items_dir):
|
|
119
119
|
return []
|
|
120
120
|
ids = []
|
|
@@ -363,9 +363,9 @@ def find_task_list(state_dir):
|
|
|
363
363
|
|
|
364
364
|
# Pipeline type configurations
|
|
365
365
|
PIPELINE_CONFIG = {
|
|
366
|
-
"feature": {"subdir": "
|
|
367
|
-
"bugfix": {"subdir": "
|
|
368
|
-
"refactor": {"subdir": "
|
|
366
|
+
"feature": {"subdir": "", "items_key": "features", "id_label": "feature_id"},
|
|
367
|
+
"bugfix": {"subdir": "", "items_key": "bugs", "id_label": "bug_id"},
|
|
368
|
+
"refactor": {"subdir": "", "items_key": "refactors", "id_label": "refactor_id"},
|
|
369
369
|
}
|
|
370
370
|
|
|
371
371
|
|
|
@@ -392,9 +392,7 @@ def get_prev_session_status(state_dir, feature_id):
|
|
|
392
392
|
return "N/A (first run)"
|
|
393
393
|
|
|
394
394
|
# Try to read the feature status file to find the last session
|
|
395
|
-
feature_status_path = os.path.join(
|
|
396
|
-
state_dir, "features", feature_id, "status.json"
|
|
397
|
-
)
|
|
395
|
+
feature_status_path = os.path.join(state_dir, feature_id, "status.json")
|
|
398
396
|
if not os.path.isfile(feature_status_path):
|
|
399
397
|
return "N/A (first run)"
|
|
400
398
|
|
|
@@ -409,8 +407,7 @@ def get_prev_session_status(state_dir, feature_id):
|
|
|
409
407
|
return "N/A (first run)"
|
|
410
408
|
|
|
411
409
|
# Try to read the last session's session-status.json
|
|
412
|
-
session_status_path = os.path.join(
|
|
413
|
-
state_dir, "features", feature_id, "sessions",
|
|
410
|
+
session_status_path = os.path.join(state_dir, feature_id, "sessions",
|
|
414
411
|
last_session_id, "session-status.json"
|
|
415
412
|
)
|
|
416
413
|
if not os.path.isfile(session_status_path):
|
|
@@ -220,7 +220,7 @@ def get_prev_session_status(state_dir, bug_id):
|
|
|
220
220
|
if not state_dir:
|
|
221
221
|
return "N/A (first run)"
|
|
222
222
|
|
|
223
|
-
bug_status_path = os.path.join(state_dir,
|
|
223
|
+
bug_status_path = os.path.join(state_dir, bug_id, "status.json")
|
|
224
224
|
if not os.path.isfile(bug_status_path):
|
|
225
225
|
return "N/A (first run)"
|
|
226
226
|
|
|
@@ -234,8 +234,7 @@ def get_prev_session_status(state_dir, bug_id):
|
|
|
234
234
|
if not last_session_id:
|
|
235
235
|
return "N/A (first run)"
|
|
236
236
|
|
|
237
|
-
session_status_path = os.path.join(
|
|
238
|
-
state_dir, "bugs", bug_id, "sessions",
|
|
237
|
+
session_status_path = os.path.join(state_dir, bug_id, "sessions",
|
|
239
238
|
last_session_id, "session-status.json"
|
|
240
239
|
)
|
|
241
240
|
if not os.path.isfile(session_status_path):
|
|
@@ -306,7 +305,7 @@ def build_replacements(args, bug, global_context, script_dir):
|
|
|
306
305
|
|
|
307
306
|
# Session status path
|
|
308
307
|
session_status_path = os.path.join(
|
|
309
|
-
project_root, ".prizmkit", "state", "bugfix",
|
|
308
|
+
project_root, ".prizmkit", "state", "bugfix", args.bug_id,
|
|
310
309
|
"sessions", args.session_id, "session-status.json"
|
|
311
310
|
)
|
|
312
311
|
|
|
@@ -371,15 +370,15 @@ def build_replacements(args, bug, global_context, script_dir):
|
|
|
371
370
|
"{{MAX_LOG_SIZE_HUMAN}}": _format_bytes(max_log_size),
|
|
372
371
|
"{{LOG_MONITOR_POLL_INTERVAL}}": str(poll_interval),
|
|
373
372
|
"{{LOG_MONITOR_STATUS_FILE}}": os.path.join(
|
|
374
|
-
".prizmkit", "state", "bugfix",
|
|
373
|
+
".prizmkit", "state", "bugfix", args.bug_id,
|
|
375
374
|
"sessions", args.session_id, "logs", "log-monitor-status.txt",
|
|
376
375
|
),
|
|
377
376
|
"{{LOG_MONITOR_BASELINE_FILE}}": os.path.join(
|
|
378
|
-
".prizmkit", "state", "bugfix",
|
|
377
|
+
".prizmkit", "state", "bugfix", args.bug_id,
|
|
379
378
|
"sessions", args.session_id, "logs", "log-monitor-baseline.txt",
|
|
380
379
|
),
|
|
381
380
|
"{{SESSION_LOG_PATH}}": os.path.join(
|
|
382
|
-
".prizmkit", "state", "bugfix",
|
|
381
|
+
".prizmkit", "state", "bugfix", args.bug_id,
|
|
383
382
|
"sessions", args.session_id, "logs", "session.log",
|
|
384
383
|
),
|
|
385
384
|
"{{LOG_MONITOR_SCRIPT}}": os.path.join(
|
|
@@ -375,7 +375,7 @@ def get_prev_session_status(state_dir, refactor_id):
|
|
|
375
375
|
if not state_dir:
|
|
376
376
|
return "N/A (first run)"
|
|
377
377
|
|
|
378
|
-
refactor_status_path = os.path.join(state_dir,
|
|
378
|
+
refactor_status_path = os.path.join(state_dir, refactor_id, "status.json")
|
|
379
379
|
try:
|
|
380
380
|
with open(refactor_status_path, "r", encoding="utf-8") as f:
|
|
381
381
|
refactor_status = json.load(f)
|
|
@@ -386,8 +386,7 @@ def get_prev_session_status(state_dir, refactor_id):
|
|
|
386
386
|
if not last_session_id:
|
|
387
387
|
return "N/A (first run)"
|
|
388
388
|
|
|
389
|
-
session_status_path = os.path.join(
|
|
390
|
-
state_dir, "refactors", refactor_id, "sessions",
|
|
389
|
+
session_status_path = os.path.join(state_dir, refactor_id, "sessions",
|
|
391
390
|
last_session_id, "session-status.json"
|
|
392
391
|
)
|
|
393
392
|
try:
|
|
@@ -455,7 +454,7 @@ def build_replacements(args, refactor, refactors, global_context, script_dir):
|
|
|
455
454
|
|
|
456
455
|
# Session status path
|
|
457
456
|
session_status_path = os.path.join(
|
|
458
|
-
project_root, ".prizmkit", "state", "refactor",
|
|
457
|
+
project_root, ".prizmkit", "state", "refactor", args.refactor_id,
|
|
459
458
|
"sessions", args.session_id, "session-status.json"
|
|
460
459
|
)
|
|
461
460
|
|
|
@@ -531,15 +530,15 @@ def build_replacements(args, refactor, refactors, global_context, script_dir):
|
|
|
531
530
|
"{{MAX_LOG_SIZE_HUMAN}}": _format_bytes(max_log_size),
|
|
532
531
|
"{{LOG_MONITOR_POLL_INTERVAL}}": str(poll_interval),
|
|
533
532
|
"{{LOG_MONITOR_STATUS_FILE}}": os.path.join(
|
|
534
|
-
".prizmkit", "state", "refactor",
|
|
533
|
+
".prizmkit", "state", "refactor", args.refactor_id,
|
|
535
534
|
"sessions", args.session_id, "logs", "log-monitor-status.txt",
|
|
536
535
|
),
|
|
537
536
|
"{{LOG_MONITOR_BASELINE_FILE}}": os.path.join(
|
|
538
|
-
".prizmkit", "state", "refactor",
|
|
537
|
+
".prizmkit", "state", "refactor", args.refactor_id,
|
|
539
538
|
"sessions", args.session_id, "logs", "log-monitor-baseline.txt",
|
|
540
539
|
),
|
|
541
540
|
"{{SESSION_LOG_PATH}}": os.path.join(
|
|
542
|
-
".prizmkit", "state", "refactor",
|
|
541
|
+
".prizmkit", "state", "refactor", args.refactor_id,
|
|
543
542
|
"sessions", args.session_id, "logs", "session.log",
|
|
544
543
|
),
|
|
545
544
|
"{{LOG_MONITOR_SCRIPT}}": os.path.join(
|
|
@@ -207,7 +207,7 @@ def create_state_directory(state_dir, bug_list_path, bugs):
|
|
|
207
207
|
abs_bug_list_path = os.path.abspath(bug_list_path)
|
|
208
208
|
# Store as relative path from state_dir so pipeline.json is portable across machines
|
|
209
209
|
rel_bug_list_path = os.path.relpath(abs_bug_list_path, abs_state_dir)
|
|
210
|
-
bugs_dir =
|
|
210
|
+
bugs_dir = abs_state_dir
|
|
211
211
|
|
|
212
212
|
now = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
213
213
|
run_id = "bugfix-run-" + datetime.now(timezone.utc).strftime("%Y%m%d%H%M%S")
|
|
@@ -242,7 +242,7 @@ def create_state_directory(state_dir, feature_list_path, features):
|
|
|
242
242
|
abs_feature_list_path = os.path.abspath(feature_list_path)
|
|
243
243
|
# Store as relative path from state_dir so pipeline.json is portable across machines
|
|
244
244
|
rel_feature_list_path = os.path.relpath(abs_feature_list_path, abs_state_dir)
|
|
245
|
-
features_dir =
|
|
245
|
+
features_dir = abs_state_dir
|
|
246
246
|
|
|
247
247
|
now = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
248
248
|
run_id = "run-" + datetime.now(timezone.utc).strftime("%Y%m%d%H%M%S")
|
|
@@ -283,7 +283,7 @@ def create_state_directory(state_dir, refactor_list_path, refactors):
|
|
|
283
283
|
abs_refactor_list_path = os.path.abspath(refactor_list_path)
|
|
284
284
|
# Store as relative path from state_dir so pipeline.json is portable across machines
|
|
285
285
|
rel_refactor_list_path = os.path.relpath(abs_refactor_list_path, abs_state_dir)
|
|
286
|
-
refactors_dir =
|
|
286
|
+
refactors_dir = abs_state_dir
|
|
287
287
|
|
|
288
288
|
now = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
289
289
|
run_id = "refactor-run-" + datetime.now(timezone.utc).strftime("%Y%m%d%H%M%S")
|
|
@@ -92,7 +92,7 @@ def load_bug_status(state_dir, bug_id):
|
|
|
92
92
|
The 'status' field is NOT included — status lives exclusively
|
|
93
93
|
in bug-fix-list.json.
|
|
94
94
|
"""
|
|
95
|
-
status_path = os.path.join(state_dir,
|
|
95
|
+
status_path = os.path.join(state_dir, bug_id, "status.json")
|
|
96
96
|
if not os.path.isfile(status_path):
|
|
97
97
|
now = now_iso()
|
|
98
98
|
return {
|
|
@@ -133,7 +133,7 @@ def save_bug_status(state_dir, bug_id, status_data):
|
|
|
133
133
|
"""Write the status.json for a bug (runtime fields only)."""
|
|
134
134
|
# Defensively strip status — it belongs in bug-fix-list.json
|
|
135
135
|
status_data.pop("status", None)
|
|
136
|
-
status_path = os.path.join(state_dir,
|
|
136
|
+
status_path = os.path.join(state_dir, bug_id, "status.json")
|
|
137
137
|
return write_json_file(status_path, status_data)
|
|
138
138
|
|
|
139
139
|
|
|
@@ -402,7 +402,7 @@ def cleanup_bug_artifacts(state_dir, bug_id, project_root=None):
|
|
|
402
402
|
cleaned = []
|
|
403
403
|
|
|
404
404
|
# 1) Remove all session history
|
|
405
|
-
sessions_dir = os.path.join(state_dir,
|
|
405
|
+
sessions_dir = os.path.join(state_dir, bug_id, "sessions")
|
|
406
406
|
sessions_deleted = 0
|
|
407
407
|
if os.path.isdir(sessions_dir):
|
|
408
408
|
for entry in os.listdir(sessions_dir):
|
|
@@ -413,7 +413,7 @@ def cleanup_bug_artifacts(state_dir, bug_id, project_root=None):
|
|
|
413
413
|
cleaned.append("Deleted {} session(s) from {}".format(sessions_deleted, sessions_dir))
|
|
414
414
|
|
|
415
415
|
# 2) Remove transient files under bug dir (keep status.json)
|
|
416
|
-
bug_dir = os.path.join(state_dir,
|
|
416
|
+
bug_dir = os.path.join(state_dir, bug_id)
|
|
417
417
|
if os.path.isdir(bug_dir):
|
|
418
418
|
for entry in os.listdir(bug_dir):
|
|
419
419
|
if entry == "status.json" or entry == "sessions":
|
|
@@ -446,8 +446,7 @@ def cleanup_bug_artifacts(state_dir, bug_id, project_root=None):
|
|
|
446
446
|
|
|
447
447
|
|
|
448
448
|
def load_session_status(state_dir, bug_id, session_id):
|
|
449
|
-
session_status_path = os.path.join(
|
|
450
|
-
state_dir, "bugs", bug_id, "sessions",
|
|
449
|
+
session_status_path = os.path.join(state_dir, bug_id, "sessions",
|
|
451
450
|
session_id, "session-status.json"
|
|
452
451
|
)
|
|
453
452
|
data, err = load_json_file(session_status_path)
|
|
@@ -649,7 +648,7 @@ def action_clean(args, bug_list_path, state_dir):
|
|
|
649
648
|
cleaned = []
|
|
650
649
|
|
|
651
650
|
# 1. Delete session history
|
|
652
|
-
sessions_dir = os.path.join(state_dir,
|
|
651
|
+
sessions_dir = os.path.join(state_dir, bug_id, "sessions")
|
|
653
652
|
sessions_deleted = 0
|
|
654
653
|
if os.path.isdir(sessions_dir):
|
|
655
654
|
for entry in os.listdir(sessions_dir):
|
|
@@ -167,9 +167,7 @@ def load_feature_status(state_dir, feature_id):
|
|
|
167
167
|
The 'status' field is NOT included — status lives exclusively
|
|
168
168
|
in feature-list.json.
|
|
169
169
|
"""
|
|
170
|
-
status_path = os.path.join(
|
|
171
|
-
state_dir, "features", feature_id, "status.json"
|
|
172
|
-
)
|
|
170
|
+
status_path = os.path.join(state_dir, feature_id, "status.json")
|
|
173
171
|
if not os.path.isfile(status_path):
|
|
174
172
|
now = now_iso()
|
|
175
173
|
return {
|
|
@@ -210,9 +208,7 @@ def save_feature_status(state_dir, feature_id, status_data):
|
|
|
210
208
|
"""Write the status.json for a feature (runtime fields only)."""
|
|
211
209
|
# Defensively strip status — it belongs in feature-list.json
|
|
212
210
|
status_data.pop("status", None)
|
|
213
|
-
status_path = os.path.join(
|
|
214
|
-
state_dir, "features", feature_id, "status.json"
|
|
215
|
-
)
|
|
211
|
+
status_path = os.path.join(state_dir, feature_id, "status.json")
|
|
216
212
|
return write_json_file(status_path, status_data)
|
|
217
213
|
|
|
218
214
|
|
|
@@ -296,7 +292,7 @@ def cleanup_feature_artifacts(feature_list_path, state_dir, feature_id, project_
|
|
|
296
292
|
cleaned = []
|
|
297
293
|
|
|
298
294
|
# 1) Remove all session history
|
|
299
|
-
sessions_dir = os.path.join(state_dir,
|
|
295
|
+
sessions_dir = os.path.join(state_dir, feature_id, "sessions")
|
|
300
296
|
sessions_deleted = 0
|
|
301
297
|
if os.path.isdir(sessions_dir):
|
|
302
298
|
for entry in os.listdir(sessions_dir):
|
|
@@ -307,7 +303,7 @@ def cleanup_feature_artifacts(feature_list_path, state_dir, feature_id, project_
|
|
|
307
303
|
cleaned.append("Deleted {} session(s) from {}".format(sessions_deleted, sessions_dir))
|
|
308
304
|
|
|
309
305
|
# 2) Remove transient files under feature state dir (keep status.json)
|
|
310
|
-
feature_dir = os.path.join(state_dir,
|
|
306
|
+
feature_dir = os.path.join(state_dir, feature_id)
|
|
311
307
|
if os.path.isdir(feature_dir):
|
|
312
308
|
for entry in os.listdir(feature_dir):
|
|
313
309
|
if entry == "status.json" or entry == "sessions":
|
|
@@ -344,8 +340,7 @@ def cleanup_feature_artifacts(feature_list_path, state_dir, feature_id, project_
|
|
|
344
340
|
|
|
345
341
|
def load_session_status(state_dir, feature_id, session_id):
|
|
346
342
|
"""Load a session's session-status.json file."""
|
|
347
|
-
session_status_path = os.path.join(
|
|
348
|
-
state_dir, "features", feature_id, "sessions",
|
|
343
|
+
session_status_path = os.path.join(state_dir, feature_id, "sessions",
|
|
349
344
|
session_id, "session-status.json"
|
|
350
345
|
)
|
|
351
346
|
data, err = load_json_file(session_status_path)
|
|
@@ -785,7 +780,7 @@ def _calc_feature_duration(state_dir, feature_id):
|
|
|
785
780
|
to the last update time for the calculation.
|
|
786
781
|
Returns None if the duration cannot be calculated.
|
|
787
782
|
"""
|
|
788
|
-
fs_path = os.path.join(state_dir,
|
|
783
|
+
fs_path = os.path.join(state_dir, feature_id, "status.json")
|
|
789
784
|
if not os.path.isfile(fs_path):
|
|
790
785
|
return None
|
|
791
786
|
data, err = load_json_file(fs_path)
|
|
@@ -1261,7 +1256,7 @@ def action_clean(args, feature_list_path, state_dir):
|
|
|
1261
1256
|
cleaned = []
|
|
1262
1257
|
|
|
1263
1258
|
# 1. Delete session history
|
|
1264
|
-
sessions_dir = os.path.join(state_dir,
|
|
1259
|
+
sessions_dir = os.path.join(state_dir, feature_id, "sessions")
|
|
1265
1260
|
sessions_deleted = 0
|
|
1266
1261
|
if os.path.isdir(sessions_dir):
|
|
1267
1262
|
for entry in os.listdir(sessions_dir):
|
|
@@ -122,7 +122,7 @@ def load_refactor_status(state_dir, refactor_id):
|
|
|
122
122
|
The 'status' field is NOT included — status lives exclusively
|
|
123
123
|
in refactor-list.json.
|
|
124
124
|
"""
|
|
125
|
-
status_path = os.path.join(state_dir,
|
|
125
|
+
status_path = os.path.join(state_dir, refactor_id, "status.json")
|
|
126
126
|
if not os.path.isfile(status_path):
|
|
127
127
|
return _default_status(refactor_id)
|
|
128
128
|
data, err = load_json_file(status_path)
|
|
@@ -137,7 +137,7 @@ def save_refactor_status(state_dir, refactor_id, status_data):
|
|
|
137
137
|
"""Write the status.json for a refactor (runtime fields only)."""
|
|
138
138
|
# Defensively strip status — it belongs in refactor-list.json
|
|
139
139
|
status_data.pop("status", None)
|
|
140
|
-
status_path = os.path.join(state_dir,
|
|
140
|
+
status_path = os.path.join(state_dir, refactor_id, "status.json")
|
|
141
141
|
return write_json_file(status_path, status_data)
|
|
142
142
|
|
|
143
143
|
|
|
@@ -442,7 +442,7 @@ def cleanup_refactor_artifacts(state_dir, refactor_id, project_root=None):
|
|
|
442
442
|
cleaned = []
|
|
443
443
|
|
|
444
444
|
# 1) Remove all session history
|
|
445
|
-
sessions_dir = os.path.join(state_dir,
|
|
445
|
+
sessions_dir = os.path.join(state_dir, refactor_id, "sessions")
|
|
446
446
|
sessions_deleted = 0
|
|
447
447
|
if os.path.isdir(sessions_dir):
|
|
448
448
|
for entry in os.listdir(sessions_dir):
|
|
@@ -453,7 +453,7 @@ def cleanup_refactor_artifacts(state_dir, refactor_id, project_root=None):
|
|
|
453
453
|
cleaned.append("Deleted {} session(s) from {}".format(sessions_deleted, sessions_dir))
|
|
454
454
|
|
|
455
455
|
# 2) Remove transient files under refactor dir (keep status.json)
|
|
456
|
-
refactor_dir = os.path.join(state_dir,
|
|
456
|
+
refactor_dir = os.path.join(state_dir, refactor_id)
|
|
457
457
|
if os.path.isdir(refactor_dir):
|
|
458
458
|
for entry in os.listdir(refactor_dir):
|
|
459
459
|
if entry == "status.json" or entry == "sessions":
|
|
@@ -482,8 +482,7 @@ def cleanup_refactor_artifacts(state_dir, refactor_id, project_root=None):
|
|
|
482
482
|
|
|
483
483
|
|
|
484
484
|
def load_session_status(state_dir, refactor_id, session_id):
|
|
485
|
-
session_status_path = os.path.join(
|
|
486
|
-
state_dir, "refactors", refactor_id, "sessions",
|
|
485
|
+
session_status_path = os.path.join(state_dir, refactor_id, "sessions",
|
|
487
486
|
session_id, "session-status.json"
|
|
488
487
|
)
|
|
489
488
|
data, err = load_json_file(session_status_path)
|
|
@@ -797,7 +796,7 @@ def action_clean(args, refactor_list_path, state_dir):
|
|
|
797
796
|
cleaned = []
|
|
798
797
|
|
|
799
798
|
# 1. Delete session history
|
|
800
|
-
sessions_dir = os.path.join(state_dir,
|
|
799
|
+
sessions_dir = os.path.join(state_dir, refactor_id, "sessions")
|
|
801
800
|
sessions_deleted = 0
|
|
802
801
|
if os.path.isdir(sessions_dir):
|
|
803
802
|
for entry in os.listdir(sessions_dir):
|
|
@@ -38,11 +38,11 @@ def _make_feature_list(features):
|
|
|
38
38
|
|
|
39
39
|
def _init_state(tmp_path, feature_ids):
|
|
40
40
|
"""Create state dir with status.json for each feature."""
|
|
41
|
-
state_dir = str(tmp_path / "state")
|
|
41
|
+
state_dir = str(tmp_path / "state" / "features")
|
|
42
42
|
for fid in feature_ids:
|
|
43
|
-
feature_dir = os.path.join(state_dir,
|
|
43
|
+
feature_dir = os.path.join(state_dir, fid, "sessions")
|
|
44
44
|
os.makedirs(feature_dir, exist_ok=True)
|
|
45
|
-
status_path = os.path.join(state_dir,
|
|
45
|
+
status_path = os.path.join(state_dir, fid, "status.json")
|
|
46
46
|
write_json_file(status_path, {
|
|
47
47
|
"feature_id": fid,
|
|
48
48
|
"status": "pending",
|
|
@@ -325,7 +325,7 @@ class TestInfraErrorUpdate:
|
|
|
325
325
|
features = [_make_feature("F-001", "Root", status="in_progress")]
|
|
326
326
|
fl_path = _write_fl(tmp_path, features)
|
|
327
327
|
state_dir = _init_state(tmp_path, ["F-001"])
|
|
328
|
-
status_path = os.path.join(state_dir, "
|
|
328
|
+
status_path = os.path.join(state_dir, "F-001", "status.json")
|
|
329
329
|
fs = load_feature_status(state_dir, "F-001")
|
|
330
330
|
fs["retry_count"] = 2
|
|
331
331
|
write_json_file(status_path, fs)
|
|
@@ -357,7 +357,7 @@ class TestInfraErrorUpdate:
|
|
|
357
357
|
features = [_make_feature("F-001", "Root", status="in_progress")]
|
|
358
358
|
fl_path = _write_fl(tmp_path, features)
|
|
359
359
|
state_dir = _init_state(tmp_path, ["F-001"])
|
|
360
|
-
status_path = os.path.join(state_dir, "
|
|
360
|
+
status_path = os.path.join(state_dir, "F-001", "status.json")
|
|
361
361
|
fs = load_feature_status(state_dir, "F-001")
|
|
362
362
|
fs["retry_count"] = 1
|
|
363
363
|
fs["infra_error_count"] = 2
|
|
@@ -389,7 +389,7 @@ class TestInfraErrorUpdate:
|
|
|
389
389
|
features = [_make_feature("F-001", "Root", status="failed")]
|
|
390
390
|
fl_path = _write_fl(tmp_path, features)
|
|
391
391
|
state_dir = _init_state(tmp_path, ["F-001"])
|
|
392
|
-
status_path = os.path.join(state_dir, "
|
|
392
|
+
status_path = os.path.join(state_dir, "F-001", "status.json")
|
|
393
393
|
fs = load_feature_status(state_dir, "F-001")
|
|
394
394
|
fs["retry_count"] = 3
|
|
395
395
|
fs["infra_error_count"] = 3
|
|
@@ -416,7 +416,7 @@ class TestInfraErrorUpdate:
|
|
|
416
416
|
features = [_make_feature("F-001", "Root", status="failed")]
|
|
417
417
|
fl_path = _write_fl(tmp_path, features)
|
|
418
418
|
state_dir = _init_state(tmp_path, ["F-001"])
|
|
419
|
-
status_path = os.path.join(state_dir, "
|
|
419
|
+
status_path = os.path.join(state_dir, "F-001", "status.json")
|
|
420
420
|
fs = load_feature_status(state_dir, "F-001")
|
|
421
421
|
fs["retry_count"] = 3
|
|
422
422
|
fs["infra_error_count"] = 3
|
|
@@ -563,7 +563,7 @@ class TestAutoSkipIntegration:
|
|
|
563
563
|
fl_path = _write_fl(tmp_path, features)
|
|
564
564
|
state_dir = _init_state(tmp_path, ["F-001"])
|
|
565
565
|
# Simulate retry_count = 3
|
|
566
|
-
fs_path = os.path.join(state_dir, "
|
|
566
|
+
fs_path = os.path.join(state_dir, "F-001", "status.json")
|
|
567
567
|
with open(fs_path) as f:
|
|
568
568
|
fs = json.load(f)
|
|
569
569
|
fs["retry_count"] = 3
|
|
@@ -647,7 +647,7 @@ function Invoke-PrizmPipeline {
|
|
|
647
647
|
}
|
|
648
648
|
|
|
649
649
|
if ($dryRun) {
|
|
650
|
-
$statusPath = Join-Path $stateDir "$
|
|
650
|
+
$statusPath = Join-Path $stateDir "$CurrentItemId\status.json"
|
|
651
651
|
if (Test-Path $statusPath) {
|
|
652
652
|
try {
|
|
653
653
|
$itemStatus = Get-Content -Raw $statusPath | ConvertFrom-Json
|
|
@@ -682,7 +682,7 @@ function Invoke-PrizmPipeline {
|
|
|
682
682
|
$sessionDir = if ($dryRun) {
|
|
683
683
|
Join-Path ([System.IO.Path]::GetTempPath()) "prizmkit-dry-run\$sessionId"
|
|
684
684
|
} else {
|
|
685
|
-
Join-Path $stateDir "$
|
|
685
|
+
Join-Path $stateDir "$CurrentItemId\sessions\$sessionId"
|
|
686
686
|
}
|
|
687
687
|
$logsDir = Join-Path $sessionDir 'logs'
|
|
688
688
|
New-Item -ItemType Directory -Force -Path $logsDir | Out-Null
|
|
@@ -113,8 +113,8 @@ def load_json(path):
|
|
|
113
113
|
|
|
114
114
|
|
|
115
115
|
def discover_item_ids(state_dir, subdir):
|
|
116
|
-
"""Return a sorted list of item IDs found
|
|
117
|
-
items_dir = os.path.join(state_dir, subdir)
|
|
116
|
+
"""Return a sorted list of item IDs found directly under the typed state dir."""
|
|
117
|
+
items_dir = os.path.join(state_dir, subdir) if subdir else state_dir
|
|
118
118
|
if not os.path.isdir(items_dir):
|
|
119
119
|
return []
|
|
120
120
|
ids = []
|
|
@@ -363,9 +363,9 @@ def find_task_list(state_dir):
|
|
|
363
363
|
|
|
364
364
|
# Pipeline type configurations
|
|
365
365
|
PIPELINE_CONFIG = {
|
|
366
|
-
"feature": {"subdir": "
|
|
367
|
-
"bugfix": {"subdir": "
|
|
368
|
-
"refactor": {"subdir": "
|
|
366
|
+
"feature": {"subdir": "", "items_key": "features", "id_label": "feature_id"},
|
|
367
|
+
"bugfix": {"subdir": "", "items_key": "bugs", "id_label": "bug_id"},
|
|
368
|
+
"refactor": {"subdir": "", "items_key": "refactors", "id_label": "refactor_id"},
|
|
369
369
|
}
|
|
370
370
|
|
|
371
371
|
|
|
@@ -430,9 +430,7 @@ def get_prev_session_status(state_dir, feature_id):
|
|
|
430
430
|
return "N/A (first run)"
|
|
431
431
|
|
|
432
432
|
# Try to read the feature status file to find the last session
|
|
433
|
-
feature_status_path = os.path.join(
|
|
434
|
-
state_dir, "features", feature_id, "status.json"
|
|
435
|
-
)
|
|
433
|
+
feature_status_path = os.path.join(state_dir, feature_id, "status.json")
|
|
436
434
|
if not os.path.isfile(feature_status_path):
|
|
437
435
|
return "N/A (first run)"
|
|
438
436
|
|
|
@@ -447,8 +445,7 @@ def get_prev_session_status(state_dir, feature_id):
|
|
|
447
445
|
return "N/A (first run)"
|
|
448
446
|
|
|
449
447
|
# Try to read the last session's session-status.json
|
|
450
|
-
session_status_path = os.path.join(
|
|
451
|
-
state_dir, "features", feature_id, "sessions",
|
|
448
|
+
session_status_path = os.path.join(state_dir, feature_id, "sessions",
|
|
452
449
|
last_session_id, "session-status.json"
|
|
453
450
|
)
|
|
454
451
|
if not os.path.isfile(session_status_path):
|
|
@@ -221,7 +221,7 @@ def get_prev_session_status(state_dir, bug_id):
|
|
|
221
221
|
if not state_dir:
|
|
222
222
|
return "N/A (first run)"
|
|
223
223
|
|
|
224
|
-
bug_status_path = os.path.join(state_dir,
|
|
224
|
+
bug_status_path = os.path.join(state_dir, bug_id, "status.json")
|
|
225
225
|
if not os.path.isfile(bug_status_path):
|
|
226
226
|
return "N/A (first run)"
|
|
227
227
|
|
|
@@ -235,8 +235,7 @@ def get_prev_session_status(state_dir, bug_id):
|
|
|
235
235
|
if not last_session_id:
|
|
236
236
|
return "N/A (first run)"
|
|
237
237
|
|
|
238
|
-
session_status_path = os.path.join(
|
|
239
|
-
state_dir, "bugs", bug_id, "sessions",
|
|
238
|
+
session_status_path = os.path.join(state_dir, bug_id, "sessions",
|
|
240
239
|
last_session_id, "session-status.json"
|
|
241
240
|
)
|
|
242
241
|
if not os.path.isfile(session_status_path):
|
|
@@ -307,7 +306,7 @@ def build_replacements(args, bug, global_context, script_dir):
|
|
|
307
306
|
|
|
308
307
|
# Session status path
|
|
309
308
|
session_status_path = os.path.join(
|
|
310
|
-
project_root, ".prizmkit", "state", "bugfix",
|
|
309
|
+
project_root, ".prizmkit", "state", "bugfix", args.bug_id,
|
|
311
310
|
"sessions", args.session_id, "session-status.json"
|
|
312
311
|
)
|
|
313
312
|
|
|
@@ -372,15 +371,15 @@ def build_replacements(args, bug, global_context, script_dir):
|
|
|
372
371
|
"{{MAX_LOG_SIZE_HUMAN}}": _format_bytes(max_log_size),
|
|
373
372
|
"{{LOG_MONITOR_POLL_INTERVAL}}": str(poll_interval),
|
|
374
373
|
"{{LOG_MONITOR_STATUS_FILE}}": os.path.join(
|
|
375
|
-
".prizmkit", "state", "bugfix",
|
|
374
|
+
".prizmkit", "state", "bugfix", args.bug_id,
|
|
376
375
|
"sessions", args.session_id, "logs", "log-monitor-status.txt",
|
|
377
376
|
),
|
|
378
377
|
"{{LOG_MONITOR_BASELINE_FILE}}": os.path.join(
|
|
379
|
-
".prizmkit", "state", "bugfix",
|
|
378
|
+
".prizmkit", "state", "bugfix", args.bug_id,
|
|
380
379
|
"sessions", args.session_id, "logs", "log-monitor-baseline.txt",
|
|
381
380
|
),
|
|
382
381
|
"{{SESSION_LOG_PATH}}": os.path.join(
|
|
383
|
-
".prizmkit", "state", "bugfix",
|
|
382
|
+
".prizmkit", "state", "bugfix", args.bug_id,
|
|
384
383
|
"sessions", args.session_id, "logs", "session.log",
|
|
385
384
|
),
|
|
386
385
|
"{{LOG_MONITOR_SCRIPT}}": os.path.join(
|
|
@@ -376,7 +376,7 @@ def get_prev_session_status(state_dir, refactor_id):
|
|
|
376
376
|
if not state_dir:
|
|
377
377
|
return "N/A (first run)"
|
|
378
378
|
|
|
379
|
-
refactor_status_path = os.path.join(state_dir,
|
|
379
|
+
refactor_status_path = os.path.join(state_dir, refactor_id, "status.json")
|
|
380
380
|
try:
|
|
381
381
|
with open(refactor_status_path, "r", encoding="utf-8") as f:
|
|
382
382
|
refactor_status = json.load(f)
|
|
@@ -387,8 +387,7 @@ def get_prev_session_status(state_dir, refactor_id):
|
|
|
387
387
|
if not last_session_id:
|
|
388
388
|
return "N/A (first run)"
|
|
389
389
|
|
|
390
|
-
session_status_path = os.path.join(
|
|
391
|
-
state_dir, "refactors", refactor_id, "sessions",
|
|
390
|
+
session_status_path = os.path.join(state_dir, refactor_id, "sessions",
|
|
392
391
|
last_session_id, "session-status.json"
|
|
393
392
|
)
|
|
394
393
|
try:
|
|
@@ -456,7 +455,7 @@ def build_replacements(args, refactor, refactors, global_context, script_dir):
|
|
|
456
455
|
|
|
457
456
|
# Session status path
|
|
458
457
|
session_status_path = os.path.join(
|
|
459
|
-
project_root, ".prizmkit", "state", "refactor",
|
|
458
|
+
project_root, ".prizmkit", "state", "refactor", args.refactor_id,
|
|
460
459
|
"sessions", args.session_id, "session-status.json"
|
|
461
460
|
)
|
|
462
461
|
|
|
@@ -532,15 +531,15 @@ def build_replacements(args, refactor, refactors, global_context, script_dir):
|
|
|
532
531
|
"{{MAX_LOG_SIZE_HUMAN}}": _format_bytes(max_log_size),
|
|
533
532
|
"{{LOG_MONITOR_POLL_INTERVAL}}": str(poll_interval),
|
|
534
533
|
"{{LOG_MONITOR_STATUS_FILE}}": os.path.join(
|
|
535
|
-
".prizmkit", "state", "refactor",
|
|
534
|
+
".prizmkit", "state", "refactor", args.refactor_id,
|
|
536
535
|
"sessions", args.session_id, "logs", "log-monitor-status.txt",
|
|
537
536
|
),
|
|
538
537
|
"{{LOG_MONITOR_BASELINE_FILE}}": os.path.join(
|
|
539
|
-
".prizmkit", "state", "refactor",
|
|
538
|
+
".prizmkit", "state", "refactor", args.refactor_id,
|
|
540
539
|
"sessions", args.session_id, "logs", "log-monitor-baseline.txt",
|
|
541
540
|
),
|
|
542
541
|
"{{SESSION_LOG_PATH}}": os.path.join(
|
|
543
|
-
".prizmkit", "state", "refactor",
|
|
542
|
+
".prizmkit", "state", "refactor", args.refactor_id,
|
|
544
543
|
"sessions", args.session_id, "logs", "session.log",
|
|
545
544
|
),
|
|
546
545
|
"{{LOG_MONITOR_SCRIPT}}": os.path.join(
|
|
@@ -207,7 +207,7 @@ def create_state_directory(state_dir, bug_list_path, bugs):
|
|
|
207
207
|
abs_bug_list_path = os.path.abspath(bug_list_path)
|
|
208
208
|
# Store as relative path from state_dir so pipeline.json is portable across machines
|
|
209
209
|
rel_bug_list_path = os.path.relpath(abs_bug_list_path, abs_state_dir)
|
|
210
|
-
bugs_dir =
|
|
210
|
+
bugs_dir = abs_state_dir
|
|
211
211
|
|
|
212
212
|
now = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
213
213
|
run_id = "bugfix-run-" + datetime.now(timezone.utc).strftime("%Y%m%d%H%M%S")
|
|
@@ -242,7 +242,7 @@ def create_state_directory(state_dir, feature_list_path, features):
|
|
|
242
242
|
abs_feature_list_path = os.path.abspath(feature_list_path)
|
|
243
243
|
# Store as relative path from state_dir so pipeline.json is portable across machines
|
|
244
244
|
rel_feature_list_path = os.path.relpath(abs_feature_list_path, abs_state_dir)
|
|
245
|
-
features_dir =
|
|
245
|
+
features_dir = abs_state_dir
|
|
246
246
|
|
|
247
247
|
now = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
248
248
|
run_id = "run-" + datetime.now(timezone.utc).strftime("%Y%m%d%H%M%S")
|
|
@@ -283,7 +283,7 @@ def create_state_directory(state_dir, refactor_list_path, refactors):
|
|
|
283
283
|
abs_refactor_list_path = os.path.abspath(refactor_list_path)
|
|
284
284
|
# Store as relative path from state_dir so pipeline.json is portable across machines
|
|
285
285
|
rel_refactor_list_path = os.path.relpath(abs_refactor_list_path, abs_state_dir)
|
|
286
|
-
refactors_dir =
|
|
286
|
+
refactors_dir = abs_state_dir
|
|
287
287
|
|
|
288
288
|
now = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
289
289
|
run_id = "refactor-run-" + datetime.now(timezone.utc).strftime("%Y%m%d%H%M%S")
|
|
@@ -92,7 +92,7 @@ def load_bug_status(state_dir, bug_id):
|
|
|
92
92
|
The 'status' field is NOT included — status lives exclusively
|
|
93
93
|
in bug-fix-list.json.
|
|
94
94
|
"""
|
|
95
|
-
status_path = os.path.join(state_dir,
|
|
95
|
+
status_path = os.path.join(state_dir, bug_id, "status.json")
|
|
96
96
|
if not os.path.isfile(status_path):
|
|
97
97
|
now = now_iso()
|
|
98
98
|
return {
|
|
@@ -133,7 +133,7 @@ def save_bug_status(state_dir, bug_id, status_data):
|
|
|
133
133
|
"""Write the status.json for a bug (runtime fields only)."""
|
|
134
134
|
# Defensively strip status — it belongs in bug-fix-list.json
|
|
135
135
|
status_data.pop("status", None)
|
|
136
|
-
status_path = os.path.join(state_dir,
|
|
136
|
+
status_path = os.path.join(state_dir, bug_id, "status.json")
|
|
137
137
|
return write_json_file(status_path, status_data)
|
|
138
138
|
|
|
139
139
|
|
|
@@ -402,7 +402,7 @@ def cleanup_bug_artifacts(state_dir, bug_id, project_root=None):
|
|
|
402
402
|
cleaned = []
|
|
403
403
|
|
|
404
404
|
# 1) Remove all session history
|
|
405
|
-
sessions_dir = os.path.join(state_dir,
|
|
405
|
+
sessions_dir = os.path.join(state_dir, bug_id, "sessions")
|
|
406
406
|
sessions_deleted = 0
|
|
407
407
|
if os.path.isdir(sessions_dir):
|
|
408
408
|
for entry in os.listdir(sessions_dir):
|
|
@@ -413,7 +413,7 @@ def cleanup_bug_artifacts(state_dir, bug_id, project_root=None):
|
|
|
413
413
|
cleaned.append("Deleted {} session(s) from {}".format(sessions_deleted, sessions_dir))
|
|
414
414
|
|
|
415
415
|
# 2) Remove transient files under bug dir (keep status.json)
|
|
416
|
-
bug_dir = os.path.join(state_dir,
|
|
416
|
+
bug_dir = os.path.join(state_dir, bug_id)
|
|
417
417
|
if os.path.isdir(bug_dir):
|
|
418
418
|
for entry in os.listdir(bug_dir):
|
|
419
419
|
if entry == "status.json" or entry == "sessions":
|
|
@@ -446,8 +446,7 @@ def cleanup_bug_artifacts(state_dir, bug_id, project_root=None):
|
|
|
446
446
|
|
|
447
447
|
|
|
448
448
|
def load_session_status(state_dir, bug_id, session_id):
|
|
449
|
-
session_status_path = os.path.join(
|
|
450
|
-
state_dir, "bugs", bug_id, "sessions",
|
|
449
|
+
session_status_path = os.path.join(state_dir, bug_id, "sessions",
|
|
451
450
|
session_id, "session-status.json"
|
|
452
451
|
)
|
|
453
452
|
data, err = load_json_file(session_status_path)
|
|
@@ -649,7 +648,7 @@ def action_clean(args, bug_list_path, state_dir):
|
|
|
649
648
|
cleaned = []
|
|
650
649
|
|
|
651
650
|
# 1. Delete session history
|
|
652
|
-
sessions_dir = os.path.join(state_dir,
|
|
651
|
+
sessions_dir = os.path.join(state_dir, bug_id, "sessions")
|
|
653
652
|
sessions_deleted = 0
|
|
654
653
|
if os.path.isdir(sessions_dir):
|
|
655
654
|
for entry in os.listdir(sessions_dir):
|
|
@@ -167,9 +167,7 @@ def load_feature_status(state_dir, feature_id):
|
|
|
167
167
|
The 'status' field is NOT included — status lives exclusively
|
|
168
168
|
in feature-list.json.
|
|
169
169
|
"""
|
|
170
|
-
status_path = os.path.join(
|
|
171
|
-
state_dir, "features", feature_id, "status.json"
|
|
172
|
-
)
|
|
170
|
+
status_path = os.path.join(state_dir, feature_id, "status.json")
|
|
173
171
|
if not os.path.isfile(status_path):
|
|
174
172
|
now = now_iso()
|
|
175
173
|
return {
|
|
@@ -210,9 +208,7 @@ def save_feature_status(state_dir, feature_id, status_data):
|
|
|
210
208
|
"""Write the status.json for a feature (runtime fields only)."""
|
|
211
209
|
# Defensively strip status — it belongs in feature-list.json
|
|
212
210
|
status_data.pop("status", None)
|
|
213
|
-
status_path = os.path.join(
|
|
214
|
-
state_dir, "features", feature_id, "status.json"
|
|
215
|
-
)
|
|
211
|
+
status_path = os.path.join(state_dir, feature_id, "status.json")
|
|
216
212
|
return write_json_file(status_path, status_data)
|
|
217
213
|
|
|
218
214
|
|
|
@@ -296,7 +292,7 @@ def cleanup_feature_artifacts(feature_list_path, state_dir, feature_id, project_
|
|
|
296
292
|
cleaned = []
|
|
297
293
|
|
|
298
294
|
# 1) Remove all session history
|
|
299
|
-
sessions_dir = os.path.join(state_dir,
|
|
295
|
+
sessions_dir = os.path.join(state_dir, feature_id, "sessions")
|
|
300
296
|
sessions_deleted = 0
|
|
301
297
|
if os.path.isdir(sessions_dir):
|
|
302
298
|
for entry in os.listdir(sessions_dir):
|
|
@@ -307,7 +303,7 @@ def cleanup_feature_artifacts(feature_list_path, state_dir, feature_id, project_
|
|
|
307
303
|
cleaned.append("Deleted {} session(s) from {}".format(sessions_deleted, sessions_dir))
|
|
308
304
|
|
|
309
305
|
# 2) Remove transient files under feature state dir (keep status.json)
|
|
310
|
-
feature_dir = os.path.join(state_dir,
|
|
306
|
+
feature_dir = os.path.join(state_dir, feature_id)
|
|
311
307
|
if os.path.isdir(feature_dir):
|
|
312
308
|
for entry in os.listdir(feature_dir):
|
|
313
309
|
if entry == "status.json" or entry == "sessions":
|
|
@@ -344,8 +340,7 @@ def cleanup_feature_artifacts(feature_list_path, state_dir, feature_id, project_
|
|
|
344
340
|
|
|
345
341
|
def load_session_status(state_dir, feature_id, session_id):
|
|
346
342
|
"""Load a session's session-status.json file."""
|
|
347
|
-
session_status_path = os.path.join(
|
|
348
|
-
state_dir, "features", feature_id, "sessions",
|
|
343
|
+
session_status_path = os.path.join(state_dir, feature_id, "sessions",
|
|
349
344
|
session_id, "session-status.json"
|
|
350
345
|
)
|
|
351
346
|
data, err = load_json_file(session_status_path)
|
|
@@ -785,7 +780,7 @@ def _calc_feature_duration(state_dir, feature_id):
|
|
|
785
780
|
to the last update time for the calculation.
|
|
786
781
|
Returns None if the duration cannot be calculated.
|
|
787
782
|
"""
|
|
788
|
-
fs_path = os.path.join(state_dir,
|
|
783
|
+
fs_path = os.path.join(state_dir, feature_id, "status.json")
|
|
789
784
|
if not os.path.isfile(fs_path):
|
|
790
785
|
return None
|
|
791
786
|
data, err = load_json_file(fs_path)
|
|
@@ -1261,7 +1256,7 @@ def action_clean(args, feature_list_path, state_dir):
|
|
|
1261
1256
|
cleaned = []
|
|
1262
1257
|
|
|
1263
1258
|
# 1. Delete session history
|
|
1264
|
-
sessions_dir = os.path.join(state_dir,
|
|
1259
|
+
sessions_dir = os.path.join(state_dir, feature_id, "sessions")
|
|
1265
1260
|
sessions_deleted = 0
|
|
1266
1261
|
if os.path.isdir(sessions_dir):
|
|
1267
1262
|
for entry in os.listdir(sessions_dir):
|
|
@@ -122,7 +122,7 @@ def load_refactor_status(state_dir, refactor_id):
|
|
|
122
122
|
The 'status' field is NOT included — status lives exclusively
|
|
123
123
|
in refactor-list.json.
|
|
124
124
|
"""
|
|
125
|
-
status_path = os.path.join(state_dir,
|
|
125
|
+
status_path = os.path.join(state_dir, refactor_id, "status.json")
|
|
126
126
|
if not os.path.isfile(status_path):
|
|
127
127
|
return _default_status(refactor_id)
|
|
128
128
|
data, err = load_json_file(status_path)
|
|
@@ -137,7 +137,7 @@ def save_refactor_status(state_dir, refactor_id, status_data):
|
|
|
137
137
|
"""Write the status.json for a refactor (runtime fields only)."""
|
|
138
138
|
# Defensively strip status — it belongs in refactor-list.json
|
|
139
139
|
status_data.pop("status", None)
|
|
140
|
-
status_path = os.path.join(state_dir,
|
|
140
|
+
status_path = os.path.join(state_dir, refactor_id, "status.json")
|
|
141
141
|
return write_json_file(status_path, status_data)
|
|
142
142
|
|
|
143
143
|
|
|
@@ -442,7 +442,7 @@ def cleanup_refactor_artifacts(state_dir, refactor_id, project_root=None):
|
|
|
442
442
|
cleaned = []
|
|
443
443
|
|
|
444
444
|
# 1) Remove all session history
|
|
445
|
-
sessions_dir = os.path.join(state_dir,
|
|
445
|
+
sessions_dir = os.path.join(state_dir, refactor_id, "sessions")
|
|
446
446
|
sessions_deleted = 0
|
|
447
447
|
if os.path.isdir(sessions_dir):
|
|
448
448
|
for entry in os.listdir(sessions_dir):
|
|
@@ -453,7 +453,7 @@ def cleanup_refactor_artifacts(state_dir, refactor_id, project_root=None):
|
|
|
453
453
|
cleaned.append("Deleted {} session(s) from {}".format(sessions_deleted, sessions_dir))
|
|
454
454
|
|
|
455
455
|
# 2) Remove transient files under refactor dir (keep status.json)
|
|
456
|
-
refactor_dir = os.path.join(state_dir,
|
|
456
|
+
refactor_dir = os.path.join(state_dir, refactor_id)
|
|
457
457
|
if os.path.isdir(refactor_dir):
|
|
458
458
|
for entry in os.listdir(refactor_dir):
|
|
459
459
|
if entry == "status.json" or entry == "sessions":
|
|
@@ -482,8 +482,7 @@ def cleanup_refactor_artifacts(state_dir, refactor_id, project_root=None):
|
|
|
482
482
|
|
|
483
483
|
|
|
484
484
|
def load_session_status(state_dir, refactor_id, session_id):
|
|
485
|
-
session_status_path = os.path.join(
|
|
486
|
-
state_dir, "refactors", refactor_id, "sessions",
|
|
485
|
+
session_status_path = os.path.join(state_dir, refactor_id, "sessions",
|
|
487
486
|
session_id, "session-status.json"
|
|
488
487
|
)
|
|
489
488
|
data, err = load_json_file(session_status_path)
|
|
@@ -797,7 +796,7 @@ def action_clean(args, refactor_list_path, state_dir):
|
|
|
797
796
|
cleaned = []
|
|
798
797
|
|
|
799
798
|
# 1. Delete session history
|
|
800
|
-
sessions_dir = os.path.join(state_dir,
|
|
799
|
+
sessions_dir = os.path.join(state_dir, refactor_id, "sessions")
|
|
801
800
|
sessions_deleted = 0
|
|
802
801
|
if os.path.isdir(sessions_dir):
|
|
803
802
|
for entry in os.listdir(sessions_dir):
|
|
@@ -245,9 +245,9 @@ Detect user intent from their message, then follow the corresponding workflow:
|
|
|
245
245
|
4. **For per-bug session logs** (when user asks about a specific bug):
|
|
246
246
|
```bash
|
|
247
247
|
# Check bug status for last session ID
|
|
248
|
-
cat .prizmkit/state/bugfix
|
|
248
|
+
cat .prizmkit/state/bugfix/<BUG_ID>/status.json 2>/dev/null
|
|
249
249
|
# Then tail that bug's session log
|
|
250
|
-
tail -100 .prizmkit/state/bugfix
|
|
250
|
+
tail -100 .prizmkit/state/bugfix/<BUG_ID>/sessions/<SESSION_ID>/logs/session.log
|
|
251
251
|
```
|
|
252
252
|
|
|
253
253
|
---
|
|
@@ -285,9 +285,9 @@ Detect user intent from their message, then follow the corresponding workflow:
|
|
|
285
285
|
4. **For per-feature session logs** (when user asks about a specific feature):
|
|
286
286
|
```bash
|
|
287
287
|
# Check feature status for last session ID
|
|
288
|
-
cat .prizmkit/state/features
|
|
288
|
+
cat .prizmkit/state/features/<FEATURE_ID>/status.json 2>/dev/null
|
|
289
289
|
# Then tail that feature's session log
|
|
290
|
-
tail -100 .prizmkit/state/features
|
|
290
|
+
tail -100 .prizmkit/state/features/<FEATURE_ID>/sessions/<SESSION_ID>/logs/session.log
|
|
291
291
|
```
|
|
292
292
|
|
|
293
293
|
---
|
|
@@ -48,8 +48,8 @@ Pipeline commands (for reference — Phase 1.3 will present these as a selectabl
|
|
|
48
48
|
| Workflow | Branch Pattern | Key Artifacts |
|
|
49
49
|
|----------|---------------|---------------|
|
|
50
50
|
| bug-fix-workflow | `fix/<BUG_ID>-*` | `.prizmkit/bugfix/<BUG_ID>/fix-plan.md`, `fix-report.md` |
|
|
51
|
-
| feature-workflow | `feat/*` | `.prizmkit/plans/feature-list.json`, `.prizmkit/state/features
|
|
52
|
-
| refactor-workflow | `refactor/*` | `.prizmkit/plans/refactor-list.json`, `.prizmkit/state/refactor
|
|
51
|
+
| feature-workflow | `feat/*` | `.prizmkit/plans/feature-list.json`, `.prizmkit/state/features/` |
|
|
52
|
+
| refactor-workflow | `refactor/*` | `.prizmkit/plans/refactor-list.json`, `.prizmkit/state/refactor/` |
|
|
53
53
|
|
|
54
54
|
---
|
|
55
55
|
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"name": "feature-list-exists",
|
|
24
24
|
"prompt": "resume",
|
|
25
25
|
"expected_output": "Should auto-detect feature-workflow from .prizmkit/plans/feature-list.json. Should detect .prizmkit/plans/feature-list.json exists but no pipeline state → infer Phase 3 (Launch). Should invoke feature-pipeline-launcher to start the pipeline.",
|
|
26
|
-
"setup_description": "On main branch, create .prizmkit/plans/feature-list.json with 3 features. No .prizmkit/state/features/
|
|
26
|
+
"setup_description": "On main branch, create .prizmkit/plans/feature-list.json with 3 features. No .prizmkit/state/features/ directory.",
|
|
27
27
|
"files": []
|
|
28
28
|
},
|
|
29
29
|
{
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"name": "refactor-monitoring",
|
|
32
32
|
"prompt": "pick up where it left off",
|
|
33
33
|
"expected_output": "Should auto-detect refactor-workflow from .prizmkit/plans/refactor-list.json + pipeline state. Should infer Phase 4 (Monitor). Should check pipeline status and report results.",
|
|
34
|
-
"setup_description": "On main branch, create .prizmkit/plans/refactor-list.json with 2 items. Create .prizmkit/state/refactor/
|
|
34
|
+
"setup_description": "On main branch, create .prizmkit/plans/refactor-list.json with 2 items. Create .prizmkit/state/refactor/ with status files showing 1 completed, 1 in-progress.",
|
|
35
35
|
"files": []
|
|
36
36
|
},
|
|
37
37
|
{
|
|
@@ -288,9 +288,9 @@ Detect user intent from their message, then follow the corresponding workflow:
|
|
|
288
288
|
4. **For per-refactor session logs** (when user asks about a specific refactor):
|
|
289
289
|
```bash
|
|
290
290
|
# Check refactor status for last session ID
|
|
291
|
-
cat .prizmkit/state/refactor
|
|
291
|
+
cat .prizmkit/state/refactor/<REFACTOR_ID>/status.json 2>/dev/null
|
|
292
292
|
# Then tail that refactor's session log
|
|
293
|
-
tail -100 .prizmkit/state/refactor
|
|
293
|
+
tail -100 .prizmkit/state/refactor/<REFACTOR_ID>/sessions/<SESSION_ID>/logs/session.log
|
|
294
294
|
```
|
|
295
295
|
|
|
296
296
|
---
|
|
@@ -271,9 +271,9 @@ Detect user intent from their message, then follow the corresponding workflow:
|
|
|
271
271
|
4. **For per-bug session logs** (when user asks about a specific bug):
|
|
272
272
|
```powershell
|
|
273
273
|
# Check bug status for last session ID
|
|
274
|
-
Get-Content .prizmkit/state/bugfix
|
|
274
|
+
Get-Content .prizmkit/state/bugfix/<BUG_ID>/status.json -ErrorAction SilentlyContinue
|
|
275
275
|
# Then tail that bug's session log
|
|
276
|
-
Get-Content -Tail 100 .prizmkit/state/bugfix
|
|
276
|
+
Get-Content -Tail 100 .prizmkit/state/bugfix/<BUG_ID>/sessions/<SESSION_ID>/logs/session.log
|
|
277
277
|
```
|
|
278
278
|
|
|
279
279
|
---
|
|
@@ -312,9 +312,9 @@ Detect user intent from their message, then follow the corresponding workflow:
|
|
|
312
312
|
4. **For per-feature session logs** (when user asks about a specific feature):
|
|
313
313
|
```powershell
|
|
314
314
|
# Check feature status for last session ID
|
|
315
|
-
Get-Content .prizmkit/state/features
|
|
315
|
+
Get-Content .prizmkit/state/features/<FEATURE_ID>/status.json -ErrorAction SilentlyContinue
|
|
316
316
|
# Then tail that feature's session log
|
|
317
|
-
Get-Content -Tail 100 .prizmkit/state/features
|
|
317
|
+
Get-Content -Tail 100 .prizmkit/state/features/<FEATURE_ID>/sessions/<SESSION_ID>/logs/session.log
|
|
318
318
|
```
|
|
319
319
|
|
|
320
320
|
---
|
|
@@ -48,8 +48,8 @@ Pipeline commands (for reference — Phase 1.3 will present these as a selectabl
|
|
|
48
48
|
| Workflow | Branch Pattern | Key Artifacts |
|
|
49
49
|
|----------|---------------|---------------|
|
|
50
50
|
| bug-fix-workflow | `fix/<BUG_ID>-*` | `.prizmkit/bugfix/<BUG_ID>/fix-plan.md`, `fix-report.md` |
|
|
51
|
-
| feature-workflow | `feat/*` | `.prizmkit/plans/feature-list.json`, `.prizmkit/state/features
|
|
52
|
-
| refactor-workflow | `refactor/*` | `.prizmkit/plans/refactor-list.json`, `.prizmkit/state/refactor
|
|
51
|
+
| feature-workflow | `feat/*` | `.prizmkit/plans/feature-list.json`, `.prizmkit/state/features/` |
|
|
52
|
+
| refactor-workflow | `refactor/*` | `.prizmkit/plans/refactor-list.json`, `.prizmkit/state/refactor/` |
|
|
53
53
|
|
|
54
54
|
---
|
|
55
55
|
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"name": "feature-list-exists",
|
|
24
24
|
"prompt": "resume",
|
|
25
25
|
"expected_output": "Should auto-detect feature-workflow from .prizmkit/plans/feature-list.json. Should detect .prizmkit/plans/feature-list.json exists but no pipeline state → infer Phase 3 (Launch). Should invoke feature-pipeline-launcher to start the pipeline.",
|
|
26
|
-
"setup_description": "On main branch, create .prizmkit/plans/feature-list.json with 3 features. No .prizmkit/state/features/
|
|
26
|
+
"setup_description": "On main branch, create .prizmkit/plans/feature-list.json with 3 features. No .prizmkit/state/features/ directory.",
|
|
27
27
|
"files": []
|
|
28
28
|
},
|
|
29
29
|
{
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"name": "refactor-monitoring",
|
|
32
32
|
"prompt": "pick up where it left off",
|
|
33
33
|
"expected_output": "Should auto-detect refactor-workflow from .prizmkit/plans/refactor-list.json + pipeline state. Should infer Phase 4 (Monitor). Should check pipeline status and report results.",
|
|
34
|
-
"setup_description": "On main branch, create .prizmkit/plans/refactor-list.json with 2 items. Create .prizmkit/state/refactor/
|
|
34
|
+
"setup_description": "On main branch, create .prizmkit/plans/refactor-list.json with 2 items. Create .prizmkit/state/refactor/ with status files showing 1 completed, 1 in-progress.",
|
|
35
35
|
"files": []
|
|
36
36
|
},
|
|
37
37
|
{
|
|
@@ -311,9 +311,9 @@ Detect user intent from their message, then follow the corresponding workflow:
|
|
|
311
311
|
4. **For per-refactor session logs** (when user asks about a specific refactor):
|
|
312
312
|
```powershell
|
|
313
313
|
# Check refactor status for last session ID
|
|
314
|
-
Get-Content .prizmkit/state/refactor
|
|
314
|
+
Get-Content .prizmkit/state/refactor/<REFACTOR_ID>/status.json -ErrorAction SilentlyContinue
|
|
315
315
|
# Then tail that refactor's session log
|
|
316
|
-
Get-Content -Tail 100 .prizmkit/state/refactor
|
|
316
|
+
Get-Content -Tail 100 .prizmkit/state/refactor/<REFACTOR_ID>/sessions/<SESSION_ID>/logs/session.log
|
|
317
317
|
```
|
|
318
318
|
|
|
319
319
|
---
|