agent-dag 1.33.48 → 1.33.49

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.
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
6
  <title>agents-deck</title>
7
7
  <link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ctext y='84' font-size='84'%3E%E2%97%89%3C/text%3E%3C/svg%3E" />
8
- <script type="module" crossorigin src="/assets/index-Be_fgBgZ.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-DXPYK_Sr.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="/assets/index-CF2yG9oG.css">
10
10
  </head>
11
11
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-dag",
3
- "version": "1.33.48",
3
+ "version": "1.33.49",
4
4
  "description": "Live deck of Claude Code and Codex agents — watch parallel subagents fork, call tools, and return on one calm canvas. Also available as npx ccdeck and npx agent-dag.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -158,7 +158,27 @@ export function extractLoginUrl(text) {
158
158
 
159
159
  // The prompt the CLI blocks on. Matched rather than assumed: writing a code
160
160
  // into a child that is not asking for one would send it somewhere unknown.
161
- const CODE_PROMPT = /paste code here/i;
161
+ const CODE_PROMPT = /paste code here/gi;
162
+
163
+ /**
164
+ * How many times one line of output asks for the code.
165
+ *
166
+ * Per LINE, not per delivery. The prompt ends without a newline, so exec.mjs
167
+ * re-offers the same unterminated line on every chunk as it grows — and both
168
+ * streams share that buffer, so a progress dot, a `\r` spinner frame on stderr,
169
+ * or simply the prompt split across two writes all arrive as the ask again,
170
+ * a few characters longer. Counting an ask whenever the text merely CHANGED, as
171
+ * this used to, turned any of those into a phantom second prompt, and a second
172
+ * prompt is exactly how submitLoginCode hears "that code was rejected": a
173
+ * login the CLI was busy completing came back as `code_rejected`, with the
174
+ * account unregistered and the live credentials left switched.
175
+ *
176
+ * A real re-ask writes the prompt again — on a fresh line, or after a `\r`
177
+ * redraw of this one — so it shows up as another match, not as a longer tail.
178
+ */
179
+ export function countCodePrompts(line) {
180
+ return (stripTerminalEscapes(line).match(CODE_PROMPT) ?? []).length;
181
+ }
162
182
 
163
183
  /**
164
184
  * The whole login, as one object, because the browser talks to it twice: once
@@ -219,23 +239,27 @@ export async function startLogin({ email } = {}) {
219
239
  // exit, it just asks again, so waiting for exit would hang for the whole
220
240
  // five-minute window on a typo.
221
241
  prompts: 0,
222
- lastPromptText: "",
223
242
  };
224
243
  const flow = _login;
225
244
 
226
- child.onLine((line) => {
245
+ // How many asks the line currently being written has already contributed.
246
+ // The prompt is an unterminated line, re-delivered as it grows, so the same
247
+ // ask arrives over and over — and once more, whole, when something else
248
+ // finally ends the line.
249
+ let countedOnLine = 0;
250
+
251
+ child.onLine((line, partial) => {
227
252
  if (!flow.url) {
228
253
  const url = extractLoginUrl(line);
229
254
  if (url) { flow.url = url; flow.state = "awaiting_code"; }
230
255
  }
231
- // The prompt is an unterminated line, re-delivered as it grows, so the
232
- // same ask must not count twice.
233
- const clean = stripTerminalEscapes(line);
234
- if (CODE_PROMPT.test(clean)) {
235
- if (clean !== flow.lastPromptText) { flow.prompts += 1; flow.lastPromptText = clean; }
236
- } else if (clean.trim()) {
237
- flow.lastPromptText = "";
256
+ const asks = countCodePrompts(line);
257
+ if (asks > countedOnLine) {
258
+ flow.prompts += asks - countedOnLine;
259
+ countedOnLine = asks;
238
260
  }
261
+ // A newline ended that line; whatever comes next is a new one.
262
+ if (!partial) countedOnLine = 0;
239
263
  });
240
264
  // The child dying before the code was accepted is a failure of the login, not
241
265
  // of the deck; say so rather than leaving the dialog spinning.