sisyphi 1.1.17 → 1.1.19

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 (237) hide show
  1. package/README.md +347 -25
  2. package/dist/chunk-36VJ7ZBD.js +1898 -0
  3. package/dist/chunk-36VJ7ZBD.js.map +1 -0
  4. package/dist/chunk-M6Z3KHOH.js +1165 -0
  5. package/dist/chunk-M6Z3KHOH.js.map +1 -0
  6. package/dist/chunk-O4ZHSQ5R.js +544 -0
  7. package/dist/chunk-O4ZHSQ5R.js.map +1 -0
  8. package/dist/chunk-P2HHTIPM.js +478 -0
  9. package/dist/chunk-P2HHTIPM.js.map +1 -0
  10. package/dist/{chunk-GSXF3TCZ.js → chunk-PNDCVKBN.js} +91 -3
  11. package/dist/chunk-PNDCVKBN.js.map +1 -0
  12. package/dist/chunk-SVGIQ2G4.js +1076 -0
  13. package/dist/chunk-SVGIQ2G4.js.map +1 -0
  14. package/dist/cli.js +4426 -818
  15. package/dist/cli.js.map +1 -1
  16. package/dist/daemon.js +4351 -857
  17. package/dist/daemon.js.map +1 -1
  18. package/dist/paths-JXFLR5BN.js +102 -0
  19. package/dist/single-ask-6G4BIVY2.js +132 -0
  20. package/dist/single-ask-6G4BIVY2.js.map +1 -0
  21. package/dist/templates/CLAUDE.md +1 -56
  22. package/dist/templates/agent-plugin/agents/CLAUDE.md +2 -65
  23. package/dist/templates/agent-plugin/agents/debug.md +43 -6
  24. package/dist/templates/agent-plugin/agents/debug.settings.json +57 -0
  25. package/dist/templates/agent-plugin/agents/explore.md +28 -1
  26. package/dist/templates/agent-plugin/agents/explore.settings.json +57 -0
  27. package/dist/templates/agent-plugin/agents/implementor.md +94 -0
  28. package/dist/templates/agent-plugin/agents/implementor.settings.json +57 -0
  29. package/dist/templates/agent-plugin/agents/operator.md +43 -1
  30. package/dist/templates/agent-plugin/agents/operator.settings.json +57 -0
  31. package/dist/templates/agent-plugin/agents/plan/sub-planner.md +75 -0
  32. package/dist/templates/agent-plugin/agents/plan.md +176 -86
  33. package/dist/templates/agent-plugin/agents/plan.settings.json +57 -0
  34. package/dist/templates/agent-plugin/agents/problem/adversarial.md +26 -0
  35. package/dist/templates/agent-plugin/agents/problem/contrarian.md +26 -0
  36. package/dist/templates/agent-plugin/agents/problem/first-principles.md +26 -0
  37. package/dist/templates/agent-plugin/agents/problem/precedent.md +25 -0
  38. package/dist/templates/agent-plugin/agents/problem/simplifier.md +26 -0
  39. package/dist/templates/agent-plugin/agents/problem/systems-thinker.md +26 -0
  40. package/dist/templates/agent-plugin/agents/problem/time-traveler.md +26 -0
  41. package/dist/templates/agent-plugin/agents/problem/user-empathy.md +26 -0
  42. package/dist/templates/agent-plugin/agents/problem.md +334 -79
  43. package/dist/templates/agent-plugin/agents/problem.settings.json +57 -0
  44. package/dist/templates/agent-plugin/agents/research-lead/CLAUDE.md +26 -0
  45. package/dist/templates/agent-plugin/agents/research-lead/critic.md +61 -0
  46. package/dist/templates/agent-plugin/agents/research-lead/researcher.md +60 -0
  47. package/dist/templates/agent-plugin/agents/research-lead.md +184 -0
  48. package/dist/templates/agent-plugin/agents/research-lead.settings.json +57 -0
  49. package/dist/templates/agent-plugin/agents/review/CLAUDE.md +3 -29
  50. package/dist/templates/agent-plugin/agents/review/compliance.md +14 -3
  51. package/dist/templates/agent-plugin/agents/review/efficiency.md +15 -4
  52. package/dist/templates/agent-plugin/agents/review/quality.md +20 -6
  53. package/dist/templates/agent-plugin/agents/review/reuse.md +17 -5
  54. package/dist/templates/agent-plugin/agents/review/security.md +10 -3
  55. package/dist/templates/agent-plugin/agents/review/tests.md +58 -0
  56. package/dist/templates/agent-plugin/agents/review-plan/CLAUDE.md +28 -0
  57. package/dist/templates/agent-plugin/agents/review-plan/code-smells.md +4 -2
  58. package/dist/templates/agent-plugin/agents/review-plan/pattern-consistency.md +4 -2
  59. package/dist/templates/agent-plugin/agents/review-plan/requirements-coverage.md +3 -1
  60. package/dist/templates/agent-plugin/agents/review-plan/security.md +5 -2
  61. package/dist/templates/agent-plugin/agents/review-plan.md +52 -5
  62. package/dist/templates/agent-plugin/agents/review-plan.settings.json +57 -0
  63. package/dist/templates/agent-plugin/agents/review.md +89 -16
  64. package/dist/templates/agent-plugin/agents/review.settings.json +57 -0
  65. package/dist/templates/agent-plugin/agents/spec/engineer.md +175 -0
  66. package/dist/templates/agent-plugin/agents/spec/requirements-writer.md +149 -0
  67. package/dist/templates/agent-plugin/agents/spec.md +444 -0
  68. package/dist/templates/agent-plugin/agents/spec.settings.json +57 -0
  69. package/dist/templates/agent-plugin/agents/test-spec.md +58 -2
  70. package/dist/templates/agent-plugin/agents/test-spec.settings.json +57 -0
  71. package/dist/templates/agent-plugin/hooks/CLAUDE.md +9 -57
  72. package/dist/templates/agent-plugin/hooks/ask-background-guard.sh +57 -0
  73. package/dist/templates/agent-plugin/hooks/intercept-send-message.sh +1 -1
  74. package/dist/templates/agent-plugin/hooks/plan-user-prompt.sh +8 -7
  75. package/dist/templates/agent-plugin/hooks/plan-validate.sh +97 -0
  76. package/dist/templates/agent-plugin/hooks/plan-write-path.sh +55 -0
  77. package/dist/templates/agent-plugin/hooks/problem-user-prompt.sh +26 -0
  78. package/dist/templates/agent-plugin/hooks/register-bg-task.sh +37 -0
  79. package/dist/templates/agent-plugin/hooks/require-submit.sh +51 -42
  80. package/dist/templates/agent-plugin/hooks/review-user-prompt.sh +6 -2
  81. package/dist/templates/agent-plugin/hooks/spec-user-prompt.sh +43 -0
  82. package/dist/templates/agent-plugin/skills/humanloop/SKILL.md +147 -0
  83. package/dist/templates/agent-plugin/skills/perspective-fanout/SKILL.md +115 -0
  84. package/dist/templates/agent-plugin/skills/problem-document/SKILL.md +105 -0
  85. package/dist/templates/agent-plugin/skills/problem-plateau-breakers/SKILL.md +83 -0
  86. package/dist/templates/agent-suffix.md +7 -4
  87. package/dist/templates/baleia.lua +42 -0
  88. package/dist/templates/companion-plugin/hooks/user-prompt-context.sh +1 -1
  89. package/dist/templates/dashboard-claude.md +7 -3
  90. package/dist/templates/orchestrator-base.md +89 -52
  91. package/dist/templates/orchestrator-completion.md +47 -24
  92. package/dist/templates/orchestrator-discovery.md +183 -0
  93. package/dist/templates/orchestrator-impl.md +47 -18
  94. package/dist/templates/orchestrator-planning.md +109 -20
  95. package/dist/templates/orchestrator-plugin/commands/sisyphus/scratch.md +19 -0
  96. package/dist/templates/orchestrator-plugin/commands/sisyphus/spec.md +11 -0
  97. package/dist/templates/orchestrator-plugin/commands/sisyphus/strategize.md +5 -5
  98. package/dist/templates/orchestrator-plugin/hooks/hooks.json +0 -10
  99. package/dist/templates/orchestrator-plugin/skills/humanloop/SKILL.md +149 -0
  100. package/dist/templates/orchestrator-plugin/skills/orchestration/CLAUDE.md +1 -0
  101. package/dist/templates/orchestrator-plugin/skills/orchestration/SKILL.md +2 -1
  102. package/dist/templates/orchestrator-plugin/skills/orchestration/strategy.md +160 -0
  103. package/dist/templates/orchestrator-plugin/skills/orchestration/task-patterns.md +26 -28
  104. package/dist/templates/orchestrator-plugin/skills/orchestration/workflow-examples.md +133 -25
  105. package/dist/templates/orchestrator-settings.json +55 -0
  106. package/dist/templates/orchestrator-validation.md +17 -14
  107. package/dist/templates/sisyphus-init.lua +30 -0
  108. package/dist/templates/sisyphus-tmux-plugin/hooks/hooks.json +54 -0
  109. package/dist/templates/sisyphus-tmux-plugin/hooks/tmux-state.sh +19 -0
  110. package/dist/templates/termrender-haiku-system.md +82 -0
  111. package/dist/templates/whip-animation.sh +345 -0
  112. package/dist/tui.js +3789 -2406
  113. package/dist/tui.js.map +1 -1
  114. package/native/SisyphusNotify/AppIcon.icns +0 -0
  115. package/native/SisyphusNotify/Info.plist +26 -0
  116. package/native/SisyphusNotify/main.swift +136 -0
  117. package/native/SisyphusNotify/sisyphus-icon.jpg +0 -0
  118. package/native/build-notify.sh +58 -0
  119. package/package.json +9 -6
  120. package/templates/CLAUDE.md +1 -56
  121. package/templates/agent-plugin/agents/CLAUDE.md +2 -65
  122. package/templates/agent-plugin/agents/debug.md +43 -6
  123. package/templates/agent-plugin/agents/debug.settings.json +57 -0
  124. package/templates/agent-plugin/agents/explore.md +28 -1
  125. package/templates/agent-plugin/agents/explore.settings.json +57 -0
  126. package/templates/agent-plugin/agents/implementor.md +94 -0
  127. package/templates/agent-plugin/agents/implementor.settings.json +57 -0
  128. package/templates/agent-plugin/agents/operator.md +43 -1
  129. package/templates/agent-plugin/agents/operator.settings.json +57 -0
  130. package/templates/agent-plugin/agents/plan/sub-planner.md +75 -0
  131. package/templates/agent-plugin/agents/plan.md +176 -86
  132. package/templates/agent-plugin/agents/plan.settings.json +57 -0
  133. package/templates/agent-plugin/agents/problem/adversarial.md +26 -0
  134. package/templates/agent-plugin/agents/problem/contrarian.md +26 -0
  135. package/templates/agent-plugin/agents/problem/first-principles.md +26 -0
  136. package/templates/agent-plugin/agents/problem/precedent.md +25 -0
  137. package/templates/agent-plugin/agents/problem/simplifier.md +26 -0
  138. package/templates/agent-plugin/agents/problem/systems-thinker.md +26 -0
  139. package/templates/agent-plugin/agents/problem/time-traveler.md +26 -0
  140. package/templates/agent-plugin/agents/problem/user-empathy.md +26 -0
  141. package/templates/agent-plugin/agents/problem.md +334 -79
  142. package/templates/agent-plugin/agents/problem.settings.json +57 -0
  143. package/templates/agent-plugin/agents/research-lead/CLAUDE.md +26 -0
  144. package/templates/agent-plugin/agents/research-lead/critic.md +61 -0
  145. package/templates/agent-plugin/agents/research-lead/researcher.md +60 -0
  146. package/templates/agent-plugin/agents/research-lead.md +184 -0
  147. package/templates/agent-plugin/agents/research-lead.settings.json +57 -0
  148. package/templates/agent-plugin/agents/review/CLAUDE.md +3 -29
  149. package/templates/agent-plugin/agents/review/compliance.md +14 -3
  150. package/templates/agent-plugin/agents/review/efficiency.md +15 -4
  151. package/templates/agent-plugin/agents/review/quality.md +20 -6
  152. package/templates/agent-plugin/agents/review/reuse.md +17 -5
  153. package/templates/agent-plugin/agents/review/security.md +10 -3
  154. package/templates/agent-plugin/agents/review/tests.md +58 -0
  155. package/templates/agent-plugin/agents/review-plan/CLAUDE.md +28 -0
  156. package/templates/agent-plugin/agents/review-plan/code-smells.md +4 -2
  157. package/templates/agent-plugin/agents/review-plan/pattern-consistency.md +4 -2
  158. package/templates/agent-plugin/agents/review-plan/requirements-coverage.md +3 -1
  159. package/templates/agent-plugin/agents/review-plan/security.md +5 -2
  160. package/templates/agent-plugin/agents/review-plan.md +52 -5
  161. package/templates/agent-plugin/agents/review-plan.settings.json +57 -0
  162. package/templates/agent-plugin/agents/review.md +89 -16
  163. package/templates/agent-plugin/agents/review.settings.json +57 -0
  164. package/templates/agent-plugin/agents/spec/engineer.md +175 -0
  165. package/templates/agent-plugin/agents/spec/requirements-writer.md +149 -0
  166. package/templates/agent-plugin/agents/spec.md +444 -0
  167. package/templates/agent-plugin/agents/spec.settings.json +57 -0
  168. package/templates/agent-plugin/agents/test-spec.md +58 -2
  169. package/templates/agent-plugin/agents/test-spec.settings.json +57 -0
  170. package/templates/agent-plugin/hooks/CLAUDE.md +9 -57
  171. package/templates/agent-plugin/hooks/ask-background-guard.sh +57 -0
  172. package/templates/agent-plugin/hooks/intercept-send-message.sh +1 -1
  173. package/templates/agent-plugin/hooks/plan-user-prompt.sh +8 -7
  174. package/templates/agent-plugin/hooks/plan-validate.sh +97 -0
  175. package/templates/agent-plugin/hooks/plan-write-path.sh +55 -0
  176. package/templates/agent-plugin/hooks/problem-user-prompt.sh +26 -0
  177. package/templates/agent-plugin/hooks/register-bg-task.sh +37 -0
  178. package/templates/agent-plugin/hooks/require-submit.sh +51 -42
  179. package/templates/agent-plugin/hooks/review-user-prompt.sh +6 -2
  180. package/templates/agent-plugin/hooks/spec-user-prompt.sh +43 -0
  181. package/templates/agent-plugin/skills/humanloop/SKILL.md +147 -0
  182. package/templates/agent-plugin/skills/perspective-fanout/SKILL.md +115 -0
  183. package/templates/agent-plugin/skills/problem-document/SKILL.md +105 -0
  184. package/templates/agent-plugin/skills/problem-plateau-breakers/SKILL.md +83 -0
  185. package/templates/agent-suffix.md +7 -4
  186. package/templates/baleia.lua +42 -0
  187. package/templates/companion-plugin/hooks/user-prompt-context.sh +1 -1
  188. package/templates/dashboard-claude.md +7 -3
  189. package/templates/orchestrator-base.md +89 -52
  190. package/templates/orchestrator-completion.md +47 -24
  191. package/templates/orchestrator-discovery.md +183 -0
  192. package/templates/orchestrator-impl.md +47 -18
  193. package/templates/orchestrator-planning.md +109 -20
  194. package/templates/orchestrator-plugin/commands/sisyphus/scratch.md +19 -0
  195. package/templates/orchestrator-plugin/commands/sisyphus/spec.md +11 -0
  196. package/templates/orchestrator-plugin/commands/sisyphus/strategize.md +5 -5
  197. package/templates/orchestrator-plugin/hooks/hooks.json +0 -10
  198. package/templates/orchestrator-plugin/skills/humanloop/SKILL.md +149 -0
  199. package/templates/orchestrator-plugin/skills/orchestration/CLAUDE.md +1 -0
  200. package/templates/orchestrator-plugin/skills/orchestration/SKILL.md +2 -1
  201. package/templates/orchestrator-plugin/skills/orchestration/strategy.md +160 -0
  202. package/templates/orchestrator-plugin/skills/orchestration/task-patterns.md +26 -28
  203. package/templates/orchestrator-plugin/skills/orchestration/workflow-examples.md +133 -25
  204. package/templates/orchestrator-settings.json +55 -0
  205. package/templates/orchestrator-validation.md +17 -14
  206. package/templates/sisyphus-init.lua +30 -0
  207. package/templates/sisyphus-tmux-plugin/hooks/hooks.json +54 -0
  208. package/templates/sisyphus-tmux-plugin/hooks/tmux-state.sh +19 -0
  209. package/templates/termrender-haiku-system.md +82 -0
  210. package/templates/whip-animation.sh +345 -0
  211. package/dist/chunk-6TIO23U3.js +0 -67
  212. package/dist/chunk-6TIO23U3.js.map +0 -1
  213. package/dist/chunk-GSXF3TCZ.js.map +0 -1
  214. package/dist/chunk-HQZOAX6D.js +0 -240
  215. package/dist/chunk-HQZOAX6D.js.map +0 -1
  216. package/dist/chunk-IF55HPWX.js +0 -44
  217. package/dist/chunk-IF55HPWX.js.map +0 -1
  218. package/dist/chunk-UIVQXCWB.js +0 -46
  219. package/dist/chunk-UIVQXCWB.js.map +0 -1
  220. package/dist/paths-3EL2SCHI.js +0 -58
  221. package/dist/templates/agent-plugin/agents/design.md +0 -134
  222. package/dist/templates/agent-plugin/agents/requirements.md +0 -138
  223. package/dist/templates/begin.md +0 -22
  224. package/dist/templates/nvim-tutorial.txt +0 -68
  225. package/dist/templates/orchestrator-plugin/commands/sisyphus/design.md +0 -13
  226. package/dist/templates/orchestrator-plugin/commands/sisyphus/requirements.md +0 -13
  227. package/dist/templates/orchestrator-plugin/hooks/idle-notify.sh +0 -71
  228. package/dist/templates/orchestrator-strategy.md +0 -238
  229. package/templates/agent-plugin/agents/design.md +0 -134
  230. package/templates/agent-plugin/agents/requirements.md +0 -138
  231. package/templates/begin.md +0 -22
  232. package/templates/nvim-tutorial.txt +0 -68
  233. package/templates/orchestrator-plugin/commands/sisyphus/design.md +0 -13
  234. package/templates/orchestrator-plugin/commands/sisyphus/requirements.md +0 -13
  235. package/templates/orchestrator-plugin/hooks/idle-notify.sh +0 -71
  236. package/templates/orchestrator-strategy.md +0 -238
  237. /package/dist/{paths-3EL2SCHI.js.map → paths-JXFLR5BN.js.map} +0 -0
