@useorgx/openclaw-plugin 0.7.3 → 0.7.4

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 (110) hide show
  1. package/dashboard/dist/assets/{CgaottFX.js → B1mDqDdy.js} +1 -1
  2. package/dashboard/dist/assets/B1mDqDdy.js.br +0 -0
  3. package/dashboard/dist/assets/B1mDqDdy.js.gz +0 -0
  4. package/dashboard/dist/assets/BDMstdfu.js +1 -0
  5. package/dashboard/dist/assets/BDMstdfu.js.br +0 -0
  6. package/dashboard/dist/assets/BDMstdfu.js.gz +0 -0
  7. package/dashboard/dist/assets/BTAEErUY.js +1 -0
  8. package/dashboard/dist/assets/BTAEErUY.js.br +0 -0
  9. package/dashboard/dist/assets/BTAEErUY.js.gz +0 -0
  10. package/dashboard/dist/assets/{8dksYiq4.js → BXapfumA.js} +1 -1
  11. package/dashboard/dist/assets/BXapfumA.js.br +0 -0
  12. package/dashboard/dist/assets/BXapfumA.js.gz +0 -0
  13. package/dashboard/dist/assets/BZZKPNDb.css +1 -0
  14. package/dashboard/dist/assets/BZZKPNDb.css.br +0 -0
  15. package/dashboard/dist/assets/BZZKPNDb.css.gz +0 -0
  16. package/dashboard/dist/assets/{rttbDbEx.js → BdusVDcP.js} +1 -1
  17. package/dashboard/dist/assets/BdusVDcP.js.br +0 -0
  18. package/dashboard/dist/assets/BdusVDcP.js.gz +0 -0
  19. package/dashboard/dist/assets/{D8JNX8kq.js → BwkNYH6r.js} +1 -1
  20. package/dashboard/dist/assets/BwkNYH6r.js.br +0 -0
  21. package/dashboard/dist/assets/BwkNYH6r.js.gz +0 -0
  22. package/dashboard/dist/assets/{CzCxAZlW.js → CRhvoVeH.js} +1 -1
  23. package/dashboard/dist/assets/CRhvoVeH.js.br +0 -0
  24. package/dashboard/dist/assets/CRhvoVeH.js.gz +0 -0
  25. package/dashboard/dist/assets/{B6wPWJ35.js → CYchPSem.js} +1 -1
  26. package/dashboard/dist/assets/CYchPSem.js.br +0 -0
  27. package/dashboard/dist/assets/CYchPSem.js.gz +0 -0
  28. package/dashboard/dist/assets/Cn07669c.js +212 -0
  29. package/dashboard/dist/assets/Cn07669c.js.br +0 -0
  30. package/dashboard/dist/assets/Cn07669c.js.gz +0 -0
  31. package/dashboard/dist/assets/{C8uM3AX8.js → DBG89Wsz.js} +1 -1
  32. package/dashboard/dist/assets/DBG89Wsz.js.br +0 -0
  33. package/dashboard/dist/assets/DBG89Wsz.js.gz +0 -0
  34. package/dashboard/dist/assets/{CZaT3ob_.js → DHoYGJ9i.js} +1 -1
  35. package/dashboard/dist/assets/DHoYGJ9i.js.br +0 -0
  36. package/dashboard/dist/assets/DHoYGJ9i.js.gz +0 -0
  37. package/dashboard/dist/assets/DHtZPEKd.js +1 -0
  38. package/dashboard/dist/assets/DHtZPEKd.js.br +0 -0
  39. package/dashboard/dist/assets/DHtZPEKd.js.gz +0 -0
  40. package/dashboard/dist/assets/{B5zYRHc3.js → DUaqjbT7.js} +1 -1
  41. package/dashboard/dist/assets/DUaqjbT7.js.br +0 -0
  42. package/dashboard/dist/assets/DUaqjbT7.js.gz +0 -0
  43. package/dashboard/dist/assets/{IUexzymk.js → Dlz0Cm_E.js} +1 -1
  44. package/dashboard/dist/assets/Dlz0Cm_E.js.br +0 -0
  45. package/dashboard/dist/assets/Dlz0Cm_E.js.gz +0 -0
  46. package/dashboard/dist/assets/{CC63EwFD.js → E8q3xNGK.js} +1 -1
  47. package/dashboard/dist/assets/E8q3xNGK.js.br +0 -0
  48. package/dashboard/dist/assets/E8q3xNGK.js.gz +0 -0
  49. package/dashboard/dist/assets/VH0fzk6I.js +1 -0
  50. package/dashboard/dist/assets/VH0fzk6I.js.br +0 -0
  51. package/dashboard/dist/assets/VH0fzk6I.js.gz +0 -0
  52. package/dashboard/dist/assets/bxgRC96y.js +1 -0
  53. package/dashboard/dist/assets/bxgRC96y.js.br +0 -0
  54. package/dashboard/dist/assets/bxgRC96y.js.gz +0 -0
  55. package/dashboard/dist/index.html +2 -2
  56. package/dashboard/dist/index.html.br +0 -0
  57. package/dashboard/dist/index.html.gz +0 -0
  58. package/dist/http/helpers/auto-continue-engine.js +29 -11
  59. package/dist/http/helpers/autopilot-slice-utils.js +7 -10
  60. package/dist/http/helpers/openclaw-cli.js +2 -2
  61. package/dist/http/index.js +160 -4
  62. package/dist/http/routes/live-legacy.d.ts +2 -0
  63. package/dist/http/routes/live-legacy.js +97 -0
  64. package/dist/http/routes/mission-control-read.js +106 -63
  65. package/dist/openclaw-settings.js +3 -2
  66. package/dist/sync/outbox-replay.js +17 -8
  67. package/package.json +1 -1
  68. package/dashboard/dist/assets/6mILZQ2a.js +0 -1
  69. package/dashboard/dist/assets/6mILZQ2a.js.br +0 -0
  70. package/dashboard/dist/assets/6mILZQ2a.js.gz +0 -0
  71. package/dashboard/dist/assets/8dksYiq4.js.br +0 -0
  72. package/dashboard/dist/assets/8dksYiq4.js.gz +0 -0
  73. package/dashboard/dist/assets/B5zYRHc3.js.br +0 -0
  74. package/dashboard/dist/assets/B5zYRHc3.js.gz +0 -0
  75. package/dashboard/dist/assets/B6wPWJ35.js.br +0 -0
  76. package/dashboard/dist/assets/B6wPWJ35.js.gz +0 -0
  77. package/dashboard/dist/assets/BWEwjt1W.js +0 -1
  78. package/dashboard/dist/assets/BWEwjt1W.js.br +0 -0
  79. package/dashboard/dist/assets/BWEwjt1W.js.gz +0 -0
  80. package/dashboard/dist/assets/BzRbDCAD.css +0 -1
  81. package/dashboard/dist/assets/BzRbDCAD.css.br +0 -0
  82. package/dashboard/dist/assets/BzRbDCAD.css.gz +0 -0
  83. package/dashboard/dist/assets/C8uM3AX8.js.br +0 -0
  84. package/dashboard/dist/assets/C8uM3AX8.js.gz +0 -0
  85. package/dashboard/dist/assets/C9jy61eu.js +0 -212
  86. package/dashboard/dist/assets/C9jy61eu.js.br +0 -0
  87. package/dashboard/dist/assets/C9jy61eu.js.gz +0 -0
  88. package/dashboard/dist/assets/CC63EwFD.js.br +0 -0
  89. package/dashboard/dist/assets/CC63EwFD.js.gz +0 -0
  90. package/dashboard/dist/assets/CZaT3ob_.js.br +0 -0
  91. package/dashboard/dist/assets/CZaT3ob_.js.gz +0 -0
  92. package/dashboard/dist/assets/CgaottFX.js.br +0 -0
  93. package/dashboard/dist/assets/CgaottFX.js.gz +0 -0
  94. package/dashboard/dist/assets/CzCxAZlW.js.br +0 -0
  95. package/dashboard/dist/assets/CzCxAZlW.js.gz +0 -0
  96. package/dashboard/dist/assets/D3iMTYEj.js +0 -1
  97. package/dashboard/dist/assets/D3iMTYEj.js.br +0 -0
  98. package/dashboard/dist/assets/D3iMTYEj.js.gz +0 -0
  99. package/dashboard/dist/assets/D8JNX8kq.js.br +0 -0
  100. package/dashboard/dist/assets/D8JNX8kq.js.gz +0 -0
  101. package/dashboard/dist/assets/DnA8dpj6.js +0 -1
  102. package/dashboard/dist/assets/DnA8dpj6.js.br +0 -0
  103. package/dashboard/dist/assets/DnA8dpj6.js.gz +0 -0
  104. package/dashboard/dist/assets/IUexzymk.js.br +0 -0
  105. package/dashboard/dist/assets/IUexzymk.js.gz +0 -0
  106. package/dashboard/dist/assets/ic2FaMnh.js +0 -1
  107. package/dashboard/dist/assets/ic2FaMnh.js.br +0 -0
  108. package/dashboard/dist/assets/ic2FaMnh.js.gz +0 -0
  109. package/dashboard/dist/assets/rttbDbEx.js.br +0 -0
  110. package/dashboard/dist/assets/rttbDbEx.js.gz +0 -0
@@ -101,6 +101,64 @@ export function registerLiveLegacyRoutes(router, deps) {
101
101
  router.add("*", "live/filesystem/open", ({ res }) => {
102
102
  deps.sendJson(res, 405, { error: "Use GET /orgx/api/live/filesystem/open?path=..." });
103
103
  }, "Reject unsupported methods for live/filesystem/open");
104
+ router.add("POST", "live/terminal/open", async ({ body, res }) => {
105
+ const payload = body && typeof body === "object" && !Array.isArray(body)
106
+ ? body
107
+ : {};
108
+ const runId = typeof payload.runId === "string" ? payload.runId.trim() : "";
109
+ const rawPath = typeof payload.path === "string" ? payload.path.trim() : "";
110
+ if (!runId && !rawPath) {
111
+ deps.sendJson(res, 400, {
112
+ ok: false,
113
+ error: "runId or path is required",
114
+ });
115
+ return;
116
+ }
117
+ let resolvedPath = "";
118
+ if (rawPath) {
119
+ resolvedPath = deps.resolveFilesystemOpenPath(rawPath);
120
+ }
121
+ else if (runId) {
122
+ const candidates = deps.resolveAutopilotLogCandidates
123
+ ? deps.resolveAutopilotLogCandidates(runId)
124
+ : [];
125
+ resolvedPath =
126
+ candidates.find((candidate) => deps.existsSync(candidate)) ?? "";
127
+ }
128
+ if (!resolvedPath || !deps.existsSync(resolvedPath)) {
129
+ deps.sendJson(res, 404, {
130
+ ok: false,
131
+ error: "Terminal target not found",
132
+ });
133
+ return;
134
+ }
135
+ if (!deps.openPathInTerminal) {
136
+ deps.sendJson(res, 501, {
137
+ ok: false,
138
+ error: "Terminal open is unavailable in this runtime.",
139
+ });
140
+ return;
141
+ }
142
+ try {
143
+ await deps.openPathInTerminal(resolvedPath);
144
+ deps.sendJson(res, 200, {
145
+ ok: true,
146
+ path: resolvedPath,
147
+ });
148
+ }
149
+ catch (err) {
150
+ deps.sendJson(res, 500, {
151
+ ok: false,
152
+ error: deps.safeErrorMessage(err),
153
+ });
154
+ }
155
+ }, "Open run logs in local terminal");
156
+ router.add("*", "live/terminal/open", ({ res }) => {
157
+ deps.sendJson(res, 405, {
158
+ ok: false,
159
+ error: "Use POST /orgx/api/live/terminal/open",
160
+ });
161
+ }, "Reject unsupported methods for live/terminal/open");
104
162
  async function renderLiveStream(query, req, res) {
105
163
  sendDeprecated(res, "/orgx/api/live/stream", "/orgx/api/live/snapshot-v2");
106
164
  void query;
@@ -109,4 +167,43 @@ export function registerLiveLegacyRoutes(router, deps) {
109
167
  }
110
168
  router.add("GET", "live/stream", async ({ query, req, res }) => renderLiveStream(query, req, res), "Proxy live SSE stream");
111
169
  router.add("HEAD", "live/stream", async ({ query, req, res }) => renderLiveStream(query, req, res), "Proxy live SSE stream (HEAD)");
170
+ router.add("POST", "live/terminal/open", async ({ body, res }) => {
171
+ try {
172
+ const payload = (typeof body === "string" ? JSON.parse(body) : body);
173
+ const runId = payload?.runId;
174
+ if (!runId) {
175
+ deps.sendJson(res, 400, { error: "runId is required" });
176
+ return;
177
+ }
178
+ const os = await import("os");
179
+ const cp = await import("child_process");
180
+ const path = await import("path");
181
+ const homedir = os.homedir();
182
+ const logPath = path.join(homedir, ".config", "useorgx", "openclaw-plugin", "autopilot-logs", `${runId}.log`);
183
+ if (!deps.existsSync(logPath)) {
184
+ deps.sendJson(res, 404, { error: `Log file not found: ${logPath}` });
185
+ return;
186
+ }
187
+ const shellPath = logPath.replaceAll("'", "'\\''");
188
+ let command = "";
189
+ if (os.platform() === "darwin") {
190
+ command = `osascript -e 'tell app "Terminal" to do script "tail -f \\"${shellPath}\\""'`;
191
+ }
192
+ else if (os.platform() === "win32") {
193
+ command = `start cmd.exe /k "tail -f \\"${shellPath}\\""`;
194
+ }
195
+ else {
196
+ command = `gnome-terminal -- bash -c "tail -f \\"${shellPath}\\"; exec bash"`;
197
+ }
198
+ cp.exec(command, (error) => {
199
+ if (error) {
200
+ console.error("Failed to open terminal:", error);
201
+ }
202
+ });
203
+ deps.sendJson(res, 200, { success: true });
204
+ }
205
+ catch (err) {
206
+ deps.sendJson(res, 500, { error: deps.safeErrorMessage(err) });
207
+ }
208
+ }, "Open run session in native terminal");
112
209
  }
@@ -11,6 +11,24 @@ function asString(value) {
11
11
  const trimmed = value.trim();
12
12
  return trimmed.length > 0 ? trimmed : null;
13
13
  }
14
+ function asArray(value) {
15
+ if (Array.isArray(value))
16
+ return value;
17
+ if (typeof value !== "string")
18
+ return [];
19
+ const trimmed = value.trim();
20
+ try {
21
+ const parsed = JSON.parse(trimmed);
22
+ if (Array.isArray(parsed))
23
+ return parsed;
24
+ if (parsed && typeof parsed === "object")
25
+ return [parsed];
26
+ return [];
27
+ }
28
+ catch {
29
+ return [];
30
+ }
31
+ }
14
32
  function normalizeRunnerValue(value) {
15
33
  const raw = asString(value);
16
34
  if (!raw)
@@ -40,11 +58,12 @@ function normalizeRunnerSource(value) {
40
58
  return null;
41
59
  }
42
60
  function normalizeRunnerAgents(value) {
43
- if (!Array.isArray(value))
61
+ const entries = asArray(value);
62
+ if (entries.length === 0)
44
63
  return [];
45
64
  const output = [];
46
65
  const seen = new Set();
47
- for (const entry of value) {
66
+ for (const entry of entries) {
48
67
  const record = asRecord(entry);
49
68
  if (!record)
50
69
  continue;
@@ -97,10 +116,11 @@ function asNumber(value) {
97
116
  return null;
98
117
  }
99
118
  function asStringArray(value) {
100
- if (!Array.isArray(value))
119
+ const entries = asArray(value);
120
+ if (entries.length === 0)
101
121
  return [];
102
122
  const values = [];
103
- for (const entry of value) {
123
+ for (const entry of entries) {
104
124
  const normalized = asString(entry);
105
125
  if (!normalized)
106
126
  continue;
@@ -198,10 +218,12 @@ function parsePaginationEnvelope(value, fallback) {
198
218
  const offset = Math.max(0, Math.min(100_000, Math.floor(asNumber(record?.offset) ?? fallback.offset)));
199
219
  const limit = Math.max(1, Math.min(300, Math.floor(asNumber(record?.limit) ?? fallback.limit)));
200
220
  const total = Math.max(0, Math.floor(asNumber(record?.total) ?? fallback.total));
201
- const nextCursor = asString(record?.nextCursor);
221
+ const nextCursor = asString(record?.nextCursor) ?? asString(record?.next_cursor);
202
222
  const hasMore = typeof record?.hasMore === "boolean"
203
223
  ? record.hasMore
204
- : offset + limit < total;
224
+ : typeof record?.has_more === "boolean"
225
+ ? record.has_more
226
+ : offset + limit < total;
205
227
  return { offset, limit, total, nextCursor, hasMore };
206
228
  }
207
229
  const WARMUP_MIN_INTERVAL_MS = 12_000;
@@ -225,7 +247,9 @@ function shouldRunWarmup(key) {
225
247
  return true;
226
248
  }
227
249
  function canonicalReadCacheKey(input) {
250
+ const cacheNamespace = process.env.ORGX_OPENCLAW_PLUGIN_CONFIG_DIR ?? "__default__";
228
251
  return [
252
+ cacheNamespace,
229
253
  input.route,
230
254
  input.workspaceId ?? "__all__",
231
255
  input.scopeMode ?? "implicit",
@@ -339,16 +363,22 @@ async function requestCanonicalWithLegacyFallback(deps, input) {
339
363
  }
340
364
  function normalizeQueueState(value) {
341
365
  const normalized = normalizeStatus(asString(value));
342
- if (normalized === "running" || normalized === "in_progress" || normalized === "active") {
366
+ if (normalized === "running" || normalized === "in_progress") {
343
367
  return "running";
344
368
  }
345
- if (normalized === "queued" || normalized === "pending" || normalized === "todo" || normalized === "ready") {
369
+ if (normalized === "active" ||
370
+ normalized === "queued" ||
371
+ normalized === "pending" ||
372
+ normalized === "todo" ||
373
+ normalized === "ready") {
346
374
  return "queued";
347
375
  }
348
376
  if (normalized === "blocked" ||
349
377
  normalized === "waiting" ||
350
378
  normalized === "needs_decision" ||
351
- normalized === "waiting_on_decision") {
379
+ normalized === "waiting_on_decision" ||
380
+ normalized === "waiting_dependency" ||
381
+ normalized === "blocked_by_dependency") {
352
382
  return "blocked";
353
383
  }
354
384
  if (normalized === "completed" || normalized === "done")
@@ -495,9 +525,11 @@ function normalizeQueueItems(input) {
495
525
  ? runnerSourceHint ?? "inferred"
496
526
  : "fallback";
497
527
  const queueState = normalizeQueueState(record.queueState ?? record.queue_state);
498
- const rawSliceScope = asString(record.sliceScope) ?? asString(record.slice_scope);
499
- const sliceScope = rawSliceScope === "task" || rawSliceScope === "milestone" || rawSliceScope === "workstream"
500
- ? rawSliceScope
528
+ const normalizedSliceScope = normalizeStatus(asString(record.sliceScope) ?? asString(record.slice_scope));
529
+ const sliceScope = normalizedSliceScope === "task" ||
530
+ normalizedSliceScope === "milestone" ||
531
+ normalizedSliceScope === "workstream"
532
+ ? normalizedSliceScope
501
533
  : null;
502
534
  const sliceTaskCountRaw = asNumber(record.sliceTaskCount ?? record.slice_task_count);
503
535
  const blockReason = asString(record.blockReason) ??
@@ -574,58 +606,54 @@ function normalizeQueueItems(input) {
574
606
  return left.workstreamTitle.localeCompare(right.workstreamTitle);
575
607
  });
576
608
  }
577
- function blockedItemSeverity(item) {
609
+ function isHighSeverityQueueItem(item) {
578
610
  if (item.scoringTier === "urgent")
579
- return "high";
580
- if (item.scoringTier === "deferred")
581
- return "low";
582
- const reason = (item.blockReason ?? "").toLowerCase();
583
- if (!reason)
584
- return "medium";
585
- if (/\b(critical|sev-?1|severity\s*1|outage|security|incident|prod(?:uction)?\s+down)\b/.test(reason)) {
586
- return "high";
611
+ return true;
612
+ if (typeof item.nextTaskPriority === "number" && item.nextTaskPriority <= 2) {
613
+ return true;
587
614
  }
588
- if (/\b(review|approval|capacity|queue|backlog|follow[\s-]?up)\b/.test(reason)) {
589
- return "low";
615
+ if (typeof item.initiativePriorityNum === "number" && item.initiativePriorityNum <= 2) {
616
+ return true;
590
617
  }
591
- return "medium";
618
+ if (typeof item.compositeScore === "number" && item.compositeScore >= 80) {
619
+ return true;
620
+ }
621
+ const reason = (item.blockReason ?? "").toLowerCase();
622
+ return /(critical|sev[ -]?0|sev[ -]?1|p0|p1|incident|outage)/.test(reason);
592
623
  }
593
- function applyNextUpNoiseAndDedup(items, noiseThreshold, dedupWindowMs) {
594
- const filtered = items.filter((item) => {
595
- if (item.queueState !== "blocked")
596
- return true;
597
- const severity = blockedItemSeverity(item);
598
- if (noiseThreshold === "low")
599
- return true;
600
- if (noiseThreshold === "high")
601
- return severity === "high";
602
- return severity !== "low";
603
- });
604
- if (dedupWindowMs <= 0)
605
- return filtered;
624
+ function applyQueueNoiseControls(items, options) {
625
+ const filteredByThreshold = options.noiseThreshold === "low"
626
+ ? items
627
+ : items.filter((item) => {
628
+ if (item.queueState !== "blocked" && item.queueState !== "idle") {
629
+ return true;
630
+ }
631
+ const highSeverity = isHighSeverityQueueItem(item);
632
+ if (options.noiseThreshold === "medium") {
633
+ return highSeverity;
634
+ }
635
+ return item.queueState === "blocked" && highSeverity;
636
+ });
637
+ if (options.dedupWindowMs <= 0)
638
+ return filteredByThreshold;
606
639
  const deduped = [];
607
- const latestByKey = new Map();
608
- for (const item of filtered) {
640
+ const lastSeenByReason = new Map();
641
+ for (const item of filteredByThreshold) {
609
642
  if (item.queueState !== "blocked") {
610
643
  deduped.push(item);
611
644
  continue;
612
645
  }
613
- const reason = (item.blockReason ?? "").trim().toLowerCase().replace(/\s+/g, " ");
614
- if (!reason) {
646
+ const updated = updatedEpoch(item.updatedAt);
647
+ if (updated <= 0) {
615
648
  deduped.push(item);
616
649
  continue;
617
650
  }
618
- const updatedAt = Date.parse(item.updatedAt ?? "");
619
- if (!Number.isFinite(updatedAt)) {
620
- deduped.push(item);
621
- continue;
622
- }
623
- const dedupKey = `${item.initiativeId}:${reason}`;
624
- const lastSeen = latestByKey.get(dedupKey);
625
- if (typeof lastSeen === "number" && Math.abs(updatedAt - lastSeen) <= dedupWindowMs) {
651
+ const reasonKey = `${item.initiativeId}|${(item.blockReason ?? item.nextTaskTitle ?? "blocked").trim().toLowerCase()}`;
652
+ const previous = lastSeenByReason.get(reasonKey);
653
+ if (typeof previous === "number" && Math.abs(updated - previous) <= options.dedupWindowMs) {
626
654
  continue;
627
655
  }
628
- latestByKey.set(dedupKey, updatedAt);
656
+ lastSeenByReason.set(reasonKey, updated);
629
657
  deduped.push(item);
630
658
  }
631
659
  return deduped;
@@ -688,9 +716,9 @@ function mapCanonicalSlicesToQueueItems(input) {
688
716
  : []);
689
717
  const runnerSourceHint = normalizeRunnerSource(record.runnerSource) ?? normalizeRunnerSource(record.runner_source);
690
718
  const runnerSource = runnerAgents.length > 0 ? runnerSourceHint ?? "inferred" : "fallback";
691
- const suggestedScope = asString(dispatch.suggestedScope) ??
719
+ const suggestedScope = normalizeStatus(asString(dispatch.suggestedScope) ??
692
720
  asString(dispatch.suggested_scope) ??
693
- asString(record.level);
721
+ asString(record.level));
694
722
  const sliceScope = suggestedScope === "task" ||
695
723
  suggestedScope === "milestone" ||
696
724
  suggestedScope === "workstream"
@@ -720,8 +748,14 @@ function mapCanonicalSlicesToQueueItems(input) {
720
748
  rawStatus,
721
749
  nextTaskId: taskId ?? sliceTaskIds[0] ?? null,
722
750
  nextTaskTitle: asString(record.nextTaskTitle) ?? asString(record.next_task_title),
723
- nextTaskPriority: asNumber(record.priorityNum ?? record.nextTaskPriority),
724
- nextTaskDueAt: asString(record.dueAt) ?? asString(record.nextTaskDueAt),
751
+ nextTaskPriority: asNumber(record.priorityNum ??
752
+ record.priority_num ??
753
+ record.nextTaskPriority ??
754
+ record.next_task_priority),
755
+ nextTaskDueAt: asString(record.dueAt) ??
756
+ asString(record.due_at) ??
757
+ asString(record.nextTaskDueAt) ??
758
+ asString(record.next_task_due_at),
725
759
  nextTaskMilestoneId: asString(record.milestoneId) ?? asString(record.milestone_id),
726
760
  runnerAgentId: runnerAgentIdRaw,
727
761
  runnerAgentName: runnerAgentNameRaw,
@@ -851,16 +885,23 @@ export function registerMissionControlReadRoutes(router, deps) {
851
885
  const requestedOrderMode = query.get("order_mode") ?? query.get("orderMode");
852
886
  const includeLineage = parseBoolean(query.get("include_lineage") ?? query.get("includeLineage"));
853
887
  // Noise reduction params — suppress blocked/idle queue items by severity.
854
- // noise_threshold: 'low' (show all) | 'medium' (default, hide low-severity blocked) | 'high' (only critical/high blocked)
888
+ // noise_threshold: 'low' (default, show all) | 'medium' (hide low-severity blocked/idle) | 'high' (only critical/high blocked)
855
889
  const noiseThresholdRaw = query.get("noise_threshold") ?? query.get("noiseThreshold");
856
890
  const noiseThreshold = noiseThresholdRaw === "low" || noiseThresholdRaw === "high"
857
891
  ? noiseThresholdRaw
858
- : "medium";
892
+ : noiseThresholdRaw === "medium"
893
+ ? "medium"
894
+ : "low";
859
895
  // dedup_window: time window in ms for grouping duplicate blocked items (default: 60000)
860
896
  const dedupWindowRaw = query.get("dedup_window") ?? query.get("dedupWindow");
861
897
  const dedupWindowMs = dedupWindowRaw != null
862
898
  ? Math.max(0, parseInt(dedupWindowRaw, 10) || 60000)
863
899
  : 60000;
900
+ const queueNoiseCacheTag = dedupeStrings([
901
+ includeLineage ? "lineage:1" : "",
902
+ `noise:${noiseThreshold}`,
903
+ `dedup:${dedupWindowMs}`,
904
+ ]).join(",");
864
905
  const nextUpCanonicalCacheKey = canonicalReadCacheKey({
865
906
  route: "next-up",
866
907
  workspaceId: projectId,
@@ -872,9 +913,7 @@ export function registerMissionControlReadRoutes(router, deps) {
872
913
  scope: requestedSliceLevelContext,
873
914
  order: requestedOrderMode,
874
915
  mixPolicy: requestedMixPolicy,
875
- noiseThreshold,
876
- dedupWindowMs,
877
- search: includeLineage ? "lineage:1" : null,
916
+ search: queueNoiseCacheTag || null,
878
917
  });
879
918
  const cachedCanonicalNextUp = readCanonicalReadCache(nextUpCanonicalCacheKey, {
880
919
  allowStale: false,
@@ -922,6 +961,8 @@ export function registerMissionControlReadRoutes(router, deps) {
922
961
  params.set("offset", String(offset));
923
962
  params.set("limit", String(pageSize));
924
963
  params.set("include_completed", includeCompleted ? "1" : "0");
964
+ params.set("noise_threshold", noiseThreshold);
965
+ params.set("dedup_window", String(dedupWindowMs));
925
966
  if (requestedSliceLevelContext) {
926
967
  params.set("slice_level_context", requestedSliceLevelContext);
927
968
  }
@@ -946,7 +987,7 @@ export function registerMissionControlReadRoutes(router, deps) {
946
987
  if (isCanonicalAllScopeMismatch(canonicalRecord, useAllScope)) {
947
988
  throw new Error("canonical next-up all-workspaces scope mismatch");
948
989
  }
949
- const canonicalItems = applyNextUpNoiseAndDedup(normalizeQueueItems(canonicalRecord.items).filter((item) => includeCompleted ? true : item.queueState !== "completed"), noiseThreshold, dedupWindowMs);
990
+ const canonicalItems = applyQueueNoiseControls(normalizeQueueItems(canonicalRecord.items).filter((item) => includeCompleted ? true : item.queueState !== "completed"), { noiseThreshold, dedupWindowMs });
950
991
  const canonicalTotal = Math.max(canonicalItems.length, Math.floor(asNumber(canonicalRecord.total) ?? canonicalItems.length)) ?? canonicalItems.length;
951
992
  const canonicalPagination = parsePaginationEnvelope(canonicalRecord.pagination, {
952
993
  offset,
@@ -1055,6 +1096,8 @@ export function registerMissionControlReadRoutes(router, deps) {
1055
1096
  bridgeParams.set("offset", String(Math.max(0, offset)));
1056
1097
  bridgeParams.set("limit", String(Math.min(300, Math.max(pageSize, offset + pageSize))));
1057
1098
  bridgeParams.set("include_completed", includeCompleted ? "1" : "0");
1099
+ bridgeParams.set("noise_threshold", noiseThreshold);
1100
+ bridgeParams.set("dedup_window", String(dedupWindowMs));
1058
1101
  bridgeParams.set("mix_policy", requestedMixPolicy ?? "iwmt_v1");
1059
1102
  if (requestedOrderMode) {
1060
1103
  bridgeParams.set("order_mode", requestedOrderMode);
@@ -1072,7 +1115,7 @@ export function registerMissionControlReadRoutes(router, deps) {
1072
1115
  if (isCanonicalAllScopeMismatch(canonicalSlicesRecord, useAllScope)) {
1073
1116
  throw new Error("canonical slices all-workspaces scope mismatch");
1074
1117
  }
1075
- const bridgedItems = applyNextUpNoiseAndDedup(mapCanonicalSlicesToQueueItems(canonicalSlicesRecord.items).filter((item) => includeCompleted ? true : item.queueState !== "completed"), noiseThreshold, dedupWindowMs);
1118
+ const bridgedItems = applyQueueNoiseControls(mapCanonicalSlicesToQueueItems(canonicalSlicesRecord.items).filter((item) => includeCompleted ? true : item.queueState !== "completed"), { noiseThreshold, dedupWindowMs });
1076
1119
  if (bridgedItems.length > 0) {
1077
1120
  const paged = applySliceSearchAndPagination({
1078
1121
  items: bridgedItems,
@@ -1115,7 +1158,7 @@ export function registerMissionControlReadRoutes(router, deps) {
1115
1158
  initiativeId,
1116
1159
  projectId,
1117
1160
  });
1118
- const items = applyNextUpNoiseAndDedup(normalizeQueueItems(queue.items ?? []).filter((item) => includeCompleted ? true : item.queueState !== "completed"), noiseThreshold, dedupWindowMs);
1161
+ const items = applyQueueNoiseControls(normalizeQueueItems(queue.items ?? []).filter((item) => includeCompleted ? true : item.queueState !== "completed"), { noiseThreshold, dedupWindowMs });
1119
1162
  const paged = applySliceSearchAndPagination({
1120
1163
  items,
1121
1164
  searchTerm: "",
@@ -1148,7 +1191,7 @@ export function registerMissionControlReadRoutes(router, deps) {
1148
1191
  initiativeId,
1149
1192
  projectId,
1150
1193
  });
1151
- const items = applyNextUpNoiseAndDedup(normalizeQueueItems(queue.items ?? []).filter((item) => includeCompleted ? true : item.queueState !== "completed"), noiseThreshold, dedupWindowMs);
1194
+ const items = applyQueueNoiseControls(normalizeQueueItems(queue.items ?? []).filter((item) => includeCompleted ? true : item.queueState !== "completed"), { noiseThreshold, dedupWindowMs });
1152
1195
  const paged = applySliceSearchAndPagination({
1153
1196
  items,
1154
1197
  searchTerm: "",
@@ -101,16 +101,17 @@ export function readOpenClawPrimaryModel(raw) {
101
101
  return primary || null;
102
102
  }
103
103
  export function readOpenClawGatewayPort(raw) {
104
+ const isValidPort = (value) => Number.isFinite(value) && value >= 1 && value <= 65_535;
104
105
  if (!raw)
105
106
  return 18789;
106
107
  const gateway = readObject(raw.gateway);
107
108
  const port = gateway.port;
108
- if (typeof port === "number" && Number.isFinite(port) && port > 0) {
109
+ if (typeof port === "number" && isValidPort(port)) {
109
110
  return Math.floor(port);
110
111
  }
111
112
  if (typeof port === "string") {
112
113
  const parsed = Number.parseInt(port, 10);
113
- if (Number.isFinite(parsed) && parsed > 0) {
114
+ if (isValidPort(parsed)) {
114
115
  return parsed;
115
116
  }
116
117
  }
@@ -537,9 +537,14 @@ export function createOutboxReplayer(deps) {
537
537
  continue;
538
538
  }
539
539
  const remaining = [];
540
+ let replayedCount = 0;
541
+ let droppedCount = 0;
542
+ let deadLetteredCount = 0;
543
+ let failedCount = 0;
540
544
  for (const event of pending) {
541
545
  const skipReason = classifyOutboxReplaySkip(event);
542
546
  if (skipReason) {
547
+ droppedCount += 1;
543
548
  await appendOutboxDeadLetter(queue, event, `dropped_before_replay:${skipReason}`, null);
544
549
  logger.warn?.("[orgx] Dropping non-replayable outbox event", {
545
550
  queue,
@@ -550,6 +555,7 @@ export function createOutboxReplayer(deps) {
550
555
  }
551
556
  try {
552
557
  await replayOutboxEvent(event);
558
+ replayedCount += 1;
553
559
  }
554
560
  catch (err) {
555
561
  hadReplayFailure = true;
@@ -558,6 +564,7 @@ export function createOutboxReplayer(deps) {
558
564
  ? Math.max(0, Math.floor(event.replayFailures)) + 1
559
565
  : 1;
560
566
  if (nextFailures >= OUTBOX_MAX_REPLAY_FAILURES) {
567
+ deadLetteredCount += 1;
561
568
  await appendOutboxDeadLetter(queue, {
562
569
  ...event,
563
570
  replayFailures: nextFailures,
@@ -573,6 +580,7 @@ export function createOutboxReplayer(deps) {
573
580
  });
574
581
  continue;
575
582
  }
583
+ failedCount += 1;
576
584
  remaining.push({
577
585
  ...event,
578
586
  replayFailures: nextFailures,
@@ -588,14 +596,15 @@ export function createOutboxReplayer(deps) {
588
596
  }
589
597
  }
590
598
  await replaceOutbox(queue, remaining);
591
- const replayedCount = pending.length - remaining.length;
592
- if (replayedCount > 0) {
593
- logger.info?.("[orgx] Replayed buffered outbox events", {
594
- queue,
595
- replayed: replayedCount,
596
- remaining: remaining.length,
597
- });
598
- }
599
+ logger.info?.("[orgx] Processed buffered outbox events", {
600
+ queue,
601
+ pending: pending.length,
602
+ replayed: replayedCount,
603
+ dropped: droppedCount,
604
+ deadLettered: deadLetteredCount,
605
+ failed: failedCount,
606
+ remaining: remaining.length,
607
+ });
599
608
  }
600
609
  if (hadReplayFailure) {
601
610
  deps.writeOutboxReplayState({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useorgx/openclaw-plugin",
3
- "version": "0.7.3",
3
+ "version": "0.7.4",
4
4
  "description": "OrgX plugin for OpenClaw — agent orchestration, quality gates, model routing, and live dashboard",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1 +0,0 @@
1
- import{r as c,j as e}from"./cNrhgGc1.js";import{B as bt,u as gt,P as yt,w as de,C as Qe,K as Ve,x as V,A as He,E as ue,h as Re,y as We,z as wt,U as vt}from"./C9jy61eu.js";import{S as B}from"./CZaT3ob_.js";import{A as Se,m as te,R as kt,b as jt,a as Nt}from"./CxQ08qFN.js";async function Je(t,r){var m;const i=await(await fetch(t,r)).json().catch(()=>null),x=((m=i==null?void 0:i.data)==null?void 0:m.url)??(i==null?void 0:i.url)??null;if(typeof x=="string"&&x.trim())return x.trim();throw new Error((i==null?void 0:i.error)??"Billing link unavailable")}async function Ct(t){var x;const r=((x=t==null?void 0:t.actions)==null?void 0:x.checkout)??"/orgx/api/billing/checkout",a=((t==null?void 0:t.requiredPlan)??"starter").trim().toLowerCase()||"starter",i=await Je(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({planId:a})});window.open(i,"_blank","noopener,noreferrer")}async function It(t){var i;const r=((i=t==null?void 0:t.actions)==null?void 0:i.portal)??"/orgx/api/billing/portal",a=await Je(r,{method:"POST"});window.open(a,"_blank","noopener,noreferrer")}function St(t){return t==="success"?"border-emerald-400/30 bg-[#0A1210]/95 text-emerald-100":t==="warning"?"border-amber-300/30 bg-[#12100A]/95 text-amber-100":t==="error"?"border-red-400/32 bg-[#120A0A]/95 text-red-100":t==="info"?"border-cyan-300/28 bg-[#0A1012]/95 text-cyan-100":"border-strong bg-[#0B0F16]/95 text-primary"}function $t({open:t,tone:r="neutral",title:a,message:i=null,className:x,primaryAction:m=null,secondaryAction:b=null,onDismiss:v=null,autoDismissMs:j=null}){return c.useEffect(()=>{if(!t||!v||!j)return;const U=window.setTimeout(()=>v(),j);return()=>window.clearTimeout(U)},[j,v,t,a,i]),e.jsx(Se,{initial:!1,children:t?e.jsx(te.div,{initial:{opacity:0,y:-8,scale:.985},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,y:-8,scale:.985},transition:{duration:.2,ease:[.22,1,.36,1]},className:`pointer-events-none ${x??""}`,children:e.jsxs("div",{className:`pointer-events-none min-w-[220px] max-w-[420px] rounded-xl border px-3 py-2 shadow-[0_16px_36px_rgba(0,0,0,0.42)] backdrop-blur ${St(r)}`,children:[e.jsxs("div",{className:"flex items-start gap-2.5",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("p",{className:"text-caption font-semibold",children:a}),i?e.jsx("p",{className:"mt-0.5 text-caption opacity-85",children:i}):null]}),v?e.jsx("button",{type:"button",onClick:v,className:"pointer-events-auto inline-flex h-6 w-6 items-center justify-center rounded-md text-current/70 transition-colors hover:bg-white/[0.08] hover:text-current","aria-label":"Dismiss toast",title:"Dismiss",children:e.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("path",{d:"M18 6 6 18"}),e.jsx("path",{d:"m6 6 12 12"})]})}):null]}),m||b?e.jsxs("div",{className:"mt-2 flex items-center gap-1.5",children:[b?e.jsx("button",{type:"button",onClick:b.onClick,className:"pointer-events-auto h-7 rounded-md border border-strong bg-white/[0.06] px-2.5 text-micro font-semibold text-current transition-colors hover:bg-white/[0.12]",children:b.label}):null,m?e.jsx("button",{type:"button",onClick:m.onClick,className:"pointer-events-auto h-7 rounded-md border border-white/25 bg-white/[0.14] px-2.5 text-micro font-semibold text-current transition-colors hover:bg-white/[0.2]",children:m.label}):null]}):null]})}):null})}function Xe({className:t=""}){return e.jsx("svg",{viewBox:"0 0 20 20",fill:"none","aria-hidden":!0,className:t,children:e.jsx("path",{d:"M7 5.4v9.2c0 .7.75 1.15 1.38.83l7.6-4.6a.95.95 0 0 0 0-1.62l-7.6-4.64A.95.95 0 0 0 7 5.4Z",fill:"currentColor"})})}function qt({className:t=""}){return e.jsxs("svg",{viewBox:"0 0 20 20",fill:"none","aria-hidden":!0,className:t,children:[e.jsx("path",{d:"M6.2 9.4V6.7c0-.7.5-1.2 1.1-1.2s1.1.5 1.1 1.2v2.2",stroke:"currentColor",strokeWidth:"1.4",strokeLinecap:"round"}),e.jsx("path",{d:"M8.4 8.9V5.8c0-.7.5-1.3 1.1-1.3s1.1.6 1.1 1.3v3",stroke:"currentColor",strokeWidth:"1.4",strokeLinecap:"round"}),e.jsx("path",{d:"M10.6 8.9V6.2c0-.7.5-1.3 1.1-1.3s1.1.6 1.1 1.3v3.2",stroke:"currentColor",strokeWidth:"1.4",strokeLinecap:"round"}),e.jsx("path",{d:"M12.8 9.6V7.2c0-.7.5-1.2 1.1-1.2s1.1.5 1.1 1.2v4.2c0 2.7-1.9 4.6-4.6 4.6H9.2c-2.1 0-3.7-1-4.6-2.8l-.9-1.7c-.3-.6 0-1.4.6-1.7.6-.3 1.3 0 1.6.6l.7 1.4",stroke:"currentColor",strokeWidth:"1.4",strokeLinecap:"round",strokeLinejoin:"round"})]})}function Rt({className:t=""}){return e.jsxs("svg",{viewBox:"0 0 20 20",fill:"none","aria-hidden":!0,className:t,children:[e.jsx("path",{d:"M6.4 9.2V7.4c0-.7.5-1.2 1.1-1.2s1.1.5 1.1 1.2v1.3",stroke:"currentColor",strokeWidth:"1.4",strokeLinecap:"round"}),e.jsx("path",{d:"M8.6 8.9V7c0-.7.5-1.2 1.1-1.2s1.1.5 1.1 1.2v2",stroke:"currentColor",strokeWidth:"1.4",strokeLinecap:"round"}),e.jsx("path",{d:"M10.8 9.2V7.3c0-.7.5-1.2 1.1-1.2s1.1.5 1.1 1.2v2.6",stroke:"currentColor",strokeWidth:"1.4",strokeLinecap:"round"}),e.jsx("path",{d:"M13 9.8V8.2c0-.7.5-1.2 1.1-1.2s1.1.5 1.1 1.2v3.6c0 2.4-1.7 4-4.1 4H9.7c-2 0-3.4-.9-4.2-2.5l-.8-1.4c-.3-.6 0-1.3.5-1.6.6-.3 1.2-.1 1.6.5l.6 1",stroke:"currentColor",strokeWidth:"1.4",strokeLinecap:"round",strokeLinejoin:"round"})]})}function Ze(t){return t==="running"?"from-teal-300/0 via-teal-300/60 to-teal-300/0":t==="blocked"?"from-amber-300/0 via-amber-300/55 to-amber-300/0":t==="idle"?"from-white/0 via-white/35 to-white/0":"from-[#BFFF00]/0 via-[#BFFF00]/70 to-[#BFFF00]/0"}function $e(t){return t==="running"?"Current":t==="blocked"?"Blocked on":"Next"}function qe(t){const r=typeof t.sliceTaskCount=="number"&&Number.isFinite(t.sliceTaskCount)?Math.max(0,Math.floor(t.sliceTaskCount)):null,a=t.sliceScope==="task"?"task":t.sliceScope==="milestone"?"milestone slice":"workstream slice",i=r&&r>0?`${r} ${r===1?"task":"tasks"}`:null;return t.queueState==="running"?i?`Executing ${i} in ${a}.`:"Execution in progress. Task detail will appear as the scheduler advances.":t.queueState==="blocked"?t.blockReason?"Blocked while waiting for dependency resolution.":"Blocked. Waiting for dependency or review.":t.queueState==="queued"?i?`Queued with ${i} in ${a}.`:"Queued at workstream scope. Task detail will populate after dispatch.":t.queueState==="completed"?"Completed. No queued tasks remain.":"Idle. Ready to dispatch when started."}function Ge(t){const r=typeof t.initiativePriority=="string"?t.initiativePriority.trim().toLowerCase():"",a=typeof t.initiativePriorityNum=="number"&&Number.isFinite(t.initiativePriorityNum)?Math.max(1,Math.min(100,Math.round(t.initiativePriorityNum))):null,i=r==="urgent"||r==="high"||r==="medium"||r==="low"?r:a!==null?a<=12?"urgent":a<=30?"high":a<=60?"medium":"low":null;if(!i)return null;const x=i==="urgent"?"P1":i==="high"?"P2":i==="medium"?"P3":"P4",m=i==="urgent"?"Urgent":i==="high"?"High":i==="medium"?"Medium":"Low",b=i==="urgent"?"border-red-300/35 bg-red-500/[0.14] text-red-100":i==="high"?"border-amber-300/35 bg-amber-500/[0.14] text-amber-100":i==="medium"?"border-[#BFFF00]/35 bg-[#BFFF00]/14 text-[#E1FFB2]":"border-white/[0.2] bg-white/[0.08] text-white/70";return{shortLabel:`${x} ${m}`,longLabel:`Initiative priority ${m} (${x})`,toneClass:b}}function Tt(t){const r=t.trim().toLowerCase();if(r.includes("timed out")||r.includes("timeout")||r.includes("request cancelled")||r.includes("signal is aborted"))return"Next Up is still syncing. Keep this panel open and it will repopulate automatically.";if(r.includes("unauthorized")||r.includes("forbidden")||r.includes("api key")||r.includes("auth"))return"Next Up is unavailable until OrgX authentication is reconnected in Settings.";if(r.includes("unknown api endpoint")||r.includes("route is unavailable"))return"This runtime is missing queue routes. Restart and update the plugin build.";const a=t.split("|").map(i=>i.trim()).filter(Boolean).map(i=>i.replace(/^[^:]+:\s*/,"").trim()).filter(Boolean).slice(0,2).join(" ");return Re(a||t)||"Next Up is temporarily unavailable."}function Bt(t){const r=t.trim().toLowerCase();return r.includes("timed out")||r.includes("timeout")||r.includes("request cancelled")||r.includes("signal is aborted")?"Signal is delayed right now. Queue data will appear as soon as sync catches up.":r.includes("fallback")?"Showing fallback queue data while full signal refreshes.":r.includes("unknown api endpoint")||r.includes("route is unavailable")?"Some queue controls are unavailable in this plugin build. Update and restart to restore full controls.":Re(t.trim())}function ke(t,r,a){const i=typeof t=="string"?t.trim():"";if(i&&!We(i))return V(i);const x=typeof r=="string"?r.trim():"";return x?We(x)?`${a} ${wt(x)}`:V(x):a}function Ye(t){const r=typeof t.runnerAgentName=="string"?t.runnerAgentName.trim():"";if(!r)return"Unassigned";const a=r.toLowerCase();return a==="undefined"||a==="null"||a==="main"&&(t.runnerAgentId==="unassigned"||t.runnerSource==="fallback")?"Unassigned":r}function Oe(t){return t.runnerSource==="inferred"?"inferred":null}function et(t,r){const a=t.runnerSource==="assigned"?"assigned":t.runnerSource==="inferred"?"inferred":"fallback";return r==="Unassigned"?`Runner ${a}`:`${r} · ${a}`}function ee(t,r){return!t||t.trim().length===0?r:Re(t.trim())||r}function De(t){return!t||typeof t!="object"||Array.isArray(t)?null:t}function tt(t,r){const a=V(t.workstreamTitle),i=De(r),x=i&&typeof i.dispatchMode=="string"?i.dispatchMode:null,m=De(i==null?void 0:i.run);return(m&&typeof m.stopReason=="string"?m.stopReason:m&&typeof m.stop_reason=="string"?m.stop_reason:null)==="budget_exhausted"?`Dispatch acknowledged for ${a}, but autopilot stopped: budget exhausted.`:x==="pending"?`Dispatching ${a}; waiting for slice start…`:x==="fallback"?`Dispatched ${a} using fallback runner.`:`Dispatched ${a}.`}function nt({className:t=""}){return e.jsxs("svg",{viewBox:"0 0 20 20",fill:"none","aria-hidden":!0,className:t,children:[e.jsx("circle",{cx:"4.5",cy:"10",r:"1.4",fill:"currentColor"}),e.jsx("circle",{cx:"10",cy:"10",r:"1.4",fill:"currentColor"}),e.jsx("circle",{cx:"15.5",cy:"10",r:"1.4",fill:"currentColor"})]})}function Lt({compact:t}){const r=t?3:6;return e.jsxs("div",{className:"space-y-2.5",children:[e.jsxs("div",{className:"flex items-center gap-2 px-1 pt-1 text-micro uppercase tracking-[0.12em] text-muted",children:[e.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-[#BFFF00]/70 status-breathe"}),e.jsx("span",{children:"Calibrating queue"})]}),Array.from({length:r}).map((a,i)=>e.jsxs("div",{className:"nextup-skeleton-card rounded-2xl border border-white/[0.08] bg-white/[0.02] px-3 py-3",children:[e.jsxs("div",{className:"flex items-start justify-between gap-2.5",children:[e.jsxs("div",{className:"flex min-w-0 flex-1 items-start gap-2.5",children:[e.jsx(B,{className:"h-8 w-8 rounded-full"}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx(B,{className:"h-3 w-40 rounded-md"}),e.jsx(B,{className:"mt-2 h-4 w-56 rounded-md"})]})]}),e.jsx(B,{className:"h-5 w-16 rounded-full"})]}),e.jsxs("div",{className:"mt-3 rounded-lg border border-white/[0.07] bg-black/[0.18] px-2.5 py-2",children:[e.jsx(B,{className:"h-3 w-14 rounded"}),e.jsx(B,{className:"mt-2 h-3 w-full rounded"}),e.jsx(B,{className:"mt-2 h-3 w-3/5 rounded"})]}),e.jsxs("div",{className:"mt-2.5 flex flex-wrap gap-1.5",children:[e.jsx(B,{className:"h-8 w-24 rounded-full"}),e.jsx(B,{className:"h-8 w-20 rounded-full"}),e.jsx(B,{className:"h-8 w-24 rounded-full"})]})]},`nextup-skeleton-${i}`))]})}function Mt({initiativeId:t=null,projectId:r=null,authToken:a=null,embedMode:i=!1,title:x="Next Up",showHeader:m=!0,compact:b=!1,className:v,disableEnterAnimation:j=!1,allowCompactToggle:U=!1,onToggleCompact:ne,onOpenInitiative:G,onOpenSettings:C,onUpgradeGate:L,onOpenSliceDetail:M,selectionEnabled:K=!0,panelStyle:xe="card",showQueueSettings:re=!0,queueModel:me,queueActions:je,snapshotVersion:H=null}){var Ke;const[pe,J]=c.useState(b);c.useEffect(()=>J(b),[b]);const u=U&&!ne?pe:b,y=n=>{ne?ne(n):J(n)},[F,h]=c.useState(null),he="bottom",[w,P]=c.useState(null),[$,Q]=c.useState(null),[E,I]=c.useState(null),[S,d]=c.useState(new Set),[fe,Y]=c.useState(null),[se,ie]=c.useState(!1),[rt,be]=c.useState(!1),Te=c.useRef(null),st=bt({initiativeId:t,projectId:r,authToken:a,embedMode:i,enabled:!me,snapshotVersion:H}),it=me??st,{items:oe,degraded:X,isLoading:A,isFetching:Be,error:ge,refetch:ot,playWorkstream:Le,startWorkstreamAutoContinue:Me}=it,at=gt({authToken:a,embedMode:i}),z=je??at,q=n=>`${n.initiativeId}:${n.workstreamId}`,ae=c.useMemo(()=>oe.filter(n=>n.queueState==="running").length,[oe]),R=c.useMemo(()=>{const n=oe.filter(l=>l.queueState!=="running");return n.length>0?n:oe},[oe]),Fe=c.useMemo(()=>R.length===0?"empty":R.some(n=>n.queueState!=="running"&&n.queueState!=="blocked")?"queued":R.some(n=>n.queueState==="blocked")?"blocked":R.some(n=>n.queueState==="running")?"running":"queued",[R]),k=c.useMemo(()=>u?R.slice(0,5):R,[u,R]),lt=c.useMemo(()=>k.filter(n=>S.has(q(n))),[S,k]),[O,Pe]=c.useState([]),Ne=c.useRef([]),Ee=c.useMemo(()=>{const n=new Map;for(const l of k)n.set(q(l),l);return n},[k]),N=c.useMemo(()=>k.map(q),[k]),ct=c.useMemo(()=>N.join("|"),[N]);c.useEffect(()=>{Pe(n=>{if(u)return[];const l=[],o=new Set(N);for(const s of n)o.has(s)&&l.push(s);for(const s of N)l.includes(s)||l.push(s);return l})},[u,ct]),c.useEffect(()=>{Ne.current=O},[O]),c.useEffect(()=>{fe&&(N.includes(fe)||Y(null))},[fe,N]),c.useEffect(()=>{d(n=>{if(n.size===0)return n;const l=new Set(k.map(q)),o=new Set;for(const s of n)l.has(s)&&o.add(s);return o.size===n.size?n:o})},[k]),c.useEffect(()=>{if(!E)return;k.some(l=>q(l)===E)||I(null)},[E,k]),c.useEffect(()=>{if(X.length===0){be(!1);return}be(!1)},[X]),c.useEffect(()=>{K&&!u&&S.size>0&&ie(!1)},[u,S.size,K]),c.useEffect(()=>{if(!se)return;const n=o=>{var p;const s=o.target;s&&((p=Te.current)!=null&&p.contains(s)||ie(!1))},l=o=>{o.key==="Escape"&&ie(!1)};return document.addEventListener("mousedown",n),document.addEventListener("touchstart",n),document.addEventListener("keydown",l),()=>{document.removeEventListener("mousedown",n),document.removeEventListener("touchstart",n),document.removeEventListener("keydown",l)}},[se]);const Ae=async n=>{const l=q(n),o=V(n.workstreamTitle);try{await z.remove({initiativeId:n.initiativeId,workstreamId:n.workstreamId}),d(s=>{if(!s.has(l))return s;const p=new Set(s);return p.delete(l),p}),Y(s=>s===l?null:s),h(`Removed ${o} from queue.`)}catch(s){const p=s instanceof Error?s.message:"";h(ee(p,"Failed to remove from queue"))}},dt=(n,l,o)=>{const s=u?N:O.length>0?O:N;d(p=>{const f=new Set(p),T=fe;if(o&&T&&s.includes(T)){const g=s.indexOf(n),D=s.indexOf(T);if(g>=0&&D>=0){const[we,ve]=g<D?[g,D]:[D,g];for(const ce of s.slice(we,ve+1))l?f.add(ce):f.delete(ce)}else l?f.add(n):f.delete(n)}else l?f.add(n):f.delete(n);return f}),Y(n)},ut=()=>{d(new Set(N)),Y(N.length>0?N[N.length-1]:null)},xt=()=>{d(new Set),Y(null)},Ce=async n=>{if(S.size===0){h("Select one or more queue items first.");return}const l=k.map(o=>({key:q(o),item:o})).filter(o=>S.has(o.key));if(l.length===0){h("Selected queue items are no longer visible.");return}Q(`bulk:${n}`),h(null);try{const o=l.map(({item:g})=>({initiativeId:g.initiativeId,workstreamId:g.workstreamId})),s=await z.bulk({action:n,items:o}),p=typeof(s==null?void 0:s.updated)=="number"?s.updated??0:0,f=typeof(s==null?void 0:s.failed)=="number"?s.failed??0:0,T=Array.isArray(s==null?void 0:s.errors)?s.errors.filter(g=>typeof g=="string").map(g=>g.trim()).filter(Boolean):[],W=n==="remove"?"removed":n==="move_top"?"moved to top":"moved to bottom";p===0&&f>0&&T.length>0?h(ee(T[0],`${f} queue action${f===1?"":"s"} failed.`)):h(f>0?`${p} item${p===1?"":"s"} ${W}; ${f} failed.`:`${p} item${p===1?"":"s"} ${W}.`),d(new Set),Y(null)}catch(o){const s=o instanceof Error?o.message:"";h(ee(s,"Bulk queue action failed"))}finally{Q(null)}},mt=async()=>{const n=Ne.current.map(l=>Ee.get(l)).filter(Boolean).map(l=>({initiativeId:l.initiativeId,workstreamId:l.workstreamId}));n.length!==0&&await z.reorder({order:n})},le=async(n,l,o)=>{h(null),P(null),L==null||L(null),Q(n);try{const s=await l();h(typeof o=="function"?o(s):o)}catch(s){if(s instanceof vt)P(s),L==null||L(s);else{const p=s instanceof Error?s.message:"";h(ee(p,"Action failed"))}}finally{Q(null)}},ye=w?"upgrade":ge?"error":F?"notice":null,ze=ge?Tt(ge):null,Ie=X.length>0?Bt(X[0]):null,pt=ye!==null,ht=X.length>0&&!rt&&E===null&&!se,Z=lt.length,_e=K&&!u&&Z>0,ft=ae>0?`No queued workstreams yet. ${ae} running item${ae===1?"":"s"} still in-flight.`:X.length>0?"Queue signal is delayed right now.":"No queued workstreams right now.",Ue=e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",onClick:ut,className:"control-pill h-8 px-2.5 text-caption font-semibold",children:"Select all"}),e.jsx("button",{type:"button",onClick:xt,disabled:S.size===0,className:"control-pill h-8 px-2.5 text-caption font-semibold disabled:opacity-45",children:"Clear"}),e.jsx("button",{type:"button",disabled:Z===0||$==="bulk:move_top",onClick:()=>void Ce("move_top"),className:"control-pill h-8 px-2.5 text-caption font-semibold disabled:opacity-45",children:"Move top"}),e.jsx("button",{type:"button",disabled:Z===0||$==="bulk:move_bottom",onClick:()=>void Ce("move_bottom"),className:"control-pill h-8 px-2.5 text-caption font-semibold disabled:opacity-45",children:"Move bottom"}),e.jsx("button",{type:"button",disabled:Z===0||$==="bulk:remove",onClick:()=>void Ce("remove"),className:"control-pill h-8 px-2.5 text-caption font-semibold disabled:opacity-45",children:"Remove"})]});return e.jsxs(yt,{surface:xe==="card",className:`flex h-full min-h-0 flex-col overflow-hidden ${j?"":"card-enter"} ${xe==="flat"?"!rounded-none !border-none !bg-transparent !shadow-none":""} ${v??""}`,children:[m?e.jsxs("div",{className:"flex items-center justify-between gap-2 border-b border-subtle px-4 py-3",children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-2",children:[e.jsx("h2",{className:"truncate text-heading font-semibold text-white",children:x}),e.jsx("span",{className:"chip inline-flex min-w-[52px] justify-center text-micro tabular-nums",children:A?e.jsx("span",{"aria-hidden":!0,className:"h-2.5 w-5 rounded bg-white/15 animate-pulse"}):R.length}),e.jsx("span",{className:de("chip inline-flex min-w-[148px] justify-center text-micro tabular-nums transition-opacity",!A&&ae>0?"text-secondary opacity-100":"pointer-events-none opacity-0"),children:`${ae} active elsewhere`}),e.jsx("span",{className:de("inline-flex min-w-[92px] justify-end text-micro text-muted transition-opacity",Be&&!A?"opacity-100":"opacity-0"),"aria-live":"polite",children:"refreshing…"})]}),e.jsx("div",{className:"flex items-center gap-1.5",children:U?e.jsx("button",{type:"button",onClick:()=>y(!u),className:"control-pill h-8 flex-shrink-0 whitespace-nowrap px-3 text-caption font-semibold",title:u?"Switch to expanded cards":"Switch to compact list","aria-label":u?"Expand Next Up queue":"Compact Next Up queue",children:u?"Expand":"Compact"}):null})]}):null,pt&&e.jsx("div",{className:"px-3 pt-2",children:e.jsx(Se,{initial:!1,mode:"wait",children:ye==="upgrade"&&w?e.jsx(te.div,{initial:{opacity:0,y:-4,scale:.99},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,y:-4,scale:.99},transition:{duration:.18,ease:[.22,1,.36,1]},className:"rounded-xl border border-amber-200/25 bg-amber-200/10 px-3 py-2 text-caption text-amber-100",children:e.jsxs("div",{className:"flex items-start justify-between gap-2",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"rounded-full border border-amber-200/25 bg-amber-200/10 px-2 py-0.5 text-micro font-semibold uppercase tracking-[0.08em] text-amber-100/90",children:"Upgrade required"}),e.jsxs("span",{className:"truncate text-micro text-secondary",children:[Qe(w.currentPlan)," →"," ",Qe(w.requiredPlan)]})]}),e.jsx("div",{className:"mt-1 line-clamp-2 text-caption leading-snug text-amber-50/90",title:w.message,children:w.message}),F?e.jsx("div",{className:"mt-1 text-micro text-rose-50/85",children:F}):null]}),e.jsxs("div",{className:"flex flex-shrink-0 flex-col items-end gap-1",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("button",{type:"button",onClick:()=>void Ct({actions:w.actions,requiredPlan:w.requiredPlan}).catch(n=>h(ee(n instanceof Error?n.message:"","Checkout failed"))),className:"h-7 rounded-full border border-amber-200/25 bg-amber-200/15 px-3 text-micro font-semibold text-amber-50 transition-colors hover:bg-amber-200/20",children:"Upgrade"}),e.jsx("button",{type:"button",onClick:()=>void It({actions:w.actions}).catch(n=>h(ee(n instanceof Error?n.message:"","Portal failed"))),className:"h-7 rounded-full border border-strong bg-white/[0.04] px-3 text-micro font-semibold text-primary transition-colors hover:bg-white/[0.08]",children:"Billing"}),C&&e.jsx("button",{type:"button",onClick:C,className:"h-7 rounded-full border border-strong bg-white/[0.04] px-2.5 text-micro font-semibold text-primary transition-colors hover:bg-white/[0.08]",children:"Settings"})]}),(Ke=w.actions)!=null&&Ke.pricing?e.jsx("a",{href:w.actions.pricing,target:"_blank",rel:"noopener noreferrer",className:"text-micro text-secondary underline decoration-white/20 hover:text-primary",children:"View pricing"}):null]})]})},"upgrade"):ye==="error"&&ze?e.jsx(te.div,{initial:{opacity:0,y:-4},animate:{opacity:1,y:0},exit:{opacity:0,y:-4},transition:{duration:.18},className:"rounded-xl border border-red-400/25 bg-red-500/[0.08] px-3 py-2 text-caption text-red-100",children:ze},"error"):ye==="notice"&&F?e.jsx(te.div,{initial:{opacity:0,y:-4},animate:{opacity:1,y:0},exit:{opacity:0,y:-4},transition:{duration:.18},className:"rounded-xl border border-white/[0.1] bg-white/[0.03] px-3 py-2 text-caption text-primary",children:F},"notice"):null})}),e.jsxs("div",{className:`flex-1 space-y-2.5 overflow-y-auto overscroll-y-contain px-3 pb-3 ${m?"pt-1":"pt-2.5"}`,children:[!A&&R.length>0?e.jsxs("div",{className:"flex flex-col gap-2.5 px-0.5 sm:flex-row sm:items-start sm:justify-between",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"truncate text-micro uppercase tracking-[0.08em] text-muted",children:Fe==="blocked"?"Needs attention":Fe==="running"?"Running now":"Queue"}),e.jsxs("div",{className:"mt-1 flex flex-wrap items-center gap-1.5",children:[Z>0?e.jsxs("span",{className:"chip text-micro",children:[Z," selected"]}):null,e.jsx("span",{className:de("inline-flex min-w-[92px] text-micro text-muted transition-opacity",Be&&!A?"opacity-100":"opacity-0"),"aria-live":"polite",children:"refreshing…"}),K&&!u&&Z===0?e.jsx("span",{className:"text-micro text-muted",children:"Shift+select to pick ranges."}):null]})]}),e.jsxs("div",{className:"flex min-w-0 flex-wrap items-center gap-1.5 sm:justify-end",children:[U?e.jsx("button",{type:"button",onClick:()=>y(!u),className:"control-pill h-8 px-2.5 text-caption font-semibold",title:u?"Switch to expanded cards":"Switch to compact list","aria-label":u?"Expand Next Up queue":"Compact Next Up queue",children:u?"Expand":"Compact"}):null,_e?e.jsx("div",{className:"flex flex-wrap justify-end gap-1.5",children:Ue}):null,!_e&&re?e.jsxs("div",{ref:Te,className:"relative",children:[e.jsxs("button",{type:"button",onClick:()=>ie(n=>!n),className:"control-pill h-8 px-2.5 text-caption font-semibold","aria-haspopup":"menu","aria-expanded":se,title:"Queue settings",children:[e.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"opacity-85","aria-hidden":!0,children:[e.jsx("path",{d:"M4 6h16"}),e.jsx("path",{d:"M7 12h10"}),e.jsx("path",{d:"M10 18h4"})]}),e.jsx("span",{children:"Queue"})]}),se?e.jsx("div",{className:"surface-tier-2 absolute right-0 top-[calc(100%+8px)] z-[280] w-[320px] max-w-[86vw] rounded-xl p-3 shadow-[0_18px_42px_rgba(0,0,0,0.46)] backdrop-blur-xl",children:e.jsxs("div",{className:"space-y-2.5",children:[K&&!u?e.jsxs("div",{children:[e.jsx("p",{className:"section-kicker",children:"Bulk actions"}),e.jsx("div",{className:"mt-1.5 flex flex-wrap items-center gap-1.5",children:Ue})]}):null,C?e.jsx("button",{type:"button",onClick:()=>{ie(!1),C()},className:"control-pill h-7 px-2.5 text-micro font-semibold",children:"Open settings"}):null]})}):null]}):null]})]}):null,A?e.jsx(Lt,{compact:u}):null,!A&&k.length===0&&!ge&&e.jsxs("div",{className:"rounded-xl border border-white/[0.08] bg-white/[0.02] px-3 py-4 text-center",children:[e.jsx("p",{className:"text-body text-secondary",children:ft}),Ie?e.jsx("p",{className:"mt-1 text-micro text-muted",children:Ie}):null,X.length>0?e.jsx("div",{className:"mt-2.5 flex items-center justify-center gap-1.5",children:e.jsx("button",{type:"button",onClick:()=>{be(!1),ot()},className:"control-pill h-7 px-2.5 text-micro font-semibold",children:"Retry now"})}):null]}),!A&&u?e.jsx(Se,{initial:!1,children:k.map((n,l)=>{const o=q(n),s=$===o,p=n.queueState==="running",f=n.nextTaskDueAt?Ve(n.nextTaskDueAt):null,T=ke(n.initiativeTitle,n.initiativeId,"Initiative"),W=ke(n.workstreamTitle,n.workstreamId,"Workstream"),g=Ge(n),D=n.nextTaskTitle?V(n.nextTaskTitle):null,we=n.blockReason?V(n.blockReason):null,ve=Ye(n),ce=Oe(n);return e.jsxs(te.article,{layout:!0,initial:{opacity:0,y:6,scale:.99},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,y:-4,scale:.99},transition:{duration:.22,delay:Math.min(l,7)*.018,ease:[.22,1,.36,1]},className:"group relative overflow-visible rounded-2xl border border-white/[0.08] bg-white/[0.02] px-2.5 py-2 cursor-pointer transition-colors hover:border-white/[0.14]",onClick:()=>M==null?void 0:M(n),role:"button",tabIndex:0,onKeyDown:_=>{(_.key==="Enter"||_.key===" ")&&(_.preventDefault(),M==null||M(n))},children:[e.jsx("div",{className:`pointer-events-none absolute inset-x-2.5 top-0 h-px bg-gradient-to-r ${Ze(n.queueState)}`,"aria-hidden":!0}),e.jsxs("div",{className:"flex min-w-0 items-center gap-2.5",children:[e.jsx(He,{name:ve,hint:et(n,ve),size:"xs"}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-1.5",children:[e.jsx(ue,{type:"initiative",size:11,className:"flex-shrink-0 opacity-85"}),e.jsx("button",{type:"button",onClick:()=>G==null?void 0:G(n.initiativeId,n.initiativeTitle),className:"block min-w-0 flex-1 truncate text-left text-micro uppercase tracking-[0.08em] text-muted transition-colors hover:text-white/72",title:T,children:T}),g?e.jsx("span",{className:de("inline-flex flex-shrink-0 items-center rounded-full border px-2 py-0.5 text-[9px] font-semibold uppercase tracking-[0.08em]",g.toneClass),title:g.longLabel,children:g.shortLabel}):null]}),e.jsxs("p",{className:"mt-0.5 flex min-w-0 items-center gap-1.5 text-caption font-semibold leading-snug text-white",title:W,children:[e.jsx(ue,{type:"workstream",size:12,className:"flex-shrink-0 opacity-95"}),e.jsx("span",{className:"line-clamp-2",children:W})]}),D?e.jsxs("p",{className:"mt-0.5 line-clamp-2 text-micro leading-snug text-secondary",title:`${$e(n.queueState)}: ${D}${f?` · ${f}`:""}`,children:[$e(n.queueState),": ",D,f?` · ${f}`:""]}):e.jsx("p",{className:"mt-0.5 line-clamp-2 text-micro leading-snug text-secondary",title:qe(n),children:qe(n)}),ce?e.jsxs("p",{className:"mt-0.5 text-micro text-muted",children:["Runner ",ce]}):null]})]}),we&&e.jsxs("div",{className:"mt-1.5 rounded-lg border border-red-400/24 bg-red-500/[0.08] px-2.5 py-1 text-micro text-red-100/85",children:["Blocked: ",we]}),e.jsxs("div",{className:"mt-1.5 flex items-center gap-1.5",onClick:_=>_.stopPropagation(),children:[e.jsx("button",{type:"button",disabled:s||p,onClick:()=>void le(o,()=>Le({initiativeId:n.initiativeId,workstreamId:n.workstreamId,agentId:n.runnerAgentId}),_=>tt(n,_)),className:"control-pill flex h-7 items-center justify-center px-2.5 text-micro font-semibold disabled:opacity-40",title:p?"Already running":"Start now",children:e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(Xe,{className:"h-3 w-3 opacity-85"}),e.jsx("span",{children:p?"Running":"Start"})]})}),e.jsxs("div",{className:"relative ml-auto",children:[e.jsx("button",{type:"button",disabled:s,onClick:()=>I(_=>_===o?null:o),className:"control-pill flex h-7 items-center justify-center px-2.5 text-micro font-semibold disabled:opacity-40",title:"Queue actions",children:e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(nt,{className:"h-3 w-3 opacity-85"}),e.jsx("span",{children:"More"})]})}),E===o&&e.jsxs("div",{className:"absolute right-0 top-[calc(100%+6px)] z-[320] min-w-[178px] rounded-xl border border-white/[0.1] bg-[#080d14]/95 p-1.5 shadow-[0_16px_36px_rgba(0,0,0,0.42)] backdrop-blur",children:[e.jsx("button",{type:"button",onClick:()=>{I(null),le(`${o}:top`,()=>z.move({initiativeId:n.initiativeId,workstreamId:n.workstreamId,placement:"top"}),`Moved ${W} to top of queue.`)},className:"flex h-8 w-full items-center rounded-md px-2.5 text-left text-caption text-primary transition-colors hover:bg-white/[0.08]",children:"Move to top"}),e.jsx("button",{type:"button",onClick:()=>{I(null),le(`${o}:bottom`,()=>z.move({initiativeId:n.initiativeId,workstreamId:n.workstreamId,placement:"bottom"}),`Moved ${W} to bottom of queue.`)},className:"flex h-8 w-full items-center rounded-md px-2.5 text-left text-caption text-primary transition-colors hover:bg-white/[0.08]",children:"Move to bottom"}),e.jsx("button",{type:"button",onClick:()=>{I(null),le(`${o}:auto`,async()=>(await z.move({initiativeId:n.initiativeId,workstreamId:n.workstreamId,placement:"top"}),Me({initiativeId:n.initiativeId,workstreamId:n.workstreamId,agentId:n.runnerAgentId,scope:"initiative"})),`Start+Auto enabled for ${T}.`)},className:"flex h-8 w-full items-center rounded-md px-2.5 text-left text-caption text-primary transition-colors hover:bg-white/[0.08]",children:"Start with auto"}),e.jsx("button",{type:"button",disabled:z.isRemoving,onClick:()=>{I(null),Ae(n)},className:"mt-1 flex h-8 w-full items-center rounded-md px-2.5 text-left text-caption text-red-100 transition-colors hover:bg-red-500/[0.12] disabled:opacity-45",children:"Remove from queue"})]})]})]})]},o)})}):A?null:e.jsx(kt,{axis:"y",values:O,onReorder:n=>{Ne.current=n,Pe(n)},className:"space-y-2.5",children:O.map(n=>Ee.get(n)).filter(Boolean).map((n,l)=>e.jsx(Ft,{item:n,index:l,actionKey:$,setNotice:h,setUpgradeGate:P,onUpgradeGate:L,onOpenInitiative:G,onOpenSliceDetail:M,selected:S.has(q(n)),selectionEnabled:K,onToggleSelection:dt,menuKey:E,setMenuKey:I,playWorkstream:Le,startWorkstreamAutoContinue:Me,triagePlacement:he,onPauseWorkstream:(o,s)=>z.stopTriage({initiativeId:o.initiativeId,workstreamId:o.workstreamId,placement:s,resetToTodo:!1}),onMoveWorkstream:(o,s)=>z.move({initiativeId:o.initiativeId,workstreamId:o.workstreamId,placement:s}),onCommitReorder:()=>void mt().catch(()=>null),onDismiss:Ae,runAction:le},q(n)))})]}),e.jsx("div",{className:"pointer-events-none absolute bottom-3 right-3 z-[250]",children:e.jsx($t,{open:ht,tone:"warning",title:"Limited signal",message:Ie,autoDismissMs:6e3,onDismiss:()=>be(!0)})})]})}function Ft({item:t,index:r,actionKey:a,setNotice:i,setUpgradeGate:x,onUpgradeGate:m,onOpenInitiative:b,onOpenSliceDetail:v,selected:j,selectionEnabled:U,onToggleSelection:ne,menuKey:G,setMenuKey:C,playWorkstream:L,startWorkstreamAutoContinue:M,triagePlacement:K,onPauseWorkstream:xe,onMoveWorkstream:re,onCommitReorder:me,onDismiss:je,runAction:H}){const pe=jt(),[J,u]=c.useState(!1),y=`${t.initiativeId}:${t.workstreamId}`,F=a===y,h=t.queueState==="running",he=t.nextTaskDueAt?Ve(t.nextTaskDueAt):null,w=ke(t.initiativeTitle,t.initiativeId,"Initiative"),P=ke(t.workstreamTitle,t.workstreamId,"Workstream"),$=Ge(t),Q=t.nextTaskTitle?V(t.nextTaskTitle):null,E=t.blockReason?V(t.blockReason):null,I=Ye(t),S=Oe(t);return e.jsx(Nt,{value:y,id:y,dragListener:!1,dragControls:pe,onDragStart:()=>u(!0),onDragEnd:()=>{u(!1),me()},whileDrag:{scale:1.02,boxShadow:"0 20px 48px rgba(0,0,0,0.5), 0 0 0 1px rgba(191,255,0,0.15)",zIndex:50,cursor:"grabbing"},className:"relative",children:e.jsxs(te.article,{layout:!0,initial:{opacity:0,y:12,scale:.97},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,y:-8,scale:.98},transition:{duration:.4,ease:[.25,.1,.25,1],delay:Math.min(r,7)*.05,opacity:{duration:.32,ease:[.25,.1,.25,1]}},className:"group relative overflow-visible rounded-2xl border border-white/[0.08] bg-white/[0.02] px-3 py-3 cursor-pointer transition-colors hover:border-white/[0.14]",onClick:()=>v==null?void 0:v(t),role:"button",tabIndex:0,onKeyDown:d=>{(d.key==="Enter"||d.key===" ")&&(d.preventDefault(),v==null||v(t))},children:[e.jsx("div",{className:`pointer-events-none absolute inset-x-3 top-0 h-px bg-gradient-to-r ${Ze(t.queueState)}`,"aria-hidden":!0}),e.jsx("div",{className:"flex items-start justify-between gap-2.5",children:e.jsxs("div",{className:"min-w-0 flex flex-1 items-start gap-2.5",children:[e.jsxs("div",{className:"relative h-8 w-8 flex-shrink-0",children:[e.jsx("div",{className:`absolute inset-0 transition-[opacity,transform] duration-200 ease-out ${U?j?"opacity-0 scale-90":"opacity-100 scale-100 group-hover:opacity-0 group-hover:scale-90 group-focus-within:opacity-0 group-focus-within:scale-90":"opacity-100 scale-100"}`,children:e.jsx(He,{name:I,hint:et(t,I),size:"sm"})}),U?e.jsx("button",{type:"button",role:"checkbox","aria-checked":j,"aria-label":"Select queue row",title:j?"Selected (Shift+click for range)":"Select (Shift+click for range)",onClick:d=>{d.stopPropagation(),ne(y,!j,d.shiftKey)},onMouseDown:d=>d.stopPropagation(),onKeyDown:d=>d.stopPropagation(),className:`absolute inset-0 flex items-center justify-center rounded-full border transition-[opacity,transform,background-color,border-color,color] duration-200 ease-out ${j?"opacity-100 scale-100 border-[#BFFF00]/40 bg-[#BFFF00]/18 text-[#E1FFB2]":"opacity-0 scale-90 border-white/[0.24] bg-black/55 text-white/78 group-hover:opacity-100 group-hover:scale-100 group-focus-within:opacity-100 group-focus-within:scale-100 hover:bg-black/62"}`,children:e.jsx("span",{className:"inline-flex h-4 w-4 items-center justify-center rounded-full border border-current/45 bg-black/30",children:j?e.jsx("svg",{viewBox:"0 0 16 16",className:"h-2.5 w-2.5",fill:"none","aria-hidden":!0,children:e.jsx("path",{d:"M3.2 8.3 6.2 11l6.6-6.1",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})}):null})}):null]}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-1.5",children:[e.jsx(ue,{type:"initiative",size:11,className:"flex-shrink-0 opacity-85"}),e.jsx("button",{type:"button",onClick:()=>b==null?void 0:b(t.initiativeId,t.initiativeTitle),className:"block min-w-0 flex-1 truncate text-left text-micro uppercase tracking-[0.08em] text-muted transition-colors hover:text-white/72",title:w,children:w}),$?e.jsx("span",{className:de("inline-flex flex-shrink-0 items-center rounded-full border px-2 py-0.5 text-[9px] font-semibold uppercase tracking-[0.08em]",$.toneClass),title:$.longLabel,children:$.shortLabel}):null]}),e.jsxs("div",{className:"mt-0.5 flex min-w-0 items-start gap-1.5",children:[e.jsx(ue,{type:"workstream",size:12,className:"mt-[3px] flex-shrink-0 opacity-95"}),e.jsx("p",{className:"min-w-0 line-clamp-2 text-body font-semibold leading-snug text-white",title:P,children:P})]}),e.jsxs("div",{className:"mt-1.5 flex items-center gap-2 text-micro text-secondary",children:[e.jsx("span",{className:"rounded-full border border-strong bg-white/[0.03] px-2 py-0.5 text-micro uppercase tracking-[0.08em] text-secondary",children:"Runner"}),e.jsxs("span",{className:"truncate text-white/68",children:[I,S?` · ${S}`:""]})]})]})]})}),e.jsx("div",{className:"mt-2 rounded-lg border border-white/[0.07] bg-black/[0.18] px-2.5 py-2 text-caption text-white/68",children:Q?e.jsxs("div",{className:"space-y-1",children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-1 text-micro uppercase tracking-[0.08em] text-white/44",children:[e.jsx(ue,{type:"task",size:10,className:"flex-shrink-0 opacity-80"}),e.jsx("span",{children:$e(t.queueState)}),he?e.jsxs("span",{className:"truncate text-micro normal-case tracking-normal text-muted",children:["· ",he]}):null]}),e.jsx("p",{className:"line-clamp-2 break-words text-caption leading-snug text-white/84",title:Q,children:Q})]}):e.jsx("span",{className:"text-secondary",children:qe(t)})}),E&&e.jsxs("div",{className:"mt-1.5 rounded-lg border border-red-400/24 bg-red-500/[0.08] px-2.5 py-1 text-micro text-red-100/85",children:["Blocked: ",E]}),e.jsxs("div",{className:"mt-2 flex items-center gap-1.5",onClick:d=>d.stopPropagation(),children:[e.jsx("button",{type:"button",disabled:F||h,onClick:()=>void H(y,()=>L({initiativeId:t.initiativeId,workstreamId:t.workstreamId,agentId:t.runnerAgentId}),d=>tt(t,d)),className:"control-pill flex h-7 items-center justify-center px-2.5 text-micro font-semibold disabled:opacity-40",title:h?"Already running":"Start this workstream now",children:e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(Xe,{className:"h-3 w-3 opacity-85"}),e.jsx("span",{children:h?"Running":"Start"})]})}),e.jsxs("button",{type:"button",onPointerDown:d=>pe.start(d),"aria-label":"Drag to reorder",title:J?"Reordering":"Drag to reorder",className:`control-pill flex h-7 items-center justify-center gap-1 px-2 text-micro font-semibold transition-colors ${J?"border-[#BFFF00]/35 bg-[#BFFF00]/14 text-[#E1FFB2] cursor-grabbing":"cursor-grab hover:bg-white/[0.08] hover:text-bright"}`,children:[J?e.jsx(Rt,{className:"h-3.5 w-3.5 opacity-90"}):e.jsx(qt,{className:"h-3.5 w-3.5 opacity-90"}),e.jsx("span",{children:J?"Reordering":"Drag"})]}),e.jsxs("div",{className:"relative ml-auto",children:[e.jsx("button",{type:"button",disabled:F,onClick:()=>C(d=>d===y?null:y),className:"control-pill flex h-7 items-center justify-center px-2.5 text-micro font-semibold disabled:opacity-40",title:"Queue actions",children:e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(nt,{className:"h-3 w-3 opacity-85"}),e.jsx("span",{children:"More"})]})}),G===y&&e.jsxs("div",{className:"absolute right-0 top-[calc(100%+6px)] z-[320] min-w-[198px] rounded-xl border border-white/[0.1] bg-[#080d14]/95 p-1.5 shadow-[0_16px_36px_rgba(0,0,0,0.42)] backdrop-blur",children:[e.jsx("button",{type:"button",onClick:()=>{C(null),H(`${y}:top`,()=>re(t,"top"),`Moved ${P} to top of queue.`)},className:"flex h-8 w-full items-center rounded-md px-2.5 text-left text-caption text-primary transition-colors hover:bg-white/[0.08]",children:"Move to top"}),e.jsx("button",{type:"button",onClick:()=>{C(null),H(`${y}:bottom`,()=>re(t,"bottom"),`Moved ${P} to bottom of queue.`)},className:"flex h-8 w-full items-center rounded-md px-2.5 text-left text-caption text-primary transition-colors hover:bg-white/[0.08]",children:"Move to bottom"}),e.jsx("button",{type:"button",onClick:()=>{C(null),H(`${y}:auto`,async()=>(await re(t,"top"),M({initiativeId:t.initiativeId,workstreamId:t.workstreamId,agentId:t.runnerAgentId,scope:"initiative"})),`Start+Auto enabled for ${w}.`)},className:"flex h-8 w-full items-center rounded-md px-2.5 text-left text-caption text-primary transition-colors hover:bg-white/[0.08]",children:"Start with auto"}),h?e.jsx("button",{type:"button",onClick:()=>{C(null),H(`${y}:pause`,()=>xe(t,K),`Paused ${P}.`)},className:"mt-1 flex h-8 w-full items-center rounded-md px-2.5 text-left text-caption text-primary transition-colors hover:bg-white/[0.08]",children:"Pause run"}):null,e.jsx("button",{type:"button",disabled:F||h,onClick:()=>{C(null),je(t)},className:"mt-1 flex h-8 w-full items-center rounded-md px-2.5 text-left text-caption text-red-100 transition-colors hover:bg-red-500/[0.12] disabled:opacity-45",children:"Remove from queue"})]})]})]})]})})}const _t=Object.freeze(Object.defineProperty({__proto__:null,NextUpPanel:Mt},Symbol.toStringTag,{value:"Module"}));export{$t as I,Mt as N,_t as a,Ct as o};