prizmkit 1.1.98 → 1.1.100

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/bundled/VERSION.json +3 -3
  2. package/bundled/dev-pipeline/README.md +5 -5
  3. package/bundled/dev-pipeline/launch-bugfix-daemon.sh +1 -1
  4. package/bundled/dev-pipeline/launch-feature-daemon.sh +1 -1
  5. package/bundled/dev-pipeline/launch-refactor-daemon.sh +1 -1
  6. package/bundled/dev-pipeline/lib/common.sh +244 -25
  7. package/bundled/dev-pipeline/reset-bug.sh +32 -2
  8. package/bundled/dev-pipeline/reset-feature.sh +32 -2
  9. package/bundled/dev-pipeline/reset-refactor.sh +32 -2
  10. package/bundled/dev-pipeline/run-bugfix.sh +133 -18
  11. package/bundled/dev-pipeline/run-feature.sh +134 -18
  12. package/bundled/dev-pipeline/run-refactor.sh +133 -18
  13. package/bundled/dev-pipeline/scripts/check-session-status.py +74 -1
  14. package/bundled/dev-pipeline/scripts/continuation.py +374 -0
  15. package/bundled/dev-pipeline/scripts/detect-stuck.py +5 -5
  16. package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +29 -35
  17. package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +19 -25
  18. package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +19 -25
  19. package/bundled/dev-pipeline/scripts/init-bugfix-pipeline.py +1 -1
  20. package/bundled/dev-pipeline/scripts/init-pipeline.py +1 -1
  21. package/bundled/dev-pipeline/scripts/init-refactor-pipeline.py +1 -1
  22. package/bundled/dev-pipeline/scripts/parse-stream-progress.py +146 -16
  23. package/bundled/dev-pipeline/scripts/update-bug-status.py +220 -13
  24. package/bundled/dev-pipeline/scripts/update-feature-status.py +244 -18
  25. package/bundled/dev-pipeline/scripts/update-refactor-status.py +220 -13
  26. package/bundled/dev-pipeline/templates/agent-prompts/dev-implement.md +1 -1
  27. package/bundled/dev-pipeline/templates/bootstrap-tier1.md +2 -2
  28. package/bundled/dev-pipeline/templates/bootstrap-tier2.md +3 -3
  29. package/bundled/dev-pipeline/templates/bootstrap-tier3.md +3 -3
  30. package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +1 -1
  31. package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +3 -3
  32. package/bundled/dev-pipeline/templates/sections/log-size-awareness.md +31 -66
  33. package/bundled/dev-pipeline/templates/session-status-schema.json +1 -1
  34. package/bundled/dev-pipeline/tests/conftest.py +1 -0
  35. package/bundled/dev-pipeline/tests/test_auto_skip.py +518 -8
  36. package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +103 -0
  37. package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +60 -0
  38. package/bundled/dev-pipeline/tests/test_generate_refactor_prompt.py +43 -0
  39. package/bundled/dev-pipeline-windows/lib/common.ps1 +172 -10
  40. package/bundled/dev-pipeline-windows/lib/pipeline.ps1 +95 -11
  41. package/bundled/dev-pipeline-windows/lib/reset.ps1 +34 -0
  42. package/bundled/dev-pipeline-windows/reset-bug.ps1 +1 -0
  43. package/bundled/dev-pipeline-windows/reset-feature.ps1 +1 -0
  44. package/bundled/dev-pipeline-windows/reset-refactor.ps1 +1 -0
  45. package/bundled/dev-pipeline-windows/scripts/check-session-status.py +74 -1
  46. package/bundled/dev-pipeline-windows/scripts/continuation.py +374 -0
  47. package/bundled/dev-pipeline-windows/scripts/detect-stuck.py +5 -5
  48. package/bundled/dev-pipeline-windows/scripts/generate-bootstrap-prompt.py +29 -35
  49. package/bundled/dev-pipeline-windows/scripts/generate-bugfix-prompt.py +20 -25
  50. package/bundled/dev-pipeline-windows/scripts/generate-refactor-prompt.py +20 -25
  51. package/bundled/dev-pipeline-windows/scripts/init-bugfix-pipeline.py +1 -1
  52. package/bundled/dev-pipeline-windows/scripts/init-pipeline.py +1 -1
  53. package/bundled/dev-pipeline-windows/scripts/init-refactor-pipeline.py +1 -1
  54. package/bundled/dev-pipeline-windows/scripts/parse-stream-progress.py +146 -16
  55. package/bundled/dev-pipeline-windows/scripts/update-bug-status.py +220 -13
  56. package/bundled/dev-pipeline-windows/scripts/update-feature-status.py +244 -18
  57. package/bundled/dev-pipeline-windows/scripts/update-refactor-status.py +220 -13
  58. package/bundled/dev-pipeline-windows/templates/agent-prompts/dev-implement.md +1 -1
  59. package/bundled/dev-pipeline-windows/templates/bootstrap-tier1.md +2 -2
  60. package/bundled/dev-pipeline-windows/templates/bootstrap-tier2.md +3 -3
  61. package/bundled/dev-pipeline-windows/templates/bootstrap-tier3.md +3 -3
  62. package/bundled/dev-pipeline-windows/templates/bugfix-bootstrap-prompt.md +1 -1
  63. package/bundled/dev-pipeline-windows/templates/refactor-bootstrap-prompt.md +3 -3
  64. package/bundled/dev-pipeline-windows/templates/sections/log-size-awareness.md +31 -68
  65. package/bundled/dev-pipeline-windows/templates/session-status-schema.json +1 -1
  66. package/bundled/skills/_metadata.json +1 -1
  67. package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +2 -2
  68. package/bundled/skills/feature-pipeline-launcher/SKILL.md +2 -2
  69. package/bundled/skills/recovery-workflow/SKILL.md +2 -2
  70. package/bundled/skills/recovery-workflow/evals/evals.json +2 -2
  71. package/bundled/skills/refactor-pipeline-launcher/SKILL.md +2 -2
  72. package/bundled/skills-windows/bugfix-pipeline-launcher/SKILL.md +2 -2
  73. package/bundled/skills-windows/feature-pipeline-launcher/SKILL.md +2 -2
  74. package/bundled/skills-windows/recovery-workflow/SKILL.md +2 -2
  75. package/bundled/skills-windows/recovery-workflow/evals/evals.json +2 -2
  76. package/bundled/skills-windows/refactor-pipeline-launcher/SKILL.md +2 -2
  77. package/package.json +1 -1
  78. package/bundled/dev-pipeline/scripts/monitor-log.sh +0 -104
  79. package/bundled/dev-pipeline-windows/scripts/monitor-log.ps1 +0 -102
