issue-flow 0.16.0 → 0.18.0
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/dist/agent-HMZTXCRT.js +30 -0
- package/dist/{analyze-556KCJKZ.js → analyze-Q4ONIWRZ.js} +22 -22
- package/dist/{apply-WVV7G7WN.js → apply-EEFPY2W4.js} +14 -14
- package/dist/{bench-UBFGKUHR.js → bench-WWWXLTFH.js} +23 -23
- package/dist/{chunk-GV2DABNZ.js → chunk-34OCSKOB.js} +12 -12
- package/dist/chunk-3R27MJ5R.js +25 -0
- package/dist/chunk-3R27MJ5R.js.map +1 -0
- package/dist/{chunk-PGN2VX4Y.js → chunk-45WZ6GMI.js} +32 -48
- package/dist/chunk-45WZ6GMI.js.map +1 -0
- package/dist/{chunk-H3EYBJZU.js → chunk-62GVVZQO.js} +10 -10
- package/dist/{chunk-GPLP7EPL.js → chunk-6K2LCFG6.js} +10 -10
- package/dist/{chunk-GPLP7EPL.js.map → chunk-6K2LCFG6.js.map} +1 -1
- package/dist/{chunk-OGVWJO4S.js → chunk-7F7LGMVO.js} +3 -3
- package/dist/{chunk-X6GY3CM2.js → chunk-7UMMFOL2.js} +104 -104
- package/dist/chunk-7UMMFOL2.js.map +1 -0
- package/dist/{chunk-OLUOZLU5.js → chunk-CWSQVHVV.js} +1691 -1075
- package/dist/chunk-CWSQVHVV.js.map +1 -0
- package/dist/{chunk-MXCOSPLJ.js → chunk-DGRTJD5R.js} +3 -3
- package/dist/{chunk-ROIIEVZH.js → chunk-DUS5ZNKL.js} +474 -361
- package/dist/chunk-DUS5ZNKL.js.map +1 -0
- package/dist/{chunk-BSBJXPLC.js → chunk-E4I6MMHD.js} +10 -10
- package/dist/{chunk-QZOBR6YF.js → chunk-ECU7YO7S.js} +4 -4
- package/dist/chunk-ECU7YO7S.js.map +1 -0
- package/dist/{chunk-EPFC4LHT.js → chunk-EG2MGDP5.js} +9 -9
- package/dist/chunk-HOAHMERN.js +229 -0
- package/dist/chunk-HOAHMERN.js.map +1 -0
- package/dist/{chunk-QVLIIGBU.js → chunk-ICM463EO.js} +60 -13
- package/dist/chunk-ICM463EO.js.map +1 -0
- package/dist/{chunk-4FUWWBTP.js → chunk-KMCS76ZW.js} +8 -8
- package/dist/{chunk-SW2MF47D.js → chunk-KRAGAUKD.js} +19 -19
- package/dist/{chunk-OOX3RMD3.js → chunk-LGHND47K.js} +4 -4
- package/dist/{chunk-VTF4RWS5.js → chunk-LI35PIIS.js} +7 -7
- package/dist/{chunk-Q2TZA6AC.js → chunk-LTH6XYZ3.js} +14 -14
- package/dist/{chunk-YA6FWFYW.js → chunk-NEWNXZ65.js} +62 -11
- package/dist/chunk-NEWNXZ65.js.map +1 -0
- package/dist/{chunk-2H43OVTU.js → chunk-OODXFCQV.js} +11 -11
- package/dist/{chunk-KV2K7MK2.js → chunk-PMLE7KAQ.js} +20 -12
- package/dist/chunk-PMLE7KAQ.js.map +1 -0
- package/dist/{chunk-R42YHLDV.js → chunk-PPZ3K4YM.js} +2 -2
- package/dist/{chunk-J2LJB2OH.js → chunk-QF7VEL3M.js} +739 -579
- package/dist/chunk-QF7VEL3M.js.map +1 -0
- package/dist/{chunk-VK65RNFA.js → chunk-QJ44VG5G.js} +3 -3
- package/dist/{chunk-FKWYD44M.js → chunk-QPGEFLMY.js} +2 -2
- package/dist/{chunk-NQCR3HSU.js → chunk-RNFUVKC3.js} +3 -3
- package/dist/{chunk-G5LACAXO.js → chunk-RYOUZ6EK.js} +2 -2
- package/dist/{chunk-MCLPSL6B.js → chunk-SA6HXL4Y.js} +3 -3
- package/dist/{chunk-GVOZ6NDO.js → chunk-SOM4QA6C.js} +3 -3
- package/dist/{chunk-73TS2H42.js → chunk-TZYINKCC.js} +154 -34
- package/dist/chunk-TZYINKCC.js.map +1 -0
- package/dist/{chunk-DBEMD34J.js → chunk-V7QOIQYC.js} +8 -8
- package/dist/{chunk-IAMIBZRF.js → chunk-WCCZJL7W.js} +2 -2
- package/dist/{chunk-OGN2NX57.js → chunk-XUEMATVY.js} +9 -9
- package/dist/{chunk-SVDEWOUD.js → chunk-XZUEFTUP.js} +6 -6
- package/dist/{chunk-WLJVL25O.js → chunk-YUNBOUQH.js} +6 -6
- package/dist/{chunk-WNROH2YE.js → chunk-YVPZUN6X.js} +2 -2
- package/dist/chunk-ZVZMWNCG.js +415 -0
- package/dist/chunk-ZVZMWNCG.js.map +1 -0
- package/dist/cli.js +57 -49
- package/dist/cli.js.map +1 -1
- package/dist/{config-UE7IP36J.js → config-LEBZZCJP.js} +13 -13
- package/dist/{conventions-Z3QC2NSG.js → conventions-XOT6YW5L.js} +15 -15
- package/dist/{diagnostics-2Z5HFQOO.js → diagnostics-HTCWF7F4.js} +7 -7
- package/dist/execute-LELOSR5T.js +37 -0
- package/dist/{generate-PB4L7V5N.js → generate-JGW5JSKB.js} +22 -22
- package/dist/{git-7MUOGVRG.js → git-A2IP32PQ.js} +2 -2
- package/dist/init-TO6MUXO4.js +26 -0
- package/dist/{operations-QDJAFZUN.js → operations-O4FORFIH.js} +15 -15
- package/dist/{permissions-XVXXENVP.js → permissions-G4XCAESF.js} +4 -4
- package/dist/plan-OXAT344Q.js +34 -0
- package/dist/{policy-6WQZB6B2.js → policy-U5NBFAO5.js} +14 -14
- package/dist/pr-UZHNKKZC.js +39 -0
- package/dist/pr-review-Q4ACAWDM.js +32 -0
- package/dist/prd-6CYEMLDY.js +33 -0
- package/dist/{ps-CX7756QG.js → ps-76L6ZAZL.js} +12 -12
- package/dist/{recorder-RK6XZYF3.js → recorder-2BAKPBRA.js} +7 -7
- package/dist/{registry-POSB35Q4.js → registry-XLHHYLTR.js} +5 -5
- package/dist/{resume-OQJZV3JH.js → resume-URCU6CIJ.js} +39 -38
- package/dist/{resume-OQJZV3JH.js.map → resume-URCU6CIJ.js.map} +1 -1
- package/dist/review-LVZT2TMW.js +35 -0
- package/dist/routing-EK6RBZM4.js +33 -0
- package/dist/run-2RXJCJKT.js +56 -0
- package/dist/{session-publisher-VVXOCJ2S.js → session-publisher-KAJQRHNZ.js} +3 -2
- package/dist/{state-manager-TIC73GQY.js → state-manager-UPHO2EA2.js} +4 -4
- package/dist/state-manager-UPHO2EA2.js.map +1 -0
- package/dist/{usage-WDDNSIHP.js → usage-KTMYXAPF.js} +12 -12
- package/dist/{web-IPGY52AK.js → web-B5UPHHR5.js} +20 -18
- package/dist/{web-IPGY52AK.js.map → web-B5UPHHR5.js.map} +1 -1
- package/package.json +6 -5
- package/web/AGENTS.md +125 -18
- package/web/public/app.css +420 -234
- package/web/public/app.js +371 -80
- package/web/public/index.html +106 -78
- package/dist/agent-PMWCDWOW.js +0 -30
- package/dist/chunk-73TS2H42.js.map +0 -1
- package/dist/chunk-7Z4Y3VKM.js +0 -26
- package/dist/chunk-7Z4Y3VKM.js.map +0 -1
- package/dist/chunk-AOAQU7PD.js +0 -180
- package/dist/chunk-AOAQU7PD.js.map +0 -1
- package/dist/chunk-J2LJB2OH.js.map +0 -1
- package/dist/chunk-KV2K7MK2.js.map +0 -1
- package/dist/chunk-OLUOZLU5.js.map +0 -1
- package/dist/chunk-PGN2VX4Y.js.map +0 -1
- package/dist/chunk-QVLIIGBU.js.map +0 -1
- package/dist/chunk-QZOBR6YF.js.map +0 -1
- package/dist/chunk-ROIIEVZH.js.map +0 -1
- package/dist/chunk-X6GY3CM2.js.map +0 -1
- package/dist/chunk-YA6FWFYW.js.map +0 -1
- package/dist/execute-QYLJ5L4T.js +0 -36
- package/dist/init-XBERAZ4O.js +0 -24
- package/dist/plan-RXOW32KY.js +0 -34
- package/dist/pr-3WFYAVA7.js +0 -39
- package/dist/pr-review-RK63ZEMM.js +0 -32
- package/dist/prd-LRV6IW3E.js +0 -33
- package/dist/review-AEFISJZD.js +0 -35
- package/dist/routing-EA5NJGNU.js +0 -94
- package/dist/routing-EA5NJGNU.js.map +0 -1
- package/dist/run-HSC7R33Y.js +0 -55
- /package/dist/{agent-PMWCDWOW.js.map → agent-HMZTXCRT.js.map} +0 -0
- /package/dist/{analyze-556KCJKZ.js.map → analyze-Q4ONIWRZ.js.map} +0 -0
- /package/dist/{apply-WVV7G7WN.js.map → apply-EEFPY2W4.js.map} +0 -0
- /package/dist/{bench-UBFGKUHR.js.map → bench-WWWXLTFH.js.map} +0 -0
- /package/dist/{chunk-GV2DABNZ.js.map → chunk-34OCSKOB.js.map} +0 -0
- /package/dist/{chunk-H3EYBJZU.js.map → chunk-62GVVZQO.js.map} +0 -0
- /package/dist/{chunk-OGVWJO4S.js.map → chunk-7F7LGMVO.js.map} +0 -0
- /package/dist/{chunk-MXCOSPLJ.js.map → chunk-DGRTJD5R.js.map} +0 -0
- /package/dist/{chunk-BSBJXPLC.js.map → chunk-E4I6MMHD.js.map} +0 -0
- /package/dist/{chunk-EPFC4LHT.js.map → chunk-EG2MGDP5.js.map} +0 -0
- /package/dist/{chunk-4FUWWBTP.js.map → chunk-KMCS76ZW.js.map} +0 -0
- /package/dist/{chunk-SW2MF47D.js.map → chunk-KRAGAUKD.js.map} +0 -0
- /package/dist/{chunk-OOX3RMD3.js.map → chunk-LGHND47K.js.map} +0 -0
- /package/dist/{chunk-VTF4RWS5.js.map → chunk-LI35PIIS.js.map} +0 -0
- /package/dist/{chunk-Q2TZA6AC.js.map → chunk-LTH6XYZ3.js.map} +0 -0
- /package/dist/{chunk-2H43OVTU.js.map → chunk-OODXFCQV.js.map} +0 -0
- /package/dist/{chunk-R42YHLDV.js.map → chunk-PPZ3K4YM.js.map} +0 -0
- /package/dist/{chunk-VK65RNFA.js.map → chunk-QJ44VG5G.js.map} +0 -0
- /package/dist/{chunk-FKWYD44M.js.map → chunk-QPGEFLMY.js.map} +0 -0
- /package/dist/{chunk-NQCR3HSU.js.map → chunk-RNFUVKC3.js.map} +0 -0
- /package/dist/{chunk-G5LACAXO.js.map → chunk-RYOUZ6EK.js.map} +0 -0
- /package/dist/{chunk-MCLPSL6B.js.map → chunk-SA6HXL4Y.js.map} +0 -0
- /package/dist/{chunk-GVOZ6NDO.js.map → chunk-SOM4QA6C.js.map} +0 -0
- /package/dist/{chunk-DBEMD34J.js.map → chunk-V7QOIQYC.js.map} +0 -0
- /package/dist/{chunk-IAMIBZRF.js.map → chunk-WCCZJL7W.js.map} +0 -0
- /package/dist/{chunk-OGN2NX57.js.map → chunk-XUEMATVY.js.map} +0 -0
- /package/dist/{chunk-SVDEWOUD.js.map → chunk-XZUEFTUP.js.map} +0 -0
- /package/dist/{chunk-WLJVL25O.js.map → chunk-YUNBOUQH.js.map} +0 -0
- /package/dist/{chunk-WNROH2YE.js.map → chunk-YVPZUN6X.js.map} +0 -0
- /package/dist/{config-UE7IP36J.js.map → config-LEBZZCJP.js.map} +0 -0
- /package/dist/{conventions-Z3QC2NSG.js.map → conventions-XOT6YW5L.js.map} +0 -0
- /package/dist/{diagnostics-2Z5HFQOO.js.map → diagnostics-HTCWF7F4.js.map} +0 -0
- /package/dist/{execute-QYLJ5L4T.js.map → execute-LELOSR5T.js.map} +0 -0
- /package/dist/{generate-PB4L7V5N.js.map → generate-JGW5JSKB.js.map} +0 -0
- /package/dist/{git-7MUOGVRG.js.map → git-A2IP32PQ.js.map} +0 -0
- /package/dist/{init-XBERAZ4O.js.map → init-TO6MUXO4.js.map} +0 -0
- /package/dist/{operations-QDJAFZUN.js.map → operations-O4FORFIH.js.map} +0 -0
- /package/dist/{permissions-XVXXENVP.js.map → permissions-G4XCAESF.js.map} +0 -0
- /package/dist/{plan-RXOW32KY.js.map → plan-OXAT344Q.js.map} +0 -0
- /package/dist/{policy-6WQZB6B2.js.map → policy-U5NBFAO5.js.map} +0 -0
- /package/dist/{pr-3WFYAVA7.js.map → pr-UZHNKKZC.js.map} +0 -0
- /package/dist/{pr-review-RK63ZEMM.js.map → pr-review-Q4ACAWDM.js.map} +0 -0
- /package/dist/{prd-LRV6IW3E.js.map → prd-6CYEMLDY.js.map} +0 -0
- /package/dist/{ps-CX7756QG.js.map → ps-76L6ZAZL.js.map} +0 -0
- /package/dist/{recorder-RK6XZYF3.js.map → recorder-2BAKPBRA.js.map} +0 -0
- /package/dist/{registry-POSB35Q4.js.map → registry-XLHHYLTR.js.map} +0 -0
- /package/dist/{review-AEFISJZD.js.map → review-LVZT2TMW.js.map} +0 -0
- /package/dist/{run-HSC7R33Y.js.map → routing-EK6RBZM4.js.map} +0 -0
- /package/dist/{session-publisher-VVXOCJ2S.js.map → run-2RXJCJKT.js.map} +0 -0
- /package/dist/{state-manager-TIC73GQY.js.map → session-publisher-KAJQRHNZ.js.map} +0 -0
- /package/dist/{usage-WDDNSIHP.js.map → usage-KTMYXAPF.js.map} +0 -0
package/web/public/index.html
CHANGED
|
@@ -30,18 +30,18 @@
|
|
|
30
30
|
</head>
|
|
31
31
|
<body>
|
|
32
32
|
<div id="banner-disconnected" class="banner" role="alert" hidden>
|
|
33
|
-
Desconectado do servidor
|
|
33
|
+
Desconectado do servidor. Tentando reconectar…
|
|
34
34
|
</div>
|
|
35
35
|
|
|
36
36
|
<main>
|
|
37
37
|
<div id="view-dashboard" class="view" hidden>
|
|
38
38
|
<header class="card header">
|
|
39
39
|
<div class="header-main">
|
|
40
|
-
<h1>
|
|
41
|
-
|
|
40
|
+
<h1>Execuções ativas</h1>
|
|
41
|
+
<p class="header-meta">
|
|
42
|
+
<span id="dashboard-summary" class="muted"></span>
|
|
42
43
|
<span id="app-version-dashboard" class="app-version" hidden></span>
|
|
43
|
-
</
|
|
44
|
-
<p class="muted">Execuções ativas</p>
|
|
44
|
+
</p>
|
|
45
45
|
</div>
|
|
46
46
|
<div class="header-side">
|
|
47
47
|
<label class="refresh-control">
|
|
@@ -70,12 +70,16 @@
|
|
|
70
70
|
<button type="button" id="back-to-dashboard" class="back-link" hidden>
|
|
71
71
|
← Todas as execuções
|
|
72
72
|
</button>
|
|
73
|
+
<!-- A linha mais visível da tela é a execução, não a marca: o produto
|
|
74
|
+
identifica-se pelo <title> do documento. Ver web/AGENTS.md. -->
|
|
73
75
|
<h1>
|
|
74
|
-
<span class="brand">issue-flow</span>
|
|
75
|
-
<span id="app-version" class="app-version" hidden></span>
|
|
76
76
|
<a id="issue-link" class="issue-link" target="_blank" rel="noopener" hidden>#—</a>
|
|
77
|
+
<span id="issue-headline">Nenhuma execução ativa</span>
|
|
77
78
|
</h1>
|
|
78
|
-
<p
|
|
79
|
+
<p class="header-meta">
|
|
80
|
+
<span id="branch-line" class="muted mono"></span>
|
|
81
|
+
<span id="app-version" class="app-version" hidden></span>
|
|
82
|
+
</p>
|
|
79
83
|
</div>
|
|
80
84
|
<div class="header-side">
|
|
81
85
|
<span id="status-badge" class="badge status-idle">aguardando</span>
|
|
@@ -105,99 +109,124 @@
|
|
|
105
109
|
|
|
106
110
|
<div class="tabs" role="tablist" aria-label="Visualizações do painel">
|
|
107
111
|
<button type="button" class="tab" role="tab" id="tab-execution"
|
|
108
|
-
aria-controls="panel-execution" aria-selected="true">Execução</button>
|
|
112
|
+
aria-controls="panel-execution" aria-selected="true" tabindex="0">Execução</button>
|
|
109
113
|
<button type="button" class="tab" role="tab" id="tab-kanban"
|
|
110
|
-
aria-controls="panel-kanban" aria-selected="false">Kanban</button>
|
|
114
|
+
aria-controls="panel-kanban" aria-selected="false" tabindex="-1">Kanban</button>
|
|
111
115
|
<button type="button" class="tab" role="tab" id="tab-history"
|
|
112
|
-
aria-controls="panel-history" aria-selected="false">Histórico</button>
|
|
116
|
+
aria-controls="panel-history" aria-selected="false" tabindex="-1">Histórico</button>
|
|
113
117
|
</div>
|
|
114
118
|
|
|
119
|
+
<!-- Aba Execução em quatro blocos, na ordem em que a pergunta aparece:
|
|
120
|
+
o que está acontecendo agora, sobre o quê, quanto já andou e o que
|
|
121
|
+
saiu disso. Cada bloco é UM cartão; o que antes era um cartão por
|
|
122
|
+
assunto virou uma sub-seção com <h3> e sem borda própria. -->
|
|
115
123
|
<div class="tab-panel" id="panel-execution" role="tabpanel" aria-labelledby="tab-execution" tabindex="0">
|
|
116
|
-
<div class="columns">
|
|
117
|
-
<section class="card">
|
|
118
|
-
<h2>Resumo da issue</h2>
|
|
119
|
-
<div id="issue-summary"></div>
|
|
120
|
-
</section>
|
|
121
|
-
<section class="card">
|
|
122
|
-
<h2>Repositório</h2>
|
|
123
|
-
<div id="repository"></div>
|
|
124
|
-
</section>
|
|
125
|
-
</div>
|
|
126
124
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
125
|
+
<!-- Estado agora. Primeiro de propósito: é o único bloco que precisa ser
|
|
126
|
+
legível sem rolagem. Não acrescente conteúdo aqui sem checar isso. -->
|
|
127
|
+
<section class="card block block-now">
|
|
128
|
+
<h2>Estado agora</h2>
|
|
129
|
+
|
|
130
|
+
<div aria-live="polite">
|
|
131
|
+
<div class="progress-row">
|
|
132
|
+
<progress id="progress-bar" max="100" value="0"></progress>
|
|
133
|
+
<span id="progress-percent" class="progress-percent">0%</span>
|
|
134
|
+
</div>
|
|
135
|
+
<p id="progress-counters" class="muted"></p>
|
|
132
136
|
</div>
|
|
133
|
-
<p id="progress-counters" class="muted"></p>
|
|
134
|
-
</section>
|
|
135
137
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
138
|
+
<div class="columns">
|
|
139
|
+
<div class="block-part">
|
|
140
|
+
<h3>Executando agora</h3>
|
|
141
|
+
<div id="now" aria-live="polite"></div>
|
|
142
|
+
</div>
|
|
143
|
+
<div class="block-part">
|
|
144
|
+
<h3>Resiliência</h3>
|
|
145
|
+
<div id="resilience" aria-live="polite"></div>
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
140
148
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
149
|
+
<p class="next-steps-line">
|
|
150
|
+
<span class="next-steps-label">Próximos passos:</span>
|
|
151
|
+
<span id="next-steps"></span>
|
|
152
|
+
</p>
|
|
144
153
|
</section>
|
|
145
154
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
155
|
+
<!-- Contexto. Estável durante a execução, então densidade menor: é
|
|
156
|
+
referência para quando o estado acima não bastar. -->
|
|
157
|
+
<section class="card block block-context">
|
|
158
|
+
<h2>Contexto</h2>
|
|
159
|
+
|
|
160
|
+
<div class="columns">
|
|
161
|
+
<div class="block-part">
|
|
162
|
+
<h3>Issue</h3>
|
|
163
|
+
<div id="issue-summary"></div>
|
|
164
|
+
</div>
|
|
165
|
+
<div class="block-part">
|
|
166
|
+
<h3>Repositório</h3>
|
|
167
|
+
<div id="repository"></div>
|
|
168
|
+
</div>
|
|
169
|
+
</div>
|
|
170
|
+
|
|
171
|
+
<div class="block-part">
|
|
172
|
+
<h3>
|
|
173
|
+
Harnesses e configuração efetiva
|
|
174
|
+
<span class="muted block-hint">versões, preferências futuras e overrides desta execução</span>
|
|
175
|
+
</h3>
|
|
176
|
+
<div id="configuration"></div>
|
|
150
177
|
</div>
|
|
151
|
-
<div id="configuration"></div>
|
|
152
178
|
</section>
|
|
153
179
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
180
|
+
<!-- Andamento: o caminho já percorrido, fase a fase e story a story. -->
|
|
181
|
+
<section class="card block block-progress">
|
|
182
|
+
<h2>Andamento</h2>
|
|
183
|
+
|
|
184
|
+
<div class="block-part">
|
|
185
|
+
<h3>Fases</h3>
|
|
157
186
|
<ol id="phases" class="plain-list"></ol>
|
|
158
|
-
</
|
|
159
|
-
<section class="card">
|
|
160
|
-
<h2>Próximos passos</h2>
|
|
161
|
-
<div id="next-steps"></div>
|
|
162
|
-
</section>
|
|
163
|
-
</div>
|
|
187
|
+
</div>
|
|
164
188
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
189
|
+
<div class="block-part">
|
|
190
|
+
<h3>User stories</h3>
|
|
191
|
+
<ol id="stories" class="plain-list"></ol>
|
|
192
|
+
</div>
|
|
168
193
|
</section>
|
|
169
194
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
<ul id="commits" class="plain-list"></ul>
|
|
174
|
-
</section>
|
|
175
|
-
<section class="card">
|
|
176
|
-
<h2>Pull requests</h2>
|
|
177
|
-
<ul id="pull-requests" class="plain-list"></ul>
|
|
178
|
-
</section>
|
|
179
|
-
</div>
|
|
195
|
+
<!-- Saída: o que a execução produziu no repositório e no log. -->
|
|
196
|
+
<section class="card block block-output">
|
|
197
|
+
<h2>Saída</h2>
|
|
180
198
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
199
|
+
<div class="columns">
|
|
200
|
+
<div class="block-part">
|
|
201
|
+
<h3>Commits</h3>
|
|
202
|
+
<ul id="commits" class="plain-list"></ul>
|
|
203
|
+
</div>
|
|
204
|
+
<div class="block-part">
|
|
205
|
+
<h3>Pull requests</h3>
|
|
206
|
+
<ul id="pull-requests" class="plain-list"></ul>
|
|
207
|
+
</div>
|
|
208
|
+
</div>
|
|
209
|
+
|
|
210
|
+
<div class="block-part">
|
|
211
|
+
<div class="section-head">
|
|
212
|
+
<h3>Logs recentes</h3>
|
|
213
|
+
<label class="log-filter-control">
|
|
214
|
+
Nível
|
|
215
|
+
<select id="log-filter" aria-label="Filtro por nível de log">
|
|
216
|
+
<option value="all">todos</option>
|
|
217
|
+
<option value="info">info</option>
|
|
218
|
+
<option value="warn">avisos</option>
|
|
219
|
+
<option value="error">erros</option>
|
|
220
|
+
</select>
|
|
221
|
+
</label>
|
|
222
|
+
</div>
|
|
223
|
+
<ol id="logs" class="plain-list logs"></ol>
|
|
193
224
|
</div>
|
|
194
|
-
<ol id="logs" class="plain-list logs"></ol>
|
|
195
225
|
</section>
|
|
196
226
|
</div>
|
|
197
227
|
|
|
198
228
|
<div class="tab-panel" id="panel-kanban" role="tabpanel" aria-labelledby="tab-kanban" tabindex="0" hidden>
|
|
199
229
|
<section class="card">
|
|
200
|
-
<h2>Kanban de user stories</h2>
|
|
201
230
|
<div id="kanban" class="kanban"></div>
|
|
202
231
|
</section>
|
|
203
232
|
</div>
|
|
@@ -205,7 +234,6 @@
|
|
|
205
234
|
<div class="tab-panel" id="panel-history" role="tabpanel" aria-labelledby="tab-history" tabindex="0" hidden>
|
|
206
235
|
<section class="card">
|
|
207
236
|
<div class="section-head">
|
|
208
|
-
<h2>Histórico da execução</h2>
|
|
209
237
|
<label class="log-filter-control">
|
|
210
238
|
Evento
|
|
211
239
|
<select id="history-filter" aria-label="Filtro do histórico">
|
|
@@ -229,7 +257,7 @@
|
|
|
229
257
|
<aside id="drawer" class="drawer" role="dialog" aria-modal="true"
|
|
230
258
|
aria-labelledby="drawer-title" tabindex="-1" hidden>
|
|
231
259
|
<div class="drawer-head">
|
|
232
|
-
<h2 id="drawer-title"
|
|
260
|
+
<h2 id="drawer-title"></h2>
|
|
233
261
|
<button type="button" id="drawer-close" class="drawer-close" aria-label="Fechar detalhes">✕</button>
|
|
234
262
|
</div>
|
|
235
263
|
<div id="drawer-body" class="drawer-body"></div>
|
package/dist/agent-PMWCDWOW.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
AGENT_COMMAND_SCHEMA_VERSION,
|
|
4
|
-
persistFirstAgentChoice,
|
|
5
|
-
runAgent,
|
|
6
|
-
runAgentUse,
|
|
7
|
-
writeAgentPreference
|
|
8
|
-
} from "./chunk-PGN2VX4Y.js";
|
|
9
|
-
import "./chunk-J2LJB2OH.js";
|
|
10
|
-
import "./chunk-VTF4RWS5.js";
|
|
11
|
-
import "./chunk-SVDEWOUD.js";
|
|
12
|
-
import "./chunk-ROIIEVZH.js";
|
|
13
|
-
import "./chunk-FKWYD44M.js";
|
|
14
|
-
import "./chunk-HAKDLR6N.js";
|
|
15
|
-
import "./chunk-WNROH2YE.js";
|
|
16
|
-
import "./chunk-GPLP7EPL.js";
|
|
17
|
-
import "./chunk-P3LRUNC6.js";
|
|
18
|
-
import "./chunk-R42YHLDV.js";
|
|
19
|
-
import "./chunk-GVOZ6NDO.js";
|
|
20
|
-
import "./chunk-QVLIIGBU.js";
|
|
21
|
-
import "./chunk-7Z4Y3VKM.js";
|
|
22
|
-
import "./chunk-XEYH6ZZI.js";
|
|
23
|
-
export {
|
|
24
|
-
AGENT_COMMAND_SCHEMA_VERSION,
|
|
25
|
-
persistFirstAgentChoice,
|
|
26
|
-
runAgent,
|
|
27
|
-
runAgentUse,
|
|
28
|
-
writeAgentPreference
|
|
29
|
-
};
|
|
30
|
-
//# sourceMappingURL=agent-PMWCDWOW.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/routing/budget.ts","../src/agents/health.ts","../src/agents/select.ts","../src/agents/invoke.ts","../src/core/decompose.ts","../src/core/headless.ts"],"sourcesContent":["import type { CostRecord, StopReason } from '../telemetry/types.js';\n\nexport interface RoutingCeilings {\n maxCostUsdPerIssue: number | null;\n maxDurationMsPerIssue: number | null;\n maxExecutionsPerIssue: number | null;\n onCeiling: 'block';\n}\n\nexport const DEFAULT_CEILINGS: RoutingCeilings = {\n maxCostUsdPerIssue: null,\n maxDurationMsPerIssue: null,\n maxExecutionsPerIssue: null,\n onCeiling: 'block',\n};\n\nexport interface SpentSnapshot {\n /** Observed reported USD only. `unknown` / `estimated` do not fill this. */\n reportedUsd: number;\n costStatus: CostRecord['status'];\n durationMs: number;\n executions: number;\n}\n\nexport type CeilingBinding = 'cost' | 'duration' | 'executions';\n\nexport type CeilingVerdict =\n | { ok: true; binding: null }\n | {\n ok: false;\n stopReason: Extract<StopReason, 'max_cost' | 'max_duration' | 'max_attempts'>;\n binding: CeilingBinding;\n onCeiling: 'block';\n numbers: { spent: number; ceiling: number };\n /** Which ceiling is actually in force when cost is unknown. */\n enforced: CeilingBinding[];\n };\n\n/**\n * Single choke point. A harness flag is never a substitute: a runner that\n * ignores `--max-budget-usd` still stops here.\n */\nexport function evaluateCeilings(input: {\n ceilings?: Partial<RoutingCeilings> | undefined;\n spent: SpentSnapshot;\n}): CeilingVerdict {\n const ceilings = { ...DEFAULT_CEILINGS, ...input.ceilings };\n const enforced: CeilingBinding[] = [];\n if (ceilings.maxCostUsdPerIssue !== null && input.spent.costStatus === 'reported') {\n enforced.push('cost');\n }\n if (ceilings.maxDurationMsPerIssue !== null) enforced.push('duration');\n if (ceilings.maxExecutionsPerIssue !== null) enforced.push('executions');\n\n if (\n ceilings.maxCostUsdPerIssue !== null &&\n input.spent.costStatus === 'reported' &&\n input.spent.reportedUsd >= ceilings.maxCostUsdPerIssue\n ) {\n return {\n ok: false,\n stopReason: 'max_cost',\n binding: 'cost',\n onCeiling: 'block',\n numbers: { spent: input.spent.reportedUsd, ceiling: ceilings.maxCostUsdPerIssue },\n enforced,\n };\n }\n\n if (\n ceilings.maxDurationMsPerIssue !== null &&\n input.spent.durationMs >= ceilings.maxDurationMsPerIssue\n ) {\n return {\n ok: false,\n stopReason: 'max_duration',\n binding: 'duration',\n onCeiling: 'block',\n numbers: { spent: input.spent.durationMs, ceiling: ceilings.maxDurationMsPerIssue },\n enforced,\n };\n }\n\n if (\n ceilings.maxExecutionsPerIssue !== null &&\n input.spent.executions >= ceilings.maxExecutionsPerIssue\n ) {\n return {\n ok: false,\n stopReason: 'max_attempts',\n binding: 'executions',\n onCeiling: 'block',\n numbers: { spent: input.spent.executions, ceiling: ceilings.maxExecutionsPerIssue },\n enforced,\n };\n }\n\n return { ok: true, binding: null };\n}\n\nexport function spendFromCost(cost: CostRecord): Pick<SpentSnapshot, 'reportedUsd' | 'costStatus'> {\n if (cost.status === 'reported') {\n return { reportedUsd: cost.amount, costStatus: 'reported' };\n }\n return { reportedUsd: 0, costStatus: cost.status };\n}\n\n/** `blocked` is only left by a human — the machine never unblocks a ceiling. */\nexport function canLeaveBlocked(actor: string): boolean {\n return actor === 'human';\n}\n","import { mkdir, readFile, rename, writeFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport type { ClassifiedFailure, FailureKind } from '../resilience/errors.js';\nimport {\n type ProviderHealthRecord,\n type ProvidersHealth,\n providersHealthSchema,\n type ResilienceProvidersConfig,\n} from '../storage/schemas.js';\n\nexport const DEFAULT_PROVIDER_COOLDOWN_MS = 60_000;\nexport const DEFAULT_PROVIDER_MAX_COOLDOWN_MS = 30 * 60_000;\nexport const DEFAULT_PROVIDER_FAILURE_WINDOW_MS = 5 * 60_000;\nexport const DEFAULT_PROVIDER_FAILURES_TO_TRIP = 3;\n\nexport interface ProviderHealthOptions {\n now?: () => number;\n config?: ResilienceProvidersConfig;\n}\n\nexport interface ResolvedProviderHealthConfig {\n cooldownMs: number;\n maxCooldownMs: number;\n failureWindowMs: number;\n failuresToTrip: number;\n}\n\nexport function resolveProviderHealthConfig(\n config: ResilienceProvidersConfig = {},\n): ResolvedProviderHealthConfig {\n return {\n cooldownMs: Math.max(0, config.cooldownMs ?? DEFAULT_PROVIDER_COOLDOWN_MS),\n maxCooldownMs: Math.max(\n config.cooldownMs ?? DEFAULT_PROVIDER_COOLDOWN_MS,\n config.maxCooldownMs ?? DEFAULT_PROVIDER_MAX_COOLDOWN_MS,\n ),\n failureWindowMs: Math.max(1, config.failureWindowMs ?? DEFAULT_PROVIDER_FAILURE_WINDOW_MS),\n failuresToTrip: Math.max(\n 1,\n Math.trunc(config.failuresToTrip ?? DEFAULT_PROVIDER_FAILURES_TO_TRIP),\n ),\n };\n}\n\nfunction emptyHealth(): ProvidersHealth {\n return providersHealthSchema.parse({});\n}\n\nfunction emptyRecord(): ProviderHealthRecord {\n return providersHealthSchema.parse({ providers: { provider: {} } }).providers.provider;\n}\n\nexport async function readProvidersHealth(filePath: string): Promise<ProvidersHealth> {\n try {\n return providersHealthSchema.parse(JSON.parse(await readFile(filePath, 'utf-8')));\n } catch {\n return emptyHealth();\n }\n}\n\nasync function writeProvidersHealth(filePath: string, value: ProvidersHealth): Promise<void> {\n await mkdir(dirname(filePath), { recursive: true });\n const tmp = `${filePath}.tmp-${process.pid}`;\n await writeFile(tmp, `${JSON.stringify(value, null, 2)}\\n`, 'utf-8');\n await rename(tmp, filePath);\n}\n\nasync function updateRecord(\n filePath: string,\n provider: string,\n update: (record: ProviderHealthRecord) => ProviderHealthRecord,\n): Promise<ProviderHealthRecord> {\n const health = await readProvidersHealth(filePath);\n const next = update(health.providers[provider] ?? emptyRecord());\n await writeProvidersHealth(filePath, {\n ...health,\n providers: { ...health.providers, [provider]: next },\n });\n return next;\n}\n\nfunction cooldownDelay(level: number, config: ResolvedProviderHealthConfig): number {\n return Math.min(config.maxCooldownMs, config.cooldownMs * 2 ** Math.max(0, level));\n}\n\nconst BREAKER_KINDS = new Set<FailureKind>([\n 'timeout',\n 'stalled',\n 'provider_down',\n 'provider_crash',\n]);\n\nexport async function recordProviderFailure(\n filePath: string,\n provider: string,\n failure: ClassifiedFailure,\n options: ProviderHealthOptions = {},\n): Promise<ProviderHealthRecord> {\n const nowMs = options.now?.() ?? Date.now();\n const at = new Date(nowMs).toISOString();\n const config = resolveProviderHealthConfig(options.config);\n\n return updateRecord(filePath, provider, (record) => {\n const failures = [\n ...record.failures.filter((entry) => {\n const timestamp = Date.parse(entry.at);\n return Number.isFinite(timestamp) && nowMs - timestamp <= config.failureWindowMs;\n }),\n { at, kind: failure.kind },\n ];\n const consecutiveFailures = record.consecutiveFailures + 1;\n\n if (failure.kind === 'authentication') {\n return {\n ...record,\n status: 'auth_failed',\n failures,\n consecutiveFailures,\n cooldownUntil: null,\n lastFailureKind: failure.kind,\n lastFailureAt: at,\n probeInFlight: false,\n probeStartedAt: null,\n };\n }\n\n if (failure.kind === 'rate_limit') {\n const delay = failure.retryAfterMs ?? cooldownDelay(record.cooldownLevel, config);\n return {\n ...record,\n status: 'rate_limited',\n failures,\n consecutiveFailures,\n cooldownLevel:\n failure.retryAfterMs === undefined ? record.cooldownLevel + 1 : record.cooldownLevel,\n cooldownUntil: new Date(nowMs + delay).toISOString(),\n lastFailureKind: failure.kind,\n lastFailureAt: at,\n probeInFlight: false,\n probeStartedAt: null,\n };\n }\n\n if (BREAKER_KINDS.has(failure.kind)) {\n const recentProviderFailures = failures.filter((entry) =>\n BREAKER_KINDS.has(entry.kind),\n ).length;\n const unavailable =\n record.status === 'half_open' || recentProviderFailures >= config.failuresToTrip;\n const delay = unavailable ? cooldownDelay(record.cooldownLevel, config) : 0;\n return {\n ...record,\n status: unavailable ? 'unavailable' : 'degraded',\n failures,\n consecutiveFailures,\n cooldownLevel: unavailable ? record.cooldownLevel + 1 : record.cooldownLevel,\n cooldownUntil: unavailable ? new Date(nowMs + delay).toISOString() : null,\n lastFailureKind: failure.kind,\n lastFailureAt: at,\n probeInFlight: false,\n probeStartedAt: null,\n };\n }\n\n // Network and task/repository/configuration failures do not describe the\n // provider's health. Keep the breaker state, but retain the diagnosis for\n // audit and dashboard surfaces.\n return {\n ...record,\n lastFailureKind: failure.kind,\n lastFailureAt: at,\n probeInFlight: false,\n probeStartedAt: null,\n };\n });\n}\n\nexport async function recordProviderSuccess(\n filePath: string,\n provider: string,\n options: Pick<ProviderHealthOptions, 'now'> = {},\n): Promise<ProviderHealthRecord> {\n const at = new Date(options.now?.() ?? Date.now()).toISOString();\n return updateRecord(filePath, provider, (record) => ({\n ...record,\n status: 'healthy',\n failures: [],\n consecutiveFailures: 0,\n cooldownLevel: 0,\n cooldownUntil: null,\n lastFailureKind: null,\n lastSuccessAt: at,\n probeInFlight: false,\n probeStartedAt: null,\n }));\n}\n\n/** Open the circuit when retry policy asks for failover before the trip count. */\nexport async function openProviderCircuit(\n filePath: string,\n provider: string,\n options: ProviderHealthOptions = {},\n): Promise<ProviderHealthRecord> {\n const nowMs = options.now?.() ?? Date.now();\n const config = resolveProviderHealthConfig(options.config);\n return updateRecord(filePath, provider, (record) => {\n if (record.status === 'unavailable' || record.status === 'rate_limited') return record;\n const delay = cooldownDelay(record.cooldownLevel, config);\n return {\n ...record,\n status: 'unavailable',\n cooldownLevel: record.cooldownLevel + 1,\n cooldownUntil: new Date(nowMs + delay).toISOString(),\n probeInFlight: false,\n probeStartedAt: null,\n };\n });\n}\n\nexport interface HalfOpenResult {\n acquired: boolean;\n record: ProviderHealthRecord;\n}\n\n/** Atomically enough for the project-level single-run lock: one half-open probe per provider. */\nexport async function acquireHalfOpenProbe(\n filePath: string,\n provider: string,\n options: ProviderHealthOptions = {},\n): Promise<HalfOpenResult> {\n const nowMs = options.now?.() ?? Date.now();\n const at = new Date(nowMs).toISOString();\n const config = resolveProviderHealthConfig(options.config);\n let acquired = false;\n const record = await updateRecord(filePath, provider, (current) => {\n const cooldownUntil = current.cooldownUntil === null ? 0 : Date.parse(current.cooldownUntil);\n if (Number.isFinite(cooldownUntil) && cooldownUntil > nowMs) return current;\n\n const probeStarted = current.probeStartedAt === null ? 0 : Date.parse(current.probeStartedAt);\n const probeIsFresh =\n current.probeInFlight &&\n Number.isFinite(probeStarted) &&\n nowMs - probeStarted < config.cooldownMs;\n if (probeIsFresh) return current;\n\n acquired = true;\n return {\n ...current,\n status: 'half_open',\n cooldownUntil: null,\n probeInFlight: true,\n probeStartedAt: at,\n };\n });\n return { acquired, record };\n}\n","import { getActiveResilienceConfig } from '../config.js';\nimport { getShutdownSignal } from '../core/shutdown.js';\nimport type { FailureKind } from '../resilience/errors.js';\nimport { abortableDelay, resolvePolicy, shouldFailover } from '../resilience/policy.js';\nimport { resolveProjectPaths } from '../storage/resolve.js';\nimport type { ProviderHealthRecord, ResilienceConfig } from '../storage/schemas.js';\nimport {\n acquireHalfOpenProbe,\n openProviderCircuit,\n readProvidersHealth,\n resolveProviderHealthConfig,\n} from './health.js';\nimport { ensureRunnersRegistered, getRegisteredProviders } from './registry.js';\nimport { resolveAgentFor } from './resolve.js';\nimport {\n type AgentPhase,\n type AgentProviderId,\n isAgentProviderId,\n type ResolvedAgentSettings,\n} from './types.js';\n\nexport interface AgentSelection {\n primary: AgentProviderId;\n provider: AgentProviderId;\n settings: ResolvedAgentSettings;\n healthFile: string | null;\n failover: boolean;\n reason: FailureKind | null;\n cooldownUntil: string | null;\n}\n\nexport class AgentSelectionBlockedError extends Error {\n readonly provider: AgentProviderId;\n readonly kind: FailureKind;\n\n constructor(provider: AgentProviderId, kind: FailureKind) {\n super(\n `Authentication failed for agent provider '${provider}' (${kind}); the run is blocked. Authenticate or repair that provider before resuming.`,\n );\n this.name = 'AgentSelectionBlockedError';\n this.provider = provider;\n this.kind = kind;\n }\n}\n\ninterface CandidateVerdict {\n available: boolean;\n waitMs: number | null;\n cooldownUntil: string | null;\n reason: FailureKind | null;\n blocked: boolean;\n}\n\nfunction remainingMs(until: string | null, nowMs: number): number | null {\n if (until === null) return null;\n const parsed = Date.parse(until);\n return Number.isFinite(parsed) ? Math.max(0, parsed - nowMs) : null;\n}\n\nfunction failoverIsDue(\n record: ProviderHealthRecord | undefined,\n config: ResilienceConfig,\n): boolean {\n if (record?.lastFailureKind == null) return false;\n return shouldFailover(resolvePolicy(record.lastFailureKind, config), record.consecutiveFailures);\n}\n\nasync function verdictFor(\n provider: AgentProviderId,\n record: ProviderHealthRecord | undefined,\n options: {\n healthFile: string;\n config: ResilienceConfig;\n primary: boolean;\n nowMs: number;\n },\n): Promise<CandidateVerdict> {\n if (record === undefined || record.status === 'healthy') {\n return { available: true, waitMs: null, cooldownUntil: null, reason: null, blocked: false };\n }\n\n const reason = record.lastFailureKind;\n if (record.status === 'auth_failed') {\n const mayFailover = reason !== null && failoverIsDue(record, options.config);\n return {\n available: false,\n waitMs: null,\n cooldownUntil: null,\n reason,\n blocked: options.primary && !mayFailover,\n };\n }\n\n if (record.status === 'degraded') {\n const due = failoverIsDue(record, options.config);\n const opened = due\n ? await openProviderCircuit(options.healthFile, provider, {\n now: () => options.nowMs,\n config: options.config.providers,\n })\n : record;\n return {\n available: !due,\n waitMs: due ? remainingMs(opened.cooldownUntil, options.nowMs) : null,\n cooldownUntil: opened.cooldownUntil,\n reason,\n blocked: false,\n };\n }\n\n // `half_open` joins the two closed states on purpose: `acquireHalfOpenProbe`\n // is the only place that knows a probe went stale, and a record left\n // `probeInFlight` by a SIGKILLed run is otherwise never reclaimed — the next\n // run just waits on a cooldown that never ends.\n if (\n record.status === 'unavailable' ||\n record.status === 'rate_limited' ||\n record.status === 'half_open'\n ) {\n const waitMs = remainingMs(record.cooldownUntil, options.nowMs);\n if (waitMs !== null && waitMs > 0) {\n return {\n available: false,\n waitMs,\n cooldownUntil: record.cooldownUntil,\n reason,\n blocked: false,\n };\n }\n const probe = await acquireHalfOpenProbe(options.healthFile, provider, {\n now: () => options.nowMs,\n config: options.config.providers,\n });\n return {\n available: probe.acquired,\n waitMs: probe.acquired\n ? null\n : resolveProviderHealthConfig(options.config.providers).cooldownMs,\n cooldownUntil: probe.record.cooldownUntil,\n reason,\n blocked: false,\n };\n }\n\n return { available: true, waitMs: null, cooldownUntil: null, reason, blocked: false };\n}\n\nfunction providerOrder(primary: AgentProviderId, config: ResilienceConfig): AgentProviderId[] {\n ensureRunnersRegistered();\n const registered = getRegisteredProviders();\n const configured = (config.providers?.chain ?? []).filter(isAgentProviderId);\n return [...new Set([primary, ...configured, ...registered])];\n}\n\nfunction settingsFor(\n base: ResolvedAgentSettings,\n provider: AgentProviderId,\n): ResolvedAgentSettings {\n if (provider === base.provider) return base;\n return {\n ...base,\n provider,\n // A model name belongs to the configured primary unless the selected\n // provider is that primary. Passing a Claude alias to Codex (or vice\n // versa) is less useful than letting the fallback use its own default.\n model: null,\n };\n}\n\n/**\n * Select one provider. When every provider is cooling down, wait for the\n * earliest circuit instead of turning a temporary absence into a failed run.\n */\nexport async function selectAgentForInvocation(\n phase: AgentPhase,\n options: {\n config?: ResilienceConfig;\n now?: () => number;\n delay?: (ms: number, options: { signal?: AbortSignal }) => Promise<boolean>;\n } = {},\n): Promise<AgentSelection> {\n const config = options.config ?? getActiveResilienceConfig();\n const base = await resolveAgentFor(phase);\n const failover = config.providers?.failover === true;\n if (!failover) {\n return {\n primary: base.provider,\n provider: base.provider,\n settings: base,\n healthFile: null,\n failover: false,\n reason: null,\n cooldownUntil: null,\n };\n }\n\n let healthFile: string;\n try {\n healthFile = (await resolveProjectPaths()).providersHealthFile;\n } catch {\n return {\n primary: base.provider,\n provider: base.provider,\n settings: base,\n healthFile: null,\n failover: true,\n reason: null,\n cooldownUntil: null,\n };\n }\n\n const delay = options.delay ?? abortableDelay;\n selection: for (;;) {\n const nowMs = options.now?.() ?? Date.now();\n const health = await readProvidersHealth(healthFile);\n const waits: number[] = [];\n let primaryReason: FailureKind | null = null;\n let primaryCooldown: string | null = null;\n\n for (const provider of providerOrder(base.provider, config)) {\n const verdict = await verdictFor(provider, health.providers[provider], {\n healthFile,\n config,\n primary: provider === base.provider,\n nowMs,\n });\n if (provider === base.provider) {\n primaryReason = verdict.reason;\n primaryCooldown = verdict.cooldownUntil;\n }\n if (verdict.blocked && verdict.reason !== null) {\n throw new AgentSelectionBlockedError(provider, verdict.reason);\n }\n if (\n provider === base.provider &&\n !verdict.available &&\n verdict.waitMs !== null &&\n !failoverIsDue(health.providers[provider], config)\n ) {\n if (!(await delay(Math.max(1, verdict.waitMs), { signal: getShutdownSignal() }))) {\n throw new Error('Agent provider selection was interrupted while waiting for cooldown.');\n }\n continue selection;\n }\n if (verdict.available) {\n return {\n primary: base.provider,\n provider,\n settings: settingsFor(base, provider),\n healthFile,\n failover: provider !== base.provider,\n reason: provider === base.provider ? null : primaryReason,\n cooldownUntil: primaryCooldown,\n };\n }\n if (verdict.waitMs !== null) waits.push(verdict.waitMs);\n }\n\n const waitMs = waits.length > 0 ? Math.max(1, Math.min(...waits)) : null;\n if (waitMs === null) {\n throw new Error(\n 'No healthy agent provider is available and none has a cooldown to wait for.',\n );\n }\n if (!(await delay(waitMs, { signal: getShutdownSignal() }))) {\n throw new Error('Agent provider selection was interrupted while waiting for cooldown.');\n }\n }\n}\n","import {\n getActiveResilienceConfig,\n getAgentCliOverrides,\n loadAgentConfig,\n loadRoutingConfig,\n} from '../config.js';\nimport { getSessionPublisher } from '../core/session-publisher.js';\nimport { isoNow } from '../core/state-manager.js';\nimport { type ClassifiedFailure, classify, type FailureKind } from '../resilience/errors.js';\nimport { evaluateCeilings } from '../routing/budget.js';\nimport { decideRouting } from '../routing/decide.js';\nimport { bindDiagnosticContext, writeDiagnostic } from '../storage/diagnostics.js';\nimport type { ProviderHealthRecord } from '../storage/schemas.js';\nimport { beginExecution, endExecution } from '../telemetry/recorder.js';\nimport { redactSecrets } from '../telemetry/redact.js';\nimport type { ExecutionPurpose, ExecutionRecord, ExecutionTrigger } from '../telemetry/types.js';\nimport { resolveAntigravityTimeoutMs } from './antigravity.js';\nimport { peekHarnessVersion } from './claude.js';\nimport { recordProviderFailure, recordProviderSuccess } from './health.js';\nimport { ensureCursorStorageGrant } from './permissions.js';\nimport { runnerFor } from './registry.js';\nimport { hasExplicitAgentSelection, resolveAgentFor } from './resolve.js';\nimport { type AgentSelection, selectAgentForInvocation } from './select.js';\nimport type { AgentInvocation, AgentProviderId, AgentRunResult } from './types.js';\n\nasync function selectionForForced(invocation: AgentInvocation): Promise<AgentSelection> {\n const settings = await resolveAgentFor(invocation.phase, {\n cli: { forceProvider: invocation.forceProvider },\n });\n return {\n primary: settings.provider,\n provider: settings.provider,\n settings,\n healthFile: null,\n failover: false,\n reason: null,\n cooldownUntil: null,\n };\n}\n\nconst attempts = new Map<string, number>();\nconst lastFailure = new Map<string, FailureKind>();\nconst issueSpend = {\n reportedUsd: 0,\n durationMs: 0,\n executions: 0,\n sawReported: false,\n};\n\n/** Declared identity of a runner — never inferred from argv or logs. */\nexport function declaredAgentIdentity(provider: AgentProviderId): {\n harness: string;\n vendor: string;\n} {\n switch (provider) {\n case 'claude':\n return { harness: 'claude-code', vendor: 'anthropic' };\n case 'codex':\n return { harness: 'codex-cli', vendor: 'openai' };\n case 'cursor':\n return { harness: 'cursor-cli', vendor: 'cursor' };\n case 'antigravity':\n return { harness: 'antigravity-cli', vendor: 'google' };\n default: {\n const _exhaustive: never = provider;\n return _exhaustive;\n }\n }\n}\n\nfunction triggerOf(\n selection: AgentSelection,\n attempt: number,\n correctionCycle = 0,\n): ExecutionTrigger {\n if (selection.failover) return 'fallback';\n if (attempt > 1) return 'retry';\n if (correctionCycle > 0) return 'correction';\n return 'initial';\n}\n\nexport interface SelectedAgentRun {\n run: AgentRunResult;\n failure: ClassifiedFailure | null;\n selection: AgentSelection;\n attempt: number;\n health: ProviderHealthRecord | null;\n blocked?: { stopReason: string; detail: string; actor: 'human' };\n}\n\nfunction nextAttempt(phase: string): number {\n const attempt = (attempts.get(phase) ?? 0) + 1;\n attempts.set(phase, attempt);\n return attempt;\n}\n\nexport function resetAgentInvocationState(): void {\n attempts.clear();\n lastFailure.clear();\n issueSpend.reportedUsd = 0;\n issueSpend.durationMs = 0;\n issueSpend.executions = 0;\n issueSpend.sawReported = false;\n}\n\n/** One invocation, including provider selection, health persistence and audit events. */\nexport async function invokeSelectedAgent(invocation: AgentInvocation): Promise<SelectedAgentRun> {\n const config = getActiveResilienceConfig();\n const selection =\n invocation.forceProvider === undefined\n ? await selectAgentForInvocation(invocation.phase, { config })\n : await selectionForForced(invocation);\n const attempt = nextAttempt(invocation.phase);\n const publisher = getSessionPublisher();\n publisher.publish({\n type: 'agent:attempt',\n at: isoNow(),\n attempt,\n provider: selection.provider,\n model: selection.settings.model,\n primaryProvider: selection.primary,\n });\n if (selection.failover) {\n publisher.publish({\n type: 'failover',\n at: isoNow(),\n from: selection.primary,\n to: selection.provider,\n reason: selection.reason,\n cooldownUntil: selection.cooldownUntil,\n });\n writeDiagnostic({\n level: 'warning',\n message: `Agent failover from ${selection.primary} to ${selection.provider}`,\n context: { reason: selection.reason, cooldownUntil: selection.cooldownUntil },\n fields: {\n phase: invocation.phase,\n harness: selection.provider,\n model: selection.settings.model,\n },\n });\n }\n\n const identity = declaredAgentIdentity(selection.provider);\n const requested = selection.settings.model;\n const routingCfg = await loadRoutingConfig();\n const agentCfg = await loadAgentConfig();\n const routingDecision = decideRouting({\n phase: invocation.phase,\n actualHarness: identity.harness,\n mode: routingCfg.mode,\n profile: routingCfg.profile,\n skipScore: hasExplicitAgentSelection(agentCfg, getAgentCliOverrides()),\n requiresExtraDirectories: (invocation.addDirs?.length ?? 0) > 0,\n });\n const executionId = await beginExecution({\n purpose: (invocation.purpose ?? invocation.phase) as ExecutionPurpose,\n attempt,\n trigger: triggerOf(selection, attempt, invocation.correctionCycle),\n triggerReason: selection.failover\n ? selection.reason\n : attempt > 1\n ? (lastFailure.get(invocation.phase) ?? null)\n : null,\n harness: identity.harness,\n provider: identity.vendor,\n harnessVersion: peekHarnessVersion(selection.provider) ?? null,\n modelRequested: requested,\n modelResolved: null,\n modelSource: requested ? 'config' : 'unavailable',\n ...(invocation.iteration === undefined ? {} : { iteration: invocation.iteration }),\n ...(invocation.correctionCycle === undefined\n ? {}\n : { correctionCycle: invocation.correctionCycle }),\n ...(invocation.storyIds === undefined ? {} : { storyIds: invocation.storyIds }),\n ...(routingDecision === null\n ? {}\n : { routingDecision: routingDecision as unknown as ExecutionRecord['routingDecision'] }),\n });\n bindDiagnosticContext({\n executionId,\n phase: invocation.phase,\n harness: identity.harness,\n model: requested,\n story: invocation.storyIds?.join(',') ?? null,\n });\n\n const runner = runnerFor(selection.provider);\n const ceiling = evaluateCeilings({\n ceilings: routingCfg.ceilings,\n spent: {\n reportedUsd: issueSpend.reportedUsd,\n costStatus: issueSpend.sawReported ? 'reported' : 'unknown',\n durationMs: issueSpend.durationMs,\n executions: issueSpend.executions,\n },\n });\n if (!ceiling.ok) {\n const detail = `blocked by ${ceiling.binding} ceiling (${ceiling.numbers.spent} ≥ ${ceiling.numbers.ceiling}). Enforced by Issue Flow, not by a harness flag.`;\n const run = {\n success: false,\n result: '',\n rawOutput: detail,\n exitCode: 1,\n usage: null,\n error: detail,\n agent: { provider: selection.provider, model: selection.settings.model },\n harnessVersion: peekHarnessVersion(selection.provider),\n };\n if (executionId !== null) {\n await endExecution({\n id: executionId,\n status: 'failed',\n error: detail,\n exitCode: 1,\n stopReason: ceiling.stopReason,\n });\n }\n return {\n run,\n failure: null,\n selection,\n attempt,\n health: null,\n blocked: { stopReason: ceiling.stopReason, detail, actor: 'human' },\n };\n }\n if (\n runner.capabilities.nativeTimeout &&\n invocation.timeout === 0 &&\n resolveAntigravityTimeoutMs(invocation, selection.settings) === null\n ) {\n const run = {\n success: false,\n result: '',\n rawOutput:\n 'configuration: provider has nativeTimeout and received timeout: 0 without a ceiling.',\n exitCode: 1,\n usage: null,\n error:\n 'configuration: provider has nativeTimeout and received timeout: 0 without a ceiling. Set agent.antigravity.executeTimeout.',\n agent: { provider: selection.provider, model: selection.settings.model },\n harnessVersion: peekHarnessVersion(selection.provider),\n };\n if (executionId !== null) {\n await endExecution({\n id: executionId,\n status: 'failed',\n error: run.error,\n exitCode: 1,\n });\n }\n const failure = classify({ source: 'agent', exitCode: 1, stdout: run.error });\n return { run, failure, selection, attempt, health: null };\n }\n if (\n (invocation.addDirs?.length ?? 0) > 0 &&\n runner.capabilities.extraDirectories === 'permission-file'\n ) {\n const grant =\n selection.settings.cursor.permissionsFile === 'none'\n ? { skipped: true as const, reason: 'none' as const }\n : await ensureCursorStorageGrant({\n mode: selection.settings.cursor.permissionsFile ?? 'global',\n });\n if ('skipped' in grant && selection.settings.cursor.permissionsFile !== 'none') {\n throw new Error(\n `Phase '${invocation.phase}' needs extraDirectories on '${selection.provider}', which only grants them via a permission file. Run \\`issue-flow agent use cursor\\` or set agent.cursor.permissionsFile.`,\n );\n }\n } else if (\n (invocation.addDirs?.length ?? 0) > 0 &&\n runner.capabilities.extraDirectories === 'none'\n ) {\n throw new Error(\n `Phase '${invocation.phase}' needs extraDirectories, but '${selection.provider}' cannot grant them.`,\n );\n }\n\n let run: AgentRunResult;\n const startedMs = Date.now();\n try {\n run = await runner.run(\n {\n ...invocation,\n onLine: (line) => {\n const sanitized = redactSecrets(line).slice(0, 4_000);\n publisher.publish({\n type: 'agent:activity',\n at: isoNow(),\n provider: selection.provider,\n });\n if (sanitized.trim() !== '') {\n publisher.publish({\n type: 'process:output',\n at: isoNow(),\n phase: invocation.phase,\n executionId,\n provider: selection.provider,\n stream: 'combined',\n message: sanitized,\n });\n writeDiagnostic({\n level: 'debug',\n message: sanitized,\n fields: {\n executionId,\n phase: invocation.phase,\n harness: identity.harness,\n model: selection.settings.model,\n },\n });\n }\n invocation.onLine?.(line);\n },\n },\n selection.settings,\n );\n } catch (err) {\n writeDiagnostic({\n level: 'error',\n message: `Agent invocation threw before producing a result: ${\n err instanceof Error ? err.message : String(err)\n }`,\n exception: err,\n fields: {\n executionId,\n phase: invocation.phase,\n harness: identity.harness,\n model: selection.settings.model,\n },\n });\n if (executionId !== null) {\n await endExecution({\n id: executionId,\n status: 'failed',\n error: err instanceof Error ? err.message : String(err),\n });\n }\n throw err;\n }\n issueSpend.executions += 1;\n issueSpend.durationMs += Math.max(0, Date.now() - startedMs);\n if (run.usage?.costUsd !== undefined) {\n issueSpend.reportedUsd += run.usage.costUsd;\n issueSpend.sawReported = true;\n }\n\n const failure =\n run.success && run.exitCode === 0\n ? null\n : classify({\n source: 'agent',\n exitCode: run.exitCode,\n stdout: run.rawOutput || run.error || '',\n });\n writeDiagnostic({\n level: failure === null ? 'info' : 'error',\n message:\n failure === null\n ? `Agent invocation completed with ${selection.provider}`\n : `Agent invocation failed with ${selection.provider}: ${failure.message}`,\n context: {\n attempt,\n exitCode: run.exitCode,\n failureKind: failure?.kind ?? null,\n trigger: triggerOf(selection, attempt, invocation.correctionCycle),\n },\n fields: {\n executionId,\n phase: invocation.phase,\n harness: identity.harness,\n model: run.agent.model,\n },\n });\n\n if (executionId !== null) {\n await endExecution({\n id: executionId,\n status: failure === null ? 'completed' : failure.kind === 'timeout' ? 'timeout' : 'failed',\n usage: run.usage,\n error: failure === null ? null : (run.error ?? run.rawOutput),\n exitCode: run.exitCode,\n modelResolved: run.agent.model,\n modelSource: run.agent.model\n ? requested\n ? 'config'\n : 'provider'\n : requested\n ? 'config'\n : 'unavailable',\n harnessVersion: run.harnessVersion ?? peekHarnessVersion(selection.provider) ?? null,\n providerSessionId: run.sessionId ?? null,\n storyIds: invocation.storyIds,\n });\n }\n\n if (failure === null) lastFailure.delete(invocation.phase);\n else lastFailure.set(invocation.phase, failure.kind);\n\n let health: ProviderHealthRecord | null = null;\n if (selection.healthFile !== null) {\n health =\n failure === null\n ? await recordProviderSuccess(selection.healthFile, selection.provider)\n : await recordProviderFailure(selection.healthFile, selection.provider, failure, {\n config: config.providers,\n });\n }\n\n publisher.publish({\n type: 'agent:result',\n at: isoNow(),\n provider: selection.provider,\n success: failure === null,\n ...(failure === null ? {} : { failureKind: failure.kind }),\n cooldownUntil: health?.cooldownUntil ?? null,\n });\n\n if (failure === null) attempts.delete(invocation.phase);\n return { run, failure, selection, attempt, health };\n}\n","import type { TaskPlan, UserStory } from '../types.js';\nimport { parseJournal } from './journal.js';\n\n/**\n * \"This issue is too large\" — detected, reported, and left to a person.\n *\n * A phase that keeps timing out, a plan with thirty stories, five iterations in\n * a row that finish nothing: each of those is ambiguous on its own, and any one\n * of them can also be a slow afternoon. Together they are the same thing said\n * three ways, and what they are saying is that the demand was never one issue.\n *\n * The tool's job here stops at saying so. **Splitting an issue is a product\n * decision**, and the default is a report plus `blocked`, not an act — which is\n * also why a failure that is merely *infrastructural* must never reach this\n * code path: an issue whose run died because the network went down is not too\n * large, and breaking it up would be the worst possible response.\n */\n\n/** The thresholds, in one place, because every one of them is a judgement. */\nexport const DECOMPOSITION_THRESHOLDS = {\n /** Timeouts on the same phase. Two is already a pattern, not bad luck. */\n timeoutsPerPhase: 2,\n /** Stories in the plan. Past this, the plan is a backlog. */\n stories: 15,\n /** Iterations in a row that completed no story. */\n barrenIterations: 5,\n /** Files touched on the branch. */\n filesTouched: 40,\n /** Characters in the issue body. */\n issueBodyChars: 20_000,\n} as const;\n\n/** How many signals have to agree before the report is written. */\nexport const DECOMPOSITION_MIN_SIGNALS = 2;\n\nexport interface DecompositionInput {\n /** Contents of `events.jsonl` (both generations), oldest first. */\n journal?: string;\n plan?: TaskPlan | null;\n /** Body of the issue as the provider resolved it. */\n issueBody?: string;\n /** Files changed on the branch, from `git diff --name-only`. */\n filesTouched?: number;\n /** Whether the execute loop stopped because it ran out of iterations. */\n hitMaxIterations?: boolean;\n}\n\nexport interface DecompositionSignal {\n id: string;\n /** One line a person can act on, naming the number that crossed the line. */\n detail: string;\n}\n\nexport interface DecompositionAssessment {\n signals: DecompositionSignal[];\n /** Two or more signals agreeing. */\n oversized: boolean;\n}\n\n/* ── the signals ────────────────────────────────────────────────────────── */\n\n/** Timeouts per phase, read off the journal. Shared with timeout escalation. */\nexport function timeoutsByPhase(journal: string): Map<string, number> {\n const counts = new Map<string, number>();\n let phase = '(unknown)';\n\n for (const { event } of parseJournal(journal)) {\n if (event.type === 'phase:start') {\n phase = event.phase;\n continue;\n }\n if (event.type !== 'retry') continue;\n const kind = (event as { kind?: string }).kind;\n const reason = (event as { reason?: string }).reason ?? '';\n const timedOut = kind === 'timeout' || kind === 'stalled' || /timed out|stalled/i.test(reason);\n if (!timedOut) continue;\n counts.set(phase, (counts.get(phase) ?? 0) + 1);\n }\n return counts;\n}\n\n/**\n * The longest run of iterations that completed no story.\n *\n * An iteration that finishes nothing is not a failure — the agent may be\n * halfway through a story — but five of them in a row means the unit of work is\n * bigger than the loop was designed for.\n */\nfunction longestBarrenRun(journal: string): number {\n let passing = 0;\n let current = 0;\n let longest = 0;\n\n for (const { event } of parseJournal(journal)) {\n if (event.type === 'iteration:start') {\n current++;\n longest = Math.max(longest, current);\n continue;\n }\n if (event.type !== 'stories:update') continue;\n const nowPassing = event.stories.filter((story) => story.passes).length;\n if (nowPassing > passing) current = 0;\n passing = Math.max(passing, nowPassing);\n }\n return longest;\n}\n\n/**\n * Weigh the evidence.\n *\n * Every signal is a number crossing a documented line, and the report quotes\n * that number: \"this is too big\" is not an argument, and \"the `prd` phase timed\n * out three times\" is.\n */\nexport function assessDecomposition(input: DecompositionInput): DecompositionAssessment {\n const signals: DecompositionSignal[] = [];\n const journal = input.journal ?? '';\n\n for (const [phase, count] of timeoutsByPhase(journal)) {\n if (count >= DECOMPOSITION_THRESHOLDS.timeoutsPerPhase) {\n signals.push({\n id: 'repeated-timeouts',\n detail: `The '${phase}' phase timed out ${count} times (threshold: ${DECOMPOSITION_THRESHOLDS.timeoutsPerPhase}).`,\n });\n }\n }\n\n const stories = input.plan?.userStories.length ?? 0;\n if (stories > DECOMPOSITION_THRESHOLDS.stories) {\n signals.push({\n id: 'story-count',\n detail: `The plan has ${stories} user stories (threshold: ${DECOMPOSITION_THRESHOLDS.stories}).`,\n });\n }\n\n const barren = longestBarrenRun(journal);\n if (barren >= DECOMPOSITION_THRESHOLDS.barrenIterations) {\n signals.push({\n id: 'barren-iterations',\n detail: `${barren} iterations in a row completed no story (threshold: ${DECOMPOSITION_THRESHOLDS.barrenIterations}).`,\n });\n }\n\n const files = input.filesTouched ?? 0;\n if (files > DECOMPOSITION_THRESHOLDS.filesTouched) {\n signals.push({\n id: 'files-touched',\n detail: `${files} files were touched on this branch (threshold: ${DECOMPOSITION_THRESHOLDS.filesTouched}).`,\n });\n }\n\n const body = input.issueBody?.length ?? 0;\n if (body > DECOMPOSITION_THRESHOLDS.issueBodyChars) {\n signals.push({\n id: 'issue-size',\n detail: `The issue body is ${body} characters (threshold: ${DECOMPOSITION_THRESHOLDS.issueBodyChars}).`,\n });\n }\n\n if (input.hitMaxIterations === true) {\n signals.push({\n id: 'max-iterations',\n detail: 'The execute loop stopped because it ran out of iterations, not because it finished.',\n });\n }\n\n return { signals, oversized: signals.length >= DECOMPOSITION_MIN_SIGNALS };\n}\n\n/* ── the report ─────────────────────────────────────────────────────────── */\n\n/** Stories per proposed sub-issue. Small enough to finish in one run. */\nconst STORIES_PER_SUBISSUE = 5;\n\nexport interface ProposedSubIssue {\n title: string;\n stories: UserStory[];\n /** Titles of the sub-issues this one has to wait for. */\n dependsOn: string[];\n}\n\n/**\n * Cut the remaining work into pieces, in priority order.\n *\n * Priority order matters twice: it is the order the execute loop already works\n * in, and it makes each piece depend only on the one before it — which is the\n * only dependency shape that can be derived without understanding the code.\n * Anything cleverer would be a guess dressed as a plan.\n */\nexport function proposeSubIssues(plan: TaskPlan | null | undefined): ProposedSubIssue[] {\n const pending = [...(plan?.userStories ?? [])]\n .filter((story) => !story.passes)\n .sort((a, b) => a.priority - b.priority);\n if (pending.length === 0) return [];\n\n const chunks: ProposedSubIssue[] = [];\n for (let index = 0; index < pending.length; index += STORIES_PER_SUBISSUE) {\n const stories = pending.slice(index, index + STORIES_PER_SUBISSUE);\n const first = stories[0];\n const last = stories[stories.length - 1];\n const range =\n first === undefined || last === undefined || first.id === last.id\n ? (first?.id ?? '')\n : `${first.id}–${last.id}`;\n chunks.push({\n title: `${plan?.description ?? 'Issue'} — part ${chunks.length + 1} (${range})`,\n stories,\n dependsOn: chunks.length === 0 ? [] : [chunks[chunks.length - 1]?.title ?? ''],\n });\n }\n return chunks;\n}\n\nexport interface DecompositionReportInput {\n issueNumber: string;\n assessment: DecompositionAssessment;\n plan: TaskPlan | null | undefined;\n at: string;\n}\n\n/**\n * The report itself: what was detected, what is proposed, and what to do.\n *\n * Written for a person to disagree with. It states each signal with its number,\n * proposes a cut it can justify, and stops — the decision is not the tool's.\n */\nexport function buildDecompositionReport(input: DecompositionReportInput): string {\n const { issueNumber, assessment, plan, at } = input;\n const proposals = proposeSubIssues(plan);\n const lines: string[] = [];\n\n lines.push(`# Issue #${issueNumber} looks larger than one run`, '');\n lines.push(`Detected at ${at}.`, '');\n lines.push(\n 'This is a report, not an action. Nothing has been split, and nothing will be',\n 'without you asking for it.',\n '',\n );\n\n lines.push('## What was detected', '');\n for (const signal of assessment.signals) {\n lines.push(`- **${signal.id}** — ${signal.detail}`);\n }\n lines.push('');\n\n if (proposals.length === 0) {\n lines.push('## Proposed split', '');\n lines.push(\n 'No pending user stories were found, so there is nothing to cut here.',\n 'The signals above are about the run rather than about the plan.',\n '',\n );\n return `${lines.join('\\n')}\\n`;\n }\n\n lines.push('## Proposed split', '');\n lines.push(\n `The ${proposals.reduce((total, proposal) => total + proposal.stories.length, 0)} pending` +\n ` stories, in priority order, cut into ${proposals.length} sub-issues of at most` +\n ` ${STORIES_PER_SUBISSUE}. Each depends on the one before it, which is the only`,\n 'dependency shape that can be derived from the plan alone — read it as a starting',\n 'point, not as an answer.',\n '',\n );\n\n for (const proposal of proposals) {\n lines.push(`### ${proposal.title}`, '');\n if (proposal.dependsOn.length > 0) {\n lines.push(`Depends on: ${proposal.dependsOn.join(', ')}`, '');\n }\n for (const story of proposal.stories) {\n lines.push(`- \\`${story.id}\\` ${story.title}`);\n }\n lines.push('');\n }\n\n lines.push('## What to do next', '');\n lines.push(\n '- Adjust the cut above until it matches how you would actually split the work;',\n '- create the sub-issues (`issue-flow generate \"…\"`) and run them as a queue;',\n '- or decide the issue is fine as it is and re-run it — nothing here blocks that,',\n ' beyond the report you are reading.',\n '',\n );\n\n return `${lines.join('\\n')}\\n`;\n}\n","import { readFile } from 'node:fs/promises';\nimport chalk from 'chalk';\nimport { invokeSelectedAgent } from '../agents/invoke.js';\nimport { resolveAgentFor } from '../agents/resolve.js';\nimport type {\n AgentEvent,\n AgentInvocation,\n AgentPermission,\n AgentPhase,\n AgentProviderId,\n AgentRunResult,\n} from '../agents/types.js';\nimport { getActiveResilienceConfig } from '../config.js';\nimport { resolvePolicy } from '../resilience/policy.js';\nimport { withRetry } from '../resilience/retry.js';\nimport { writeDiagnostic } from '../storage/diagnostics.js';\nimport { createSpinner, ElapsedTimer, formatDuration, getIcons, useColor } from '../ui/logger.js';\nimport { DECOMPOSITION_THRESHOLDS, timeoutsByPhase } from './decompose.js';\nimport { type ClaudeUsage, sumUsage } from './metrics.js';\nimport { getSessionPublisher } from './session-publisher.js';\nimport { getShutdownSignal } from './shutdown.js';\nimport { isoNow } from './state-manager.js';\nimport {\n getActivityCallback,\n getInactivityTimeout,\n getOutputCallback,\n isVerbose,\n} from './verbose.js';\n\nexport interface HeadlessOptions {\n prompt: string;\n maxTurns?: number;\n timeout?: number;\n outputFormat?: 'json' | 'text' | 'stream-json';\n allowedTools?: string[];\n /**\n * Extra directories the headless session may read from and write to, passed\n * through as `--add-dir`. Required whenever a prompt points at a path outside\n * the working tree (e.g. the global issue storage under `~/.issue-flow`).\n */\n addDirs?: string[];\n /** Status message displayed as spinner (non-verbose) or header (verbose). */\n statusMessage?: string;\n /** Optional callback for routing verbose output (e.g., through listr2 task.output). */\n onOutput?: (line: string) => void;\n /** Journal-backed identity used to apply the one-time 2× timeout escalation. */\n timeoutHistory?: {\n phase: string;\n journalFiles: string[];\n };\n /** The invoking phase. Defaults to `analyze` only for resolution; argv is unchanged. */\n phase?: AgentPhase;\n /**\n * Semantic permission. Absent means `workspace`, which is the historical\n * `runHeadless` argv (no `--permission-mode`, no `--dangerously-skip-permissions`).\n */\n permission?: AgentPermission;\n /** Pin this invocation to a provider (L2 reviewer). */\n forceProvider?: AgentProviderId;\n /** Telemetry purpose when it is not the phase name (`verify`). */\n purpose?: 'verify';\n correctionCycle?: number;\n storyIds?: string[];\n}\n\nexport type HeadlessCost = ClaudeUsage;\n\nexport interface HeadlessResult {\n success: boolean;\n result: string;\n cost: HeadlessCost | null;\n error: string | null;\n agent?: { provider: AgentProviderId; model: string | null };\n /** The resilience budget was spent inside the facade; an outer artifact retry must not repeat it. */\n retryExhausted?: boolean;\n}\n\nexport const DEFAULT_HEADLESS_TIMEOUT_MS = 900_000;\n\nasync function escalatedTimeout(\n timeoutMs: number,\n history: HeadlessOptions['timeoutHistory'],\n): Promise<number> {\n if (timeoutMs === 0 || history === undefined) return timeoutMs;\n\n const journal = (\n await Promise.all(\n history.journalFiles.map(async (file) => {\n try {\n return await readFile(file, 'utf-8');\n } catch {\n return '';\n }\n }),\n )\n ).join('');\n const timeouts = timeoutsByPhase(journal).get(history.phase) ?? 0;\n if (timeouts < DECOMPOSITION_THRESHOLDS.timeoutsPerPhase) return timeoutMs;\n return Math.min(timeoutMs * 2, Number.MAX_SAFE_INTEGER);\n}\n\nfunction printAgentEvent(event: AgentEvent, onOutput?: (line: string) => void): void {\n const icons = getIcons();\n const colored = useColor();\n const emit = onOutput ?? ((msg: string) => process.stdout.write(`${msg}\\n`));\n\n if (event.kind === 'text') {\n const lines = event.text.split('\\n');\n for (const textLine of lines) {\n if (!textLine.trim()) continue;\n const prefix = colored ? chalk.dim(` ${icons.connector} `) : ` ${icons.connector} `;\n const text = colored ? chalk.dim(textLine) : textLine;\n emit(`${prefix}${text}`);\n }\n return;\n }\n\n getSessionPublisher().publish({\n type: 'activity',\n at: isoNow(),\n tool: event.name,\n detail: event.detail,\n });\n const toolName = event.name.padEnd(12);\n const prefix = colored ? chalk.dim(` ${icons.connector} `) : ` ${icons.connector} `;\n const toolIcon = colored ? chalk.cyan(icons.tool) : icons.tool;\n const toolLabel = colored ? chalk.cyan(toolName) : toolName;\n const contextText = event.detail ? (colored ? chalk.dim(event.detail) : event.detail) : '';\n emit(`${prefix}${toolIcon} ${toolLabel} ${contextText}`);\n}\n\nasync function invokeHeadlessAgent(\n invocation: AgentInvocation,\n): Promise<{ run: AgentRunResult; retryExhausted: boolean }> {\n const config = getActiveResilienceConfig();\n if (config.providers?.failover !== true) {\n return { run: (await invokeSelectedAgent(invocation)).run, retryExhausted: false };\n }\n\n let usage: ClaudeUsage | null = null;\n const outcome = await withRetry(() => invokeSelectedAgent(invocation), {\n policy: (failure) => resolvePolicy(failure.kind, config),\n signal: getShutdownSignal(),\n evaluate: (selected) => selected.failure,\n onAttempt: ({ value, failure, willRetry, delayMs, attempt }) => {\n if (value.run.usage !== null) usage = sumUsage(usage, value.run.usage);\n if (failure === null || !willRetry) return;\n getSessionPublisher().publish({\n type: 'retry',\n at: isoNow(),\n attempt,\n delaySeconds: delayMs / 1000,\n reason: failure.message,\n kind: failure.kind,\n });\n writeDiagnostic({\n level: 'warning',\n message: `Retrying ${invocation.phase} after ${failure.kind}`,\n context: { attempt, delayMs, reason: failure.message },\n fields: { phase: invocation.phase },\n });\n },\n });\n\n return {\n run: usage === null ? outcome.value.run : { ...outcome.value.run, usage },\n retryExhausted: outcome.exhausted,\n };\n}\n\n/**\n * Invoke the resolved agent in headless mode.\n *\n * Each invocation is an isolated session. UI (spinner, verbose header, activity)\n * stays here; argv and stream parsing belong to the runner.\n */\nexport async function runHeadless(options: HeadlessOptions): Promise<HeadlessResult> {\n const {\n prompt,\n maxTurns = 10,\n timeout: configuredTimeout = DEFAULT_HEADLESS_TIMEOUT_MS,\n outputFormat = 'json',\n allowedTools,\n addDirs,\n statusMessage,\n onOutput,\n phase = 'analyze',\n permission = 'workspace',\n forceProvider,\n purpose,\n correctionCycle,\n storyIds,\n } = options;\n const timeout = await escalatedTimeout(configuredTimeout, options.timeoutHistory);\n const settings = await resolveAgentFor(phase);\n\n const verbose = isVerbose();\n const effectiveOnOutput = onOutput ?? getOutputCallback();\n\n if (verbose) {\n const icons = getIcons();\n const colored = useColor();\n const emit = effectiveOnOutput ?? ((msg: string) => process.stdout.write(`${msg}\\n`));\n if (statusMessage) {\n const msg = colored\n ? chalk.blue(`${icons.start} ${statusMessage}`)\n : `${icons.start} ${statusMessage}`;\n emit(msg);\n }\n const connectorLine = colored ? chalk.dim(` ${icons.connector}`) : ` ${icons.connector}`;\n emit(connectorLine);\n\n const startTime = Date.now();\n const { run, retryExhausted } = await invokeHeadlessAgent({\n prompt,\n phase,\n addDirs,\n timeout,\n permission,\n maxTurns,\n allowedTools,\n ...(forceProvider === undefined ? {} : { forceProvider }),\n ...(purpose === undefined ? {} : { purpose }),\n ...(correctionCycle === undefined ? {} : { correctionCycle }),\n ...(storyIds === undefined ? {} : { storyIds }),\n onEvent: (event) => printAgentEvent(event, effectiveOnOutput),\n });\n\n const elapsedSec = Math.floor((Date.now() - startTime) / 1000);\n const durationStr = formatDuration(elapsedSec);\n const doneLine = colored\n ? chalk.dim(` ${icons.connector} ${chalk.italic(`Done in ${durationStr}`)}`)\n : ` ${icons.connector} Done in ${durationStr}`;\n emit(doneLine);\n emit(connectorLine);\n\n return mapHeadlessResult(run, outputFormat, retryExhausted);\n }\n\n const spinner = statusMessage ? createSpinner(statusMessage).start() : null;\n let timer: ElapsedTimer | null = null;\n if (spinner) {\n timer = new ElapsedTimer((elapsed) => {\n spinner.suffixText = useColor() ? chalk.dim(`(${elapsed})`) : `(${elapsed})`;\n }).start();\n }\n\n try {\n const { run, retryExhausted } = await invokeHeadlessAgent({\n prompt,\n phase,\n addDirs,\n timeout,\n permission,\n maxTurns,\n allowedTools,\n inactivityTimeoutMs: getInactivityTimeout(),\n ...(forceProvider === undefined ? {} : { forceProvider }),\n ...(purpose === undefined ? {} : { purpose }),\n ...(correctionCycle === undefined ? {} : { correctionCycle }),\n ...(storyIds === undefined ? {} : { storyIds }),\n onEvent: (event) => {\n if (event.kind === 'text') return;\n getSessionPublisher().publish({\n type: 'activity',\n at: isoNow(),\n tool: event.name,\n detail: event.detail,\n });\n getActivityCallback()?.({ tool: event.name, detail: event.detail });\n },\n });\n\n const elapsed = timer?.stop() ?? 0;\n const dur = useColor()\n ? chalk.dim(` (${formatDuration(elapsed)})`)\n : ` (${formatDuration(elapsed)})`;\n\n if (!run.success) {\n spinner?.fail(`${statusMessage}${dur}`);\n return mapHeadlessResult(run, outputFormat, retryExhausted);\n }\n\n spinner?.succeed(`${statusMessage}${dur}`);\n return mapHeadlessResult(run, outputFormat, retryExhausted);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const catchElapsed = timer?.stop() ?? 0;\n const catchDur = useColor()\n ? chalk.dim(` (${formatDuration(catchElapsed)})`)\n : ` (${formatDuration(catchElapsed)})`;\n spinner?.fail(`${statusMessage}${catchDur}`);\n return {\n success: false,\n result: '',\n cost: null,\n error: message,\n agent: { provider: settings.provider, model: settings.model },\n };\n }\n}\n\nfunction mapHeadlessResult(\n run: {\n success: boolean;\n result: string;\n rawOutput: string;\n usage: ClaudeUsage | null;\n error: string | null;\n agent: { provider: AgentProviderId; model: string | null };\n },\n outputFormat: 'json' | 'text' | 'stream-json',\n retryExhausted = false,\n): HeadlessResult {\n if (outputFormat === 'text') {\n return {\n success: run.success,\n result: run.success ? run.rawOutput || run.result : '',\n cost: null,\n error: run.error,\n agent: run.agent,\n ...(retryExhausted ? { retryExhausted: true } : {}),\n };\n }\n if (!run.success) {\n return {\n success: false,\n result: '',\n cost: null,\n error: run.error,\n agent: run.agent,\n ...(retryExhausted ? { retryExhausted: true } : {}),\n };\n }\n return {\n success: true,\n result: run.result,\n cost: run.usage,\n error: null,\n agent: run.agent,\n ...(retryExhausted ? { retryExhausted: true } : {}),\n };\n}\n"],"mappings":"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","names":["run","failure","readFile","readFile","prefix"]}
|
package/dist/chunk-7Z4Y3VKM.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// src/utils/fs.ts
|
|
4
|
-
import { copyFile, mkdtemp, rename, unlink, writeFile } from "fs/promises";
|
|
5
|
-
import { tmpdir } from "os";
|
|
6
|
-
import { basename, join } from "path";
|
|
7
|
-
async function writeFileAtomic(path, content) {
|
|
8
|
-
const tmpDir = await mkdtemp(join(tmpdir(), "issue-flow-"));
|
|
9
|
-
const tmpFile = join(tmpDir, basename(path));
|
|
10
|
-
await writeFile(tmpFile, content, "utf-8");
|
|
11
|
-
try {
|
|
12
|
-
await rename(tmpFile, path);
|
|
13
|
-
} catch (err) {
|
|
14
|
-
if (err.code === "EXDEV") {
|
|
15
|
-
await copyFile(tmpFile, path);
|
|
16
|
-
await unlink(tmpFile);
|
|
17
|
-
} else {
|
|
18
|
-
throw err;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export {
|
|
24
|
-
writeFileAtomic
|
|
25
|
-
};
|
|
26
|
-
//# sourceMappingURL=chunk-7Z4Y3VKM.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/fs.ts"],"sourcesContent":["import { copyFile, mkdtemp, rename, unlink, writeFile } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { basename, join } from 'node:path';\n\n/**\n * Write a file atomically (write-to-temp + rename).\n *\n * A crash mid-write leaves the previous content untouched instead of a\n * truncated file, which matters for every artifact the pipeline reloads on the\n * next run (tasks.json, metadata.json).\n */\nexport async function writeFileAtomic(path: string, content: string): Promise<void> {\n const tmpDir = await mkdtemp(join(tmpdir(), 'issue-flow-'));\n const tmpFile = join(tmpDir, basename(path));\n\n await writeFile(tmpFile, content, 'utf-8');\n\n try {\n await rename(tmpFile, path);\n } catch (err: unknown) {\n // EXDEV: rename fails across different devices/drives (common on Windows)\n if ((err as NodeJS.ErrnoException).code === 'EXDEV') {\n await copyFile(tmpFile, path);\n await unlink(tmpFile);\n } else {\n throw err;\n }\n }\n}\n"],"mappings":";;;AAAA,SAAS,UAAU,SAAS,QAAQ,QAAQ,iBAAiB;AAC7D,SAAS,cAAc;AACvB,SAAS,UAAU,YAAY;AAS/B,eAAsB,gBAAgB,MAAc,SAAgC;AAClF,QAAM,SAAS,MAAM,QAAQ,KAAK,OAAO,GAAG,aAAa,CAAC;AAC1D,QAAM,UAAU,KAAK,QAAQ,SAAS,IAAI,CAAC;AAE3C,QAAM,UAAU,SAAS,SAAS,OAAO;AAEzC,MAAI;AACF,UAAM,OAAO,SAAS,IAAI;AAAA,EAC5B,SAAS,KAAc;AAErB,QAAK,IAA8B,SAAS,SAAS;AACnD,YAAM,SAAS,SAAS,IAAI;AAC5B,YAAM,OAAO,OAAO;AAAA,IACtB,OAAO;AACL,YAAM;AAAA,IACR;AAAA,EACF;AACF;","names":[]}
|