@neriros/ralphy 2.13.6 โ†’ 2.13.8

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.
Files changed (3) hide show
  1. package/README.md +34 -1
  2. package/dist/cli/index.js +106 -132
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -82,12 +82,15 @@ ralph status --name fix-auth # Detailed view of one task
82
82
  ```bash
83
83
  export LINEAR_API_KEY=lin_api_xxx
84
84
  ralph agent --linear-team ENG --linear-assignee me --concurrency 3 --poll-interval 60
85
+
86
+ # Limit the number of tickets processed in this run
87
+ ralph agent --max-tickets 5 --linear-team ENG --linear-assignee me
85
88
  ```
86
89
 
87
90
  What it does on each tick:
88
91
 
89
92
  1. Polls Linear for open issues matching the filter (team / assignee / status / labels)
90
- 2. Dedupes against `.ralph/agent-state.json` (already processed) plus any in-flight workers
93
+ 2. Dedupes against in-flight workers and any already-active issues
91
94
  3. For each new issue: fetches existing comments, scaffolds `openspec/changes/<id-slug>/{proposal.md,tasks.md,design.md}` (with the comments embedded so the worker sees prior discussion), then spawns `ralph task --name <id-slug>` up to the concurrency cap
92
95
  4. Posts a "๐Ÿค– started" comment on the Linear issue and applies the `setInProgress` indicator (if configured)
93
96
  5. On worker exit, posts a success/failure comment and applies the `setDone` indicator on success or `setError` on failure (if configured)
@@ -196,11 +199,41 @@ Failed workers (non-zero exit) are not marked processed, so they'll be retried o
196
199
  | `--linear-assignee <id>` | Filter by assignee (user id, email, or `me`) |
197
200
  | `--poll-interval <s>` | Seconds between Linear polls (default: 60) |
198
201
  | `--concurrency <n>` | Max concurrent task loops (default: 1) |
202
+ | `--max-tickets <n>` | Stop picking up new issues after N have been started this run (0 = unlimited) |
199
203
  | `--worktree` | Run each task in its own git worktree |
200
204
  | `--indicator <k>:<t>:<v>` | Override a `linear.indicators` entry; repeatable (e.g. `setDone:status:Done`) |
201
205
  | `--create-pr` | Push worker branch + open a GitHub PR on success (needs `--worktree`) |
202
206
  | `--fix-ci` | After PR opens, re-run task on CI failures until green (needs `--create-pr`) |
203
207
 
