kaizen-agent 1.4.0 → 1.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.
package/web/board.html ADDED
@@ -0,0 +1,361 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <title>kaizen</title>
7
+ <style>
8
+ :root{--bg:#f6f8fc;--bg-2:#fff;--line:#d9e0ee;--ink:#0c162f;--ink-hi:#0c162f;--dim:#5b6b8c;--accent:#2d50a5;--run:#0f8fa3;--ok:#1f9d55;--warn:#a8720a;--danger:#c8322f;color-scheme:light}
9
+ @media(prefers-color-scheme:dark){:root:not([data-theme=light]){--bg:#0c162f;--bg-2:#121e3c;--line:#22305a;--ink:#eef2fa;--ink-hi:#deeeff;--dim:#96aacd;--accent:#486ed9;--run:#4fd6e6;--ok:#5fd28a;--warn:#e6b450;--danger:#e85050;color-scheme:dark}}
10
+ :root[data-theme=dark]{--bg:#0c162f;--bg-2:#121e3c;--line:#22305a;--ink:#eef2fa;--ink-hi:#deeeff;--dim:#96aacd;--accent:#486ed9;--run:#4fd6e6;--ok:#5fd28a;--warn:#e6b450;--danger:#e85050;color-scheme:dark}
11
+ *{box-sizing:border-box}
12
+ :root{--r:6px;--r-s:4px}
13
+ body{margin:0;background:var(--bg);color:var(--ink);font:14px/1.5 ui-monospace,"JetBrains Mono","Cascadia Code","SF Mono",Menlo,Consolas,monospace;min-height:100vh;display:flex;flex-direction:column}
14
+ button,input,select{font:inherit;color:inherit;background:none;border:0;padding:0}
15
+ button{cursor:pointer}
16
+ :focus-visible{outline:2px solid var(--accent);outline-offset:2px}
17
+ svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;display:block}
18
+
19
+ /* header */
20
+ .hdr{display:flex;align-items:center;gap:16px;padding:10px 24px;border-bottom:1px solid var(--line);flex-wrap:wrap}
21
+ pre.mark{margin:0;font-size:8px;line-height:1;font-weight:700}
22
+ pre.mark span:nth-child(1){color:var(--ink-hi)}pre.mark span:nth-child(2){color:color-mix(in srgb,var(--ink-hi),var(--accent))}pre.mark span:nth-child(3){color:var(--accent)}
23
+ .sel{border:1px solid var(--line);border-radius:var(--r);padding:5px 8px;background:var(--bg-2);cursor:pointer;color:var(--ink);appearance:auto;font-size:13px}
24
+ .sp{flex:1}
25
+ .ib{width:34px;height:34px;display:grid;place-items:center;color:var(--dim);border:1px solid transparent;border-radius:var(--r)}
26
+ .ib:hover{color:var(--ink);border-color:var(--line)}
27
+ .ib.pri{color:var(--accent)}
28
+ .ib.sm{width:26px;height:26px}.ib.sm svg{width:15px;height:15px}
29
+ .btn{border:1px solid var(--line);border-radius:var(--r);padding:5px 12px;color:var(--ink);background:var(--bg-2);min-height:30px;font-size:13px}
30
+ .btn:hover{border-color:var(--dim)}
31
+ .btn.pri{background:var(--accent);border-color:var(--accent);color:#fff}
32
+ .btn.warn{border-color:var(--warn);color:var(--warn)}.btn.warn:hover{background:var(--warn);color:var(--bg)}
33
+ .btn.danger{color:var(--danger)}.btn.danger:hover{border-color:var(--danger)}
34
+ .btn.ghost{background:none;border-color:transparent;color:var(--dim)}.btn.ghost:hover{color:var(--ink);border-color:var(--line)}
35
+
36
+ /* summary strip */
37
+ .strip{display:flex;gap:18px;padding:8px 24px;border-bottom:1px solid var(--line);flex-wrap:wrap;align-items:center;font-size:13px;color:var(--dim)}
38
+ .strip button{color:var(--dim);padding:2px 8px;border-radius:var(--r-s)}
39
+ .strip button:hover,.strip button.on{color:var(--ink);background:color-mix(in srgb,var(--dim) 12%,transparent)}
40
+ .strip button.attn{color:var(--warn)}
41
+
42
+ /* board */
43
+ main{flex:1;display:grid;grid-template-columns:repeat(5,minmax(200px,1fr));gap:20px;padding:16px 24px;overflow:auto;align-content:start}
44
+ section h2{margin:0;font-size:12px;color:var(--ink);font-weight:600;display:flex;align-items:center;gap:8px;height:30px}
45
+ section h2 i{font-style:normal;font-weight:400}
46
+ section h2 .ib{margin-left:auto}
47
+ ul{list-style:none;margin:0;padding:8px 0 0;display:flex;flex-direction:column;gap:8px}
48
+
49
+ /* card, Linear grammar in our palette
50
+ line 1 status icon · id (dim mono) · ⋯ menu on hover
51
+ line 2 title, regular weight, wraps to 2 lines
52
+ line 3 chips, only when set
53
+ Card ground is --bg-2 on a --bg column. Actions never sit on the card. */
54
+ .card{background:var(--bg-2);border:1px solid var(--line);border-radius:var(--r);padding:10px 12px;cursor:pointer;display:flex;flex-direction:column;gap:6px;position:relative}
55
+ .card:hover{border-color:var(--dim)}
56
+ .card.open{border-color:var(--accent)}
57
+ .c-id{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--dim);min-height:20px}
58
+ .c-id .st{width:14px;height:14px;display:grid;place-items:center;flex-shrink:0}
59
+ .c-id .st svg{width:14px;height:14px;stroke-width:1.8}
60
+ .c-id .idt{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-variant-numeric:tabular-nums}
61
+ .c-id .age{font-variant-numeric:tabular-nums}
62
+ .c-id .more{display:none;margin:-4px -6px -4px 0}
63
+ .card:hover .more,.card:focus-within .more,.card.menu .more{display:flex}
64
+ .card:hover .age,.card.menu .age{display:none}
65
+ .c-title{font-size:13px;line-height:1.45;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;color:var(--ink)}
66
+ .c-chips{display:flex;gap:6px;flex-wrap:wrap}
67
+ .c-chips:empty{display:none}
68
+ .chip{display:inline-flex;align-items:center;gap:5px;height:20px;padding:0 7px;border-radius:var(--r-s);font-size:11px;color:var(--dim);background:color-mix(in srgb,var(--dim) 12%,transparent)}
69
+ .chip i{width:6px;height:6px;border-radius:50%;background:var(--dim)}
70
+ .chip svg{width:11px;height:11px;stroke-width:1.7}
71
+ .chip.warn{color:var(--warn);background:color-mix(in srgb,var(--warn) 14%,transparent)}.chip.warn i{background:var(--warn)}
72
+ .chip.accent{color:var(--accent);background:color-mix(in srgb,var(--accent) 14%,transparent)}.chip.accent i{background:var(--accent)}
73
+ .chip.run{color:var(--run);background:color-mix(in srgb,var(--run) 14%,transparent)}.chip.run i{background:var(--run)}
74
+ .st.d-idea{color:var(--dim)}.st.d-run{color:var(--run)}.st.d-stall{color:var(--dim)}.st.d-wait{color:var(--warn)}.st.d-done{color:var(--ok)}.st.d-aband{color:var(--dim)}
75
+ .d-run{color:var(--run)}.d-wait{color:var(--warn)}.d-done{color:var(--ok)}
76
+ .pulse{display:inline-block;width:7px;height:7px;border-radius:50%;background:currentColor;vertical-align:middle}
77
+ .d-run .pulse,.st.d-run svg{animation:pl 1.6s infinite}
78
+ @keyframes pl{50%{opacity:.35}}
79
+ /* hover menu */
80
+ .menu-pop{position:absolute;right:8px;top:30px;background:var(--bg-2);border:1px solid var(--line);border-radius:var(--r);padding:4px;z-index:2;min-width:140px;display:flex;flex-direction:column}
81
+ .menu-pop button{text-align:left;padding:6px 10px;font-size:12px;color:var(--ink);border-radius:var(--r-s);display:flex;gap:8px;align-items:center}
82
+ .menu-pop button:hover{background:color-mix(in srgb,var(--dim) 12%,transparent)}
83
+ .menu-pop button.danger{color:var(--danger)}
84
+ .menu-pop hr{border:0;border-top:1px solid var(--line);margin:4px 0}
85
+
86
+ /* inline forms replace a card while editing */
87
+ .inl{display:flex;flex-direction:column;gap:8px;padding:10px 12px;background:var(--bg-2);border:1px solid var(--accent);border-radius:var(--r)}
88
+ .inl input{width:100%;border:1px solid var(--line);border-radius:var(--r);padding:7px 10px;background:var(--bg-2)}
89
+ .inl input::placeholder{color:var(--dim)}
90
+ .inl .row{display:flex;gap:6px;justify-content:flex-end}
91
+ .inl .q{font-size:13px}.inl .q.dim{color:var(--dim)}
92
+ .empty{grid-column:1/-1;display:flex;flex-direction:column;align-items:center;gap:14px;padding-block:60px;color:var(--dim)}
93
+ .mascot{width:120px;height:112px;background:var(--ink);-webkit-mask:url(data:image/png;base64,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) center/contain no-repeat;mask:url(data:image/png;base64,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) center/contain no-repeat;animation:fi .2s}
94
+ @keyframes fi{from{opacity:0}}
95
+
96
+ /* footer */
97
+ .ftr{display:flex;justify-content:space-between;gap:16px;padding:8px 24px;border-top:1px solid var(--line);color:var(--dim);font-size:12px;flex-wrap:wrap;align-items:center}
98
+ .ftr span+span{margin-left:14px}.ftr .st svg{width:12px;height:12px}
99
+ .ftr a{color:var(--dim);cursor:pointer;text-decoration:underline}
100
+
101
+ /* side panel */
102
+ .scrim{position:fixed;inset:0;background:color-mix(in srgb,var(--bg) 55%,transparent);display:none}
103
+ .scrim.on{display:block}
104
+ aside{position:fixed;top:0;right:0;bottom:0;width:480px;max-width:100%;background:var(--bg-2);border-left:1px solid var(--line);display:flex;flex-direction:column;transform:translateX(100%);transition:transform .18s}
105
+ aside.open{transform:none}
106
+ aside header{display:flex;align-items:flex-start;gap:12px;padding:16px 20px;border-bottom:1px solid var(--line)}
107
+ aside header .t{flex:1;min-width:0}
108
+ aside header b{display:block;font-size:15px}
109
+ aside header .sub{color:var(--dim);font-size:12px;margin-top:2px}
110
+ aside nav{display:flex;border-bottom:1px solid var(--line);padding-inline:8px}
111
+ aside nav:empty{display:none}
112
+ aside nav button{padding:10px 12px;color:var(--dim);border-bottom:2px solid transparent;margin-bottom:-1px}
113
+ aside nav button:hover{color:var(--ink)}
114
+ aside nav button.on{color:var(--ink);border-bottom-color:var(--accent)}
115
+ aside .body{padding:20px;overflow:auto;flex:1}
116
+ aside .foot{padding:14px 20px;border-top:1px solid var(--line);display:flex;gap:8px;flex-wrap:wrap}
117
+ aside .foot:empty{display:none}
118
+ .md h3{font-size:12px;text-transform:uppercase;letter-spacing:.08em;color:var(--dim);margin:18px 0 6px}.md h3:first-child{margin-top:0}
119
+ .md p{margin:0 0 10px;max-width:62ch}.md ol,.md ul{padding-left:1.4em;margin:0 0 10px}.md li{margin:3px 0}
120
+ .md pre{background:var(--bg);border:1px solid var(--line);border-radius:var(--r-s);padding:8px 10px;overflow-x:auto;margin:0 0 8px;font-size:12px}
121
+ .md h1,.md h2{font-size:13px;margin:16px 0 6px}.md h1:first-child,.md h2:first-child{margin-top:0}.md code{background:var(--bg);padding:0 4px;border-radius:var(--r-s)}.md table{border-collapse:collapse;font-size:12px;margin:0 0 10px}.md td,.md th{border:1px solid var(--line);padding:3px 8px;text-align:left}.md hr{border:0;border-top:1px solid var(--line);margin:12px 0}
122
+ .find{border-bottom:1px solid var(--line);padding:10px 0;display:flex;gap:10px;align-items:flex-start}
123
+ .find input{margin-top:4px}
124
+ .find .sev{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--warn)}.find .sev.hi{color:var(--danger)}
125
+ .find .loc{color:var(--dim);font-size:12px;margin-left:8px}
126
+ .set{display:grid;grid-template-columns:auto 1fr;gap:10px 20px;align-items:center;font-size:13px}
127
+ .set label{color:var(--dim)}
128
+ .set .opts{display:flex;gap:4px}
129
+ .set .opts button{border:1px solid var(--line);border-radius:var(--r);padding:3px 10px;color:var(--dim)}
130
+ .set .opts button.on{color:var(--ink);border-color:var(--ink)}
131
+ .toast{position:fixed;left:24px;bottom:52px;background:var(--ink);color:var(--bg);border-radius:var(--r);padding:8px 14px;font-size:13px;opacity:0;transition:opacity .2s;pointer-events:none}
132
+ .toast.on{opacity:1}
133
+ .help{position:fixed;inset:0;display:none;align-items:center;justify-content:center;background:color-mix(in srgb,var(--bg) 70%,transparent)}
134
+ .help.on{display:flex}.help div{background:var(--bg-2);border:1px solid var(--line);border-radius:var(--r);padding:20px 24px;line-height:2}
135
+ .help kbd{display:inline-block;width:7ch;color:var(--accent)}
136
+ @media(max-width:900px){main{grid-template-columns:1fr;padding-inline:16px;gap:8px}.hdr,.strip,.ftr{padding-inline:16px}section h2{position:sticky;top:0;background:var(--bg);z-index:1}.more{display:flex}.card:hover .age{display:inline}}
137
+ @media(prefers-reduced-motion:reduce){aside,.toast,.mascot,.d-run .pulse{transition:none;animation:none}}
138
+ </style>
139
+ </head>
140
+ <body>
141
+
142
+ <svg style="display:none"><defs>
143
+ <symbol id="i-plus" viewBox="0 0 24 24"><path d="M12 5v14M5 12h14"/></symbol>
144
+ <symbol id="i-gear" viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 1 1-4 0v-.1a1.7 1.7 0 0 0-1.1-1.5 1.7 1.7 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.1a1.7 1.7 0 0 0 1.5-1.1 1.7 1.7 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.8.3H9a1.7 1.7 0 0 0 1-1.5V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.8V9a1.7 1.7 0 0 0 1.5 1H21a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1z"/></symbol>
145
+ <symbol id="i-play" viewBox="0 0 24 24"><path d="M6 4l14 8-14 8z"/></symbol>
146
+ <symbol id="i-pen" viewBox="0 0 24 24"><path d="M12 20h9M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4z"/></symbol>
147
+ <symbol id="i-x" viewBox="0 0 24 24"><path d="M18 6L6 18M6 6l12 12"/></symbol>
148
+ <symbol id="i-trash" viewBox="0 0 24 24"><path d="M3 6h18M8 6V4h8v2M6 6l1 14h10l1-14M10 11v6M14 11v6"/></symbol>
149
+ <symbol id="i-close" viewBox="0 0 24 24"><path d="M18 6L6 18M6 6l12 12"/></symbol>
150
+ <symbol id="i-more" viewBox="0 0 24 24"><circle cx="5" cy="12" r="1.2" fill="currentColor"/><circle cx="12" cy="12" r="1.2" fill="currentColor"/><circle cx="19" cy="12" r="1.2" fill="currentColor"/></symbol>
151
+ <symbol id="s-idea" viewBox="0 0 16 16"><circle cx="8" cy="8" r="6" stroke-dasharray="2 2.5"/></symbol>
152
+ <symbol id="s-run" viewBox="0 0 16 16"><circle cx="8" cy="8" r="6"/><path d="M8 2a6 6 0 0 1 0 12z" fill="currentColor" stroke="none"/></symbol>
153
+ <symbol id="s-stall" viewBox="0 0 16 16"><circle cx="8" cy="8" r="6"/><path d="M8 2a6 6 0 0 1 0 12z" fill="currentColor" stroke="none" opacity=".35"/></symbol>
154
+ <symbol id="s-wait" viewBox="0 0 16 16"><circle cx="8" cy="8" r="6"/><path d="M8 5v3.5M8 11v.1"/></symbol>
155
+ <symbol id="s-done" viewBox="0 0 16 16"><circle cx="8" cy="8" r="6" fill="currentColor" stroke="none"/><path d="M5.5 8l1.8 1.8L10.8 6" stroke="var(--bg-2)"/></symbol>
156
+ <symbol id="s-aband" viewBox="0 0 16 16"><circle cx="8" cy="8" r="6"/><path d="M5.5 5.5l5 5M10.5 5.5l-5 5"/></symbol>
157
+ <!-- chip marks: agents and run kinds. Simple strokes, no trademark art. -->
158
+ <symbol id="c-claude" viewBox="0 0 16 16"><path d="M8 2v12M2 8h12M3.8 3.8l8.4 8.4M12.2 3.8l-8.4 8.4"/></symbol>
159
+ <symbol id="c-codex" viewBox="0 0 16 16"><path d="M8 2l5.2 3v6L8 14l-5.2-3V5z"/><circle cx="8" cy="8" r="2"/></symbol>
160
+ <symbol id="c-agy" viewBox="0 0 16 16"><path d="M8 13V4M4.5 7.5L8 4l3.5 3.5M4 13h8"/></symbol>
161
+ <symbol id="c-opencode" viewBox="0 0 16 16"><path d="M3 4l4 4-4 4M8.5 12H13"/></symbol>
162
+ <symbol id="c-gemini" viewBox="0 0 16 16"><path d="M8 2c0 4 2 6 6 6-4 0-6 2-6 6 0-4-2-6-6-6 4 0 6-2 6-6z"/></symbol>
163
+ <symbol id="c-cursor" viewBox="0 0 16 16"><path d="M4 3l9 5-4 1-1 4z"/></symbol>
164
+ <symbol id="c-full" viewBox="0 0 16 16"><circle cx="5.5" cy="8" r="3"/><circle cx="11" cy="8" r="3"/></symbol>
165
+ <symbol id="c-lite" viewBox="0 0 16 16"><circle cx="8" cy="8" r="3"/></symbol>
166
+ </defs></svg>
167
+
168
+ <div class="hdr">
169
+ <pre class="mark" aria-label="kaizen"><span>█ █ ▄▀█ █ ▀▀█ █▀▀ █▄ █</span>
170
+ <span>█▀▄ █▀█ █ ▄▀ ██▄ █ ▀█</span>
171
+ <span>█ █ █ █ █ █▄▄ █▄▄ █ █</span></pre>
172
+ <select class="sel" id="proj" aria-label="project"></select>
173
+ <span class="sp"></span>
174
+ <button class="btn pri" id="newtop">New idea</button>
175
+ <button class="ib" id="settings" title="Settings" aria-label="Settings"><svg><use href="#i-gear"/></svg></button>
176
+ </div>
177
+ <div class="strip" id="strip"></div>
178
+
179
+ <main id="board" aria-live="polite"></main>
180
+
181
+ <div class="ftr"><span id="legend"></span><span><a id="kbd">Keyboard shortcuts</a></span></div>
182
+
183
+ <div class="scrim" id="scrim"></div>
184
+ <aside id="panel" aria-label="detail">
185
+ <header><div class="t"><b id="ptitle"></b><div class="sub" id="psub"></div></div><button class="ib" id="pclose" aria-label="Close" title="Close"><svg><use href="#i-close"/></svg></button></header>
186
+ <nav id="ptabs"></nav>
187
+ <div class="body md" id="pbody"></div>
188
+ <div class="foot" id="pfoot"></div>
189
+ </aside>
190
+ <div class="toast" id="toast" role="status"></div>
191
+ <div class="help" id="help"><div>
192
+ Optional. Everything here is also a button.<br>
193
+ <kbd>n</kbd>new idea<br><kbd>e</kbd>edit<br><kbd>x</kbd>reject / abandon<br><kbd>r</kbd>run<br><kbd>a</kbd>all projects<br><kbd>Esc</kbd>close<br><kbd>?</kbd>this list</div></div>
194
+
195
+ <script>
196
+ // The page never touches the filesystem. Everything comes from /state and the run
197
+ // files behind /run/:id; every change goes through a POST and comes back as an SSE
198
+ // tick that reloads the board. See design.md for the visual rules.
199
+ const $=id=>document.getElementById(id);
200
+ const esc=s=>String(s).replace(/[&<>"]/g,c=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"})[c]);
201
+ const ico=n=>`<svg><use href="#i-${n}"/></svg>`;
202
+ const m=60e3,h=3600e3,d=86400e3;
203
+ const age=(t,now)=>{const x=now-t;return x<h?Math.round(x/m)+"m":x<d?Math.round(x/h)+"h":Math.round(x/d)+"d"};
204
+ const NAMES={claude:"Claude Code",codex:"Codex",agy:"Antigravity",opencode:"OpenCode",gemini:"Gemini",cursor:"Cursor"};
205
+ const MARKS={claude:1,codex:1,agy:1,opencode:1,gemini:1,cursor:1,full:1,lite:1};
206
+ const COLS=["Ideas","Planning","Building","Review","Done"];
207
+ // state.ts statuses onto the icon set in the <defs> above.
208
+ const ICON={idea:"idea",starting:"start",running:"run",stalled:"stall",waiting:"wait",done:"done",abandoned:"aband"};
209
+ const WORD={idea:"idea",starting:"starting",running:"running",stalled:"stalled",waiting:"waiting on you",done:"done",abandoned:"abandoned"};
210
+
211
+ let S={project:null,projects:[],cards:[],now:Date.now(),all:false};
212
+ let all=new URLSearchParams(location.search).get("all")==="1",openKey=null,mode=null,modeKey=null,filter=null,menuKey=null,tab=0,runDoc=null;
213
+ const wasAwaiting=new Map();let first=true;
214
+
215
+ const key=c=>c.kind==="idea"?"idea:"+c.state+":"+c.text:"run:"+c.state+":"+c.id;
216
+
217
+ async function load(){
218
+ const r=await fetch("/state"+(all?"?all=1":""));S=await r.json();
219
+ for(const c of S.cards){if(c.kind!=="run")continue;const k=key(c),before=wasAwaiting.get(k);
220
+ if(!first&&before===null&&c.awaiting)notifyUser("kaizen — waiting on you",c.text+" · "+c.awaiting);wasAwaiting.set(k,c.awaiting)}
221
+ first=false;render();
222
+ if(openKey&&runDoc){const c=S.cards.find(x=>key(x)===openKey);if(c)openRun(c,true)}}
223
+ async function post(path,body){const r=await fetch(path,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(body)});const j=await r.json().catch(()=>({}));if(!r.ok){toast(j.error||j.why||"failed");if(j.manual)console.log("run manually:",j.manual)}return j}
224
+
225
+ function card(c){
226
+ const k=key(c),el=document.createElement("div");el.className="card"+(k===openKey?" open":"")+(k===menuKey?" menu":"");el.tabIndex=0;el.setAttribute("role","button");
227
+ const st=ICON[c.status]||"idea",idt=c.kind==="idea"?"idea":c.text;
228
+ const chips=[];
229
+ if(c.status==="waiting")chips.push(`<span class="chip warn"><i></i>${esc(c.awaiting||"needs you")}</span>`);
230
+ else if(c.status==="running")chips.push(`<span class="chip run"><i></i>running</span>`);
231
+ if(all)chips.push(`<span class="chip">${esc(c.where)}</span>`);
232
+ el.innerHTML=`<div class="c-id"><span class="st d-${st}"><svg><use href="#s-${st}"/></svg></span><span class="idt">${esc(idt)}</span><span class="age">${c.kind==="run"?age(c.moved||S.now,S.now):""}</span><button class="ib sm more" data-a="menu" title="Actions" aria-label="Actions">${ico("more")}</button></div>
233
+ <div class="c-title">${esc(c.kind==="idea"?c.text:(c.title||c.id))}</div>
234
+ <div class="c-chips">${chips.join("")}</div>`;
235
+ if(k===menuKey){
236
+ const items=[];
237
+ if(c.kind==="idea"&&c.status==="idea")items.push(["run","Run",ico("play")],["edit","Edit",ico("pen")],["reject","Reject",ico("x")],null,["delete","Delete",ico("trash"),"danger"]);
238
+ else if(c.kind==="idea")items.push(["delete","Remove",ico("trash"),"danger"]);
239
+ else if(c.status==="waiting"||c.status==="running"||c.status==="stalled")items.push(["open","Open",ico("play")],null,["reject","Abandon",ico("x"),"danger"]);
240
+ else items.push(["open","Open",ico("play")]);
241
+ el.innerHTML+=`<div class="menu-pop">${items.map(i=>i?`<button data-a="${i[0]}" class="${i[3]||""}">${i[2]}${i[1]}</button>`:"<hr>").join("")}</div>`}
242
+ el.querySelectorAll("[data-a]").forEach(bt=>bt.onclick=e=>{e.stopPropagation();const a=bt.dataset.a;menuKey=null;if(a==="menu"){menuKey=k;render();return}if(a==="open"){open(c);return}mode=a;modeKey=k;render()});
243
+ el.onclick=()=>{if(menuKey){menuKey=null;render();return}open(c)};el.onkeydown=e=>{if(e.key==="Enter"||e.key===" "){e.preventDefault();open(c)}};
244
+ return el;}
245
+
246
+ function inlineForm(c){
247
+ const li=document.createElement("li");li.className="inl";const dir=c.state;
248
+ if(mode==="edit"){li.innerHTML=`<input value="${esc(c.text)}"><div class="row"><button class="btn ghost" data-a="c">Cancel</button><button class="btn pri" data-a="s">Save</button></div>`;li.querySelector('[data-a=s]').onclick=async()=>{const next=li.querySelector("input").value.trim();mode=null;if(next&&next!==c.text)await post("/inbox",{op:"edit",dir,text:c.text,next});load()}}
249
+ if(mode==="reject"){const idea=c.kind==="idea";li.innerHTML=`<div class="q">${idea?"Reject this idea?":"Abandon this run?"} The reason is recorded.</div><input placeholder="Reason"><div class="row"><button class="btn ghost" data-a="c">Keep it</button><button class="btn warn" data-a="s">${idea?"Reject":"Abandon"}</button></div>`;li.querySelector('[data-a=s]').onclick=async()=>{const why=li.querySelector("input").value.trim();if(!why){toast("A reason is required");return}mode=null;const r=idea?await post("/inbox",{op:"reject",dir,text:c.text,reason:why}):await post("/abort",{dir,id:c.id,why});if(r.ok)toast(idea?"Rejected":"Abandoned, reason recorded");load()}}
250
+ if(mode==="delete"){li.innerHTML=`<div class="q">Delete "${esc(c.text)}"?</div><div class="q dim">Not recorded anywhere.</div><div class="row"><button class="btn ghost" data-a="c">Keep it</button><button class="btn danger" data-a="s">Delete</button></div>`;li.querySelector('[data-a=s]').onclick=async()=>{mode=null;const r=await post("/inbox",{op:"delete",dir,text:c.text});if(r.ok)toast("Deleted");load()}}
251
+ if(mode==="run"){li.innerHTML=`<div class="q">Start a run for "${esc(c.text)}"</div><div class="q dim">Opens your agent in a new terminal with the request typed in.</div><div class="row"><button class="btn ghost" data-a="c">Cancel</button><button class="btn" data-a="l">Lite</button><button class="btn pri" data-a="s">Full run</button></div>`;li.querySelector('[data-a=s]').onclick=()=>startRun(c,"full");li.querySelector('[data-a=l]').onclick=()=>startRun(c,"lite")}
252
+ li.querySelector('[data-a=c]').onclick=()=>{mode=null;render()};
253
+ const inp=li.querySelector("input");if(inp){inp.onkeydown=e=>{if(e.key==="Enter")li.querySelector('[data-a=s]').click();if(e.key==="Escape"){mode=null;render()}};setTimeout(()=>inp.focus())}
254
+ return li;}
255
+
256
+ async function startRun(c,kind){
257
+ mode=null;askNotify();
258
+ const r=await post("/run",{dir:c.state,text:c.text,kind});
259
+ if(r.ok)toast(kind+" run opened in your terminal: "+r.agent.name);
260
+ load()}
261
+
262
+ function render(){
263
+ const cs=S.cards,b=$("board");b.innerHTML="";
264
+ const n=s=>cs.filter(c=>c.status===s).length;
265
+ const strip=[];
266
+ if(n("waiting"))strip.push(`<button class="attn ${filter==="waiting"?"on":""}" data-f="waiting">● ${n("waiting")} waiting on you</button>`);
267
+ strip.push(`<button class="${filter==="running"?"on":""}" data-f="running"><span class="d-run"><span class="pulse"></span></span> ${n("running")} running</button>`);
268
+ if(n("stalled"))strip.push(`<button class="${filter==="stalled"?"on":""}" data-f="stalled">◐ ${n("stalled")} stalled</button>`);
269
+ strip.push(`<span class="sp"></span><span>${cs.filter(c=>c.kind==="idea").length} ideas · ${cs.filter(c=>c.kind==="run").length} runs</span>`);
270
+ $("strip").innerHTML=strip.join("");
271
+ $("strip").querySelectorAll("button").forEach(c=>c.onclick=()=>{filter=filter===c.dataset.f?null:c.dataset.f;render()});
272
+ const sel=$("proj");sel.innerHTML=(S.project?`<option value="cur">${esc(S.project)}</option>`:"")+`<option value="all">All projects</option>`;sel.value=all||!S.project?"all":"cur";
273
+ if(!cs.length&&mode!=="new"){b.innerHTML='<div class="empty"><div class="mascot"></div><div>Nothing here yet.</div><button class="btn pri" id="newempty">New idea</button></div>';$("newempty").onclick=()=>{mode="new";render()};}
274
+ COLS.forEach((name,ci)=>{
275
+ const s=document.createElement("section");const list=cs.filter(c=>c.column===ci&&(!filter||c.status===filter));
276
+ s.innerHTML=`<h2>${name}<i>${list.length||""}</i>${ci===0?`<button class="ib sm" title="New idea" aria-label="New idea">${ico("plus")}</button>`:""}</h2>`;
277
+ if(ci===0)s.querySelector(".ib").onclick=()=>{mode="new";render()};
278
+ const ul=document.createElement("ul");
279
+ if(ci===0&&mode==="new"){const f=document.createElement("li");f.className="inl";f.innerHTML=`<input id="newidea" placeholder="One line, like a commit subject"><div class="row"><button class="btn ghost" id="nc">Cancel</button><button class="btn pri" id="ns">Add to inbox</button></div>`;ul.appendChild(f);
280
+ const inp=f.querySelector("input");const save=async()=>{const text=inp.value.trim();if(!text)return;mode=null;const r=await post("/inbox",{op:"add",text});if(r.ok)toast("Added to inbox.md");load()};
281
+ f.querySelector("#ns").onclick=save;f.querySelector("#nc").onclick=()=>{mode=null;render()};inp.onkeydown=e=>{if(e.key==="Enter")save();if(e.key==="Escape"){mode=null;render()}};setTimeout(()=>inp.focus())}
282
+ list.forEach(c=>{if(modeKey===key(c)&&mode){ul.appendChild(inlineForm(c));return}const li=document.createElement("li");li.appendChild(card(c));ul.appendChild(li)});
283
+ s.appendChild(ul);b.appendChild(s)});
284
+ const seen=new Map();cs.forEach(c=>seen.set(c.status,1));
285
+ $("legend").innerHTML=[...seen.keys()].map(s=>`<span class="st d-${ICON[s]}" style="display:inline-grid;vertical-align:-2px"><svg><use href="#s-${ICON[s]}"/></svg></span> ${WORD[s]||s}`).join(" ");}
286
+
287
+ // ---- detail panel
288
+ function open(c){
289
+ openKey=key(c);$("panel").classList.add("open");$("scrim").classList.add("on");$("ptitle").textContent=c.text;render();
290
+ if(c.kind==="idea"){runDoc=null;$("psub").textContent="idea · inbox.md · "+c.where;$("ptabs").innerHTML="";$("pbody").innerHTML=`<p>${esc(c.text)}</p><p style="color:var(--dim)">Run turns this into a plan you approve before any work starts.</p>`;
291
+ const foot=$("pfoot");foot.innerHTML=c.status==="idea"?`<button class="btn pri" data-a="run">Run</button><button class="btn" data-a="edit">Edit</button><button class="btn" data-a="reject">Reject</button><button class="btn ghost danger" data-a="delete">Delete</button>`:`<span style="color:var(--dim);font-size:12px">Starting: a run was launched for this idea.</span>`;
292
+ foot.querySelectorAll("[data-a]").forEach(b=>b.onclick=()=>{close();mode=b.dataset.a;modeKey=openKey;render()});return}
293
+ openRun(c,false)}
294
+ async function openRun(c,refresh){
295
+ if(!refresh||!runDoc||runDoc.id!==c.id){runDoc=await fetch(`/run/${encodeURIComponent(c.id)}?dir=${encodeURIComponent(c.state)}`).then(r=>r.json())}
296
+ if(openKey!==key(c))return;
297
+ $("psub").textContent=c.id+" · "+(WORD[c.status]||c.status)+(c.awaiting?" · "+c.awaiting:"");
298
+ const tabs=[["Request","request"],["Plan","plan"],["Impl","impl"],["Review","review"],["Backlog","backlog"]];
299
+ $("ptabs").innerHTML=tabs.map((t,i)=>`<button class="${i===tab?"on":""}" data-i="${i}">${t[0]}</button>`).join("");
300
+ [...$("ptabs").children].forEach(b=>b.onclick=()=>{tab=+b.dataset.i;openRun(c,true)});
301
+ const k=tabs[tab][1],doc=runDoc[k];
302
+ $("pbody").innerHTML=doc?md(doc):`<p style="color:var(--dim)">No ${({request:"00-request.md",plan:"01-plan.md",impl:"03-impl.md",review:"04-review.md",backlog:"06-backlog.md"})[k]} yet.</p>`;
303
+ const foot=$("pfoot");
304
+ if(c.status==="waiting")foot.innerHTML=`<span style="color:var(--dim);font-size:12px;flex:1">Waiting on <b>${esc(c.awaiting)}</b>. Answer in the terminal running this run.</span><button class="btn ghost" data-a="ab">Abandon</button>`;
305
+ else if(c.status==="done"||c.status==="abandoned")foot.innerHTML="";
306
+ else foot.innerHTML=`<button class="btn ghost" data-a="ab">Abandon run</button>`;
307
+ foot.querySelectorAll("[data-a]").forEach(b=>b.onclick=()=>{close();mode="reject";modeKey=key(c);render()})}
308
+ function close(){openKey=null;runDoc=null;$("panel").classList.remove("open");$("scrim").classList.remove("on");render()}
309
+ $("pclose").onclick=close;$("scrim").onclick=close;
310
+
311
+ // Enough markdown for kaizen's own files: headings, lists, fences, tables,
312
+ // inline code, bold. Everything is escaped first.
313
+ function md(src){
314
+ const lines=src.split("\n"),out=[];let i=0,list=null;
315
+ const inl=s=>esc(s).replace(/`([^`]+)`/g,"<code>$1</code>").replace(/\*\*([^*]+)\*\*/g,"<b>$1</b>");
316
+ const endList=()=>{if(list){out.push(`</${list}>`);list=null}};
317
+ while(i<lines.length){const l=lines[i];
318
+ if(/^```/.test(l)){endList();const buf=[];i++;while(i<lines.length&&!/^```/.test(lines[i]))buf.push(lines[i++]);out.push(`<pre>${esc(buf.join("\n"))}</pre>`);i++;continue}
319
+ const hm=/^(#{1,6})\s+(.*)$/.exec(l);if(hm){endList();out.push(`<h${Math.min(hm[1].length,3)}>${inl(hm[2])}</h${Math.min(hm[1].length,3)}>`);i++;continue}
320
+ if(/^---+$/.test(l.trim())){endList();out.push("<hr>");i++;continue}
321
+ if(/^\|/.test(l)){endList();const rows=[];while(i<lines.length&&/^\|/.test(lines[i]))rows.push(lines[i++]);const cells=r=>r.replace(/^\||\|$/g,"").split("|").map(c=>inl(c.trim()));out.push("<table>"+rows.filter(r=>!/^\|\s*-/.test(r)).map((r,n)=>`<tr>${cells(r).map(c=>n?`<td>${c}</td>`:`<th>${c}</th>`).join("")}</tr>`).join("")+"</table>");continue}
322
+ const li=/^\s*(?:[-*]|\d+\.)\s+(.*)$/.exec(l);if(li){const t=/^\s*\d+\./.test(l)?"ol":"ul";if(list!==t){endList();out.push(`<${t}>`);list=t}out.push(`<li>${inl(li[1])}</li>`);i++;continue}
323
+ if(!l.trim()){endList();i++;continue}
324
+ endList();const buf=[l];i++;while(i<lines.length&&lines[i].trim()&&!/^(#|```|\||\s*[-*]\s|\s*\d+\.\s|---)/.test(lines[i]))buf.push(lines[i++]);out.push(`<p>${inl(buf.join(" "))}</p>`)}
325
+ endList();return out.join("")}
326
+
327
+ // ---- settings, toast, notifications, keys
328
+ function openSettings(){
329
+ openKey=null;runDoc=null;$("panel").classList.add("open");$("scrim").classList.add("on");$("ptitle").textContent="Settings";$("psub").textContent="theme is this browser's; everything else is kaizen settings in a terminal";$("ptabs").innerHTML="";$("pfoot").innerHTML="";
330
+ const cur=document.documentElement.dataset.theme||"system";
331
+ $("pbody").innerHTML=`<div class="set"><label>Theme</label><div class="opts" id="th">${["system","light","dark"].map(t=>`<button class="${t===cur?"on":""}" data-t="${t}">${t}</button>`).join("")}</div>
332
+ <label>Notifications</label><div class="opts" id="nt"><button>${typeof Notification==="undefined"?"unsupported":Notification.permission==="granted"?"on":"ask"}</button></div></div>
333
+ <p style="color:var(--dim);margin-top:20px;max-width:52ch">Agent, runner, approvals and the rest live in <code>config.yml</code>. Run <code>kaizen settings</code> to change them.</p>`;
334
+ $("th").querySelectorAll("button").forEach(b=>b.onclick=()=>{const t=b.dataset.t;if(t==="system")delete document.documentElement.dataset.theme;else document.documentElement.dataset.theme=t;try{t==="system"?localStorage.removeItem("kz-theme"):localStorage.setItem("kz-theme",t)}catch(e){}openSettings()});
335
+ $("nt").querySelector("button").onclick=()=>{askNotify();setTimeout(openSettings,300)}}
336
+ let tt;function toast(s){const t=$("toast");t.textContent=s;t.classList.add("on");clearTimeout(tt);tt=setTimeout(()=>t.classList.remove("on"),4000)}
337
+ function askNotify(){try{if(typeof Notification!=="undefined"&&Notification.permission==="default")Notification.requestPermission()}catch(e){}}
338
+ function notifyUser(title,body){try{if(typeof Notification!=="undefined"&&Notification.permission==="granted")new Notification(title,{body})}catch(e){}}
339
+ $("proj").onchange=e=>{all=e.target.value==="all";load()};
340
+ $("newtop").onclick=()=>{mode="new";render();$("board").scrollTo(0,0)};
341
+ $("settings").onclick=openSettings;
342
+ try{const t=localStorage.getItem("kz-theme");if(t)document.documentElement.dataset.theme=t}catch(e){}
343
+ $("kbd").onclick=()=>$("help").classList.add("on");$("help").onclick=()=>$("help").classList.remove("on");
344
+ document.addEventListener("click",()=>{if(menuKey){menuKey=null;render()}});
345
+ document.onkeydown=e=>{
346
+ if(e.target.matches("input,select"))return;
347
+ if(e.key==="?"){$("help").classList.toggle("on");return}
348
+ if(e.key==="Escape"){$("help").classList.remove("on");if(mode){mode=null;render()}else close();return}
349
+ if(e.key==="n"){mode="new";render()}
350
+ if(e.key==="a"){all=!all;load()}
351
+ const oc=openKey&&S.cards.find(c=>key(c)===openKey);if(!oc)return;
352
+ if(e.key==="e"&&oc.kind==="idea"){close();mode="edit";modeKey=key(oc);render()}
353
+ if(e.key==="x"&&!["done","abandoned","starting"].includes(oc.status)){close();mode="reject";modeKey=key(oc);render()}
354
+ if(e.key==="r"&&oc.kind==="idea"){close();mode="run";modeKey=key(oc);render()}};
355
+
356
+ // ---- live
357
+ function listen(){const es=new EventSource("/events");es.onmessage=ev=>{if(ev.data==="changed")load()};es.onerror=()=>{es.close();setTimeout(listen,3000)}}
358
+ load();listen();
359
+ </script>
360
+ </body>
361
+ </html>