@songsid/agend 2.1.4-beta.24 → 2.1.4-beta.26

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.
@@ -23,20 +23,28 @@ export declare class ClaudeCodeBackend implements CliBackend {
23
23
  getReadyPattern(): RegExp;
24
24
  /**
25
25
  * The live spinner line, which is on screen only while generating. Captured from
26
- * two running panes:
26
+ * running panes and their pipe-pane recordings:
27
27
  *
28
28
  * working → `✢ Accomplishing… (11m 26s · ↓ 38.0k tokens)`
29
29
  * idle → `✻ Worked for 6m 49s`
30
30
  *
31
31
  * Both panes also showed `❯` and the `ok` statusline, which is why neither of
32
- * those can carry the distinction. The discriminator is the ellipsis followed by
33
- * a parenthesised live elapsed counter; the completed line is past tense with no
34
- * `…` and no counter. The verb and the glyph both rotate, so neither is matched.
32
+ * those can carry the distinction. The discriminator is the rotating glyph plus
33
+ * Claude's one-word spinner label ending in an ellipsis. The completed line is
34
+ * past tense with no ellipsis. The verb and glyph both rotate, so neither
35
+ * specific value is matched.
35
36
  *
36
- * The leading class is "any non-ASCII symbol, or an asterisk". It used to be
37
- * `[^\x00-\x7F\p{L}\p{N}\s]` alone, requiring a non-ASCII glyph — but the
38
- * animation cycles through six frames and one of them is a plain ASCII
39
- * asterisk. Sampling a continuously working pane 50 times at 250ms:
37
+ * Claude Code 2.1.239 paints that line incrementally. For roughly the first
38
+ * three seconds — and briefly during later repaints — capture-pane can see only
39
+ * `* Nesting…` before `(3s · ↓ 9 tokens)` is appended. It also emits hyphenated
40
+ * labels such as `Razzle-dazzling…` and `Sock-hopping…`. Requiring the elapsed
41
+ * counter and a letters-only verb made both real shapes look idle. Since `❯`
42
+ * remains visible throughout generation, a settled capture in either shape
43
+ * retired Cancel and the progress bubble while the turn was still running.
44
+ *
45
+ * The animation cycles through six measured frames, including one plain ASCII
46
+ * asterisk. The older leading class required a non-ASCII glyph, so sampling a
47
+ * continuously working pane 50 times at 250ms produced:
40
48
  *
41
49
  * ✻ 11/11 ✽ 10/10 ✢ 10/10 · 9/9 ✶ 4/4 * 0/6 ← U+002A never matched
42
50
  *
@@ -46,19 +54,13 @@ export declare class ClaudeCodeBackend implements CliBackend {
46
54
  * retired cancel buttons mid-turn. 12% of frames, so it hit some turns and not
47
55
  * others.
48
56
  *
49
- * `*` is spelled out rather than opening the class to all ASCII punctuation:
50
- * `> quoted… (2s)` in agent output would otherwise read as a spinner, and a
51
- * false positive on a *stable* pane pins the instance in `working` forever.
52
- * If a future release adds another ASCII frame this pattern misses it again —
53
- * but a missed frame can no longer flip the state on its own, because the
54
- * state machine only decides on patterns once output has settled.
55
- *
56
- * Deliberately narrow, because the cost is asymmetric. Missing the spinner just
57
- * restores today's behaviour; matching prose that happens to sit on a *stable*
58
- * pane would hold the instance in `working` forever — no auto-pause, no cancel
59
- * button retirement, and eventually a bogus hang alert. So the line must start
60
- * with a non-ASCII, non-letter glyph and carry a single word ending in `…`:
61
- * `- Something… (5s)` and `I waited… (30s) for the build` are both rejected.
57
+ * Deliberately narrow, because the cost is asymmetric. Matching prose that
58
+ * happens to sit on a *stable* pane would hold the instance in `working`
59
+ * forever — no auto-pause, no cancel-button retirement, and eventually a bogus
60
+ * hang alert. Therefore this accepts only Claude's six measured spinner glyphs,
61
+ * exactly one word (optionally hyphenated), and the Unicode ellipsis. Markdown
62
+ * prose such as `* bullet point…`, `- Something…`, and a completed
63
+ * `✻ Worked for 6m 49s` remain rejected.
62
64
  *
63
65
  * Note when this actually decides anything: while the CLI really is generating,
64
66
  * the elapsed counter ticks, the pane changes, and motion already reports
@@ -123,20 +123,28 @@ export class ClaudeCodeBackend {
123
123
  }
124
124
  /**
125
125
  * The live spinner line, which is on screen only while generating. Captured from
126
- * two running panes:
126
+ * running panes and their pipe-pane recordings:
127
127
  *
128
128
  * working → `✢ Accomplishing… (11m 26s · ↓ 38.0k tokens)`
129
129
  * idle → `✻ Worked for 6m 49s`
130
130
  *
131
131
  * Both panes also showed `❯` and the `ok` statusline, which is why neither of
132
- * those can carry the distinction. The discriminator is the ellipsis followed by
133
- * a parenthesised live elapsed counter; the completed line is past tense with no
134
- * `…` and no counter. The verb and the glyph both rotate, so neither is matched.
132
+ * those can carry the distinction. The discriminator is the rotating glyph plus
133
+ * Claude's one-word spinner label ending in an ellipsis. The completed line is
134
+ * past tense with no ellipsis. The verb and glyph both rotate, so neither
135
+ * specific value is matched.
135
136
  *
136
- * The leading class is "any non-ASCII symbol, or an asterisk". It used to be
137
- * `[^\x00-\x7F\p{L}\p{N}\s]` alone, requiring a non-ASCII glyph — but the
138
- * animation cycles through six frames and one of them is a plain ASCII
139
- * asterisk. Sampling a continuously working pane 50 times at 250ms:
137
+ * Claude Code 2.1.239 paints that line incrementally. For roughly the first
138
+ * three seconds — and briefly during later repaints — capture-pane can see only
139
+ * `* Nesting…` before `(3s · ↓ 9 tokens)` is appended. It also emits hyphenated
140
+ * labels such as `Razzle-dazzling…` and `Sock-hopping…`. Requiring the elapsed
141
+ * counter and a letters-only verb made both real shapes look idle. Since `❯`
142
+ * remains visible throughout generation, a settled capture in either shape
143
+ * retired Cancel and the progress bubble while the turn was still running.
144
+ *
145
+ * The animation cycles through six measured frames, including one plain ASCII
146
+ * asterisk. The older leading class required a non-ASCII glyph, so sampling a
147
+ * continuously working pane 50 times at 250ms produced:
140
148
  *
141
149
  * ✻ 11/11 ✽ 10/10 ✢ 10/10 · 9/9 ✶ 4/4 * 0/6 ← U+002A never matched
142
150
  *
@@ -146,19 +154,13 @@ export class ClaudeCodeBackend {
146
154
  * retired cancel buttons mid-turn. 12% of frames, so it hit some turns and not
147
155
  * others.
148
156
  *
149
- * `*` is spelled out rather than opening the class to all ASCII punctuation:
150
- * `> quoted… (2s)` in agent output would otherwise read as a spinner, and a
151
- * false positive on a *stable* pane pins the instance in `working` forever.
152
- * If a future release adds another ASCII frame this pattern misses it again —
153
- * but a missed frame can no longer flip the state on its own, because the
154
- * state machine only decides on patterns once output has settled.
155
- *
156
- * Deliberately narrow, because the cost is asymmetric. Missing the spinner just
157
- * restores today's behaviour; matching prose that happens to sit on a *stable*
158
- * pane would hold the instance in `working` forever — no auto-pause, no cancel
159
- * button retirement, and eventually a bogus hang alert. So the line must start
160
- * with a non-ASCII, non-letter glyph and carry a single word ending in `…`:
161
- * `- Something… (5s)` and `I waited… (30s) for the build` are both rejected.
157
+ * Deliberately narrow, because the cost is asymmetric. Matching prose that
158
+ * happens to sit on a *stable* pane would hold the instance in `working`
159
+ * forever — no auto-pause, no cancel-button retirement, and eventually a bogus
160
+ * hang alert. Therefore this accepts only Claude's six measured spinner glyphs,
161
+ * exactly one word (optionally hyphenated), and the Unicode ellipsis. Markdown
162
+ * prose such as `* bullet point…`, `- Something…`, and a completed
163
+ * `✻ Worked for 6m 49s` remain rejected.
162
164
  *
163
165
  * Note when this actually decides anything: while the CLI really is generating,
164
166
  * the elapsed counter ticks, the pane changes, and motion already reports
@@ -166,7 +168,7 @@ export class ClaudeCodeBackend {
166
168
  * an in-progress spinner — which is exactly the hang this is meant to surface.
167
169
  */
168
170
  getBusyPattern() {
169
- return /^[ \t]*(?:[^\x00-\x7F\p{L}\p{N}\s]|\*)\s+\p{L}+…\s*\(\d+[hms]\b/mu;
171
+ return /^[ \t]*[✻✽✢·✶*][ \t]+\p{L}+(?:-\p{L}+)*…(?:[ \t]+\([^\n]*)?[ \t]*$/mu;
170
172
  }
171
173
  getContextUsage() {
172
174
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/backend/claude-code.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/backend/claude-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7F,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAqG,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAE9L,2EAA2E;AAC3E,SAAS,gBAAgB,CAAC,GAAW;IACnC,IAAI,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC;QAAC,SAAS,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,4DAA4D,CAAC,CAAC;IAEnH,wEAAwE;IACxE,uEAAuE;IACvE,6EAA6E;IAC7E,MAAM,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;IAC1D,IAAI,SAAS,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,SAAS,CAAC;IAE9C,4EAA4E;IAC5E,+DAA+D;IAC/D,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;AACrE,CAAC;AAGD,MAAM,OAAO,iBAAiB;IAKR;IAJX,UAAU,GAAG,QAAQ,CAAC;IACtB,4BAA4B,GAAG,IAAI,CAAC;IACrC,UAAU,CAAS;IAE3B,YAAoB,WAAmB;QAAnB,gBAAW,GAAX,WAAW,CAAQ;QACrC,IAAI,CAAC,UAAU,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC5C,CAAC;IAED,YAAY,CAAC,MAAwB;QACnC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,sBAAsB,CAAC,CAAC;QACpE,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAChE,MAAM,SAAS,GAAG,CAAC,8BAA8B,EAAE,wCAAwC,CAAC,CAAC;QAC7F,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB;YAAE,SAAS,CAAC,IAAI,CAAC,sBAAsB,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;QACvH,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;YAC7D,SAAS,CAAC,IAAI,CAAC,qBAAqB,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QACnF,CAAC;QACD,IAAI,GAAG,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,eAAe,YAAY,iBAAiB,aAAa,EAAE,CAAC;QAC/G,IAAI,MAAM,CAAC,eAAe,KAAK,KAAK;YAAE,GAAG,IAAI,iCAAiC,CAAC;QAE/E,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;QAC3D,0EAA0E;QAC1E,2EAA2E;QAC3E,2EAA2E;QAC3E,0EAA0E;QAC1E,uEAAuE;QACvE,yEAAyE;QACzE,kDAAkD;QAClD,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,UAAU,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC;YACvG,GAAG,IAAI,aAAa,CAAC;QACvB,CAAC;QAED,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC1C,mBAAmB,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;YAC1C,GAAG,IAAI,YAAY,KAAK,EAAE,CAAC;QAC7B,CAAC;QAED,gGAAgG;QAChG,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,uBAAuB,CAAC,CAAC;QAClE,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1B,GAAG,IAAI,gCAAgC,SAAS,EAAE,CAAC;QACrD,CAAC;QAED,OAAO,GAAG,CAAC;IACb,CAAC;IAEO,iBAAiB,CAAC,gBAAwB;QAChD,MAAM,GAAG,GAAG,gBAAgB,CAAC,IAAI,EAAE,CAAC;QACpC,IAAI,CAAC,GAAG;YAAE,OAAO,KAAK,CAAC;QACvB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;QACtF,MAAM,UAAU,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,CAAC;YACH,OAAO,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,CAAC,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;iBACjF,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;QACpE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,WAAW,CAAC,MAAwB;QAClC,qEAAqE;QACrE,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAChE,MAAM,SAAS,GAAG,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC;QACpD,aAAa,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAEjE,6BAA6B;QAC7B,MAAM,iBAAiB,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAEvD,wFAAwF;QACxF,MAAM,QAAQ,GAA4B;YACxC,UAAU,EAAE;gBACV,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,iBAAiB;aAC3B;SACF,CAAC;QACF,aAAa,CACX,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,sBAAsB,CAAC,EAC9C,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CACzB,CAAC;QAEF,+DAA+D;QAC/D,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;QAE9B,4EAA4E;QAC5E,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;YACxB,IAAI,CAAC;gBAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,uBAAuB,CAAC,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;QAC1H,CAAC;IACH,CAAC;IAED;;;;;;;;;;;OAWG;IACH,eAAe;QACb,OAAO,GAAG,CAAC;IACb,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6CG;IACH,cAAc;QACZ,OAAO,sEAAsE,CAAC;IAChF,CAAC;IAED,eAAe;QACb,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;YACrD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;YACnD,OAAO,IAAI,CAAC,cAAc,EAAE,eAAe,IAAI,IAAI,CAAC;QACtD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,4EAA4E;YAC5E,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,YAAY;QACV,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;YACrD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;YACnD,OAAO,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,gBAAgB;QACd,OAAO;YACL,EAAE,OAAO,EAAE,wBAAwB,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,wBAAwB,EAAE;YAChH,EAAE,OAAO,EAAE,iDAAiD,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,gDAAgD,EAAE;YAC/J,EAAE,OAAO,EAAE,4BAA4B,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,sBAAsB,EAAE;YAC/G,EAAE,OAAO,EAAE,wBAAwB,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,gBAAgB,EAAE;YACtG,EAAE,OAAO,EAAE,4BAA4B,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,0BAA0B,EAAE;SAC/G,CAAC;IACJ,CAAC;IAED,iBAAiB;QACf,OAAO;YACL,2EAA2E;YAC3E,wEAAwE;YACxE,EAAE,OAAO,EAAE,qCAAqC,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,EAAE,mEAAmE,EAAE;YAC7J,EAAE,OAAO,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,EAAE,kDAAkD,EAAE;YAC3H,EAAE,OAAO,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,qCAAqC,EAAE;YACrG,EAAE,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC,EAAE,WAAW,EAAE,4CAA4C,EAAE;SAC5G,CAAC;IACJ,CAAC;IAED,iBAAiB;QACf,OAAO;YACL;gBACE,uEAAuE;gBACvE,wEAAwE;gBACxE,OAAO,EAAE,qCAAqC;gBAC9C,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;gBACvB,WAAW,EAAE,mEAAmE;aACjF;SACF,CAAC;IACJ,CAAC;IAED,cAAc,KAAa,OAAO,OAAO,CAAC,CAAC,CAAC;IAE5C,iBAAiB,KAAa,OAAO,UAAU,CAAC,CAAC,CAAC;IAClD,eAAe,KAAa,OAAO,QAAQ,CAAC,CAAC,CAAC;IAE9C,YAAY,KAAa,OAAO,QAAQ,CAAC,CAAC,CAAC;IAE3C,4EAA4E;IAC5E,0EAA0E;IAC1E,iBAAiB,KAA4C,OAAO,SAAS,CAAC,CAAC,CAAC;IAChF,eAAe,KAAe,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAEjF,gFAAgF;IAChF,sBAAsB,KAA4B,OAAO,SAAS,CAAC,CAAC,CAAC;IAErE,KAAK,CAAC,UAAU;QACd,OAAO;YACL,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,iBAAiB,EAAE;YACnE,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;YACjC,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;YAC7B,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;YAC/B,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,6BAA6B,EAAE;YACjF,6DAA6D;YAC7D,8DAA8D;YAC9D,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE;SAC/D,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,WAAW;QACf,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QACvD,OAAO,EAAE,OAAO,EAAE,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;IACxF,CAAC;IAED,OAAO,CAAC,OAAyB;QAC/B,0EAA0E;IAC5E,CAAC;IAED,qFAAqF;IAC7E,gBAAgB,CAAC,OAAyB;QAChD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;QAC7C,IAAI,CAAC,MAAM;YAAE,OAAO;QAEpB,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QACpE,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,cAAc,CAAC,CAAC;QAEvD,IAAI,SAAS,GAA4B,EAAE,CAAC;QAC5C,IAAI,CAAC;YACH,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC;QAChE,CAAC;QAAC,MAAM,CAAC,CAAC,6BAA6B,CAAC,CAAC;QAEzC,MAAM,QAAQ,GAAG,SAAS,CAAC,qBAAiF,CAAC;QAC7G,MAAM,QAAQ,GAAG,QAAQ,EAAE,QAAQ,IAAI,EAAE,CAAC;QAC1C,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YACpC,SAAS,CAAC,qBAAqB,GAAG;gBAChC,QAAQ,EAAE,CAAC,GAAG,QAAQ,EAAE,WAAW,CAAC;gBACpC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE;aACnC,CAAC;YACF,aAAa,CAAC,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,kEAAkE;IAC1D,eAAe;QACrB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;YAC/E,OAAO,CAAC,CAAC,GAAG,CAAC,YAAY,EAAE,WAAW,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAEO,qBAAqB;QAC3B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAC7D,oFAAoF;QACpF,MAAM,MAAM,GAAG;YACb,qBAAqB;YACrB,2BAA2B;YAC3B,iBAAiB;YACjB,4CAA4C;YAC5C,oDAAoD,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,kCAAkC;SACjH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;QAC3D,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACnD,OAAO,UAAU,CAAC;IACpB,CAAC;CACF"}
@@ -10,7 +10,7 @@ export interface InstanceStatusData {
10
10
  costCents: number;
11
11
  }
12
12
  export interface AlertData {
13
- type: "hang" | "cost_warn" | "cost_limit" | "schedule_deferred" | "rotation" | "cancel" | "interactive_prompt" | "exit_restart" | "clear_confirm" | "tip";
13
+ type: "hang" | "cost_warn" | "cost_limit" | "schedule_deferred" | "rotation" | "cancel" | "interactive_prompt" | "exit_restart" | "clear_confirm" | "tip" | "login";
14
14
  instanceName: string;
15
15
  message: string;
16
16
  choices?: Choice[];
@@ -93,6 +93,29 @@ export interface FleetContext {
93
93
  promptTip?(generalName: string, adapter: import("./channel/types.js").ChannelAdapter, chatId: string, threadId?: string): Promise<"posted" | "empty" | "unavailable">;
94
94
  /** Persistently enable advanced tips without waiting for the dismissal threshold. */
95
95
  unlockAdvancedTips?(userId: string): boolean;
96
+ /** `/login` backend chooser buttons. Caller enforces fleet-admin. */
97
+ promptLoginBackends?(chat: {
98
+ adapter: import("./channel/types.js").ChannelAdapter;
99
+ adapterId: string;
100
+ chatId: string;
101
+ threadId?: string;
102
+ }): Promise<void>;
103
+ /**
104
+ * Start a remote login session for one backend; returns a status line, or
105
+ * null when a still-valid-auth confirmation prompt was posted instead.
106
+ */
107
+ startLoginSession?(backend: string, chat: {
108
+ adapter: import("./channel/types.js").ChannelAdapter;
109
+ adapterId: string;
110
+ chatId: string;
111
+ threadId?: string;
112
+ }, opts?: {
113
+ skipAuthCheck?: boolean;
114
+ }): Promise<string | null>;
115
+ /** Paste admin-supplied text (auth code / start URL) into the login window. */
116
+ loginSubmitInput?(text: string): Promise<string>;
117
+ /** Abort the active login session. */
118
+ cancelLoginSession?(): Promise<string>;
96
119
  /** Human-readable effective model for an instance (resolves inherited defaults). */
97
120
  modelDisplayForInstance?(name: string): string;
98
121
  /**
@@ -811,6 +811,52 @@ export declare class FleetManager implements FleetContext, LifecycleContext, Arc
811
811
  private isDeliveryEpochCurrent;
812
812
  /** Invalidate work queued before a user cancel and wake idle-gate waiters. */
813
813
  private cancelPendingDeliveries;
814
+ private activeLogin;
815
+ /** Post the backend chooser for a bare `/login`. Caller enforces admin. */
816
+ promptLoginBackends(chat: {
817
+ adapter: ChannelAdapter;
818
+ adapterId: string;
819
+ chatId: string;
820
+ threadId?: string;
821
+ }): Promise<void>;
822
+ /**
823
+ * Start a login session for one backend. Caller enforces admin.
824
+ * Returns a status line to post, or null when a confirmation prompt was
825
+ * posted instead (auth still valid — see the pre-check below).
826
+ */
827
+ startLoginSession(backendArg: string, chat: {
828
+ adapter: ChannelAdapter;
829
+ adapterId: string;
830
+ chatId: string;
831
+ threadId?: string;
832
+ }, opts?: {
833
+ skipAuthCheck?: boolean;
834
+ }): Promise<string | null>;
835
+ /** Create the login window and session (pre-check already settled). */
836
+ private launchLoginSession;
837
+ /** `/login code <text>` — paste admin-supplied text into the login window. */
838
+ loginSubmitInput(text: string): Promise<string>;
839
+ /** `/login cancel` — abort the active session and remove its window. */
840
+ cancelLoginSession(): Promise<string>;
841
+ /**
842
+ * The URL (+ code) is a live credential: whoever completes it binds THEIR
843
+ * account to this fleet's CLI. Telegram gets an HTML spoiler (same treatment
844
+ * as the dashboard token); other adapters get plain text with the warning.
845
+ */
846
+ private sendLoginSecret;
847
+ /**
848
+ * After a successful login: wake the paused instances of that backend AND
849
+ * restart the running ones — a live CLI holds the old token in memory and
850
+ * only re-reads credentials on process start (a paused instance's CLI is
851
+ * already dead, so waking it respawns with the new token for free).
852
+ */
853
+ private recoverBackendInstances;
854
+ /** Backend chooser button → start that backend's login session. */
855
+ private handleLoginBackendSelect;
856
+ /** Re-login confirmation (auth pre-check said credentials still work). */
857
+ private handleLoginConfirm;
858
+ /** Kiro provider button → drive the CLI's arrow-key selector. */
859
+ private handleLoginMenuSelect;
814
860
  queueMirrorMessage(text: string): void;
815
861
  /** Push an SSE event to all connected Web UI clients. */
816
862
  emitSseEvent(event: string, data: unknown): void;
@@ -44,6 +44,8 @@ import { outboundHandlers } from "./outbound-handlers.js";
44
44
  import { handleWebRequest, broadcastSseEvent } from "./web-api.js";
45
45
  import { handleViewRequest, isViewPath } from "./view-api.js";
46
46
  import { handleUsageRequest, isUsagePath, usageProviderIdForBackend } from "./usage/usage-api.js";
47
+ import { LOGIN_FLOWS, LOGIN_BACKEND_ALIASES, checkAuthStatus } from "./login-flows.js";
48
+ import { LoginSession } from "./login-manager.js";
47
49
  import { handleSettingsRequest } from "./settings-api.js";
48
50
  import { setLocale, detectLocale, getLocale, t } from "./locale.js";
49
51
  import { handleAgentRequest } from "./agent-endpoint.js";
@@ -209,6 +211,9 @@ const HANG_CALLBACK_PREFIX = "hang:";
209
211
  const CLEAR_CONFIRM_CALLBACK_PREFIX = "clear-confirm:";
210
212
  const TIP_DISMISS_CALLBACK_PREFIX = "tip-dismiss:";
211
213
  const TIP_UNLOCK_CALLBACK_PREFIX = "tip-unlock:";
214
+ const LOGIN_CALLBACK_PREFIX = "login:";
215
+ const LOGIN_MENU_CALLBACK_PREFIX = "login-menu:";
216
+ const LOGIN_CONFIRM_CALLBACK_PREFIX = "login-confirm:";
212
217
  const CLEAR_CONFIRM_TIMEOUT_MS = 15_000;
213
218
  /** Default lifetime for long-lived nonce prompts (clear overrides this to 15s). */
214
219
  const NONCE_BUTTON_TIMEOUT_MS = 15 * 60_000;
@@ -2364,6 +2369,12 @@ export class FleetManager {
2364
2369
  return;
2365
2370
  if (await this.handleTipUnlock(data, adapterId, this.adapter ?? undefined))
2366
2371
  return;
2372
+ if (await this.handleLoginBackendSelect(data, adapterId, this.adapter ?? undefined))
2373
+ return;
2374
+ if (await this.handleLoginMenuSelect(data, adapterId, this.adapter ?? undefined))
2375
+ return;
2376
+ if (await this.handleLoginConfirm(data, adapterId, this.adapter ?? undefined))
2377
+ return;
2367
2378
  if (await this.handleClearConfirmation(data, adapterId, this.adapter ?? undefined))
2368
2379
  return;
2369
2380
  if (await this.handleExitRestartPrompt(data, adapterId, this.adapter ?? undefined))
@@ -2737,6 +2748,12 @@ export class FleetManager {
2737
2748
  return;
2738
2749
  if (await this.handleTipUnlock(data, adapterId, adapter))
2739
2750
  return;
2751
+ if (await this.handleLoginBackendSelect(data, adapterId, adapter))
2752
+ return;
2753
+ if (await this.handleLoginMenuSelect(data, adapterId, adapter))
2754
+ return;
2755
+ if (await this.handleLoginConfirm(data, adapterId, adapter))
2756
+ return;
2740
2757
  if (await this.handleClearConfirmation(data, adapterId, adapter))
2741
2758
  return;
2742
2759
  if (await this.handleExitRestartPrompt(data, adapterId, adapter))
@@ -6175,6 +6192,261 @@ export class FleetManager {
6175
6192
  check();
6176
6193
  return next;
6177
6194
  }
6195
+ // ── Remote CLI login (`/login`) ──────────────────────────────────────────
6196
+ //
6197
+ // One session at a time, in a dedicated tmux window — never an instance
6198
+ // pane. Credentials are per-backend (codex homes symlink auth.json to the
6199
+ // shared ~/.codex; the other CLIs use one real home), so a single sign-in
6200
+ // repairs every instance of that backend, and instance delivery, pane-state
6201
+ // detection, tool progress, and mcp_proxy_reply never observe login output.
6202
+ activeLogin = null;
6203
+ /** Post the backend chooser for a bare `/login`. Caller enforces admin. */
6204
+ async promptLoginBackends(chat) {
6205
+ const configured = new Set();
6206
+ for (const [, config] of Object.entries(this.fleetConfig?.instances ?? {})) {
6207
+ configured.add(config.backend ?? this.fleetConfig?.defaults?.backend ?? "claude-code");
6208
+ }
6209
+ const choices = Object.keys(LOGIN_FLOWS)
6210
+ .filter(backend => configured.size === 0 || configured.has(backend))
6211
+ .map(backend => ({ action: backend, label: backend }));
6212
+ if (choices.length === 0) {
6213
+ await chat.adapter.sendText(chat.chatId, t("login.unsupported", [...configured].join(", ")), { threadId: chat.threadId });
6214
+ return;
6215
+ }
6216
+ await this.postNonceButtonPrompt({
6217
+ prefix: LOGIN_CALLBACK_PREFIX,
6218
+ alertType: "login",
6219
+ instanceName: "login",
6220
+ adapter: chat.adapter,
6221
+ adapterId: chat.adapterId,
6222
+ chatId: chat.chatId,
6223
+ threadId: chat.threadId,
6224
+ message: t("login.choose_backend"),
6225
+ choices,
6226
+ expiredText: t("buttons.stale"),
6227
+ });
6228
+ }
6229
+ /**
6230
+ * Start a login session for one backend. Caller enforces admin.
6231
+ * Returns a status line to post, or null when a confirmation prompt was
6232
+ * posted instead (auth still valid — see the pre-check below).
6233
+ */
6234
+ async startLoginSession(backendArg, chat, opts = {}) {
6235
+ const backend = LOGIN_BACKEND_ALIASES[backendArg.toLowerCase()] ?? backendArg.toLowerCase();
6236
+ const flow = LOGIN_FLOWS[backend];
6237
+ if (!flow)
6238
+ return t("login.unsupported", backendArg);
6239
+ if (this.activeLogin)
6240
+ return t("login.busy", this.activeLogin.backend);
6241
+ // Token-free pre-check (5s cap): re-login while auth still works is
6242
+ // usually a mistake, so it needs a confirmed click. An invalid OR
6243
+ // uncertain result (timeout, missing binary) proceeds straight to login —
6244
+ // an unreliable probe must never block the re-login the admin asked for.
6245
+ if (!opts.skipAuthCheck && flow.authCheck) {
6246
+ const status = await checkAuthStatus(flow.authCheck);
6247
+ if (status === "valid") {
6248
+ await this.postNonceButtonPrompt({
6249
+ prefix: LOGIN_CONFIRM_CALLBACK_PREFIX,
6250
+ alertType: "login",
6251
+ instanceName: backend,
6252
+ adapter: chat.adapter,
6253
+ adapterId: chat.adapterId,
6254
+ chatId: chat.chatId,
6255
+ threadId: chat.threadId,
6256
+ message: t("login.still_valid", backend),
6257
+ choices: [
6258
+ { action: "go", label: t("login.relogin_go") },
6259
+ { action: "cancel", label: t("login.relogin_cancel") },
6260
+ ],
6261
+ expiredText: t("buttons.stale"),
6262
+ });
6263
+ return null;
6264
+ }
6265
+ }
6266
+ return this.launchLoginSession(flow, backend, chat);
6267
+ }
6268
+ /** Create the login window and session (pre-check already settled). */
6269
+ async launchLoginSession(flow, backend, chat) {
6270
+ if (this.activeLogin)
6271
+ return t("login.busy", this.activeLogin.backend);
6272
+ const sessionName = getTmuxSession();
6273
+ await TmuxManager.ensureSession(sessionName);
6274
+ const tmux = new TmuxManager(sessionName, "");
6275
+ const session = new LoginSession(flow, tmux, {
6276
+ onMenu: async (options) => {
6277
+ await this.postNonceButtonPrompt({
6278
+ prefix: LOGIN_MENU_CALLBACK_PREFIX,
6279
+ alertType: "login",
6280
+ instanceName: backend,
6281
+ adapter: chat.adapter,
6282
+ adapterId: chat.adapterId,
6283
+ chatId: chat.chatId,
6284
+ threadId: chat.threadId,
6285
+ message: t("login.choose_provider"),
6286
+ choices: options.map((label, index) => ({ action: String(index), label })),
6287
+ expiredText: t("buttons.stale"),
6288
+ });
6289
+ },
6290
+ onAuthHint: async (url, code) => {
6291
+ await this.sendLoginSecret(chat, backend, url, code);
6292
+ },
6293
+ onNeedInput: async (promptExcerpt) => {
6294
+ await chat.adapter.sendText(chat.chatId, t("login.need_input", backend, promptExcerpt), { threadId: chat.threadId }).catch(() => { });
6295
+ },
6296
+ onDone: async ({ ok, detail }) => {
6297
+ this.activeLogin = null;
6298
+ let text;
6299
+ if (ok) {
6300
+ const { woken, restarted } = await this.recoverBackendInstances(backend);
6301
+ const none = t("login.none");
6302
+ text = t("login.success", backend, woken.length ? woken.join(", ") : none, restarted.length ? restarted.join(", ") : none);
6303
+ }
6304
+ else if (detail === "cancelled") {
6305
+ text = t("login.cancelled", backend);
6306
+ }
6307
+ else {
6308
+ text = t("login.failed", backend, detail);
6309
+ }
6310
+ await chat.adapter.sendText(chat.chatId, text, { threadId: chat.threadId }).catch(() => { });
6311
+ },
6312
+ }, this.logger);
6313
+ // Claim the slot before the first await so two admins racing /login cannot
6314
+ // both create windows; release on startup failure.
6315
+ this.activeLogin = { session, backend, chat };
6316
+ try {
6317
+ await session.start();
6318
+ }
6319
+ catch (err) {
6320
+ this.activeLogin = null;
6321
+ return t("login.failed", backend, err.message);
6322
+ }
6323
+ return t("login.started", backend);
6324
+ }
6325
+ /** `/login code <text>` — paste admin-supplied text into the login window. */
6326
+ async loginSubmitInput(text) {
6327
+ if (!this.activeLogin)
6328
+ return t("login.no_session");
6329
+ const ok = await this.activeLogin.session.submitInput(text);
6330
+ return ok ? t("login.input_sent") : t("login.input_failed");
6331
+ }
6332
+ /** `/login cancel` — abort the active session and remove its window. */
6333
+ async cancelLoginSession() {
6334
+ if (!this.activeLogin)
6335
+ return t("login.no_session");
6336
+ const backend = this.activeLogin.backend;
6337
+ await this.activeLogin.session.cancel();
6338
+ return t("login.cancelled", backend);
6339
+ }
6340
+ /**
6341
+ * The URL (+ code) is a live credential: whoever completes it binds THEIR
6342
+ * account to this fleet's CLI. Telegram gets an HTML spoiler (same treatment
6343
+ * as the dashboard token); other adapters get plain text with the warning.
6344
+ */
6345
+ async sendLoginSecret(chat, backend, url, code) {
6346
+ const codeLine = code ? `\n${t("login.auth_code", code)}` : "";
6347
+ try {
6348
+ if (chat.adapter.type === "telegram") {
6349
+ const esc = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
6350
+ await chat.adapter.sendText(chat.chatId, `${esc(t("login.auth_hint", backend))}\n<tg-spoiler>${esc(url)}${esc(codeLine)}</tg-spoiler>`, { threadId: chat.threadId, format: "html" });
6351
+ }
6352
+ else {
6353
+ await chat.adapter.sendText(chat.chatId, `${t("login.auth_hint", backend)}\n${url}${codeLine}`, { threadId: chat.threadId });
6354
+ }
6355
+ }
6356
+ catch (err) {
6357
+ this.logger.warn({ err: err.message, backend }, "Failed to deliver login URL");
6358
+ }
6359
+ }
6360
+ /**
6361
+ * After a successful login: wake the paused instances of that backend AND
6362
+ * restart the running ones — a live CLI holds the old token in memory and
6363
+ * only re-reads credentials on process start (a paused instance's CLI is
6364
+ * already dead, so waking it respawns with the new token for free).
6365
+ */
6366
+ async recoverBackendInstances(backend) {
6367
+ const woken = [];
6368
+ const restarted = [];
6369
+ for (const [name, config] of Object.entries(this.fleetConfig?.instances ?? {})) {
6370
+ const effective = config.backend ?? this.fleetConfig?.defaults?.backend ?? "claude-code";
6371
+ if (effective !== backend)
6372
+ continue;
6373
+ const status = this.getInstanceStatus(name);
6374
+ try {
6375
+ if (status === "paused") {
6376
+ if (this.daemons.has(name))
6377
+ await this.lifecycle.wake(name, 30_000);
6378
+ else
6379
+ await this.startPersistedPausedInstance(name);
6380
+ woken.push(name);
6381
+ }
6382
+ else if (status === "running") {
6383
+ await this.restartSingleInstance(name);
6384
+ restarted.push(name);
6385
+ }
6386
+ }
6387
+ catch (err) {
6388
+ this.logger.warn({ err: err.message, name, status }, "Post-login recovery failed");
6389
+ }
6390
+ }
6391
+ return { woken, restarted };
6392
+ }
6393
+ /** Backend chooser button → start that backend's login session. */
6394
+ async handleLoginBackendSelect(data, callbackAdapterId, receivingAdapter) {
6395
+ const claimed = this.consumeNonceCallback(LOGIN_CALLBACK_PREFIX, /^login:([0-9a-f]+):([a-z][a-z-]*)$/, data, callbackAdapterId, receivingAdapter);
6396
+ if (claimed === null)
6397
+ return false;
6398
+ if (claimed === "consumed")
6399
+ return true;
6400
+ const { entry, action: backend } = claimed;
6401
+ await this.retireNonceButtons(entry, entry.messageId ?? data.messageId, t("login.starting_backend", backend));
6402
+ const text = await this.startLoginSession(backend, {
6403
+ adapter: entry.adapter,
6404
+ adapterId: entry.adapterId,
6405
+ chatId: entry.chatId,
6406
+ threadId: entry.threadId,
6407
+ });
6408
+ if (text)
6409
+ await entry.adapter.sendText(entry.chatId, text, { threadId: entry.threadId }).catch(() => { });
6410
+ return true;
6411
+ }
6412
+ /** Re-login confirmation (auth pre-check said credentials still work). */
6413
+ async handleLoginConfirm(data, callbackAdapterId, receivingAdapter) {
6414
+ const claimed = this.consumeNonceCallback(LOGIN_CONFIRM_CALLBACK_PREFIX, /^login-confirm:([0-9a-f]+):(go|cancel)$/, data, callbackAdapterId, receivingAdapter);
6415
+ if (claimed === null)
6416
+ return false;
6417
+ if (claimed === "consumed")
6418
+ return true;
6419
+ const { entry, action } = claimed;
6420
+ const backend = entry.instanceName;
6421
+ if (action === "cancel") {
6422
+ await this.retireNonceButtons(entry, entry.messageId ?? data.messageId, t("login.cancelled", backend));
6423
+ return true;
6424
+ }
6425
+ await this.retireNonceButtons(entry, entry.messageId ?? data.messageId, t("login.starting_backend", backend));
6426
+ const text = await this.startLoginSession(backend, {
6427
+ adapter: entry.adapter,
6428
+ adapterId: entry.adapterId,
6429
+ chatId: entry.chatId,
6430
+ threadId: entry.threadId,
6431
+ }, { skipAuthCheck: true });
6432
+ if (text)
6433
+ await entry.adapter.sendText(entry.chatId, text, { threadId: entry.threadId }).catch(() => { });
6434
+ return true;
6435
+ }
6436
+ /** Kiro provider button → drive the CLI's arrow-key selector. */
6437
+ async handleLoginMenuSelect(data, callbackAdapterId, receivingAdapter) {
6438
+ const claimed = this.consumeNonceCallback(LOGIN_MENU_CALLBACK_PREFIX, /^login-menu:([0-9a-f]+):(\d)$/, data, callbackAdapterId, receivingAdapter);
6439
+ if (claimed === null)
6440
+ return false;
6441
+ if (claimed === "consumed")
6442
+ return true;
6443
+ const { entry, action } = claimed;
6444
+ const index = Number(action);
6445
+ const label = this.activeLogin?.session.flow.menu?.options[index] ?? action;
6446
+ const ok = await this.activeLogin?.session.selectMenuOption(index) ?? false;
6447
+ await this.retireNonceButtons(entry, entry.messageId ?? data.messageId, ok ? t("login.provider_selected", label) : t("login.no_session"));
6448
+ return true;
6449
+ }
6178
6450
  queueMirrorMessage(text) {
6179
6451
  const mirrorTopicId = this.fleetConfig?.channel?.mirror_topic_id;
6180
6452
  if (mirrorTopicId == null || !this.adapter)