208
+ #### `--max-tickets`
209
+
210
+ Use `--max-tickets N` to cap how many issues ralph picks up in a single agent run. Once N issues have been started (across fresh, resume, and conflict-fix modes), the coordinator stops enqueuing new work. In-flight workers continue to completion. The limit resets each time you restart `ralph agent`.
211
+
212
+ ```bash
213
+ # Process at most 3 issues this session, then idle
214
+ ralph agent --max-tickets 3 --linear-team ENG
215
+ ```
216
+
217
+ When the limit is reached, ralph logs a yellow notice and the dashboard header shows `โ”‚ tickets โ‰คN`. Polling continues (to handle conflict re-fixes on already-started issues), but no new issues are queued.
218
+
219
+ #### Dashboard
220
+
221
+ The `ralph agent` terminal dashboard shows a full-terminal layout with three always-visible panels:
222
+
223
+ - **RALPH AGENT** (blue box): engine/model, concurrency, poll interval, active limits (`iter โ‰คN`, `cost โ‰ค$N`, `tickets โ‰คN`), feature flags (โ— PR โ— fixCI โ— worktree), and the Linear filter on the second line
224
+ - **POLL STATUS + WORKERS** (side-by-side): last-poll counts and next-poll countdown; active/queued worker totals with colored counts
225
+ - **TASKS tab bar** (when multiple workers run): numbered worker tabs with priority glyph and phase โ€” Tab/โ† โ†’ to switch, 1-9 to jump
226
+
227
+ Each worker card shows:
228
+
229
+ - Priority badge (`โ–ฒ URGENT` / `โ†‘ HIGH` / `ยท MED` / `โ†“ LOW`) + issue identifier + title + mode badge (`[NEW]` / `[RESUME]` / `[FIX]`)
230
+ - `โ†— LINEAR ISSUE-ID` and `โ†— PR #N` (short labels, not full URLs)
231
+ - `โ–ถ TASK` โ€” first unchecked task from `tasks.md`, updated every second
232
+ - `PHASE` with color (cyan = working, yellow = git ops, blue = CI, green = done, red = gave-up) + time in phase
233
+ - `โต CMD` when a shell command is in flight (shows the command and how long it's been running)
234
+ - `LOG` โ€” path to the worker's log file for `tail -f`
235
+ - `โ”€ OUTPUT โ”€` section with live stdout/stderr (scales to fill remaining terminal height for the focused worker)
236
+
204
237
  ## OpenSpec Flow
205
238
 
206
239
  There are no phases. One loop, one prompt, one `tasks.md` checklist.
package/dist/cli/index.js CHANGED
@@ -56409,7 +56409,7 @@ function log(msg) {
56409
56409
  // package.json
56410
56410
  var package_default = {
56411
56411
  name: "@neriros/ralphy",
56412
- version: "2.13.6",
56412
+ version: "2.13.8",
56413
56413
  description: "An iterative AI task execution framework. Orchestrates multi-phase autonomous work using Claude or Codex engines.",
56414
56414
  keywords: [
56415
56415
  "agent",
@@ -56559,6 +56559,7 @@ var HELP_TEXT = [
56559
56559
  " Types: label, status",
56560
56560
  " --create-pr Push the worker branch and open a GitHub PR on success (needs --worktree)",
56561
56561
  " --fix-ci After opening the PR, re-run on CI failures until green (needs --create-pr)",
56562
+ " --max-tickets <n> Stop picking up new issues after N have been started (0 = unlimited)",
56562
56563
  "",
56563
56564
  " --help, -h Show this help message",
56564
56565
  "",
@@ -56643,7 +56644,8 @@ async function parseArgs(argv) {
56643
56644
  worktree: false,
56644
56645
  indicators: {},
56645
56646
  createPr: false,
56646
- fixCi: false
56647
+ fixCi: false,
56648
+ maxTickets: 0
56647
56649
  };
56648
56650
  let expectModel = false;
56649
56651
  let expectModelFlag = false;
@@ -56659,6 +56661,7 @@ async function parseArgs(argv) {
56659
56661
  let expectLinearAssignee = false;
56660
56662
  let expectPollInterval = false;
56661
56663
  let expectConcurrency = false;
56664
+ let expectMaxTickets = false;
56662
56665
  let expectIndicator = false;
56663
56666
  for (const arg of argv) {
56664
56667
  if (expectModel) {
@@ -56737,6 +56740,11 @@ async function parseArgs(argv) {
56737
56740
  expectConcurrency = false;
56738
56741
  continue;
56739
56742
  }
56743
+ if (expectMaxTickets) {
56744
+ result2.maxTickets = parseInt(arg, 10);
56745
+ expectMaxTickets = false;
56746
+ continue;
56747
+ }
56740
56748
  if (expectIndicator) {
56741
56749
  const { key, marker } = parseIndicatorArg(arg);
56742
56750
  mergeIndicator(result2.indicators, key, marker);
@@ -56807,6 +56815,9 @@ async function parseArgs(argv) {
56807
56815
  case "--concurrency":
56808
56816
  expectConcurrency = true;
56809
56817
  break;
56818
+ case "--max-tickets":
56819
+ expectMaxTickets = true;
56820
+ break;
56810
56821
  case "--worktree":
56811
56822
  result2.worktree = true;
56812
56823
  break;
@@ -70562,6 +70573,7 @@ class AgentCoordinator {
70562
70573
  queue = [];
70563
70574
  stopped = false;
70564
70575
  conflictNotified = new Set;
70576
+ ticketsStarted = 0;
70565
70577
  constructor(deps, opts) {
70566
70578
  this.deps = deps;
70567
70579
  this.opts = opts;
@@ -70575,6 +70587,9 @@ class AgentCoordinator {
70575
70587
  get activeWorkers() {
70576
70588
  return this.workers;
70577
70589
  }
70590
+ get ticketsStartedCount() {
70591
+ return this.ticketsStarted;
70592
+ }
70578
70593
  async init() {}
70579
70594
  async pollOnce() {
70580
70595
  if (this.stopped)
@@ -70596,8 +70611,17 @@ class AgentCoordinator {
70596
70611
  const queuedIds = new Set(this.queue.map((q) => q.issue.id));
70597
70612
  const activeIds = new Set(this.workers.map((w) => w.issueId));
70598
70613
  const eligible = (id) => !queuedIds.has(id) && !activeIds.has(id) && !this.pendingIds.has(id);
70614
+ const maxT = this.opts.maxTickets ?? 0;
70615
+ const atTicketLimit = () => {
70616
+ if (maxT === 0)
70617
+ return false;
70618
+ const inFlight = this.ticketsStarted + this.queue.length + this.workers.length + this.pendingIds.size;
70619
+ return inFlight >= maxT;
70620
+ };
70599
70621
  let added = 0;
70600
70622
  for (const issue of inProgress) {
70623
+ if (atTicketLimit())
70624
+ break;
70601
70625
  if (!eligible(issue.id))
70602
70626
  continue;
70603
70627
  if (!this.dependenciesResolved(issue))
@@ -70607,6 +70631,8 @@ class AgentCoordinator {
70607
70631
  added += 1;
70608
70632
  }
70609
70633
  for (const issue of conflicted) {
70634
+ if (atTicketLimit())
70635
+ break;
70610
70636
  if (!eligible(issue.id))
70611
70637
  continue;
70612
70638
  this.queue.push({ issue, mode: "conflict-fix" });
@@ -70614,6 +70640,8 @@ class AgentCoordinator {
70614
70640
  added += 1;
70615
70641
  }
70616
70642
  for (const issue of todo) {
70643
+ if (atTicketLimit())
70644
+ break;
70617
70645
  if (!eligible(issue.id))
70618
70646
  continue;
70619
70647
  if (!this.dependenciesResolved(issue))
@@ -70808,6 +70836,11 @@ class AgentCoordinator {
70808
70836
  };
70809
70837
  this.workers.push(worker);
70810
70838
  this.pendingIds.delete(issue.id);
70839
+ this.ticketsStarted += 1;
70840
+ const maxT = this.opts.maxTickets ?? 0;
70841
+ if (maxT > 0 && this.ticketsStarted >= maxT) {
70842
+ this.deps.onLog(` ticket limit reached (${maxT}) \u2014 no new issues will be picked up`, "yellow");
70843
+ }
70811
70844
  capture("agent_worker_spawned", {
70812
70845
  spawn_mode: mode,
70813
70846
  issue_identifier: issue.identifier
@@ -72054,7 +72087,8 @@ PR: ${prUrl}` : ""
72054
72087
  ...indicators.setConflicted !== undefined ? { setConflicted: indicators.setConflicted } : {},
72055
72088
  ...indicators.clearConflicted !== undefined ? { clearConflicted: indicators.clearConflicted } : {},
72056
72089
  postComments: cfg.linear.postComments,
72057
- commentEveryIterations: cfg.linear.updateEveryIterations
72090
+ commentEveryIterations: cfg.linear.updateEveryIterations,
72091
+ ...args.maxTickets > 0 ? { maxTickets: args.maxTickets } : {}
72058
72092
  });
72059
72093
  const filterDesc = describeIndicators(indicators, team, assignee);
72060
72094
  return {
@@ -72109,6 +72143,26 @@ function fmtElapsed(ms) {
72109
72143
  function trunc(s, max2) {
72110
72144
  return s.length > max2 ? s.slice(0, max2 - 1) + "\u2026" : s;
72111
72145
  }
72146
+ function prLabel(prUrl) {
72147
+ const m = prUrl.match(/\/pull\/(\d+)/);
72148
+ return m ? `#${m[1]}` : "PR";
72149
+ }
72150
+ var ANSI_STRIP_RE = /\x1b(?:\[[0-9;]*[A-Za-z]|\][^\x07\x1b]*(?:\x07|\x1b\\)|.)/g;
72151
+ var BOX_ONLY_RE = /^[\s\u2500\u2502\u256D\u256E\u2570\u256F\u254C\u2504\u2501\u2503]+$/;
72152
+ var STATUS_BAR_LINE_RE = /^[\u280B\u2819\u2839\u2838\u283C\u2834\u2826\u2827\u2807\u280F\u2713\u2717]\s+iter\s+\d+/;
72153
+ var ITER_HEADER_LINE_RE = /^\u2500\u2500/;
72154
+ function cleanOutputLine(raw) {
72155
+ const clean = raw.replace(ANSI_STRIP_RE, "").trim();
72156
+ if (!clean)
72157
+ return null;
72158
+ if (BOX_ONLY_RE.test(clean))
72159
+ return null;
72160
+ if (STATUS_BAR_LINE_RE.test(clean))
72161
+ return null;
72162
+ if (ITER_HEADER_LINE_RE.test(clean))
72163
+ return null;
72164
+ return clean;
72165
+ }
72112
72166
  function priorityBadge(p) {
72113
72167
  switch (p) {
72114
72168
  case 1:
@@ -72194,14 +72248,6 @@ function displayTailLines(activeCount) {
72194
72248
  return 8;
72195
72249
  return 5;
72196
72250
  }
72197
- function parseFilterParts(filterDesc) {
72198
- return filterDesc.split(", ").map((part) => {
72199
- const eq = part.indexOf("=");
72200
- if (eq < 0)
72201
- return { key: part, val: "" };
72202
- return { key: part.slice(0, eq), val: part.slice(eq + 1) };
72203
- });
72204
- }
72205
72251
  function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
72206
72252
  const { exit } = use_app_default();
72207
72253
  const { stdout } = use_stdout_default();
@@ -72273,7 +72319,10 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
72273
72319
  const m = workerMetaRef.current.get(changeName);
72274
72320
  if (!m)
72275
72321
  return;
72276
- m.tail.push(line);
72322
+ const clean = cleanOutputLine(line);
72323
+ if (!clean)
72324
+ return;
72325
+ m.tail.push(clean);
72277
72326
  if (m.tail.length > TAIL_BUFFER_SIZE)
72278
72327
  m.tail.splice(0, m.tail.length - TAIL_BUFFER_SIZE);
72279
72328
  },
@@ -72379,7 +72428,6 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
72379
72428
  const activeCount = coord?.activeCount ?? 0;
72380
72429
  const termWidth = (stdout?.columns ?? 100) - 2;
72381
72430
  const termHeight = stdout?.rows ?? 40;
72382
- const filterParts = pollStatus.filterDesc ? parseFilterParts(pollStatus.filterDesc) : [];
72383
72431
  const safeFocusedIdx = activeCount > 0 ? Math.min(focusedIdx, activeCount - 1) : 0;
72384
72432
  use_input_default((input, key) => {
72385
72433
  if (activeCount === 0)
@@ -72421,14 +72469,16 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
72421
72469
  paddingX: 1,
72422
72470
  width: termWidth,
72423
72471
  children: [
72424
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
72425
- gap: 2,
72472
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72426
72473
  children: [
72427
72474
  /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72428
72475
  bold: true,
72429
72476
  color: "cyan",
72430
- children: "\u25C8 RALPH AGENT"
72431
- }, undefined, false, undefined, this),
72477
+ children: [
72478
+ "\u25C8 RALPH AGENT",
72479
+ " "
72480
+ ]
72481
+ }, undefined, true, undefined, this),
72432
72482
  /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72433
72483
  dimColor: true,
72434
72484
  children: [
@@ -72436,15 +72486,11 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
72436
72486
  VERSION
72437
72487
  ]
72438
72488
  }, undefined, true, undefined, this),
72439
- cfg && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(jsx_dev_runtime9.Fragment, {
72489
+ cfg && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72440
72490
  children: [
72441
72491
  /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72442
72492
  dimColor: true,
72443
- children: "\u2502"
72444
- }, undefined, false, undefined, this),
72445
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72446
- dimColor: true,
72447
- children: "ENGINE"
72493
+ children: " \u2502 "
72448
72494
  }, undefined, false, undefined, this),
72449
72495
  /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72450
72496
  color: "cyan",
@@ -72457,133 +72503,61 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
72457
72503
  }, undefined, true, undefined, this),
72458
72504
  /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72459
72505
  dimColor: true,
72460
- children: "\u2502"
72461
- }, undefined, false, undefined, this),
72462
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72463
- dimColor: true,
72464
- children: "CONCURRENCY"
72465
- }, undefined, false, undefined, this),
72466
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72467
- color: "white",
72468
- bold: true,
72469
- children: cfg.concurrency
72470
- }, undefined, false, undefined, this),
72471
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72472
- dimColor: true,
72473
- children: "\u2502"
72474
- }, undefined, false, undefined, this),
72506
+ children: [
72507
+ " \u2502 \xD7",
72508
+ cfg.concurrency
72509
+ ]
72510
+ }, undefined, true, undefined, this),
72475
72511
  /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72476
72512
  dimColor: true,
72477
- children: "POLL"
72478
- }, undefined, false, undefined, this),
72479
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72480
- color: "white",
72481
72513
  children: [
72514
+ " \u2502 poll ",
72482
72515
  cfg.pollIntervalSeconds,
72483
72516
  "s"
72484
72517
  ]
72485
72518
  }, undefined, true, undefined, this),
72486
- cfg.maxIterationsPerTask > 0 && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(jsx_dev_runtime9.Fragment, {
72519
+ cfg.maxIterationsPerTask > 0 && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72520
+ color: "yellow",
72487
72521
  children: [
72488
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72489
- dimColor: true,
72490
- children: "\u2502"
72491
- }, undefined, false, undefined, this),
72492
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72493
- dimColor: true,
72494
- children: "MAX ITER"
72495
- }, undefined, false, undefined, this),
72496
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72497
- color: "yellow",
72498
- children: cfg.maxIterationsPerTask
72499
- }, undefined, false, undefined, this)
72522
+ " \u2502 iter \u2264",
72523
+ cfg.maxIterationsPerTask
72500
72524
  ]