@@ -50,8 +50,7 @@ function Invoke-PrizmPipeline {
50
50
  Write-Host ""
51
51
  Write-Host "Environment Variables:"
52
52
  Write-Host " PRIZMKIT_EFFORT AI reasoning effort (low|medium|high|xhigh|max; max is Claude Code only)"
53
- Write-Host " MAX_LOG_SIZE Session log size threshold for compact warning (default: 2097152 = 2MB, set 0 to disable)"
54
- Write-Host " LOG_MONITOR_POLL_INTERVAL Log monitor poll interval in seconds (default: 30)"
53
+ Write-Host " MAX_LOG_SIZE Include passive log-size checkpoint guidance above this threshold (default: 2097152 = 2MB, set 0 to disable)"
55
54
  $global:PRIZM_EXIT_CODE = 0
56
55
  return
57
56
  }
@@ -626,7 +625,10 @@ function Invoke-PrizmPipeline {
626
625
  }
627
626
 
628
627
  function Invoke-PrizmPipelineItem {
629
- param([string]$CurrentItemId)
628
+ param(
629
+ [string]$CurrentItemId,
630
+ [object]$ContinuationState = $null
631
+ )
630
632
  $script:PRIZM_ITEM_EXIT_CODE = 0
631
633
 
632
634
  $sessionId = New-PrizmSessionId $Kind
@@ -636,6 +638,27 @@ function Invoke-PrizmPipeline {
636
638
  $isGitRepository = if (-not $dryRun) { Test-PrizmGitRepository $paths.ProjectRoot } else { $false }
637
639
  $originalBranch = if ($isGitRepository) { Get-PrizmCurrentBranch $paths.ProjectRoot } else { '' }
638
640
  $devBranchName = ''
641
+ $activeDevBranch = ''
642
+ $continuationPending = $false
643
+ $continuationReason = ''
644
+ $contextOverflowCount = 0
645
+ $continuationCount = 0
646
+ $previousSessionId = ''
647
+ $noProgressCount = 0
648
+ if ($ContinuationState) {
649
+ if ($ContinuationState.PSObject.Properties['active_dev_branch'] -and $ContinuationState.active_dev_branch) { $activeDevBranch = [string]$ContinuationState.active_dev_branch }
650
+ if ($ContinuationState.PSObject.Properties['base_branch'] -and $ContinuationState.base_branch) { $originalBranch = [string]$ContinuationState.base_branch }
651
+ if ($ContinuationState.PSObject.Properties['continuation_pending']) { $continuationPending = [bool]$ContinuationState.continuation_pending }
652
+ if ($ContinuationState.PSObject.Properties['continuation_reason'] -and $ContinuationState.continuation_reason) { $continuationReason = [string]$ContinuationState.continuation_reason }
653
+ if ($ContinuationState.PSObject.Properties['context_overflow_count'] -and $ContinuationState.context_overflow_count -ne $null) { $contextOverflowCount = [int]$ContinuationState.context_overflow_count }
654
+ if ($ContinuationState.PSObject.Properties['continuation_count'] -and $ContinuationState.continuation_count -ne $null) { $continuationCount = [int]$ContinuationState.continuation_count }
655
+ if ($ContinuationState.PSObject.Properties['last_context_overflow_session_id'] -and $ContinuationState.last_context_overflow_session_id) { $previousSessionId = [string]$ContinuationState.last_context_overflow_session_id }
656
+ if ($ContinuationState.PSObject.Properties['no_progress_count'] -and $ContinuationState.no_progress_count -ne $null) { $noProgressCount = [int]$ContinuationState.no_progress_count }
657
+ }
658
+ if ($continuationPending -and $activeDevBranch) {
659
+ Write-PrizmInfo "Continuation pending ($continuationReason); reusing dev branch: $activeDevBranch"
660
+ Write-PrizmInfo "Continuation count: $continuationCount (context overflows: $contextOverflowCount)"
661
+ }
639
662
  $hadDirtyBaseline = if ($isGitRepository) { Test-PrizmGitWorkDirty $paths.ProjectRoot $stateDir $listPath } else { $false }
640
663
  if ($hadDirtyBaseline) {
641
664
  if ($dryRun) {
@@ -647,7 +670,7 @@ function Invoke-PrizmPipeline {
647
670
  }
648
671
 
649
672
  if ($dryRun) {
650
- $statusPath = Join-Path $stateDir "$($idName)s\$CurrentItemId\status.json"
673
+ $statusPath = Join-Path $stateDir "$CurrentItemId\status.json"
651
674
  if (Test-Path $statusPath) {
652
675
  try {
653
676
  $itemStatus = Get-Content -Raw $statusPath | ConvertFrom-Json
@@ -664,7 +687,7 @@ function Invoke-PrizmPipeline {
664
687
 
665
688
  if ($isGitRepository -and $originalBranch) {
666
689
  Invoke-PrizmGitCommitPath $paths.ProjectRoot $listPath "chore($CurrentItemId): mark in_progress" | Out-Null
667
- $candidateBranch = if ($devBranchOverride) { $devBranchOverride } else { New-PrizmDefaultDevBranchName $Kind $CurrentItemId }
690
+ $candidateBranch = if ($devBranchOverride) { $devBranchOverride } elseif ($continuationPending -and $activeDevBranch) { $activeDevBranch } else { New-PrizmDefaultDevBranchName $Kind $CurrentItemId }
668
691
  if (New-PrizmDevBranch $paths.ProjectRoot $candidateBranch $originalBranch) {
669
692
  $devBranchName = $candidateBranch
670
693
  Write-PrizmInfo "Dev branch: $devBranchName"
@@ -679,10 +702,11 @@ function Invoke-PrizmPipeline {
679
702
 
680
703
  $baseCommit = if ($isGitRepository) { Get-PrizmGitHead $paths.ProjectRoot } else { '' }
681
704
 
705
+ while ($true) {
682
706
  $sessionDir = if ($dryRun) {
683
707
  Join-Path ([System.IO.Path]::GetTempPath()) "prizmkit-dry-run\$sessionId"
684
708
  } else {
685
- Join-Path $stateDir "$($idName)s\$CurrentItemId\sessions\$sessionId"
709
+ Join-Path $stateDir "$CurrentItemId\sessions\$sessionId"
686
710
  }
687
711
  $logsDir = Join-Path $sessionDir 'logs'
688
712
  New-Item -ItemType Directory -Force -Path $logsDir | Out-Null
@@ -697,6 +721,15 @@ function Invoke-PrizmPipeline {
697
721
  }
698
722
 
699
723
  $promptArgs = @((Join-Path $paths.ScriptsDir $promptScript), $listOption, $listPath, $idOption, $CurrentItemId, '--session-id', $sessionId, '--run-id', $runId, '--retry-count', $retryCount, '--resume-phase', $resumePhase, '--state-dir', $stateDir, '--output', $promptPath)
724
+ $continuationSummaryPath = ".prizmkit/$Kind/$CurrentItemId/continuation-summary.md"
725
+ if ($Kind -eq 'feature') {
726
+ $featureSlug = Get-PrizmFeatureSlugFromList $listPath $CurrentItemId
727
+ if ($featureSlug) { $continuationSummaryPath = ".prizmkit/specs/$featureSlug/continuation-summary.md" }
728
+ }
729
+ if ($continuationPending) {
730
+ $modeForContinuation = if ($continuationReason) { $continuationReason } else { 'context_overflow' }
731
+ $promptArgs += @('--continuation-mode', $modeForContinuation, '--previous-session-id', $previousSessionId, '--continuation-count', [string]$continuationCount, '--context-overflow-count', [string]$contextOverflowCount, '--task-type', $Kind, '--active-dev-branch', $activeDevBranch, '--base-branch', $originalBranch, '--continuation-summary-path', $continuationSummaryPath)
732
+ }
700
733
  if ($mode) { $promptArgs += @('--mode', $mode) }
701
734
  if ($critic) { $promptArgs += @('--critic', $critic) }
702
735
  if ($dryRun) { $promptArgs += '--no-checkpoint' }
@@ -717,6 +750,10 @@ function Invoke-PrizmPipeline {
717
750
 
718
751
  Write-PrizmInfo "Starting $cli session for $CurrentItemId ($sessionId)"
719
752
 
753
+ $artifactDirForFingerprint = if ($Kind -eq 'feature') { Split-Path $continuationSummaryPath -Parent } else { ".prizmkit/$Kind/$CurrentItemId" }
754
+ $checkpointForFingerprint = Join-Path $artifactDirForFingerprint 'workflow-checkpoint.json'
755
+ $progressBefore = Get-PrizmContextProgressFingerprint -ProjectRoot $paths.ProjectRoot -TaskType $Kind -TaskId $CurrentItemId -ArtifactDir $artifactDirForFingerprint -CheckpointFile $checkpointForFingerprint
756
+
720
757
  $progressJson = Join-Path $logsDir 'progress.json'
721
758
  $parserProcess = Start-PrizmProgressParser -PythonCommand $python -ScriptsDir $paths.ScriptsDir -SessionLog $sessionLog -ProgressFile $progressJson -CliCommand $cli
722
759
 
@@ -798,22 +835,34 @@ function Invoke-PrizmPipeline {
798
835
  }
799
836
  Stop-PrizmProgressParser $parserProcess
800
837
 
838
+ $wasContextOverflow = Test-PrizmContextOverflowError -SessionLog $sessionLog -ProgressJson $progressJson
801
839
  $wasInfraError = ($exitCode -ne 0 -and (Test-PrizmInfraError -SessionLog $sessionLog -ProgressJson $progressJson))
802
840
  $wasAiRuntimeError = Test-PrizmAiRuntimeError -SessionLog $sessionLog -ProgressJson $progressJson
803
841
  $semanticCompletion = if ($Kind -eq 'feature' -and $isGitRepository) {
804
842
  Get-PrizmFeatureSemanticCompletion $paths.ProjectRoot $listPath $CurrentItemId $baseCommit $paths.PrizmkitDir
805
843
  } else { $null }
806
844
 
845
+ $hasSuccessfulCommit = $false
846
+ if ($Kind -ne 'feature' -and $isGitRepository) {
847
+ $hasSuccessfulCommit = Test-PrizmGitCommitsSince $paths.ProjectRoot $baseCommit
848
+ }
849
+
807
850
  $status = 'crashed'
808
851
  if ($semanticCompletion) {
809
852
  $status = 'success'
810
- if ($exitCode -ne 0 -or $wasStaleKilled -or $wasAiRuntimeError) {
853
+ if ($exitCode -ne 0 -or $wasStaleKilled -or $wasContextOverflow -or $wasAiRuntimeError) {
811
854
  Write-PrizmWarn "Session ended with a failure signal after semantic completion; treating as finalized success"
812
855
  Write-PrizmWarn "Semantic completion commit: $($semanticCompletion.CommitSha)"
813
856
  }
857
+ } elseif ($hasSuccessfulCommit) {
858
+ $status = 'success'
859
+ } elseif ($wasContextOverflow) {
860
+ $status = 'context_overflow'
861
+ Write-PrizmWarn "AI session failed because the AI CLI exceeded the model context window"
862
+ Write-PrizmWarn "Context overflow is retried without consuming code retry budget"
814
863
  } elseif ($wasAiRuntimeError) {
815
864
  $status = 'infra_error'
816
- Write-PrizmWarn "AI session failed due to structured AI runtime/context error"
865
+ Write-PrizmWarn "AI session failed due to structured AI runtime error"
817
866
  Write-PrizmWarn "AI runtime errors are retried without consuming code retry budget"
818
867
  } elseif ($wasInfraError) {
819
868
  $status = 'infra_error'
@@ -841,6 +890,38 @@ function Invoke-PrizmPipeline {
841
890
 
842
891
  $mergeSucceeded = $true
843
892
  $itemListStatus = ''
893
+ $activeDevBranchForStatus = $devBranchName
894
+ $progressAfter = ''
895
+ $statusContinuationArgs = @('--active-dev-branch', $activeDevBranchForStatus, '--base-branch', $originalBranch, '--last-fatal-error-code', 'context_overflow', '--continuation-summary-path', $continuationSummaryPath)
896
+ if ($status -eq 'context_overflow') {
897
+ $progressAfter = Get-PrizmContextProgressFingerprint -ProjectRoot $paths.ProjectRoot -TaskType $Kind -TaskId $CurrentItemId -ArtifactDir $artifactDirForFingerprint -CheckpointFile $checkpointForFingerprint
898
+ if (Test-PrizmContextProgressChanged -BeforeJson $progressBefore -AfterJson $progressAfter) {
899
+ $noProgressCount = 0
900
+ Write-PrizmInfo "Context-overflow session made observable progress; continuing on $devBranchName"
901
+ } else {
902
+ $noProgressCount++
903
+ Write-PrizmWarn "Context-overflow session made no observable progress ($noProgressCount consecutive)"
904
+ }
905
+ $statusContinuationArgs = @('--active-dev-branch', $activeDevBranchForStatus, '--base-branch', $originalBranch, '--last-fatal-error-code', 'context_overflow', '--continuation-summary-path', $continuationSummaryPath, '--no-progress-count', [string]$noProgressCount, '--progress-fingerprint', $progressAfter)
906
+ if ($noProgressCount -ge 2) {
907
+ Write-PrizmWarn 'Pausing automatic continuation: context_overflow_without_git_checkpoint_or_artifact_progress'
908
+ $status = 'stalled_context_continuation'
909
+ } else {
910
+ $updateResult = Invoke-PrizmPythonJson $python (@((Join-Path $paths.ScriptsDir $updateScript), $listOption, $listPath, '--state-dir', $stateDir, '--action', 'update', $idOption, $CurrentItemId, '--session-id', $sessionId, '--session-status', 'context_overflow') + $maxRetryArgs + $maxInfraRetryArgs + $statusContinuationArgs)
911
+ if ($updateResult -and $updateResult.PSObject.Properties['new_status']) { $itemListStatus = [string]$updateResult.new_status }
912
+ $continuationPending = $true
913
+ $continuationReason = 'context_overflow'
914
+ $previousSessionId = $sessionId
915
+ $activeDevBranch = $devBranchName
916
+ $contextOverflowCount++
917
+ $continuationCount++
918
+ $sessionId = New-PrizmSessionId $Kind
919
+ $runId = "run-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
920
+ Write-PrizmInfo "Launching automatic continuation for $CurrentItemId on same branch/worktree"
921
+ continue
922
+ }
923
+ }
924
+
844
925
  if ($status -eq 'success') {
845
926
  if (Test-PrizmGitDirty $paths.ProjectRoot) {
846
927
  Write-PrizmInfo "Auto-committing remaining session artifacts."
@@ -848,7 +929,7 @@ function Invoke-PrizmPipeline {
848
929
  }
849
930
 
850
931
  if ($status -eq 'success') {
851
- $updateResult = Invoke-PrizmPythonJson $python (@((Join-Path $paths.ScriptsDir $updateScript), $listOption, $listPath, '--state-dir', $stateDir, '--action', 'update', $idOption, $CurrentItemId, '--session-id', $sessionId, '--session-status', $status) + $maxRetryArgs + $maxInfraRetryArgs)
932
+ $updateResult = Invoke-PrizmPythonJson $python (@((Join-Path $paths.ScriptsDir $updateScript), $listOption, $listPath, '--state-dir', $stateDir, '--action', 'update', $idOption, $CurrentItemId, '--session-id', $sessionId, '--session-status', $status) + $maxRetryArgs + $maxInfraRetryArgs + $statusContinuationArgs)
852
933
  if ($updateResult -and $updateResult.PSObject.Properties['new_status']) {
853
934
  $itemListStatus = [string]$updateResult.new_status
854
935
  }
@@ -885,7 +966,7 @@ function Invoke-PrizmPipeline {
885
966
  Write-PrizmRuntimeFailureLog $failureLog $CurrentItemId $sessionId $status $exitCode $staleKillMarker $progressJson $checkpointPath $paths.ProjectRoot $baseCommit
886
967
  }
887
968
  }
888
- $updateResult = Invoke-PrizmPythonJson $python (@((Join-Path $paths.ScriptsDir $updateScript), $listOption, $listPath, '--state-dir', $stateDir, '--action', 'update', $idOption, $CurrentItemId, '--session-id', $sessionId, '--session-status', $status) + $maxRetryArgs + $maxInfraRetryArgs)
969
+ $updateResult = Invoke-PrizmPythonJson $python (@((Join-Path $paths.ScriptsDir $updateScript), $listOption, $listPath, '--state-dir', $stateDir, '--action', 'update', $idOption, $CurrentItemId, '--session-id', $sessionId, '--session-status', $status) + $maxRetryArgs + $maxInfraRetryArgs + $statusContinuationArgs)
889
970
  if ($updateResult -and $updateResult.PSObject.Properties['new_status']) {
890
971
  $itemListStatus = [string]$updateResult.new_status
891
972
  }
@@ -894,6 +975,9 @@ function Invoke-PrizmPipeline {
894
975
  }
895
976
  }
896
977
 
978
+ break
979
+ }
980
+
897
981
  if ($status -eq 'success' -and $mergeSucceeded) {
898
982
  Write-PrizmSuccess "$Kind item completed: $CurrentItemId"
899
983
  } else {
@@ -951,7 +1035,7 @@ function Invoke-PrizmPipeline {
951
1035
  }
952
1036
 
953
1037
  $processedCount++
954
- Invoke-PrizmPipelineItem $nextItemId
1038
+ Invoke-PrizmPipelineItem $nextItemId $next
955
1039
  $lastExitCode = $script:PRIZM_ITEM_EXIT_CODE
956
1040
  if ($dryRun) {
957
1041
  $global:PRIZM_EXIT_CODE = $lastExitCode
@@ -14,6 +14,35 @@ function Get-PrizmFeatureSlug {
14
14
  return "$numeric-$slug"
15
15
  }
16
16
 
17
+ function Write-PrizmContinuationResetWarning {
18
+ param([string]$StatusPath, [string]$ItemId, [string]$Label)
19
+ if (-not (Test-Path $StatusPath)) { return }
20
+ try {
21
+ $status = Get-Content $StatusPath -Raw | ConvertFrom-Json
22
+ } catch {
23
+ return
24
+ }
25
+ if ($status.continuation_pending -eq $true) {
26
+ $reason = $status.continuation_reason
27
+ if (-not $reason) { $reason = 'context_overflow' }
28
+ Write-PrizmWarn "Continuation pending for $Label $ItemId ($reason). Manual reset will abandon automatic continuation progress."
29
+ if ($status.active_dev_branch) {
30
+ Write-PrizmWarn "Pending continuation branch: $($status.active_dev_branch)"
31
+ }
32
+ }
33
+ }
34
+
35
+ function Write-PrizmContinuationResetWarningsForState {
36
+ param([string]$StateDir, [string]$Label)
37
+ if (-not (Test-Path $StateDir)) { return }
38
+ Get-ChildItem -Path $StateDir -Directory -ErrorAction SilentlyContinue | ForEach-Object {
39
+ Write-PrizmContinuationResetWarning `
40
+ -StatusPath (Join-Path $_.FullName 'status.json') `
41
+ -ItemId $_.Name `
42
+ -Label $Label
43
+ }
44
+ }
45
+
17
46
  function Invoke-PrizmReset {
18
47
  param(
19
48
  [ValidateSet('feature','bugfix','refactor')][string]$Kind,
@@ -60,6 +89,7 @@ function Invoke-PrizmReset {
60
89
  }
61
90
 
62
91
  if (-not $itemId) {
92
+ Write-PrizmContinuationResetWarningsForState -StateDir $stateDir -Label $label
63
93
  & (Join-Path $paths.PipelineDir $runScript) reset
64
94
  $global:PRIZM_RESET_EXIT_CODE = $LASTEXITCODE
65
95
  return
@@ -67,6 +97,10 @@ function Invoke-PrizmReset {
67
97
 
68
98
  if (-not (Test-Path $listPath)) { throw "List file not found: $listPath" }
69
99
  New-Item -ItemType Directory -Force -Path $stateDir | Out-Null
100
+ Write-PrizmContinuationResetWarning `
101
+ -StatusPath (Join-Path (Join-Path $stateDir $itemId) 'status.json') `
102
+ -ItemId $itemId `
103
+ -Label $label
70
104
 
71
105
  $action = if ($clean) { 'clean' } else { 'reset' }
72
106
  $resetArgs = @((Join-Path $paths.ScriptsDir $updateScript), $listOption, $listPath, '--state-dir', $stateDir, '--action', $action, $idOption, $itemId)
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env pwsh
2
+ # Manual reset entrypoint; shared warning/reset behavior lives in lib/reset.ps1.
2
3
  . "$PSScriptRoot\lib\reset.ps1"
3
4
  try {
4
5
  Invoke-PrizmReset -Kind bugfix -ScriptRoot $PSScriptRoot -Args $args
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env pwsh
2
+ # Manual reset entrypoint; shared warning/reset behavior lives in lib/reset.ps1.
2
3
  . "$PSScriptRoot\lib\reset.ps1"
3
4
  try {
4
5
  Invoke-PrizmReset -Kind feature -ScriptRoot $PSScriptRoot -Args $args
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env pwsh
2
+ # Manual reset entrypoint; shared warning/reset behavior lives in lib/reset.ps1.
2
3
  . "$PSScriptRoot\lib\reset.ps1"
3
4
  try {
4
5
  Invoke-PrizmReset -Kind refactor -ScriptRoot $PSScriptRoot -Args $args
@@ -22,6 +22,77 @@ ID_FIELDS = ["feature_id", "bug_id", "refactor_id"]
22
22
 
23
23
  LOGGER = setup_logging("check-session-status")
24
24
 
25
+ CONTEXT_OVERFLOW_CODE = "context_overflow"
26
+ CONTEXT_CODE_VALUES = {
27
+ "context_overflow",
28
+ "context_too_large",
29
+ "context_length_exceeded",
30
+ "model_context_window_exceeded",
31
+ }
32
+ CONTEXT_TEXT_PATTERNS = (
33
+ "input exceeds the context window",
34
+ "context window of this model",
35
+ "context window exceeded",
36
+ "maximum context length exceeded",
37
+ "prompt is too long",
38
+ "too many tokens",
39
+ "input token count exceeds",
40
+ )
41
+ REQUEST_TOO_LARGE_TEXT = "request too large"
42
+ REQUEST_TOO_LARGE_SEMANTICS = ("context", "token", "tokens", "prompt", "input", "model")
43
+ ERROR_LIKE_STATUSES = {"failed", "crashed", "timed_out", "context_overflow"}
44
+
45
+
46
+ def _flatten_values(value):
47
+ if isinstance(value, dict):
48
+ values = []
49
+ for child in value.values():
50
+ values.extend(_flatten_values(child))
51
+ return values
52
+ if isinstance(value, list):
53
+ values = []
54
+ for child in value:
55
+ values.extend(_flatten_values(child))
56
+ return values
57
+ if value is None:
58
+ return []
59
+ return [str(value)]
60
+
61
+
62
+ def _is_error_like_status(data):
63
+ status = str(data.get("status", "")).lower()
64
+ if status in ERROR_LIKE_STATUSES:
65
+ return True
66
+ if data.get("last_result_is_error") is True or data.get("is_error") is True:
67
+ return True
68
+ if data.get("api_error_status") not in (None, ""):
69
+ return True
70
+ errors = data.get("errors")
71
+ return isinstance(errors, list) and len(errors) > 0
72
+
73
+
74
+ def has_context_overflow_signal(data):
75
+ """Return true when session-status data carries a context overflow signal.
76
+
77
+ Success remains success: direct status handling happens before this helper.
78
+ Exact machine codes are accepted only from structured code fields. Natural
79
+ language context/token phrases require a failed/error-like status or an
80
+ explicit error field to avoid prompt/documentation false positives.
81
+ """
82
+ if not isinstance(data, dict):
83
+ return False
84
+ for field in ("fatal_error_code", "api_error_code", "error_code", "stop_reason"):
85
+ value = data.get(field)
86
+ if isinstance(value, str) and value.lower() in CONTEXT_CODE_VALUES:
87
+ return True
88
+ if not _is_error_like_status(data):
89
+ return False
90
+ text = " ".join(_flatten_values(data)).lower()
91
+ if any(pattern in text for pattern in CONTEXT_TEXT_PATTERNS):
92
+ return True
93
+ return REQUEST_TOO_LARGE_TEXT in text and any(
94
+ semantic in text for semantic in REQUEST_TOO_LARGE_SEMANTICS
95
+ )
25
96
 
26
97
  def parse_args():
27
98
  parser = argparse.ArgumentParser(
@@ -79,12 +150,14 @@ def determine_status(data):
79
150
  """Determine the single-line status string from the parsed data.
80
151
 
81
152
  Returns one of: success, partial_resumable, partial_not_resumable,
82
- failed, commit_missing, docs_missing, merge_conflict.
153
+ failed, commit_missing, docs_missing, merge_conflict, context_overflow.
83
154
  """
84
155
  status = data.get("status", "")
85
156
 
86
157
  if status == "success":
87
158
  return "success"
159
+ if status == "context_overflow" or has_context_overflow_signal(data):
160
+ return "context_overflow"
88
161
  elif status == "partial":
89
162
  can_resume = data.get("can_resume", False)
90
163
  if can_resume: