kaizen-agent 1.31.2 → 1.32.0
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/cli/web.ts +5 -4
- package/package.json +1 -1
- package/web/board.html +18 -9
package/cli/web.ts
CHANGED
|
@@ -49,10 +49,11 @@ export async function current(url: string) {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
// The newest kaizen on npm, asked at most every six hours; a failed ask is retried
|
|
52
|
-
// on the next one
|
|
52
|
+
// on the next one; fresh (Settings' Check for updates) skips the cache. Same registry
|
|
53
|
+
// call as npmLatest() in install.ts, which exports nothing.
|
|
53
54
|
let latest: { v: string | null; at: number } = { v: null, at: 0 };
|
|
54
|
-
async function npmLatest() {
|
|
55
|
-
if (latest.v && Date.now() - latest.at < 6 * 3600_000) return latest.v;
|
|
55
|
+
async function npmLatest(fresh = false) {
|
|
56
|
+
if (!fresh && latest.v && Date.now() - latest.at < 6 * 3600_000) return latest.v;
|
|
56
57
|
try {
|
|
57
58
|
const r = await fetch("https://registry.npmjs.org/kaizen-agent/latest", { signal: AbortSignal.timeout(10000) });
|
|
58
59
|
const v = ((await r.json()) as { version?: string }).version ?? null;
|
|
@@ -461,7 +462,7 @@ export async function web(repoDir: string, opts: Opts = {}) {
|
|
|
461
462
|
|
|
462
463
|
// What this board runs and what npm has: the page shows an Update button on a newer one.
|
|
463
464
|
if (req.method === "GET" && path === "/version") {
|
|
464
|
-
const v = await npmLatest();
|
|
465
|
+
const v = await npmLatest(url.searchParams.has("fresh"));
|
|
465
466
|
return json({ version: VERSION, latest: v, update: !!v && newer(v, VERSION) });
|
|
466
467
|
}
|
|
467
468
|
|
package/package.json
CHANGED
package/web/board.html
CHANGED
|
@@ -288,6 +288,7 @@ aside .foot .more .menu-pop{left:0;right:auto;top:auto;bottom:calc(100% + 4px)}.
|
|
|
288
288
|
.toast.on{opacity:1}
|
|
289
289
|
.rail a.upd svg{overflow:visible}.rail a.upd{position:relative}.rail a.upd::after{content:"";position:absolute;left:28px;top:8px;width:8px;height:8px;border-radius:50%;background:var(--accent);box-shadow:0 0 0 2px var(--bg)}
|
|
290
290
|
.updbar{display:flex;align-items:center;gap:12px;flex-wrap:wrap;justify-content:space-between;margin:0 0 36px;padding:10px 14px;border:1px solid var(--accent);border-radius:var(--r);background:color-mix(in srgb,var(--accent) 10%,var(--bg-2));font-size:13px}
|
|
291
|
+
.updbar.quiet{border-color:var(--line);background:var(--bg-2);color:var(--dim)}
|
|
291
292
|
.toast.on.rep{pointer-events:auto}.toast a{color:inherit;margin-left:8px;text-decoration:underline;text-underline-offset:2px}
|
|
292
293
|
.help{position:fixed;inset:0;z-index:12;display:none;align-items:center;justify-content:center;background:color-mix(in srgb,var(--bg) 60%,transparent);backdrop-filter:blur(3px)}
|
|
293
294
|
.help.on{display:flex}.help div{background:var(--bg-2);border:1px solid var(--line);border-radius:var(--r);padding:24px 28px;box-shadow:var(--shadow-2)}
|
|
@@ -311,19 +312,20 @@ aside .foot .more .menu-pop{left:0;right:auto;top:auto;bottom:calc(100% + 4px)}.
|
|
|
311
312
|
.ice-list{display:flex;flex-direction:column;gap:1px}
|
|
312
313
|
.ice-list .ice-cat{margin:0;padding:14px 12px 4px;font-size:12px;font-weight:500}.ice-cat i{font-style:normal;font-weight:400;margin-left:6px}.ice-list .ice-cat:first-child{padding-top:4px}
|
|
313
314
|
.ice-row{border-radius:var(--r-s)}.ice-open{border-radius:0 0 var(--r-s) var(--r-s);margin-top:-1px;background:var(--hover)}.ice-row:has(+.ice-open){border-radius:var(--r-s) var(--r-s) 0 0;background:var(--hover)}
|
|
314
|
-
.ice-row{display:grid;grid-template-columns:auto minmax(0,1fr) auto
|
|
315
|
+
.ice-row{display:grid;grid-template-columns:auto auto minmax(0,1fr) auto;align-items:center;gap:10px;min-height:36px;padding:2px 8px 2px 12px;cursor:pointer}
|
|
315
316
|
.ice-row:hover,.ice-row.cur{background:var(--hover)}
|
|
316
317
|
.ice-row.cur{box-shadow:inset 0 0 0 1px var(--line)}
|
|
317
318
|
.ice-row.sel{background:color-mix(in srgb,var(--accent) 8%,transparent)}
|
|
318
319
|
.ice-t{font:inherit;font-size:13px;color:var(--ink);background:none;border:0;padding:6px 0;text-align:left;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
319
320
|
.ice-t[aria-expanded=true]{font-weight:500}
|
|
320
|
-
.ice-src{
|
|
321
|
+
.ice-src{display:inline-flex;align-items:center}
|
|
322
|
+
.ice-meta{display:inline-flex;align-items:center;gap:10px;min-width:0;font-size:11px;color:var(--dim)}.ice-meta .nm{max-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
321
323
|
.ice-age{font-size:11px;color:var(--dim);font-variant-numeric:tabular-nums;white-space:nowrap;min-width:64px;text-align:right}
|
|
322
324
|
.ice-ra{display:none;gap:2px;min-width:64px;justify-content:flex-end}
|
|
323
325
|
.ice-ra .btn{padding:0 6px}
|
|
324
326
|
.ice-row:hover .ice-age,.ice-row.cur .ice-age,.ice-row:focus-within .ice-age{display:none}
|
|
325
327
|
.ice-row:hover .ice-ra,.ice-row.cur .ice-ra,.ice-row:focus-within .ice-ra{display:flex}
|
|
326
|
-
.ice-open{display:grid;gap:8px;padding:6px 12px 12px
|
|
328
|
+
.ice-open{display:grid;gap:8px;padding:6px 12px 12px 61px}
|
|
327
329
|
.ice-zero{padding:40px 16px;text-align:center;border:1px solid var(--line);border-radius:var(--r);background:var(--bg-2)}
|
|
328
330
|
.ice-zero h4{margin:0 0 6px;font-size:14px;font-weight:600;color:var(--ink)}
|
|
329
331
|
.ice-zero p{margin:0;font-size:12px;color:var(--dim);line-height:1.5}
|
|
@@ -335,7 +337,7 @@ body:not(.paged) .src-sec,body:not(.paged) .src-scrim{display:none}
|
|
|
335
337
|
.src-sec .sub a{color:var(--accent);text-decoration:none;cursor:pointer}
|
|
336
338
|
.src-sec .sub a:hover{text-decoration:underline}
|
|
337
339
|
@media(hover:none){.ice-ra{display:flex}.ice-age{display:none}}
|
|
338
|
-
@media(max-width:640px){.ice-
|
|
340
|
+
@media(max-width:640px){.ice-meta .nm{display:none}.ice-open{padding-left:12px}}
|
|
339
341
|
.src-list{display:flex;flex-direction:column;gap:10px}
|
|
340
342
|
.src-card{background:var(--bg-2);border:1px solid var(--line);border-radius:var(--r);padding:14px;box-shadow:var(--shadow-1);display:flex;flex-direction:column;gap:9px;transition:border-color .15s}
|
|
341
343
|
.src-card:hover{border-color:color-mix(in srgb,var(--line) 70%,var(--ink))}
|
|
@@ -1259,7 +1261,7 @@ async function openSources(){
|
|
|
1259
1261
|
if(r.wait)return`<div class="ice-form-acts"><span class="hint">Drafting…</span></div>`;
|
|
1260
1262
|
return`<div class="ice-form"><label for="ice-reply" class="hint" style="margin:0">Your reply${r.note?` · ${esc(r.note)}`:""}</label><textarea class="sel" id="ice-reply" rows="3" maxlength="2000" aria-label="Your reply"${r.busy||r.again?" disabled":""}>${esc(r.text)}</textarea><span class="hint" id="ice-rn" style="margin:0">${r.again?"Writing another…":`${r.text.length} chars`}</span><div class="ice-form-acts"><span class="end"></span>${G.connected?`${style(r.busy||r.again)}<button class="btn ghost sm" id="ice-rg"${r.busy||r.again?" disabled":""}>Regenerate</button>`:""}<button class="btn ghost sm" id="ice-rc"${r.busy?" disabled":""}>Cancel</button><button class="btn pri sm" id="ice-rs"${r.busy||r.again||!r.text.trim()?" disabled":""}>${r.busy?"Sending…":"Send reply"}</button></div></div>`};
|
|
1261
1263
|
const row=i=>{const it=ice[i],k=iceKey(it),open=iceForm===k;
|
|
1262
|
-
return `<div class="ice-row${iceCur===k?" cur":""}${iceSel.has(k)?" sel":""}" data-i="${i}" data-k="${esc(k)}"><input type="checkbox" id="ice-ck-${i}" data-ck="${i}"${iceSel.has(k)?" checked":""} aria-label="Select: ${esc(it.text)}"><button class="ice-t" id="ice-o-${i}" data-o="${i}" aria-expanded="${open}" title="${esc(it.text)}">${esc(it.text)}</button><span class="ice-
|
|
1264
|
+
return `<div class="ice-row${iceCur===k?" cur":""}${iceSel.has(k)?" sel":""}" data-i="${i}" data-k="${esc(k)}"><input type="checkbox" id="ice-ck-${i}" data-ck="${i}"${iceSel.has(k)?" checked":""} aria-label="Select: ${esc(it.text)}"><span class="ice-src" title="${esc(srcName(it))}">${fav(it.source,"link",list.find(x=>x.dir===it.dir&&x.url===it.source)?.social)}</span><button class="ice-t" id="ice-o-${i}" data-o="${i}" aria-expanded="${open}" title="${esc(it.text)}">${esc(it.text)}</button><span class="ice-meta">${many?`<span class="nm">${esc(it.project||"")}</span>`:""}${it.replied?`<span title="Replied ${esc(ago(it.replied))}">replied</span>`:""}<span class="ice-age">${ago(it.at)}</span><span class="ice-ra"><button class="btn ghost sm" id="ice-pr-${i}" data-pr="${i}" title="Promote to Ideas as gathered (p)" aria-label="Promote to Ideas: ${esc(it.text)}">${ico("plus")}</button><button class="btn ghost sm" id="ice-ds-${i}" data-ds="${i}" title="Dismiss (d)" aria-label="Dismiss: ${esc(it.text)}">${ico("x")}</button></span></span></div>`
|
|
1263
1265
|
+(open?`<div class="ice-open">${it.notes?`<div class="ice-notes">${esc(it.notes)}</div>`:""}<span class="hint" style="margin:0">From ${esc(srcName(it))} · ${ago(it.at)}${it.post?` · <a href="${esc(it.post)}" target="_blank" rel="noopener">open post</a>`:""}</span>${replyBox(it)}${form(it)}</div>`:"")};
|
|
1264
1266
|
const inbox=ice.length&&!order.length?`<div class="ice-zero"><h4>Nothing matches</h4><p>${ice.length} waiting outside these filters.</p><p style="margin-top:10px"><button class="btn sm" id="ice-unf">Clear filters</button></p></div>`:ice.length?`<div class="ice-list">${[...groups].map(([g,ix])=>`<div class="ice-cat">${esc(g)}<i>${ix.length}</i></div>${ix.map(row).join("")}`).join("")}</div>`
|
|
1265
1267
|
:`<div class="ice-zero"><h4>Inbox zero</h4><p>Nothing waiting. Gather all checks your sources for new requests; /kaizen discover in your agent sorts what comes in.</p></div>`;
|
|
@@ -1444,10 +1446,17 @@ document.addEventListener("click",e=>{if(!e.target.closest("#showc")){$("showpop
|
|
|
1444
1446
|
$("newtop").onclick=()=>{mode="new";render();$("board").scrollTo(0,0)};
|
|
1445
1447
|
// A newer kaizen on npm: a dot on Settings, and an Update bar at the top of that page.
|
|
1446
1448
|
// The server upgrades and starts a board on the new version, which replaces this one;
|
|
1447
|
-
// the hello with its new boot id reloads the page (listen()).
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
function
|
|
1449
|
+
// the hello with its new boot id reloads the page (listen()). With none known, the bar
|
|
1450
|
+
// is a quiet row whose Check for updates asks npm now instead of the server's 6 h cache.
|
|
1451
|
+
let upd=null,ver=null;
|
|
1452
|
+
function gotVer(v){ver=v;if(!v.update)return false;upd=v;const a=document.querySelector('.rail a[data-view="settings"]');a.classList.add("upd");a.title=`Settings: kaizen ${v.latest} is available`;return true}
|
|
1453
|
+
fetch("/version").then(r=>r.json()).then(v=>{if(gotVer(v)&&view==="settings")openSettings()}).catch(()=>{});
|
|
1454
|
+
function updBar(){if(!upd){const d=document.createElement("div");d.className="updbar quiet";d.innerHTML=`<span id="upd-msg" aria-live="polite">${ver?`You are running kaizen ${esc(ver.version)}.`:"kaizen"}</span><button class="btn" id="upd-chk">Check for updates</button>`;$("pbody").prepend(d);
|
|
1455
|
+
const b=$("upd-chk");b.onclick=async()=>{b.disabled=true;b.textContent="Checking…";const v=await fetch("/version?fresh=1").then(r=>r.json()).catch(()=>null);
|
|
1456
|
+
if(!d.isConnected)return;b.disabled=false;b.textContent="Check for updates";
|
|
1457
|
+
if(v&&gotVer(v)){d.remove();updBar();$("upd-go").focus();return}
|
|
1458
|
+
$("upd-msg").textContent=!v||!v.latest?"Could not reach npm. Try again later.":`kaizen ${v.version} is up to date.`};return}
|
|
1459
|
+
const d=document.createElement("div");d.className="updbar";d.innerHTML=`<span>kaizen <b>${esc(upd.latest)}</b> is available. You are running ${esc(upd.version)}.</span><button class="btn pri" id="upd-go">Update kaizen</button>`;$("pbody").prepend(d);
|
|
1451
1460
|
const b=$("upd-go");b.onclick=async()=>{if(!confirm(`Update kaizen to ${upd.latest}? The board restarts, and agents running inside cards stop.`))return;b.disabled=true;b.textContent="Updating…";
|
|
1452
1461
|
const r=await post("/upgrade",{});if(!r.ok){b.disabled=false;b.textContent="Update kaizen";return}b.textContent="Restarting…";setTimeout(()=>location.reload(),20000)}}
|
|
1453
1462
|
$("kbd").onclick=()=>$("help").classList.add("on");$("help").onclick=()=>$("help").classList.remove("on");
|