72501
72525
  }, undefined, true, undefined, this),
72502
- cfg.maxCostUsdPerTask > 0 && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(jsx_dev_runtime9.Fragment, {
72526
+ cfg.maxCostUsdPerTask > 0 && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72527
+ color: "yellow",
72503
72528
  children: [
72504
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72505
- dimColor: true,
72506
- children: "\u2502"
72507
- }, undefined, false, undefined, this),
72508
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72509
- dimColor: true,
72510
- children: "MAX COST"
72511
- }, undefined, false, undefined, this),
72512
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72513
- color: "yellow",
72514
- children: [
72515
- "$",
72516
- cfg.maxCostUsdPerTask
72517
- ]
72518
- }, undefined, true, undefined, this)
72529
+ " \u2502 cost \u2264$",
72530
+ cfg.maxCostUsdPerTask
72519
72531
  ]
72520
72532
  }, undefined, true, undefined, this),
72521
- cfg.maxRuntimeMinutesPerTask > 0 && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(jsx_dev_runtime9.Fragment, {
72533
+ args.maxTickets > 0 && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72534
+ color: "yellow",
72522
72535
  children: [
72523
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72524
- dimColor: true,
72525
- children: "\u2502"
72526
- }, undefined, false, undefined, this),
72527
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72528
- dimColor: true,
72529
- children: "MAX TIME"
72530
- }, undefined, false, undefined, this),
72531
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72532
- color: "yellow",
72533
- children: [
72534
- cfg.maxRuntimeMinutesPerTask,
72535
- "m"
72536
- ]
72537
- }, undefined, true, undefined, this)
72536
+ " \u2502 tickets \u2264",
72537
+ args.maxTickets
72538
72538
  ]