@@ -0,0 +1,1165 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ ACHIEVEMENTS
4
+ } from "./chunk-36VJ7ZBD.js";
5
+ import {
6
+ goalPath,
7
+ roadmapPath,
8
+ sessionsDir,
9
+ socketPath,
10
+ statePath
11
+ } from "./chunk-PNDCVKBN.js";
12
+
13
+ // src/shared/keymap.ts
14
+ function formatHelpForKeymap(km) {
15
+ const COL1 = 20;
16
+ const MAX_W = 78;
17
+ function shortLabel(raw, max) {
18
+ return raw.trimStart().replace(/\s*\([^)]*\)\s*/g, "").replace(/\s+--\S*/g, "").trimEnd().slice(0, max).trimEnd();
19
+ }
20
+ const lines = [];
21
+ lines.push(" Sisyphus Keybindings (Ctrl-s + key)");
22
+ lines.push("");
23
+ lines.push(" \u2500\u2500 Direct \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
24
+ for (const item of km.topLevel.items) {
25
+ if (item.action.type === "submenu" || item.action.type === "tui" || item.hidden) continue;
26
+ const key = item.key.trim() === "" ? "spc" : item.key;
27
+ lines.push(` ${key.padEnd(4)} ${shortLabel(item.label, 30)}`);
28
+ }
29
+ lines.push("");
30
+ lines.push(" \u2500\u2500 Submenus \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
31
+ for (const topItem of km.topLevel.items) {
32
+ if (topItem.action.type !== "submenu") continue;
33
+ const { ref } = topItem.action;
34
+ const sub = km.submenus[ref];
35
+ if (!sub) continue;
36
+ const prefix = topItem.key;
37
+ const col1Text = ` ${prefix} \u203A ${sub.title.trim()}`.padEnd(COL1);
38
+ let cur = col1Text;
39
+ for (const si of sub.items) {
40
+ const lbl = shortLabel(si.label, 13);
41
+ const tok = `${prefix} ${si.key} ${lbl}`;
42
+ const sep = cur.length === COL1 ? "" : " ";
43
+ if (cur.length !== COL1 && cur.length + 2 + tok.length > MAX_W) {
44
+ lines.push(cur);
45
+ cur = " ".repeat(COL1) + tok;
46
+ } else {
47
+ cur += sep + tok;
48
+ }
49
+ }
50
+ if (cur.length > COL1) lines.push(cur);
51
+ }
52
+ return lines.join("\n");
53
+ }
54
+ var MENU_FOR_MODE = {
55
+ "leader": "topLevel",
56
+ "copy-menu": "copy",
57
+ "open-menu": "open",
58
+ "agent-menu": "agent",
59
+ "session-menu": "session",
60
+ "go-menu": "go"
61
+ };
62
+ var KEYMAP = {
63
+ version: 1,
64
+ topLevel: {
65
+ title: " Sisyphus ",
66
+ items: [
67
+ { key: "s", label: " Cycle session", action: { type: "script", name: "sisyphus-cycle" } },
68
+ { key: "h", label: " Home / dashboard", action: { type: "script", name: "sisyphus-home" } },
69
+ { key: "n", label: " New session", action: { type: "popup", name: "sisyphus-new", popup: { w: "80%", h: "60%", cwd: "current" } } },
70
+ { key: "m", label: " Message orchestrator", action: { type: "popup", name: "sisyphus-msg", popup: { w: "80%", h: "60%", cwd: "current" } } },
71
+ { key: "t", label: " Status (where am I?)", action: { type: "popup", name: "sisyphus-status-popup", popup: { w: "90%", h: "90%", cwd: "current" } } },
72
+ { key: "l", label: " Session picker", action: { type: "popup", name: "sisyphus-pick-session", popup: { w: "60%", h: "60%", cwd: "current" } } },
73
+ { key: "z", label: " Zoom pane", action: { type: "tmux", cmd: "resize-pane -Z" } },
74
+ { key: "x", label: " Kill pane (smart)", action: { type: "script", name: "sisyphus-kill-pane" } },
75
+ { key: "?", label: " Full help reference", action: { type: "popup", name: "sisyphus-help", popup: { w: "80", h: "32", title: " Keybindings " } } },
76
+ { key: "/", label: " Search / filter", action: { type: "script", name: "sisyphus-search-reports" }, tuiAction: "search" },
77
+ { key: " ", label: " Open popup explicitly", action: { type: "tui", action: "show-leader" } },
78
+ { key: "c", label: " Copy \u203A", action: { type: "submenu", ref: "copy" } },
79
+ { key: "o", label: " Open \u203A", action: { type: "submenu", ref: "open" } },
80
+ { key: "a", label: " Agent \u203A", action: { type: "submenu", ref: "agent" } },
81
+ { key: "S", label: " Session \u203A", action: { type: "submenu", ref: "session" } },
82
+ { key: "g", label: " Go \u203A", action: { type: "submenu", ref: "go" } }
83
+ ]
84
+ },
85
+ submenus: {
86
+ copy: {
87
+ title: " Copy ",
88
+ items: [
89
+ { key: "p", label: " session dir path", action: { type: "script", name: "sisyphus-copy-path" } },
90
+ { key: "i", label: " session UUID", action: { type: "script", name: "sisyphus-copy-id" } },
91
+ { key: "c", label: " full session context XML", action: { type: "script", name: "sisyphus-copy-context" } },
92
+ { key: "l", label: " logs (last 200 lines)", action: { type: "script", name: "sisyphus-copy-logs" } },
93
+ { key: "r", label: " latest report content", action: { type: "script", name: "sisyphus-copy-latest-report" } },
94
+ { key: "a", label: " agent ID (picker)", action: { type: "script", name: "sisyphus-copy-agent-id" } }
95
+ ]
96
+ },
97
+ open: {
98
+ title: " Open ",
99
+ items: [
100
+ { key: "g", label: " goal.md", action: { type: "popup", name: "sisyphus-open-goal", popup: { w: "95%", h: "95%", cwd: "current" } } },
101
+ { key: "r", label: " roadmap.md", action: { type: "popup", name: "sisyphus-open-roadmap", popup: { w: "95%", h: "95%", cwd: "current" } } },
102
+ { key: "s", label: " strategy.md", action: { type: "popup", name: "sisyphus-open-strategy", popup: { w: "95%", h: "95%", cwd: "current" } } },
103
+ { key: "l", label: " logs popup (tail)", action: { type: "popup", name: "sisyphus-open-logs", popup: { w: "90%", h: "90%", cwd: "current" } } },
104
+ { key: "d", label: " session dir in file mgr", action: { type: "script", name: "sisyphus-open-dir" } },
105
+ { key: "R", label: " latest report file", action: { type: "popup", name: "sisyphus-open-latest-report", popup: { w: "95%", h: "95%", cwd: "current" } } },
106
+ { key: "c", label: " scratch", action: { type: "popup", name: "sisyphus-open-scratch", popup: { w: "95%", h: "95%", cwd: "current" } } },
107
+ { key: "e", label: " edit context file", action: { type: "popup", name: "sisyphus-edit-context-file", popup: { w: "95%", h: "95%", cwd: "current" } }, tuiAction: "edit-context-file" }
108
+ ]
109
+ },
110
+ agent: {
111
+ title: " Agent ",
112
+ items: [
113
+ { key: "s", label: " spawn agent", action: { type: "popup", name: "sisyphus-spawn-agent", popup: { w: "80%", h: "70%", cwd: "current" } } },
114
+ { key: "m", label: " message agent (picker)", action: { type: "popup", name: "sisyphus-msg-agent", popup: { w: "80%", h: "60%", cwd: "current" } } },
115
+ { key: "r", label: " restart agent (picker)", action: { type: "popup", name: "sisyphus-restart-agent-popup", popup: { w: "70%", h: "50%", cwd: "current" } } },
116
+ { key: "R", label: " re-run agent (picker)", action: { type: "popup", name: "sisyphus-rerun-agent", popup: { w: "70%", h: "50%", cwd: "current" } } },
117
+ { key: "j", label: " jump to agent's pane", action: { type: "popup", name: "sisyphus-jump-to-pane", popup: { w: "60%", h: "60%" } } },
118
+ { key: "o", label: " open claude --resume", action: { type: "popup", name: "sisyphus-open-claude-agent", popup: { w: "60%", h: "60%", cwd: "current" } } },
119
+ { key: "t", label: " tail agent logs (picker)", action: { type: "popup", name: "sisyphus-tail-agent-logs", popup: { w: "90%", h: "90%", cwd: "current" } } },
120
+ { key: "k", label: " kill agent (picker)", action: { type: "popup", name: "sisyphus-kill-agent", popup: { w: "60%", h: "40%", cwd: "current" } } },
121
+ { key: "e", label: " quick-spawn Explore", action: { type: "script", name: "sisyphus-quick-spawn-explore" } },
122
+ { key: "d", label: " quick-spawn Debug", action: { type: "script", name: "sisyphus-quick-spawn-debug" } }
123
+ ]
124
+ },
125
+ session: {
126
+ title: " Session ",
127
+ items: [
128
+ { key: "n", label: " new session", action: { type: "popup", name: "sisyphus-new", popup: { w: "80%", h: "60%", cwd: "current" } } },
129
+ { key: "r", label: " resume", action: { type: "popup", name: "sisyphus-resume-session", popup: { w: "80%", h: "60%", cwd: "current" } } },
130
+ { key: "c", label: " continue", action: { type: "popup", name: "sisyphus-continue-session", popup: { w: "50", h: "5", borderStyle: "fg=yellow", title: " Continue Session ", cwd: "current" } } },
131
+ { key: "b", label: " rollback (prompts cycle)", action: { type: "popup", name: "sisyphus-rollback-session", popup: { w: "50", h: "5", title: " Rollback ", cwd: "current" } } },
132
+ { key: "k", label: " kill", action: { type: "popup", name: "sisyphus-kill-session", popup: { w: "40", h: "5", borderStyle: "fg=red", title: " Kill Session ", cwd: "current" } } },
133
+ { key: "d", label: " delete (confirms)", action: { type: "popup", name: "sisyphus-delete-session", popup: { w: "40", h: "5", borderStyle: "fg=red", title: " Delete Session ", cwd: "current" } } },
134
+ { key: "e", label: " export to ~/Downloads", action: { type: "popup", name: "sisyphus-export-session", popup: { w: "60", h: "8", title: " Export Session ", cwd: "current" } } },
135
+ { key: "w", label: " go to session window", action: { type: "popup", name: "sisyphus-go-to-window", popup: { w: "70%", h: "60%", cwd: "current" } } },
136
+ { key: "C", label: " clone (sisyphus session clone)", action: { type: "popup", name: "sisyphus-clone-session", popup: { w: "60%", h: "60%", cwd: "current" } } },
137
+ { key: "i", label: " history", action: { type: "popup", name: "sisyphus-history", popup: { w: "95%", h: "95%", cwd: "current" } } }
138
+ ]
139
+ },
140
+ go: {
141
+ title: " Go ",
142
+ items: [
143
+ { key: "w", label: " go to session window", action: { type: "popup", name: "sisyphus-go-to-window", popup: { w: "70%", h: "60%", cwd: "current" } } },
144
+ { key: "p", label: " jump to pane (picker)", action: { type: "popup", name: "sisyphus-jump-to-pane", popup: { w: "60%", h: "60%" } } },
145
+ { key: "s", label: " session picker", action: { type: "popup", name: "sisyphus-pick-session", popup: { w: "60%", h: "60%", cwd: "current" } } },
146
+ { key: "n", label: " next session", action: { type: "script", name: "sisyphus-cycle" } },
147
+ { key: "r", label: " reconnect", action: { type: "popup", name: "sisyphus-reconnect", popup: { w: "80%", h: "40%", cwd: "current" } } }
148
+ ]
149
+ }
150
+ }
151
+ };
152
+
153
+ // src/shared/utils.ts
154
+ function computeActiveTimeMs(session) {
155
+ return session.activeMs;
156
+ }
157
+
158
+ // src/tui/lib/reports.ts
159
+ import { readFileSync } from "fs";
160
+ function loadReportContent(report) {
161
+ try {
162
+ return readFileSync(report.filePath, "utf-8");
163
+ } catch {
164
+ return report.summary;
165
+ }
166
+ }
167
+ function resolveReports(reports) {
168
+ return [...reports].reverse().map((r) => ({
169
+ type: r.type,
170
+ timestamp: r.timestamp,
171
+ content: loadReportContent(r),
172
+ summary: r.summary
173
+ }));
174
+ }
175
+
176
+ // src/tui/lib/context.ts
177
+ import { readFileSync as readFileSync2, readdirSync } from "fs";
178
+ function readFileSafe(filePath) {
179
+ try {
180
+ return readFileSync2(filePath, "utf-8");
181
+ } catch {
182
+ return null;
183
+ }
184
+ }
185
+ function escapeXml(s) {
186
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
187
+ }
188
+ function buildCompanionContext(cwd) {
189
+ let sessionDirs;
190
+ try {
191
+ sessionDirs = readdirSync(sessionsDir(cwd));
192
+ } catch {
193
+ return "<sessions>No sessions found.</sessions>";
194
+ }
195
+ const now = Date.now();
196
+ const sevenDaysMs = 7 * 24 * 60 * 60 * 1e3;
197
+ const sessionBlocks = [];
198
+ for (const sessionId of sessionDirs) {
199
+ const stateRaw = readFileSafe(statePath(cwd, sessionId));
200
+ if (!stateRaw) continue;
201
+ let session;
202
+ try {
203
+ session = JSON.parse(stateRaw);
204
+ } catch {
205
+ continue;
206
+ }
207
+ if (session.status === "completed" && session.completedAt) {
208
+ if (now - new Date(session.completedAt).getTime() > sevenDaysMs) continue;
209
+ }
210
+ const lines = [];
211
+ const nameAttr = session.name ? ` name="${escapeXml(session.name)}"` : "";
212
+ lines.push(` <session id="${escapeXml(session.id)}"${nameAttr} status="${escapeXml(session.status)}">`);
213
+ lines.push(` <task>${escapeXml(session.task)}</task>`);
214
+ lines.push(` <created>${escapeXml(session.createdAt)}</created>`);
215
+ lines.push(` <cycles>${session.orchestratorCycles.length}</cycles>`);
216
+ if (session.status === "completed") {
217
+ if (session.completionReport) {
218
+ const snippet = session.completionReport.slice(0, 300).replace(/\n+/g, " ").trim();
219
+ lines.push(` <completion-report>${escapeXml(snippet)}${session.completionReport.length > 300 ? "\u2026" : ""}</completion-report>`);
220
+ }
221
+ } else {
222
+ if (session.agents.length > 0) {
223
+ const counts = /* @__PURE__ */ new Map();
224
+ for (const agent of session.agents) {
225
+ counts.set(agent.status, (counts.get(agent.status) ?? 0) + 1);
226
+ }
227
+ const summary = [...counts.entries()].map(([status, n]) => `${n} ${status}`).join(", ");
228
+ lines.push(` <agents>${escapeXml(summary)}</agents>`);
229
+ }
230
+ const goalContent = readFileSafe(goalPath(cwd, session.id));
231
+ if (goalContent) {
232
+ const firstLine = goalContent.split("\n").map((l) => l.trim()).find((l) => l.length > 0 && !l.startsWith("#"));
233
+ if (firstLine) lines.push(` <goal>${escapeXml(firstLine)}</goal>`);
234
+ }
235
+ const roadmapContent = readFileSafe(roadmapPath(cwd, session.id));
236
+ if (roadmapContent) {
237
+ const todos = roadmapContent.split("\n").filter((l) => l.includes("- [ ]")).slice(0, 5).map((l) => l.trim());
238
+ if (todos.length > 0) {
239
+ lines.push(" <todos>");
240
+ for (const todo of todos) lines.push(` ${escapeXml(todo)}`);
241
+ lines.push(" </todos>");
242
+ }
243
+ }
244
+ }
245
+ lines.push(" </session>");
246
+ sessionBlocks.push(lines.join("\n"));
247
+ }
248
+ if (sessionBlocks.length === 0) {
249
+ return "<sessions>No sessions found.</sessions>";
250
+ }
251
+ return ["<sessions>", ...sessionBlocks, "</sessions>"].join("\n");
252
+ }
253
+ function buildSessionContext(session, cwd) {
254
+ const goal = readFileSafe(goalPath(cwd, session.id));
255
+ const roadmap = readFileSafe(roadmapPath(cwd, session.id));
256
+ const agentsXml = session.agents.map((agent) => {
257
+ const reportBlocks = resolveReports(agent.reports);
258
+ const reportsXml = [...reportBlocks].reverse().map((block) => {
259
+ return ` <report type="${block.type}" time="${escapeXml(block.timestamp)}">${escapeXml(block.content)}</report>`;
260
+ }).join("\n");
261
+ return [
262
+ ` <agent id="${escapeXml(agent.id)}" name="${escapeXml(agent.name)}" type="${escapeXml(agent.agentType)}" status="${escapeXml(agent.status)}">`,
263
+ ` <instruction>${escapeXml(agent.instruction)}</instruction>`,
264
+ ...reportsXml ? [reportsXml] : [],
265
+ ` </agent>`
266
+ ].join("\n");
267
+ }).join("\n");
268
+ const cyclesXml = session.orchestratorCycles.map((cycle) => {
269
+ const agents = cycle.agentsSpawned.join(", ");
270
+ const mode = cycle.mode ? ` mode="${escapeXml(cycle.mode)}"` : "";
271
+ return ` <cycle number="${cycle.cycle}"${mode} agents="${escapeXml(agents)}" />`;
272
+ }).join("\n");
273
+ const lines = [
274
+ "<context>",
275
+ `<session id="${escapeXml(session.id)}" status="${escapeXml(session.status)}">`,
276
+ ` <task>${escapeXml(session.task)}</task>`,
277
+ ` <cwd>${escapeXml(session.cwd)}</cwd>`
278
+ ];
279
+ if (goal) lines.push(` <goal>${escapeXml(goal)}</goal>`);
280
+ if (roadmap) lines.push(` <roadmap>${escapeXml(roadmap)}</roadmap>`);
281
+ if (session.agents.length > 0) {
282
+ lines.push(" <agents>");
283
+ lines.push(agentsXml);
284
+ lines.push(" </agents>");
285
+ }
286
+ if (session.orchestratorCycles.length > 0) {
287
+ lines.push(" <cycles>");
288
+ lines.push(cyclesXml);
289
+ lines.push(" </cycles>");
290
+ }
291
+ if (session.completionReport) {
292
+ lines.push(` <completion-report>${escapeXml(session.completionReport)}</completion-report>`);
293
+ }
294
+ lines.push("</session>");
295
+ lines.push("</context>");
296
+ return lines.join("\n");
297
+ }
298
+
299
+ // src/shared/companion-badges.ts
300
+ var BADGE_ART = {
301
+ // ── Milestone ─────────────────────────────────────────────────────────────
302
+ "first-blood": [
303
+ " \u2571\u2572 ",
304
+ " \u2571 \u2572 ",
305
+ " \u2571 \u25C6\u25C6 \u2572 ",
306
+ " \u2571 \u25C6\u25C6 \u2572 ",
307
+ " \u2571 \u25C6\u25C6 \u2572 ",
308
+ " \u2571 \u25C6\u25C6 \u2572 ",
309
+ " \u2571\u2500\u2500\u2500\u2500\u2500\u25C6\u25C6\u2500\u2500\u2500\u2500\u2500\u2572 ",
310
+ " \u2572 \u25C6\u25C6 \u2571 ",
311
+ " \u2572 \u25C6\u25C6 \u2571 ",
312
+ " \u2572\u2500\u2500\u2500\u25C6\u25C6\u2500\u2500\u2500\u2571 ",
313
+ " \u2502\u2502 ",
314
+ " \u2550\u2550\u256A\u256A\u2550\u2550 "
315
+ ],
316
+ "centurion": [
317
+ " \u250C\u2500\u2500\u2550\u2550\u2550\u2550\u2550\u2500\u2500\u2510 ",
318
+ " \u2502 \u2554\u2550\u2550\u2550\u2557 \u2502 ",
319
+ " \u2571\u2502 \u2551100\u2551 \u2502\u2572 ",
320
+ " \u2571 \u2502 \u255A\u2550\u2550\u2550\u255D \u2502 \u2572 ",
321
+ " \u2571 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2572 ",
322
+ " \u2572 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2571 ",
323
+ " \u2572 \u2502 \u2605 \u2605 \u2605 \u2502 \u2571 ",
324
+ " \u2572 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2571 ",
325
+ " \u2572\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2571 "
326
+ ],
327
+ "thousand-boulder": [
328
+ " \u256D\u2501\u2501\u2501\u256E ",
329
+ " \u256D\u2501\u252B1K \u2523\u2501\u256E ",
330
+ " \u256D\u2501\u252B \u2570\u2501\u2501\u2501\u256F \u2523\u2501\u256E ",
331
+ " \u2503 \u25C9\u25C9\u25C9\u25C9\u25C9\u25C9 \u2503 ",
332
+ " \u2503 \u25C9\u25C9\u25C9\u25C9\u25C9\u25C9\u25C9\u25C9 \u2503 ",
333
+ " \u2503 \u25C9\u25C9\u25C9\u25C9\u25C9\u25C9 \u2503 ",
334
+ " \u2570\u2501\u252B \u2523\u2501\u256F ",
335
+ " \u2570\u2501\u252B \u2523\u2501\u256F ",
336
+ " \u2570\u2501\u2501\u2501\u256F "
337
+ ],
338
+ "cartographer": [
339
+ " N ",
340
+ " \u25B3 ",
341
+ " \u256D\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u256E ",
342
+ " \u2502 \xB7 \u2502 \xB7 \u2502 ",
343
+ " W\u253C\xB7\xB7\xB7\xB7+\xB7\xB7\xB7\xB7\u253CE ",
344
+ " \u2502 \xB7 \u2502 \xB7 \u2502 ",
345
+ " \u2570\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u256F ",
346
+ " \u25BD ",
347
+ " S "
348
+ ],
349
+ "world-traveler": [
350
+ " \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u256E ",
351
+ " \u256D\u2500\u2500\u2524 \u251C\u2500\u2500\u256E ",
352
+ " \u2571 \xB7\u2502 \u25E0\u25E1\u25E0 \u2502\xB7 \u2572 ",
353
+ " \u2502 \xB7 \u2502\u25E0 \u25E1\u2502 \xB7 \u2502 ",
354
+ " \u2502 \xB7 \u2502 \u25E1\u25E0\u25E1 \u2502 \xB7 \u2502 ",
355
+ " \u2572 \xB7\u2502 \u2502\xB7 \u2571 ",
356
+ " \u2570\u2500\u2500\u2524 \u251C\u2500\u2500\u256F ",
357
+ " \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u256F "
358
+ ],
359
+ "hive-mind": [
360
+ " \u2571\u2572 \u2571\u2572 \u2571\u2572 ",
361
+ " \u2571\u25C6\u25C6\u2572\u2571\u25C6\u25C6\u2572\u2571\u25C6\u25C6\u2572 ",
362
+ " \u2572\u25C6\u25C6\u2571\u2572\u25C6\u25C6\u2571\u2572\u25C6\u25C6\u2571 ",
363
+ " \u2571\u2572\u2571\u2571\u25C6\u2572\u2571\u2571\u25C6\u2572\u2572\u2571\u2572 ",
364
+ " \u2571\u25C6\u25C6\u2572\u2572\u25C6\u25C6\u2572\u2572\u25C6\u25C6\u2571\u25C6\u25C6\u2572 ",
365
+ " \u2572\u25C6\u25C6\u2571\u2571\u25C6\u25C6\u2571\u2571\u25C6\u25C6\u2572\u25C6\u25C6\u2571 ",
366
+ " \u2572\u2571\u2572\u2572\u25C6\u2571\u2572\u2572\u25C6\u2571\u2571\u2572\u2571 ",
367
+ " \u2572\u25C6\u25C6\u2571\u2572\u25C6\u25C6\u2571\u2572\u25C6\u25C6\u2571 ",
368
+ " \u2572\u2571 \u2572\u2571 \u2572\u2571 "
369
+ ],
370
+ "old-growth": [
371
+ " \u2571\u2572 ",
372
+ " \u2571\u2571\u2572\u2572 ",
373
+ " \u2571\u2571 \u2572\u2572 ",
374
+ " \u2571\u2571\u2571\u2572\u2571\u2572\u2572\u2572 ",
375
+ " \u2571\u2571\u2571 \u2572\u2572\u2572 ",
376
+ " \u2571\u2571\u2571\u2571\u2572\u2571\u2572\u2571\u2572\u2572\u2572\u2572 ",
377
+ " \u2551\u2551\u2551 ",
378
+ " \u2551\u2551\u2551 ",
379
+ " \u2550\u2550\u2550\u2569\u2569\u2569\u2550\u2550\u2550 "
380
+ ],
381
+ "ancient": [
382
+ " \u250C\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2510 ",
383
+ " \u2502 \u2502 \u25C9 \u25C9 \u2502 \u2502 ",
384
+ " \u2502 \u2502 \u25BD \u2502 \u2502 ",
385
+ " \u2554\u2550\u2567\u2550\u2567\u2550\u2550\u2550\u2550\u2550\u2567\u2550\u2567\u2550\u2557 ",
386
+ " \u2551 A N C I E N \u2551 ",
387
+ " \u2551 T \u2551 ",
388
+ " \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D ",
389
+ " \u2571\u2571\u2571\u2571\u2571\u2571\u2571\u2571\u2571\u2571\u2571\u2571\u2571 ",
390
+ " \u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594 "
391
+ ],
392
+ "regular": [
393
+ " \u256D\u2500\u2500\u2500\u2500\u2500\u256E ",
394
+ " \u256D\u2500\u2524 10 \u251C\u2500\u256E ",
395
+ " \u2571 \u2570\u2500\u2500\u2500\u2500\u2500\u256F \u2572 ",
396
+ " \u2502 \u256D\u2500\u2500\u2500\u2500\u2500\u256E \u2502 ",
397
+ " \u2502 \u2502 \u25C9 \u2502 \u2502 ",
398
+ " \u2502 \u2570\u2500\u2500\u2500\u2500\u2500\u256F \u2502 ",
399
+ " \u2572 \u2571 ",
400
+ " \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F "
401
+ ],
402
+ "veteran": [
403
+ " \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557 ",
404
+ " \u2551 \u2554\u2550\u2550\u2550\u2550\u2550\u2557 \u2551 ",
405
+ " \u2551 \u2551 V \u2551 \u2551 ",
406
+ " \u2551 \u2551 500 \u2551 \u2551 ",
407
+ " \u2551 \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u2551 ",
408
+ " \u2551 \u2605 \u2605 \u2605 \u2605 \u2605 \u2551 ",
409
+ " \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D ",
410
+ " \u2571\u2571\u2571\u2571\u2571\u2571\u2571\u2571\u2571\u2571\u2571 ",
411
+ " \u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594 "
412
+ ],
413
+ "swarm-starter": [
414
+ " ",
415
+ " \u25C6 \u25C6 \u25C6 \u25C6 \u25C6 ",
416
+ " \u25C6 \u25C6 \u25C6 \u25C6 \u25C6 ",
417
+ " \u25C6 \u25C6 \u25C6 \u25C6 \u25C6 ",
418
+ " \u25C6 \u25C6 \u25C6 \u25C6 \u25C6 ",
419
+ " \u25C6 \u25C6 \u25C6 \u25C6 \u25C6 ",
420
+ " ",
421
+ " \xB7 50 out \xB7 "
422
+ ],
423
+ "legion": [
424
+ " \u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6 ",
425
+ " \u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6 ",
426
+ " \u25C6\u25C6\u25C6 2K \u25C6\u25C6\u25C6\u25C6\u25C6 ",
427
+ " \u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6 ",
428
+ " \u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6 ",
429
+ " \u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6 ",
430
+ " \u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6 "
431
+ ],
432
+ "army-of-thousands": [
433
+ " \xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7 ",
434
+ " \xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6 ",
435
+ " \xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7 ",
436
+ " \xB7\u25C6\xB7\u25C6\xB75K\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7 ",
437
+ " \xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7 ",
438
+ " \xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6 ",
439
+ " \xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7 ",
440
+ " \xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6 ",
441
+ " \xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7\xB7 "
442
+ ],
443
+ "singularity": [
444
+ " \u2572 \u2502 \u2571 \u2500 \xB7 ",
445
+ " \u2572 \u2502 \u2571 ",
446
+ " \u2572\u2502\u2571 ",
447
+ " \u2500\u2500\u2500\u2500\u25C6\u2500\u2500\u2500\u2500 ",
448
+ " \u2571\u2502\u2572 ",
449
+ " \u2571 \u2502 \u2572 ",
450
+ " \u2571 \u2502 \u2572 \u2500 \xB7 ",
451
+ " 10000 agents "
452
+ ],
453
+ "first-shift": [
454
+ " \u250C\u2500\u2500\u2500\u2500\u2500\u2510 ",
455
+ " \u2502 \u2572 \u2502 ",
456
+ " \u2571\u2502 \u2572 \u2502\u2572 ",
457
+ " \u2571 \u2502 \u2572 \u2502 \u2572 ",
458
+ " \u2572 \u2502 \u2572\u2502 \u2571 ",
459
+ " \u2572\u2502 \u2502\u2571 ",
460
+ " \u2502 \u2571 \u2502 ",
461
+ " \u2514\u2500\u2500\u2500\u2500\u2500\u2518 ",
462
+ " 10 hrs "
463
+ ],
464
+ "workaholic": [
465
+ " \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E ",
466
+ " \u2571 12 \u2572 ",
467
+ " \u2502 \xB7 \u2502 \u2502 ",
468
+ " \u25029 \xB7 \u2502 3 \u2502 ",
469
+ " \u2502 \u2572 \u2502 ",
470
+ " \u2572 6 \xB7 \u2571 ",
471
+ " \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F ",
472
+ " 100 hrs "
473
+ ],
474
+ "time-lord": [
475
+ " \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557 ",
476
+ " \u2571 \u2572 ",
477
+ " \u2502 \xB7 11 12 1 \xB7 \u2502 ",
478
+ " \u2502 10 \u2572 2 \u2502 ",
479
+ " \u2502 9 \xB7 3 \u2502 ",
480
+ " \u2502 8 4 \u2502 ",
481
+ " \u2572 7 5 \u2571 ",
482
+ " \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D ",
483
+ " 500 hrs "
484
+ ],
485
+ "eternal-grind": [
486
+ " \u256D\u2500\u2500\u2500\u256E \u256D\u2500\u2500\u2500\u256E ",
487
+ " \u2571 \u2572 \u2571 \u2572 ",
488
+ " \u2502 \u221E \u2573 \u221E \u2502 ",
489
+ " \u2572 \u2571 \u2572 \u2571 ",
490
+ " \u2570\u2500\u2500\u2500\u256F \u2570\u2500\u2500\u2500\u256F ",
491
+ " \u250C\u2500\u2500\u2500\u2500\u2500\u2510 ",
492
+ " \u2502 \u2572 \u2571 \u2502 ",
493
+ " \u2502 \xD7 \u2502 ",
494
+ " \u2514\u2500\u2500\u2500\u2500\u2500\u2518 "
495
+ ],
496
+ "epoch": [
497
+ " \xB7 \u2605 \xB7 ",
498
+ " \xB7 \u2571\u2502\u2572 \xB7 ",
499
+ " \u2572 \u2571 \u2502 \u2572 \u2571 ",
500
+ " \u2572\u2571 \u2502 \u2572\u2571 ",
501
+ " \u2500\u2500\u2500\u2500\u25C6\u2500\u2500\u253C\u2500\u2500\u25C6\u2500\u2500\u2500\u2500 ",
502
+ " \u2571\u2572 \u2502 \u2571\u2572 ",
503
+ " \u2571 \u2572 \u2502 \u2571 \u2572 ",
504
+ " \xB7 \u2572\u2502\u2571 \xB7 ",
505
+ " 5000 hrs "
506
+ ],
507
+ "seasoned": [
508
+ " \u2571\u2572 ",
509
+ " \u2571 \u2572 ",
510
+ " \u2571\u2571\u2572\u2571\u2572\u2572 ",
511
+ " \u2571\u2571 \u2572\u2572 ",
512
+ " \u2571\u2571\u2571\u2571\u2572\u2571\u2572\u2572\u2572\u2572 ",
513
+ " \u2551\u2551 ",
514
+ " \u2500\u2500\u2500\u2500\u2500\u2568\u2568\u2500\u2500\u2500\u2500\u2500 ",
515
+ " \u2572\u2572\u2572\u2572\u2572\u2572\u2572\u2572\u2572\u2572\u2572\u2572\u2572 ",
516
+ " 90 day roots "
517
+ ],
518
+ "omnipresent": [
519
+ " N ",
520
+ " \xB7 \u25B3 \xB7 ",
521
+ " NW \u256D\u2500\u253C\u2500\u256E NE ",
522
+ " \xB7 \u256D\u2500\u2524\xB7+\xB7\u251C\u2500\u256E \xB7 ",
523
+ " W\u2500\u2500\u2524\xB7\u2502 \xB7 \u2502\xB7\u251C\u2500\u2500E ",
524
+ " \xB7 \u2570\u2500\u2524\xB7+\xB7\u251C\u2500\u256F \xB7 ",
525
+ " SW \u2570\u2500\u253C\u2500\u256F SE ",
526
+ " \xB7 \u25BD \xB7 ",
527
+ " S "
528
+ ],
529
+ "apprentice": [
530
+ " ",
531
+ " \u2571\u2572 ",
532
+ " \u2571 \u2572 ",
533
+ " \u2571 \u2572 ",
534
+ " \u2571 \u2572 ",
535
+ " \u2571\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2572 ",
536
+ " \u2571 level 5 \u2572 ",
537
+ " \u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594 "
538
+ ],
539
+ "journeyman": [
540
+ " \u2571\u2572 ",
541
+ " \u2571 \u2572 \u2571\u2572 ",
542
+ " \u2571 \u2572 \u2571 \u2572 ",
543
+ " \u2571 \u2573 \u2572 ",
544
+ " \u2571 \u2571 \u2572 \u2572 ",
545
+ " \u2571\u2500\u2500\u2500\u2500\u2500\u2500\u2571\u2500\u2500\u2500\u2572\u2500\u2500\u2500\u2500\u2572",
546
+ " \u2571 level 15 ",
547
+ " \u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594 "
548
+ ],
549
+ "master": [
550
+ " \u2605\u2572\u2571\u2605 ",
551
+ " \u2571\u2572 ",
552
+ " \u2571 \u2572 ",
553
+ " \u2571\u2571\u2572\u2571\u2572\u2572 ",
554
+ " \u2571\u2571 \u2572\u2572 ",
555
+ " \u2571\u2571 \u2572\u2572 ",
556
+ " \u2571\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2572\u2572 ",
557
+ " \u2571 level 30 \u2572 ",
558
+ " \u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594 "
559
+ ],
560
+ "grandmaster": [
561
+ " \u2605 \u2605 \u2605 ",
562
+ " \u2572\u2502\u2571 ",
563
+ " \u2571\u2572 ",
564
+ " \u2571 \u2572 ",
565
+ " \u2571\u2571\u2572\u2571\u2572\u2572 ",
566
+ " \u2571\u2571 \u2572\u2572 ",
567
+ " \u2571\u2571 \u2605 \u2572\u2572 ",
568
+ " \u2571\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2572\u2572 ",
569
+ " \u2571 level 50 \u2572 "
570
+ ],
571
+ // ── Session ───────────────────────────────────────────────────────────────
572
+ "marathon": [
573
+ " \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E ",
574
+ " \u2502 \u2571\u2572 \u2571\u2572 \u2571\u2572 \u2571\u2572 \u2502 ",
575
+ " \u2502\u2571 \u2573 \u2573 \u2573 \u2572 \u2502 ",
576
+ " \u2502 \u2571\u2572 \u2571\u2572 \u2571\u2572 \u2502 ",
577
+ " \u2502 \u2571 \u2573 \u2573 \u2572 \u2502 ",
578
+ " \u2502 \u2571 \u2571 \u2572\u2571 \u2572 \u2572 \u2502 ",
579
+ " \u2502\u2571 \u2571 \u2572 \u2572\u2502 ",
580
+ " \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 ",
581
+ " \u2502 ~ ^ ~ \u2502 ",
582
+ " \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F "
583
+ ],
584
+ "blitz": [
585
+ " \u2571\u2571 ",
586
+ " \u2571\u2571 ",
587
+ " \u2571\u2571 ",
588
+ " \u2571\u2571\u2571\u2571\u2571\u2571 ",
589
+ " \u2571\u2571 ",
590
+ " \u2571\u2571 ",
591
+ " \u2571\u2571 ",
592
+ " \u2571\u2571 "
593
+ ],
594
+ "speed-run": [
595
+ " \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E ",
596
+ " \u2571 \u2572 ",
597
+ " \u2502 10 \u2571\u2571 \u2502 ",
598
+ " \u2502 \xB7 \u2571\u2571 \u2502 ",
599
+ " \u2502 \u2571 \u2571\u2571 \u2502 ",
600
+ " \u2502 \u2571 \u2571\u2571 \u2502 ",
601
+ " \u2572 \u2571\u2571 \u2571 ",
602
+ " \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F "
603
+ ],
604
+ "flawless": [
605
+ " \u2726 \u2726 ",
606
+ " \u2726 \u2571\u2572 \u2726 ",
607
+ " \u2554\u2550\u2550\u2567\u2550\u2550\u2550\u2557 ",
608
+ " \u2726 \u2551 \u2551 \u2726 ",
609
+ " \u2551 \u25C6 \u2551 ",
610
+ " \u2551 \u2551 ",
611
+ " \u2726 \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u2726 ",
612
+ " \u2726 \u2726 "
613
+ ],
614
+ "speed-demon": [
615
+ " ",
616
+ " \u2571\u2571 ",
617
+ " \u2571\u2571 ",
618
+ " \u2571\u2571\u2571\u2571\u2571\u2571 ",
619
+ " \u2571\u2571 ",
620
+ " \u2571\u2571 ",
621
+ " \u26A1 \u22643 \u26A1 ",
622
+ " x10 streak "
623
+ ],
624
+ "iron-will": [
625
+ " \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557 ",
626
+ " \u2551 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2551 ",
627
+ " \u2551 \u2502\u2554\u2550\u2550\u2550\u2550\u2550\u2557\u2502 \u2551 ",
628
+ " \u2551 \u2502\u2551 8+ \u2551\u2502 \u2551 ",
629
+ " \u2551 \u2502\u2551cycle\u2551\u2502 \u2551 ",
630
+ " \u2551 \u2502\u255A\u2550\u2550\u2550\u2550\u2550\u255D\u2502 \u2551 ",
631
+ " \u2551 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2551 ",
632
+ " \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D "
633
+ ],
634
+ "glass-cannon": [
635
+ " \u2571\u2572 ",
636
+ " \u2571\u2571\u2572\u2572 ",
637
+ " \u2571\u2571 \u2572\u2572 ",
638
+ " \u2571\u2571 \u2573\u2573 \u2572\u2572 ",
639
+ " \u2571\u2571 \u2573\u2573 \u2572\u2572 ",
640
+ " \u2572\u2572 \u2573\u2573 \u2571\u2571 ",
641
+ " \u2572\u2572 \u2571\u2571 ",
642
+ " \u2572\u2572 \u2571\u2571 ",
643
+ " \u2572\u2572\u2571\u2571 ",
644
+ " \u2550\u2550\u2550\u2567\u2567\u2550\u2550\u2550 "
645
+ ],
646
+ "solo": [
647
+ " ",
648
+ " \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E ",
649
+ " \u2502 \u2502 ",
650
+ " \u2502 \u25C6 \u2502 ",
651
+ " \u2502 \u2502 ",
652
+ " \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F ",
653
+ " "
654
+ ],
655
+ "one-more-cycle": [
656
+ " \u256D\u2500\u2500\u2192\u2500\u2500\u256E ",
657
+ " \u2502 \u2502 ",
658
+ " \u2191 \u221E \u2193 ",
659
+ " \u2502 \u2502 ",
660
+ " \u2570\u2500\u2500\u2190\u2500\u2500\u256F ",
661
+ " ",
662
+ " \u256D\u2500\u2500\u2192\u2500\u2500\u256E ",
663
+ " \u2502 \u2502 ",
664
+ " \u2191 \u221E \u2193 ",
665
+ " \u2502 \u2502 ",
666
+ " \u2570\u2500\u2500\u2190\u2500\u2500\u256F "
667
+ ],
668
+ "quick-draw": [
669
+ " \u2571\u2502 ",
670
+ " \u2571 \u2502 ",
671
+ " \u2500\u2500\u2571\u2500\u2500\u2502\u2500\u2500 ",
672
+ " \u2571 \u2502 ",
673
+ " \u2571 \u256D\u2500\u256F ",
674
+ " \u2571 \u2502 ",
675
+ " \u2571 \u256D\u2500\u256F ",
676
+ " \u2502 ",
677
+ " \u2500\u2500\u2568\u2500\u2500 "
678
+ ],
679
+ "squad": [
680
+ " ",
681
+ " \u25C6 \u25C6 \u25C6 \u25C6 ",
682
+ " ",
683
+ " \u25C6 \u25C6 \u25C6 \u25C6 ",
684
+ " ",
685
+ " \u25C6 \u25C6 ",
686
+ " ",
687
+ " \xB7 10 strong \xB7 "
688
+ ],
689
+ "battalion": [
690
+ " \u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6 ",
691
+ " ",
692
+ " \u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6 ",
693
+ " ",
694
+ " \u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6\u25C6 ",
695
+ " ",
696
+ " \xB7 25 strong \xB7 "
697
+ ],
698
+ "swarm": [
699
+ " \u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7 ",
700
+ " \xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6 ",
701
+ " \u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7 ",
702
+ " \xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6 ",
703
+ " \u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7 ",
704
+ " \xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6\xB7\u25C6 ",
705
+ " \xB7 50 strong \xB7 "
706
+ ],
707
+ "deep-dive": [
708
+ " \u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248 ",
709
+ " \u2193 ",
710
+ " \u2571\u2502\u2572 ",
711
+ " \u2502 ",
712
+ " \u2502 ",
713
+ " \u25BC ",
714
+ " \xB7 \xB7 \xB7 \xB7 \xB7 \xB7 \xB7 ",
715
+ " 15 deep "
716
+ ],
717
+ "abyss": [
718
+ " \u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248 ",
719
+ " \u2502 ",
720
+ " \u2502 ",
721
+ " \u2502 ",
722
+ " \u25BC ",
723
+ " \u2502 ",
724
+ " \u2502 ",
725
+ " \u25BC ",
726
+ " 25 deep "
727
+ ],
728
+ "eternal-recurrence": [
729
+ " \u256D\u2500\u2500\u2192\u2500\u2500\u256E ",
730
+ " \u2571 \u221E \u2572 ",
731
+ " \u2502 \u256D\u2500\u2500\u2500\u256E \u2502 ",
732
+ " \u2502 \u2502 \u221E \u2502 \u2502 ",
733
+ " \u2502 \u2570\u2500\u2500\u2500\u256F \u2502 ",
734
+ " \u2572 \u221E \u2571 ",
735
+ " \u2570\u2500\u2500\u2190\u2500\u2500\u256F ",
736
+ " 40 cycles "
737
+ ],
738
+ "endurance": [
739
+ " ",
740
+ " \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557 ",
741
+ " \u2551\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2551 ",
742
+ " \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D ",
743
+ " ",
744
+ " \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557 ",
745
+ " \u2551\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593 \u2551 ",
746
+ " \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D ",
747
+ " 4 hours "
748
+ ],
749
+ "ultramarathon": [
750
+ " \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557 ",
751
+ " \u2551\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2551 ",
752
+ " \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D ",
753
+ " \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2192 ",
754
+ " \xB7 ",
755
+ " \xB7 ",
756
+ " \xB7 ",
757
+ " \xB7 ",
758
+ " 6 hours "
759
+ ],
760
+ "one-shot": [
761
+ " \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E ",
762
+ " \u2502 \u256D\u2500\u2500\u2500\u256E \u2502 ",
763
+ " \u2502 \u2502 \u25C9 \u2502 \u2502 ",
764
+ " \u2502 \u2570\u2500\u2500\u2500\u256F \u2502 ",
765
+ " \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F ",
766
+ " \u2191 ",
767
+ " \u2571\u2502 ",
768
+ " \u2571 \u2502 ",
769
+ " \u2192 \u25C9 \u2502 "
770
+ ],
771
+ "flash": [
772
+ " \u2571\u2571 ",
773
+ " \u2571\u2571 ",
774
+ " \u2571\u2571 ",
775
+ " \u2571\u2571\u2571\u2571\u2571\u2571 ",
776
+ " \u2571\u2571 ",
777
+ " \u2571\u2571 ",
778
+ " \u2571\u2571 ",
779
+ " \u2571\u2571 ",
780
+ " < 2 min "
781
+ ],
782
+ // ── Time ──────────────────────────────────────────────────────────────────
783
+ "night-owl": [
784
+ " \u263D ",
785
+ " \u256D\u2500\u2500\u2500\u2500\u2500\u256E \xB7 ",
786
+ " \u2571 \u25C9 \u25C9 \u2572 \xB7 ",
787
+ " \u2502 \u25BD \u2502 \xB7 ",
788
+ " \u2502 \u2571\u2500\u2500\u2500\u2572 \u2502 ",
789
+ " \u2572\u2571 \u2572\u2571 ",
790
+ " \u2571\u2572 \u2571\u2572 \xB7 ",
791
+ " \u2571 \u2572\u2500\u2500\u2500\u2571 \u2572 \xB7 ",
792
+ " \u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594 "
793
+ ],
794
+ "dawn-patrol": [
795
+ " ",
796
+ " \u2500 \u2500 \u2500 \u2500 \u2500 \u2500 \u2500 \u2500 ",
797
+ " \u2572 \u2502 \u2571 ",
798
+ " \u2572 \u2502 \u2571 ",
799
+ " \u2500\u2500\u2500\u2500\u25D1\u2500\u2500\u2500\u2500 ",
800
+ " \u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593 ",
801
+ " \u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591 ",
802
+ " "
803
+ ],
804
+ "early-bird": [
805
+ " \u2571\u2571 ",
806
+ " \u25E0 \u2571\u2571 ",
807
+ " \u2571 \u2572 \u2571\u2571 ",
808
+ " \u2502 \u25C9 \u2572>\u2571 ",
809
+ " \u2502 \u2550\u2571 ",
810
+ " \u2572 \u2571 ",
811
+ " \u2572\u2571\u2572 ",
812
+ " \u2572 \u2572 ",
813
+ " \u2594\u2594 "
814
+ ],
815
+ "weekend-warrior": [
816
+ " \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557 ",
817
+ " \u2551 S M T W T \u2551 ",
818
+ " \u2551 \u2551 ",
819
+ " \u2551 \u25C6 \u2551 ",
820
+ " \u2551 \u25C6 \u2551 ",
821
+ " \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D "
822
+ ],
823
+ "all-nighter": [
824
+ " \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E ",
825
+ " \u2571 12 \u2572 ",
826
+ " \u2502 \xB7 \u2502 \u2502 ",
827
+ " \u25029 \u2502 3 \u2502 ",
828
+ " \u2502 \xB7 \u2502 ",
829
+ " \u2572 6 \u2571 ",
830
+ " \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F ",
831
+ " \u221E \u221E \u221E "
832
+ ],
833
+ "witching-hour": [
834
+ " \xB7 \xB7 \u2726 \xB7 \xB7 ",
835
+ " \xB7 \u2571\u2572 \xB7 ",
836
+ " \u2571 \u2572 ",
837
+ " \u2502 3:00 \u2502 ",
838
+ " \u2502 AM \u2502 ",
839
+ " \u2572 \u2571 ",
840
+ " \xB7 \u2572\u2571 \xB7 ",
841
+ " \xB7 \xB7 \u2726 \xB7 \xB7 "
842
+ ],
843
+ // ── Behavioral ────────────────────────────────────────────────────────────
844
+ "sisyphean": [
845
+ " \u2571 ",
846
+ " \u2571 \u25C9 ",
847
+ " \u2571 \u25C9\u25C9\u25C9 ",
848
+ " \u2571 \u25C9\u25C9\u25C9 ",
849
+ " \u2571 \u25C9 ",
850
+ " \u2571 ; ",
851
+ " \u2571 (>.<) ",
852
+ " \u2571 \u2571\u2571 \u2572\u2572 ",
853
+ " \u2571 \u2571 \u2572 "
854
+ ],
855
+ "stubborn": [
856
+ " \u2571\u2571\u2571\u2571\u2571\u2571\u2571\u2571\u2571 ",
857
+ " \u2571\u2571\u2571\u2571\u2571\u2571\u2571\u2571\u2571\u2571 ",
858
+ " \u25C9 ",
859
+ " \u25C9\u25C9\u25C9 ",
860
+ " (>.<) ",
861
+ " \u2571\u2571\u2571\u2571\u2571\u2571\u2571\u2571\u2571 ",
862
+ " \u2571\u2571\u2571\u2571\u2571\u2571\u2571\u2571\u2571\u2571 ",
863
+ " \u2713 "
864
+ ],
865
+ "creature-of-habit": [
866
+ " \u256D\u2500\u2500\u2500\u256E \u256D\u2500\u2500\u2500\u256E ",
867
+ " \u2502 \u2192 \u2502\u2192\u2502 \u2192 \u2502\u2192 ",
868
+ " \u2570\u2500\u2500\u2500\u256F \u2570\u2500\u2500\u2500\u256F ",
869
+ " \u256D\u2500\u2500\u2500\u256E \u256D\u2500\u2500\u2500\u256E ",
870
+ " \u2502 \u2192 \u2502\u2192\u2502 \u2192 \u2502\u2192 ",
871
+ " \u2570\u2500\u2500\u2500\u256F \u2570\u2500\u2500\u2500\u256F ",
872
+ " \u256D\u2500\u2500\u2500\u256E \u256D\u2500\u2500\u2500\u256E ",
873
+ " \u2502 \u2192 \u2502\u2192\u2502 \u2192 \u2502\u2192 ",
874
+ " \u2570\u2500\u2500\u2500\u256F \u2570\u2500\u2500\u2500\u256F "
875
+ ],
876
+ "loyal": [
877
+ " \u2571\u2572 ",
878
+ " \u2571 \u2572 ",
879
+ " \u2571 \u2665\u2665 \u2572 ",
880
+ " \u2571 \u2665\u2665 \u2572 ",
881
+ " \u2572 50 \u2571 ",
882
+ " \u2572 \u2571 ",
883
+ " \u2572 \u2571 ",
884
+ " \u2572\u2571 "
885
+ ],
886
+ "wanderer": [
887
+ " \xB7 \xB7 \xB7 ",
888
+ " \u2572 \u2502 \u2571 ",
889
+ " \u2572 \u2502 \u2571 ",
890
+ " \xB7 + \xB7 ",
891
+ " \u2571 \u2502 \u2572 ",
892
+ " \u2571 \u2502 \u2572 ",
893
+ " \xB7 \xB7 \xB7 "
894
+ ],
895
+ "streak": [
896
+ " \u2554\u2550\u2550\u2557\u2554\u2550\u2550\u2557\u2554\u2550\u2550\u2557\u2554\u2550\u2550\u2557 ",
897
+ " \u2551M \u2551\u2551T \u2551\u2551W \u2551\u2551T \u2551 ",
898
+ " \u2551\u25C6 \u2551\u2551\u25C6 \u2551\u2551\u25C6 \u2551\u2551\u25C6 \u2551 ",
899
+ " \u255A\u2550\u2550\u255D\u255A\u2550\u2550\u255D\u255A\u2550\u2550\u255D\u255A\u2550\u2550\u255D ",
900
+ " \u2554\u2550\u2550\u2557\u2554\u2550\u2550\u2557\u2554\u2550\u2550\u2557 ",
901
+ " \u2551F \u2551\u2551S \u2551\u2551S \u2551 ",
902
+ " \u2551\u25C6 \u2551\u2551\u25C6 \u2551\u2551\u25C6 \u2551 ",
903
+ " \u255A\u2550\u2550\u255D\u255A\u2550\u2550\u255D\u255A\u2550\u2550\u255D "
904
+ ],
905
+ "hot-streak": [
906
+ " \u2571\u2572 ",
907
+ " \u2571\u2571\u2572\u2572 ",
908
+ " \u2571\u2571\u25C6\u25C6\u2572\u2572 ",
909
+ " \u2571\u2571 \u25C6\u25C6 \u2572\u2572 ",
910
+ " \u2572\u2572 \u25C6\u25C6 \u2571\u2571 ",
911
+ " \u2572\u2572\u25C6\u25C6\u2571\u2571 ",
912
+ " \u2572\u2572\u2571\u2571 ",
913
+ " \xD77 clean "
914
+ ],
915
+ "momentum": [
916
+ " \u25C9 \u25C9 ",
917
+ " \u2502\u2572 \u2571\u2502 ",
918
+ " \u2502 \u2572 \u2571 \u2502 ",
919
+ " \u2502 \u2572 \u2571 \u2502 ",
920
+ " \u2502 \u25C9\u25C9 \u2502 ",
921
+ " \u2502 \u2571 \u2572 \u2502 ",
922
+ " \u2502 \u2571 \u2572 \u2502 ",
923
+ " \u2502\u2571 \u2572\u2502 ",
924
+ " \u25C9 \u25C9 "
925
+ ],
926
+ "patient-one": [
927
+ " \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E ",
928
+ " \u2502 \u203E.\u203E \u2502 ",
929
+ " \u2502 \u2502 ",
930
+ " \u2502 zzz \u2502 ",
931
+ " \u2502 zz \u2502 ",
932
+ " \u2502 z \u2502 ",
933
+ " \u2502 \u2502 ",
934
+ " \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F ",
935
+ " 30 min+ "
936
+ ],
937
+ "message-in-a-bottle": [
938
+ " \u256D\u2500\u256E ",
939
+ " \u2502\xD7\u2502 ",
940
+ " \u256D\u2500\u2534\u2500\u2534\u2500\u256E ",
941
+ " \u2502 \u2591\u2591\u2591 \u2502 ",
942
+ " \u2502 \u2591\u2591\u2591 \u2502 ",
943
+ " \u2502 \u2591\u2591\u2591 \u2502 ",
944
+ " \u2570\u2500\u2500\u2500\u2500\u2500\u256F ",
945
+ " \u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248 ",
946
+ " \u2248\u2248\u2248\u2248\u2248\u2248\u2248 "
947
+ ],
948
+ "comeback-kid": [
949
+ " \u2571\u2572 \u2571\u2572 ",
950
+ " \u2571 \u2572 \u2571 \u2572 ",
951
+ " \u2571 \u2572 \u2571 \u2572 ",
952
+ " \u2571 \u2573 \u2572 ",
953
+ " \u2572 \u2571\u2572 \u2571 ",
954
+ " \u2572 \u2571 \u2572 \u2571 ",
955
+ " \u2572 \u2571 \u2572 \u2571 ",
956
+ " \u2572\u2571 \u2572\u2571 \u2713 "
957
+ ],
958
+ "pair-programming": [
959
+ " \u256D\u2500\u2500\u2500\u2500\u2500\u256E\u256D\u2500\u2500\u2500\u2500\u2500\u256E ",
960
+ " \u2502 \u25C9 \u25C9 \u2502\u2502 \u25C9 \u25C9 \u2502 ",
961
+ " \u2502 \u25BD \u2502\u2502 \u25BD \u2502 ",
962
+ " \u2570\u2500\u2500\u252C\u2500\u2500\u256F\u2570\u2500\u2500\u252C\u2500\u2500\u256F ",
963
+ " \u2502 \u2571\u2500\u2500\u2572 \u2502 ",
964
+ " \u2502\u2571 \u2572\u2502 ",
965
+ " \u2571 \u2550\u2550 \u2572 ",
966
+ " \u2571 \u2550\u2550\u2550\u2550 \u2572 ",
967
+ " \u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594 "
968
+ ],
969
+ "overdrive": [
970
+ " \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E ",
971
+ " \u2571 \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u256E \u2572 ",
972
+ " \u2502 \u2571 \xD76 \u2572 \u2502 ",
973
+ " \u2502 \u2502 \u25C9 \u2502 \u2502 ",
974
+ " \u2502 \u2572 \u2571 \u2502 ",
975
+ " \u2572 \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u256F \u2571 ",
976
+ " \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F ",
977
+ " same day \xD76 "
978
+ ],
979
+ "iron-streak": [
980
+ " \u2554\u2550\u2550\u2557\u2500\u2554\u2550\u2550\u2557\u2500\u2554\u2550\u2550\u2557 ",
981
+ " \u2551\u25C6 \u2551 \u2551\u25C6 \u2551 \u2551\u25C6 \u2551 ",
982
+ " \u255A\u2550\u2550\u255D\u2500\u255A\u2550\u2550\u255D\u2500\u255A\u2550\u2550\u255D ",
983
+ " \u2502 \u2502 ",
984
+ " \u2554\u2550\u2550\u2557\u2500\u2554\u2550\u2550\u2557\u2500\u2554\u2550\u2550\u2557 ",
985
+ " \u2551\u25C6 \u2551 \u2551\u25C6 \u2551 \u2551\u25C6 \u2551 ",
986
+ " \u255A\u2550\u2550\u255D\u2500\u255A\u2550\u2550\u255D\u2500\u255A\u2550\u2550\u255D ",
987
+ " 14 day chain "
988
+ ],
989
+ "deep-conversation": [
990
+ " \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E ",
991
+ " \u2571 \u256D\u2500\u2500\u256E 20 \u2572 ",
992
+ " \u2502 \u2502 \u2502 \u2502 ",
993
+ " \u2502 \u2570\u2500\u2500\u256F \u2502 ",
994
+ " \u2502 \xB7 \xB7 \xB7 \xB7 \xB7 \u2502 ",
995
+ " \u2572 \u2571 ",
996
+ " \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F ",
997
+ " \u2572 ",
998
+ " \u25CF "
999
+ ],
1000
+ "one-must-imagine": [
1001
+ " \u25C9\u25C9\u25C9\u25C9\u25C9 ",
1002
+ " \u2571 \u25C9\u25C9\u25C9\u25C9 ",
1003
+ " \u2571 \u25C9 \u2571 \u2190\u2500\u256E ",
1004
+ "\u2571 (>.<) \u2502 ",
1005
+ " \u2571\u2571 \u2572\u2572 \u2502 ",
1006
+ " \u2571 \u2572 \u2502 ",
1007
+ " \u2571 \u2572\u2500\u256F ",
1008
+ " \u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594\u2594 ",
1009
+ " \xD710 restarts "
1010
+ ]
1011
+ };
1012
+ var CARD_WIDTH = 34;
1013
+ var CARD_HEIGHT = 18;
1014
+ var CARD_INNER = CARD_WIDTH - 2;
1015
+ function centerLine(text, width) {
1016
+ const stripped = stripAnsiForWidth(text);
1017
+ if (stripped.length >= width) return text.slice(0, width);
1018
+ const pad = Math.floor((width - stripped.length) / 2);
1019
+ return " ".repeat(pad) + text + " ".repeat(width - stripped.length - pad);
1020
+ }
1021
+ function stripAnsiForWidth(s) {
1022
+ return s.replace(/\x1b\[[0-9;]*m/g, "");
1023
+ }
1024
+ function renderBadgeCard(def, unlock, opts) {
1025
+ const dim = opts?.dim === true || unlock === null;
1026
+ const art = BADGE_ART[def.id] ?? [];
1027
+ const lines = [];
1028
+ const category = def.category.toUpperCase();
1029
+ const borderLabel = ` ${category} `;
1030
+ const topPad = CARD_INNER - borderLabel.length - 2;
1031
+ const topLeft = Math.floor(topPad / 2);
1032
+ const topRight = topPad - topLeft;
1033
+ lines.push(`\u250C${"\u2500".repeat(topLeft)}${borderLabel}${"\u2500".repeat(topRight)}\u2510`);
1034
+ lines.push(`\u2502${" ".repeat(CARD_INNER)}\u2502`);
1035
+ const artMaxLines = 9;
1036
+ const artSlice = art.slice(0, artMaxLines);
1037
+ for (const artLine of artSlice) {
1038
+ const centered = centerLine(artLine, CARD_INNER);
1039
+ lines.push(`\u2502${dim ? dimText(centered) : centered}\u2502`);
1040
+ }
1041
+ for (let i = artSlice.length; i < artMaxLines; i++) {
1042
+ lines.push(`\u2502${" ".repeat(CARD_INNER)}\u2502`);
1043
+ }
1044
+ lines.push(`\u2502${" ".repeat(CARD_INNER)}\u2502`);
1045
+ const nameText = unlock !== null ? def.name : `? ${def.name} ?`;
1046
+ lines.push(`\u2502${centerLine(nameText, CARD_INNER)}\u2502`);
1047
+ const descLines = wrapText(def.description, CARD_INNER - 4);
1048
+ for (const dl of descLines.slice(0, 2)) {
1049
+ const centered = centerLine(dl, CARD_INNER);
1050
+ lines.push(`\u2502${dim ? dimText(centered) : centered}\u2502`);
1051
+ }
1052
+ const usedContent = 1 + 1 + artMaxLines + 1 + 1 + Math.min(descLines.length, 2);
1053
+ const remaining = CARD_HEIGHT - 2 - usedContent;
1054
+ for (let i = 0; i < remaining; i++) {
1055
+ if (i === remaining - 1 && unlock !== null) {
1056
+ const dateStr = unlock.unlockedAt.slice(0, 10);
1057
+ lines.push(`\u2502${centerLine(dimText(dateStr), CARD_INNER)}\u2502`);
1058
+ } else {
1059
+ lines.push(`\u2502${" ".repeat(CARD_INNER)}\u2502`);
1060
+ }
1061
+ }
1062
+ lines.push(`\u2514${"\u2500".repeat(CARD_INNER)}\u2518`);
1063
+ return { lines, width: CARD_WIDTH, height: lines.length };
1064
+ }
1065
+ function dimText(text) {
1066
+ return `\x1B[2m${text}\x1B[22m`;
1067
+ }
1068
+ function wrapText(text, maxWidth) {
1069
+ const words = text.split(" ");
1070
+ const lines = [];
1071
+ let current = "";
1072
+ for (const word of words) {
1073
+ if (current.length + word.length + 1 > maxWidth && current.length > 0) {
1074
+ lines.push(current);
1075
+ current = word;
1076
+ } else {
1077
+ current = current.length > 0 ? `${current} ${word}` : word;
1078
+ }
1079
+ }
1080
+ if (current.length > 0) lines.push(current);
1081
+ return lines;
1082
+ }
1083
+ function createBadgeGallery(unlockedAchievements, startIndex) {
1084
+ const unlocked = /* @__PURE__ */ new Map();
1085
+ for (const a of unlockedAchievements) {
1086
+ unlocked.set(a.id, a);
1087
+ }
1088
+ const sorted = [...ACHIEVEMENTS].sort((a, b) => {
1089
+ const aUnlocked = unlocked.has(a.id);
1090
+ const bUnlocked = unlocked.has(b.id);
1091
+ if (aUnlocked && !bUnlocked) return -1;
1092
+ if (!aUnlocked && bUnlocked) return 1;
1093
+ if (aUnlocked && bUnlocked) {
1094
+ const aDate = unlocked.get(a.id).unlockedAt;
1095
+ const bDate = unlocked.get(b.id).unlockedAt;
1096
+ return aDate.localeCompare(bDate);
1097
+ }
1098
+ return 0;
1099
+ });
1100
+ return {
1101
+ achievements: sorted,
1102
+ unlocked,
1103
+ currentIndex: startIndex ?? 0,
1104
+ total: sorted.length
1105
+ };
1106
+ }
1107
+ function galleryNext(gallery) {
1108
+ return (gallery.currentIndex + 1) % gallery.total;
1109
+ }
1110
+ function galleryPrev(gallery) {
1111
+ return (gallery.currentIndex - 1 + gallery.total) % gallery.total;
1112
+ }
1113
+
1114
+ // src/shared/client.ts
1115
+ import { connect } from "net";
1116
+ function rawSend(request, timeoutMs = 1e4) {
1117
+ const sock = socketPath();
1118
+ return new Promise((resolve, reject) => {
1119
+ const socket = connect(sock);
1120
+ let data = "";
1121
+ const timeout = setTimeout(() => {
1122
+ socket.destroy();
1123
+ reject(new Error(`Request timed out after ${(timeoutMs / 1e3).toFixed(0)}s. The daemon may be overloaded.
1124
+ Check: sisyphus admin doctor
1125
+ Logs: tail -20 ~/.sisyphus/daemon.log`));
1126
+ }, timeoutMs);
1127
+ socket.on("connect", () => {
1128
+ socket.write(JSON.stringify(request) + "\n");
1129
+ });
1130
+ socket.on("data", (chunk) => {
1131
+ data += chunk.toString();
1132
+ const newlineIdx = data.indexOf("\n");
1133
+ if (newlineIdx !== -1) {
1134
+ clearTimeout(timeout);
1135
+ const line = data.slice(0, newlineIdx);
1136
+ socket.destroy();
1137
+ try {
1138
+ resolve(JSON.parse(line));
1139
+ } catch {
1140
+ reject(new Error(`Invalid JSON response from daemon: ${line}`));
1141
+ }
1142
+ }
1143
+ });
1144
+ socket.on("error", (err) => {
1145
+ clearTimeout(timeout);
1146
+ reject(err);
1147
+ });
1148
+ });
1149
+ }
1150
+
1151
+ export {
1152
+ rawSend,
1153
+ formatHelpForKeymap,
1154
+ MENU_FOR_MODE,
1155
+ KEYMAP,
1156
+ computeActiveTimeMs,
1157
+ resolveReports,
1158
+ buildCompanionContext,
1159
+ buildSessionContext,
1160
+ renderBadgeCard,
1161
+ createBadgeGallery,
1162
+ galleryNext,
1163
+ galleryPrev
1164
+ };
1165
+ //# sourceMappingURL=chunk-M6Z3KHOH.js.map