codedeck 0.4.2 → 0.5.1

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 (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +15 -0
  3. package/dist/cli/charts/stacked-bar.js +2 -1
  4. package/dist/cli/charts/stacked-bar.js.map +1 -1
  5. package/dist/cli/commands/doctor.js +10 -2
  6. package/dist/cli/commands/doctor.js.map +1 -1
  7. package/dist/cli/commands/open.js +182 -38
  8. package/dist/cli/commands/open.js.map +1 -1
  9. package/dist/cli/commands/profile.js +191 -0
  10. package/dist/cli/commands/profile.js.map +1 -0
  11. package/dist/cli/commands/run.js +36 -5
  12. package/dist/cli/commands/run.js.map +1 -1
  13. package/dist/cli/commands/setup.js +175 -23
  14. package/dist/cli/commands/setup.js.map +1 -1
  15. package/dist/cli/commands/web.js +22 -1
  16. package/dist/cli/commands/web.js.map +1 -1
  17. package/dist/cli/index.js +2 -0
  18. package/dist/cli/index.js.map +1 -1
  19. package/dist/cli/usage/dashboard.js +12 -7
  20. package/dist/cli/usage/dashboard.js.map +1 -1
  21. package/dist/config/config.js +82 -2
  22. package/dist/config/config.js.map +1 -1
  23. package/dist/daemon/daemon.js +1 -0
  24. package/dist/daemon/daemon.js.map +1 -1
  25. package/dist/drivers/codex/parser.js +14 -10
  26. package/dist/drivers/codex/parser.js.map +1 -1
  27. package/dist/git/review.js +357 -0
  28. package/dist/git/review.js.map +1 -0
  29. package/dist/open/contract.js.map +1 -1
  30. package/dist/open/launchers/claude.js +8 -2
  31. package/dist/open/launchers/claude.js.map +1 -1
  32. package/dist/open/launchers/codex.js +236 -0
  33. package/dist/open/launchers/codex.js.map +1 -0
  34. package/dist/plugin/agents/auditor.md +2 -0
  35. package/dist/plugin/agents/general.md +10 -2
  36. package/dist/plugin/agents/orchestrator-edit.md +10 -2
  37. package/dist/plugin/agents/orchestrator-read.md +10 -2
  38. package/dist/plugin/agents/orchestrator.md +18 -3
  39. package/dist/plugin/prompts/_partials/dispatch.md +2 -0
  40. package/dist/plugin/prompts/_partials/reports-dispatch.md +5 -0
  41. package/dist/plugin/prompts/_partials/reports-general.md +5 -0
  42. package/dist/plugin/prompts/_partials/spec-gates.md +6 -0
  43. package/dist/plugin/prompts/_partials/worktree.md +1 -1
  44. package/dist/plugin/prompts/roles/general.md +1 -0
  45. package/dist/plugin/prompts/roles/orchestrator-edit.md +1 -0
  46. package/dist/plugin/prompts/roles/orchestrator-read.md +1 -0
  47. package/dist/plugin/prompts/roles/orchestrator.md +3 -1
  48. package/dist/web/canvas-page.js +79 -33
  49. package/dist/web/canvas-page.js.map +1 -1
  50. package/dist/web/review-page.js +664 -0
  51. package/dist/web/review-page.js.map +1 -0
  52. package/package.json +1 -1
@@ -42,12 +42,17 @@ export const CANVAS_PAGE = `<!doctype html>
42
42
  .dot.resting { background: #636366; }
43
43
  .dot.done { background: #3a3a3c; }
44
44
  .dot.failed { background: #ff453a; box-shadow: 0 0 8px rgba(255,69,58,.8); }
45
- #feed { left: 16px; top: 112px; width: 300px; }
45
+ #feed { left: 16px; top: 112px; width: 330px; }
46
46
  #feed h2 { font-size: 11px; letter-spacing: .06em; color: #98989f; margin: 0 0 8px; }
47
- #feed ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
48
- #feed li { font-size: 12.5px; color: #98989f; display: flex; gap: 8px; animation: feedIn .3s ease-out; }
49
- #feed li b { color: #f5f5f7; white-space: nowrap; }
47
+ #feed ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
48
+ #feed li { font-size: 12px; color: #98989f; display: flex; align-items: baseline; gap: 7px; animation: feedIn .3s ease-out; line-height: 1.35; }
49
+ #feed li b { color: #f5f5f7; white-space: nowrap; font-weight: 600; font-size: 12px; }
50
50
  #feed li.fresh { color: #f5f5f7; }
51
+ #feed li.warn { color: #ff9f0a; }
52
+ #feed li.bad { color: #ff453a; }
53
+ #feed .feed-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 11.5px; }
54
+ #feed .feed-count { font-size: 11px; color: #636366; font-weight: 600; margin-left: 2px; white-space: nowrap; flex-shrink: 0; font-family: system-ui, sans-serif; }
55
+ #feed li.fresh .feed-count { color: #8e8e93; }
51
56
  @keyframes feedIn { from { opacity: 0; transform: translateY(-5px); } to { opacity: 1; } }
52
57
  #hint { left: 50%; transform: translateX(-50%); bottom: 16px; font-size: 12px; color: #98989f; white-space: nowrap; }
53
58
  #detail { position: fixed; top: 0; right: 0; bottom: 0; width: min(400px, 94vw); z-index: 20;
@@ -97,14 +102,15 @@ export const CANVAS_PAGE = `<!doctype html>
97
102
  .node:active { cursor: grabbing; }
98
103
  .node { transform-origin: 0 0; }
99
104
  .node.orch { width: 228px; border-color: rgba(255,255,255,.18); }
100
- .node .row { display: flex; align-items: center; gap: 8px; }
105
+ .node .row { display: flex; align-items: center; gap: 8px; min-width: 0; }
106
+ .node .row .dot { flex-shrink: 0; }
101
107
  .node .logo { width: 22px; height: 22px; display: inline-flex; flex-shrink: 0; }
102
108
  .node .logo svg { width: 22px; height: 22px; fill: #f5f5f7; }
103
109
  .node.orch .logo { width: 26px; height: 26px; }
104
110
  .node.orch .logo svg { width: 26px; height: 26px; }
105
- .node .name { font-size: 13.5px; font-weight: 650; }
106
- .node .sub { font-size: 12px; color: #98989f; margin-top: 3px; }
107
- .node .act { font-size: 12px; color: #98989f; margin-top: 5px; min-height: 15px; }
111
+ .node .name { font-size: 13.5px; font-weight: 650; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
112
+ .node .sub { font-size: 12px; color: #98989f; margin-top: 3px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
113
+ .node .act { font-size: 12px; color: #98989f; margin-top: 5px; min-height: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
108
114
  .node .act b { color: #f5f5f7; }
109
115
  .node.alert { border-color: rgba(255,159,10,.65); animation: alertPulse 1.6s ease-in-out infinite; }
110
116
  @keyframes alertPulse { 0%,100% { border-color: rgba(255,159,10,.65); } 50% { border-color: rgba(255,159,10,1); } }
@@ -176,28 +182,41 @@ function toolHuman(name) {
176
182
  if (name === "bash" || name === "Bash") return "terminal";
177
183
  return name;
178
184
  }
185
+ function shortPath(s) {
186
+ if (!s || typeof s !== "string") return "";
187
+ var clean = s.replace(/\\\\/g, "/").replace(/\\/\\/+$/, "");
188
+ var parts = clean.split("/").filter(Boolean);
189
+ if (parts.length > 2) return parts.slice(-2).join("/");
190
+ return parts.join("/") || s;
191
+ }
179
192
  /* Pedaco do input real da ferramenta: primeira string interessante, cortada.
180
193
  "terminal" sozinho nao diz nada; "podman ps" diz. */
181
194
  function inputSnippet(input) {
182
195
  if (!input) return "";
183
196
  if (typeof input === "string") return clip(input);
184
197
  if (typeof input !== "object") return "";
185
- var keys = ["command", "cmd", "file", "path", "query", "pattern", "message", "text", "url"];
186
- for (var i = 0; i < keys.length; i++) {
187
- var v = input[keys[i]];
188
- if (typeof v === "string" && v.trim() !== "") return clip(v);
198
+ if (Array.isArray(input.todos)) return "(" + input.todos.length + " tarefas)";
199
+ var pathKeys = ["filePath", "file_path", "filename", "file", "path", "target", "dest", "directory", "dir"];
200
+ for (var p = 0; p < pathKeys.length; p++) {
201
+ var pv = input[pathKeys[p]];
202
+ if (typeof pv === "string" && pv.trim() !== "") return clip(shortPath(pv.trim()));
203
+ }
204
+ var textKeys = ["command", "cmd", "script", "query", "pattern", "regex", "title", "message", "text", "prompt", "url"];
205
+ for (var t = 0; t < textKeys.length; t++) {
206
+ var tv = input[textKeys[t]];
207
+ if (typeof tv === "string" && tv.trim() !== "") return clip(tv.trim());
189
208
  }
190
209
  return "";
191
210
  }
192
211
  function clip(s) {
193
- var one = String(s).replace(/\s+/g, " ").trim();
194
- return one.length > 42 ? one.slice(0, 42) + "…" : one;
212
+ var one = String(s).replace(/\\s+/g, " ").trim();
213
+ return one.length > 40 ? one.slice(0, 40) + "…" : one;
195
214
  }
196
215
  function toolLabel(tool) {
197
216
  var name = (tool && tool.name) || "";
198
- var snip = inputSnippet(tool && tool.input);
199
- if (!name) return snip || "uma tarefa";
200
- if (name === "bash" || name === "Bash") return snip ? '"' + snip + '"' : "terminal";
217
+ var snip = (tool && tool.title && typeof tool.title === "string") ? clip(tool.title) : inputSnippet(tool && tool.input);
218
+ if (!name) return snip || "tarefa";
219
+ if (name === "bash" || name === "Bash") return snip ? "$ " + snip : "terminal";
201
220
  return snip ? name + " " + snip : name;
202
221
  }
203
222
  function timeAgo(iso) {
@@ -317,17 +336,42 @@ function paintNode(n) {
317
336
  b.textContent = STATUS_HUMAN[n.status] || "Encerrada";
318
337
  n.actEl.appendChild(b);
319
338
  n.actEl.appendChild(document.createTextNode(" · " + n.activity));
339
+ n.actEl.title = (STATUS_HUMAN[n.status] || "") + (n.activity ? " · " + n.activity : "");
320
340
  n.el.classList.toggle("orch", !!n.isOrch);
321
341
  n.el.classList.toggle("alert", n.status === "needs_input");
322
342
  n.el.title = "sessão " + n.id + (n.label ? " · " + n.label : "");
323
343
  }
324
- function feed(agent, text) {
344
+ function feed(agent, text, kind) {
345
+ if (!text) return;
346
+ var top = feedList.firstElementChild;
347
+ if (top && top._agent === agent && top._text === text) {
348
+ var count = (top._count || 1) + 1;
349
+ top._count = count;
350
+ var badge = top.querySelector(".feed-count");
351
+ if (!badge) {
352
+ badge = document.createElement("span");
353
+ badge.className = "feed-count";
354
+ top.appendChild(badge);
355
+ }
356
+ badge.textContent = "×" + count;
357
+ top.classList.remove("fresh");
358
+ void top.offsetWidth;
359
+ top.classList.add("fresh");
360
+ return;
361
+ }
325
362
  var li = document.createElement("li");
326
- li.className = "fresh";
363
+ li.className = "fresh" + (kind ? " " + kind : "");
364
+ li._agent = agent;
365
+ li._text = text;
366
+ li._count = 1;
367
+ li.title = agent + ": " + text;
327
368
  var b = document.createElement("b");
328
369
  b.textContent = agent;
329
370
  li.appendChild(b);
330
- li.appendChild(document.createTextNode(text));
371
+ var span = document.createElement("span");
372
+ span.className = "feed-text";
373
+ span.textContent = text;
374
+ li.appendChild(span);
331
375
  feedList.insertBefore(li, feedList.firstChild);
332
376
  while (feedList.children.length > 6) feedList.removeChild(feedList.lastChild);
333
377
  var items = feedList.children;
@@ -563,15 +607,16 @@ function onEvent(n, ev) {
563
607
  spawnRing(n, "#0a84ff");
564
608
  spawnFlow(n, "#0a84ff", 1);
565
609
  touch(n, toolLabel(ev.tool));
566
- feed(agentName(n.agent), "começou: " + toolLabel(ev.tool));
610
+ feed(agentName(n.agent), toolLabel(ev.tool));
567
611
  } else if (ev.type === "tool.completed") {
568
612
  var bad = ev.tool && ev.tool.success === false;
569
613
  touch(n, toolLabel(ev.tool) + (bad ? " (com erro)" : " ✓"));
570
- if (bad) feed(agentName(n.agent), "ferramenta falhou");
614
+ if (bad) feed(agentName(n.agent), "falhou: " + toolLabel(ev.tool), "bad");
571
615
  } else if (ev.type === "message") {
572
616
  if (ev.role === "assistant") {
573
617
  touch(n, "respondendo");
574
- feed(agentName(n.agent), String(ev.content || "").slice(0, 90));
618
+ var textSnippet = clip(ev.content || "");
619
+ if (textSnippet) feed(agentName(n.agent), textSnippet);
575
620
  }
576
621
  } else if (ev.type === "message.queued") {
577
622
  touch(n, "mensagem na fila");
@@ -580,20 +625,20 @@ function onEvent(n, ev) {
580
625
  } else if (ev.type === "turn.started") {
581
626
  if (n.id && n.id === detailId && detailPending) { detailPending = null; paintSendState(); }
582
627
  } else if (ev.type === "turn.completed") {
583
- feed(agentName(n.agent), "etapa concluída");
628
+ // turn completion is recorded on node activity
584
629
  } else if (ev.type === "file.changed") {
585
- feed(agentName(n.agent), "mudou " + (ev.path || "um arquivo"));
630
+ feed(agentName(n.agent), "salvou " + (shortPath(ev.path === "unknown" ? "" : ev.path) || "arquivo"));
586
631
  } else if (ev.type === "permission.requested") {
587
632
  n.status = "needs_input";
588
633
  touch(n, "quer sua aprovação para continuar");
589
634
  paintSummary();
590
635
  spawnRing(n, "#ff9f0a");
591
- feed(agentName(n.agent), "pedindo sua aprovação");
636
+ feed(agentName(n.agent), "precisa de aprovação", "warn");
592
637
  } else if (ev.type === "session.completed" || ev.type === "session.failed") {
593
638
  n.status = ev.type === "session.failed" ? "failed" : "completed";
594
639
  touch(n, ev.type === "session.failed" ? ("falhou: " + (ev.error || "")) : "concluída");
595
640
  paintSummary();
596
- feed(agentName(n.agent), ev.type === "session.failed" ? "falhou" : "concluída");
641
+ feed(agentName(n.agent), ev.type === "session.failed" ? "falhou" : "concluída", ev.type === "session.failed" ? "bad" : "");
597
642
  // Stop/release cancels the queue server-side: drop a stale "na fila"
598
643
  // hint on the open detail, mirroring the turn.started branch.
599
644
  if (n.id && n.id === detailId && detailPending) { detailPending = null; paintSendState(); }
@@ -671,6 +716,7 @@ function frame() {
671
716
  if (nodes[i].runId === n.runId && nodes[i].isOrch) { o = nodes[i]; break; }
672
717
  }
673
718
  if (!o) return;
719
+ if (hideDone && isDone(o.status)) return;
674
720
  var e = edgeCurve(n, o);
675
721
  var pa = w2s(e.ax, e.ay), pb = w2s(e.bx, e.by), pc = w2s(e.cx, e.cy);
676
722
  ctx.beginPath();
@@ -940,8 +986,8 @@ function selectSession(id) {
940
986
  var repo = s.repository ? String(s.repository).split("/").pop() : "";
941
987
  var items = [
942
988
  ["Modelo", s.model || "—"],
943
- // effort so existe quando a sessao nasceu com --effort; ausente = padrao.
944
- ["Esforço", s.effort || "padrão"],
989
+ // effort chega sempre para claude/codex/omp/antigravity; ausente = opencode (ignora) ou sessão legada.
990
+ ["Esforço", s.effort || "n/a"],
945
991
  ["Repo", repo || "—"],
946
992
  ["Atividade", s.lastEvent ? (lastEventHuman(s.lastEvent) || s.lastEvent) : "—"],
947
993
  ];
@@ -973,14 +1019,14 @@ function selectSession(id) {
973
1019
  } else if (ev.type === "message" && ev.role === "assistant" && ev.content) {
974
1020
  chat.appendChild(chatMsg(agentName(s.agent), String(ev.content), "assistant"));
975
1021
  } else if (ev.type === "tool.started") {
976
- chat.appendChild(chatEvt("começou: " + toolLabel(ev.tool)));
1022
+ chat.appendChild(chatEvt(toolLabel(ev.tool)));
977
1023
  } else if (ev.type === "tool.completed") {
978
1024
  var bad = ev.tool && ev.tool.success === false;
979
- chat.appendChild(chatEvt("terminou: " + toolLabel(ev.tool) + (bad ? " (com erro)" : "")));
1025
+ if (bad) chat.appendChild(chatEvt("falhou: " + toolLabel(ev.tool)));
980
1026
  } else if (ev.type === "permission.requested") {
981
- chat.appendChild(chatEvt("pediu aprovação: " + (ev.tool || "uma ação")));
1027
+ chat.appendChild(chatEvt("precisa de aprovação: " + (ev.tool || "uma ação")));
982
1028
  } else if (ev.type === "file.changed") {
983
- chat.appendChild(chatEvt("mudou " + (ev.path || "um arquivo")));
1029
+ chat.appendChild(chatEvt("salvou " + (shortPath(ev.path === "unknown" ? "" : ev.path) || "arquivo")));
984
1030
  }
985
1031
  }
986
1032
  if (!chat.children.length) {
@@ -1 +1 @@
1
- {"version":3,"file":"canvas-page.js","sourceRoot":"","sources":["../../src/web/canvas-page.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,WAAW,GAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAuiC3B,CAAC"}
1
+ {"version":3,"file":"canvas-page.js","sourceRoot":"","sources":["../../src/web/canvas-page.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,WAAW,GAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAqlC3B,CAAC"}