72539
- }, undefined, true, undefined, this)
72539
+ }, undefined, true, undefined, this),
72540
+ cfg.createPrOnSuccess && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72541
+ color: "green",
72542
+ children: " \u25CF PR"
72543
+ }, undefined, false, undefined, this),
72544
+ cfg.fixCiOnFailure && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72545
+ color: "green",
72546
+ children: " \u25CF fixCI"
72547
+ }, undefined, false, undefined, this),
72548
+ cfg.useWorktree && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72549
+ color: "green",
72550
+ children: " \u25CF worktree"
72551
+ }, undefined, false, undefined, this)
72540
72552
  ]
72541
72553
  }, undefined, true, undefined, this)
72542
72554
  ]
72543
72555
  }, undefined, true, undefined, this),
72544
- cfg && (cfg.createPrOnSuccess || cfg.fixCiOnFailure || cfg.useWorktree) && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
72545
- gap: 2,
72546
- marginTop: 0,
72547
- children: [
72548
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72549
- dimColor: true,
72550
- children: "FEATURES"
72551
- }, undefined, false, undefined, this),
72552
- cfg.createPrOnSuccess && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72553
- color: "green",
72554
- children: "\u25CF create-pr"
72555
- }, undefined, false, undefined, this),
72556
- cfg.fixCiOnFailure && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72557
- color: "green",
72558
- children: "\u25CF fix-ci"
72559
- }, undefined, false, undefined, this),
72560
- cfg.useWorktree && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72561
- color: "green",
72562
- children: "\u25CF worktree"
72563
- }, undefined, false, undefined, this)
72564
- ]
72565
- }, undefined, true, undefined, this),
72566
- filterParts.length > 0 && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
72567
- gap: 3,
72568
- marginTop: 0,
72556
+ pollStatus.filterDesc && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72557
+ dimColor: true,
72569
72558
  children: [
72570
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72571
- dimColor: true,
72572
- children: "LINEAR"
72573
- }, undefined, false, undefined, this),
72574
- filterParts.map(({ key, val }) => /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
72575
- gap: 1,
72576
- children: [
72577
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72578
- dimColor: true,
72579
- children: key
72580
- }, undefined, false, undefined, this),
72581
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72582
- color: "magenta",
72583
- children: val
72584
- }, undefined, false, undefined, this)
72585
- ]
72586
- }, key, true, undefined, this))
72559
+ "Linear ",
72560
+ trunc(pollStatus.filterDesc.replace(/, /g, " \xB7 "), termWidth - 12)
72587
72561
  ]
72588
72562
  }, undefined, true, undefined, this)
72589
72563
  ]
@@ -72959,7 +72933,7 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
72959
72933
  }, undefined, false, undefined, this),
72960
72934
  /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72961
72935
  color: "blue",
72962
- children: w.issue.url
72936
+ children: w.issueIdentifier
72963
72937
  }, undefined, false, undefined, this)
72964
72938
  ]
72965
72939
  }, undefined, true, undefined, this),
@@ -72972,7 +72946,7 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
72972
72946
  }, undefined, false, undefined, this),
72973
72947
  /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
72974
72948
  color: "green",
72975
- children: prUrl
72949
+ children: prLabel(prUrl)
72976
72950
  }, undefined, false, undefined, this)
72977
72951
  ]
72978
72952
  }, undefined, true, undefined, this)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neriros/ralphy",
3
- "version": "2.13.6",
3
+ "version": "2.13.8",
4
4
  "description": "An iterative AI task execution framework. Orchestrates multi-phase autonomous work using Claude or Codex engines.",
5
5
  "keywords": [
6
6
  "agent",