neuvikon 0.2.19 → 0.2.20

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/README.md CHANGED
@@ -57,7 +57,9 @@ npx neuvikon start --tickets EWWQ-1,EWWQ-2,EWWQ-3 --spawn
57
57
 
58
58
  If [Herdr](https://herdr.dev) is installed, every ticket in the batch lands as
59
59
  its own tab in one Herdr workspace instead of separate OS windows — Herdr's
60
- own UI then shows each agent's live working/blocked/done state. Otherwise it
60
+ own UI then shows each agent's live working/blocked/done state. Run it from
61
+ inside a Herdr-managed pane and the batch adds its tabs to that same
62
+ workspace instead of opening a new one. Otherwise it
61
63
  opens one terminal per ticket the usual way (a tmux window if you're already
62
64
  in tmux, an iTerm2 or Terminal.app tab on macOS, a Windows Terminal tab on
63
65
  Windows), each `cd`'d into this directory. Either way, if a coding agent CLI
package/dist/index.mjs CHANGED
@@ -1303,9 +1303,14 @@ function agentName(ref) {
1303
1303
  * working/blocked/done state per agent — instead of scattered across OS
1304
1304
  * windows. The first successful ref seeds the workspace; every later ref in
1305
1305
  * the same batch adds a tab to it.
1306
+ *
1307
+ * Except when `--spawn` is itself run from inside a Herdr-managed pane
1308
+ * (`HERDR_WORKSPACE_ID` set, per Herdr's own caller-context injection): then
1309
+ * the batch reuses that workspace instead of creating a new one that yanks
1310
+ * focus away from wherever the user already was.
1306
1311
  */
1307
1312
  var HerdrBatch = class {
1308
- workspaceId = null;
1313
+ workspaceId = process.env.HERDR_WORKSPACE_ID || null;
1309
1314
  openPane(ref, cwd) {
1310
1315
  if (!this.workspaceId) {
1311
1316
  const created = runHerdr([
@@ -1334,15 +1339,16 @@ var HerdrBatch = class {
1334
1339
  ])?.result.root_pane.pane_id ?? null;
1335
1340
  }
1336
1341
  /**
1337
- * True once this ref has a live Herdr pane — even if starting an agent in
1338
- * it failed, in which case the pane still exists with the same
1339
- * print-and-wait fallback a plain spawned terminal gets. False only means
1340
- * Herdr itself couldn't be reached, and the caller should fall back to
1341
- * opening a native OS terminal for this ref instead.
1342
+ * "agent" — a coding agent is live in its own Herdr pane with the ticket
1343
+ * text confirmed delivered as its first prompt. "manual" — the pane exists
1344
+ * (either as a plain shell with the ticket echoed, or a started agent whose
1345
+ * prompt delivery couldn't be confirmed) but the user has to paste or type
1346
+ * into it themselves. `null` only means Herdr itself couldn't be reached,
1347
+ * and the caller should fall back to opening a native OS terminal instead.
1342
1348
  */
1343
1349
  spawn(ref, cwd, agent, ticketText) {
1344
1350
  const paneId = this.openPane(ref, cwd);
1345
- if (!paneId) return false;
1351
+ if (!paneId) return null;
1346
1352
  if (agent && ticketText) {
1347
1353
  if (runHerdr([
1348
1354
  "agent",
@@ -1352,15 +1358,17 @@ var HerdrBatch = class {
1352
1358
  HERDR_KIND[agent.id],
1353
1359
  "--pane",
1354
1360
  paneId
1355
- ])) {
1356
- runHerdr([
1357
- "agent",
1358
- "prompt",
1359
- agentName(ref),
1360
- ticketText
1361
- ]);
1362
- return true;
1363
- }
1361
+ ])) return runHerdr([
1362
+ "agent",
1363
+ "prompt",
1364
+ agentName(ref),
1365
+ ticketText,
1366
+ "--wait",
1367
+ "--until",
1368
+ "working",
1369
+ "--timeout",
1370
+ "8000"
1371
+ ]) ? "agent" : "manual";
1364
1372
  }
1365
1373
  runHerdr([
1366
1374
  "pane",
@@ -1368,7 +1376,7 @@ var HerdrBatch = class {
1368
1376
  paneId,
1369
1377
  `echo 'Ticket: ${ref}' && echo 'Paste it into your agent, or run: npx neuvikon start --ticket ${ref}'`
1370
1378
  ]);
1371
- return true;
1379
+ return "manual";
1372
1380
  }
1373
1381
  };
1374
1382
  //#endregion
@@ -1549,8 +1557,13 @@ async function spawnMode(flags, credentials, refs) {
1549
1557
  info(`Opening ${refs.length} terminal${refs.length === 1 ? "" : "s"}${herdr ? " in Herdr" : ` in ${cwd}`}...`);
1550
1558
  for (const ref of refs) {
1551
1559
  const ticketText = agent ? await fetchTicketText(credentials, ref) : null;
1552
- if (herdr?.spawn(ref, cwd, agent, ticketText)) {
1553
- success(`${bold(ref)} — ${agent && ticketText ? `${agent.label} starting in Herdr` : "opened in Herdr"}`);
1560
+ const herdrOutcome = herdr?.spawn(ref, cwd, agent, ticketText);
1561
+ if (herdrOutcome === "agent") {
1562
+ success(`${bold(ref)} — ${agent.label} starting in Herdr`);
1563
+ continue;
1564
+ }
1565
+ if (herdrOutcome === "manual") {
1566
+ info(`${bold(ref)} — opened in Herdr, paste the ticket manually: ${dim(`npx neuvikon start --ticket ${ref}`)}`);
1554
1567
  continue;
1555
1568
  }
1556
1569
  const launch = agent && ticketText ? {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neuvikon",
3
- "version": "0.2.19",
3
+ "version": "0.2.20",
4
4
  "description": "Tell Neuvikon which ticket your coding agent is working on.",
5
5
  "keywords": [
6
6
  "neuvikon",