@proagentstore/cli 0.4.15 → 0.4.17

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.
@@ -63,16 +63,21 @@ export class HeadlessSession {
63
63
  // that keeps refreshing lastOutputAt). The user can also Restart from diagnostics.
64
64
  // Rule 1 deliberately waits for first output so a slow first token can't flip us
65
65
  // to idle mid-turn (which would make the brain proceed against a half-done turn).
66
+ //
67
+ // This is derived PURELY from timers each call — it does NOT latch `this.run` to
68
+ // "idle". Latching was a one-way trap: once a >1.5s pause (slow compile / test run /
69
+ // network) flipped us idle, resumed output couldn't restore "thinking" (onStdout only
70
+ // bumps lastOutputAt), so the brain proceeded against a still-running turn and
71
+ // double-sent or falsely called done. Recomputing means fresh output → quiet resets →
72
+ // "thinking" again, all on its own.
66
73
  if (this.mode === "raw" && this.run === "thinking") {
67
74
  const now = Date.now();
68
75
  const quiet = now - this.lastOutputAt;
69
76
  const elapsed = now - this.turnStartedAt;
70
- if (this.sawOutputSinceInput && quiet > 1500)
71
- this.run = "idle";
72
- else if (!this.sawOutputSinceInput && elapsed > 8000)
73
- this.run = "idle";
74
- else if (elapsed > 15 * 60 * 1000)
75
- this.run = "idle";
77
+ const settled = (this.sawOutputSinceInput && quiet > 1500) ||
78
+ (!this.sawOutputSinceInput && elapsed > 8000) ||
79
+ elapsed > 15 * 60 * 1000;
80
+ return settled ? "idle" : "thinking";
76
81
  }
77
82
  return this.run === "thinking" ? "thinking" : "idle";
78
83
  }
@@ -1045,6 +1045,13 @@ export class LocalRunner {
1045
1045
  // "running" — report failure so the console can say "session expired, re-run".
1046
1046
  if (!session)
1047
1047
  return { ok: false };
1048
+ // Reject an empty value: browserHandoffStatus reports needs_input as solved only when
1049
+ // inputValue is a real string, so accepting "" would flip the task to "running" yet
1050
+ // never resolve → the workflow polls until it times out (15-min wedge, "failed").
1051
+ // Report failure so the caller (API/MCP) learns it wasn't accepted, like the
1052
+ // no-session branch. (The console already blocks empty; this closes the API path.)
1053
+ if (!value || !value.trim())
1054
+ return { ok: false };
1048
1055
  session.inputValue = value;
1049
1056
  const task = this.store.getTask(taskId);
1050
1057
  if (task) {
package/dist/index.js CHANGED
@@ -854,6 +854,10 @@ function openRelaySocket(instanceId, wsBase, mintToken, localUrl, runnerToken, f
854
854
  relayToken = await mintToken();
855
855
  } catch (e) {
856
856
  const msg = e instanceof Error ? e.message : String(e);
857
+ if (/^402\b/.test(msg)) {
858
+ writeLine(`Runner unavailable for ${instanceId.slice(0, 8)}\u2026: ${msg.replace(/^402\s*/, "")}`);
859
+ return;
860
+ }
857
861
  const hint = /401|token|sign/i.test(msg) ? " (run `pags login`)" : "";
858
862
  writeLine(`Relay token mint failed: ${instanceId.slice(0, 8)}\u2026${hint} \u2014 retrying in ${Math.round(backoffMs / 1e3)}s`);
859
863
  setTimeout(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proagentstore/cli",
3
- "version": "0.4.15",
3
+ "version": "0.4.17",
4
4
  "description": "CLI for creating, publishing, and running ProAgentStore agents",
5
5
  "license": "MIT",
6
6
  "type": "module",