opencode-usage-coach 0.8.2 → 0.8.3

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 (2) hide show
  1. package/dist/tui.js +83 -70
  2. package/package.json +1 -1
package/dist/tui.js CHANGED
@@ -83,8 +83,11 @@ var TLABEL = {
83
83
  completed: "done",
84
84
  failed: "fail",
85
85
  timed_out: "timeout",
86
- halted_quota: "quota-halt"
86
+ halted_quota: "quota-halt",
87
+ stale: "STALE"
87
88
  };
89
+ var STALE_MS = 5 * 6e4;
90
+ var HIDE_MS = 30 * 6e4;
88
91
  function barFill(p) {
89
92
  const n = p <= 0 ? 0 : Math.max(1, Math.min(10, Math.round(p / 10)));
90
93
  return "\u2588".repeat(n);
@@ -365,79 +368,89 @@ function initializeTui(api, disposeRoot) {
365
368
  return _el$46;
366
369
  })());
367
370
  }
368
- if (h && h.tasks.length > 0) {
369
- nodes.push((() => {
370
- var _el$48 = _$createElement("text");
371
- _$insertNode(_el$48, _$createTextNode(` `));
372
- return _el$48;
373
- })());
374
- nodes.push((() => {
375
- var _el$50 = _$createElement("text"), _el$51 = _$createTextNode(`harness: `), _el$52 = _$createTextNode(` `), _el$53 = _$createTextNode(`/`);
376
- _$insertNode(_el$50, _el$51);
377
- _$insertNode(_el$50, _el$52);
378
- _$insertNode(_el$50, _el$53);
379
- _$insert(_el$50, () => h.name, _el$52);
380
- _$insert(_el$50, () => h.current, _el$53);
381
- _$insert(_el$50, () => h.total, null);
382
- _$effect((_$p) => _$setProp(_el$50, "style", st("textMuted"), _$p));
383
- return _el$50;
384
- })());
385
- for (const t of h.tasks) {
386
- const sKey = statusKey[t.status] ?? "text";
387
- const lbl = TLABEL[t.status] ?? t.status;
388
- const rev = t.revisions > 0 && t.status === "revising" ? `(${t.revisions})` : "";
389
- const mdl = t.model ? ` ${t.model.split("/").pop() ?? t.model}` : "";
390
- const hasSub = !!t.subSessionId;
391
- const subStepStr = hasSub && t.subStep !== void 0 && t.subStep > 0 ? ` step:${t.subStep}` : "";
392
- const subEl = hasSub && t.subElapsed !== void 0 ? ` ${t.subElapsed}s` : "";
393
- const subWarn = hasSub && (t.subElapsed ?? 0) > 300;
394
- const elapsed = t.startedAt ? Math.max(0, Math.round((Date.now() - new Date(t.startedAt).getTime()) / 1e3)) : 0;
395
- const taskEl = t.status === "completed" || t.status === "failed" ? "" : elapsed > 0 ? ` ${elapsed}s` : "";
396
- const displayEl = hasSub ? subEl : taskEl;
397
- const lineKey = subWarn ? "warning" : sKey;
371
+ if (h && h.tasks.length > 0 && h.active !== false) {
372
+ const hAge = h.updatedAt ? Date.now() - new Date(h.updatedAt).getTime() : 0;
373
+ const hasActiveSub = h.tasks.some((t) => !!t.subSessionId);
374
+ const isStale = !hasActiveSub && hAge > STALE_MS;
375
+ const shouldHide = hAge > HIDE_MS && !hasActiveSub;
376
+ if (shouldHide) {
377
+ } else {
398
378
  nodes.push((() => {
399
- var _el$54 = _$createElement("text"), _el$55 = _$createTextNode(` \u25CF `), _el$56 = _$createTextNode(` `), _el$57 = _$createTextNode(` `);
400
- _$insertNode(_el$54, _el$55);
401
- _$insertNode(_el$54, _el$56);
402
- _$insertNode(_el$54, _el$57);
403
- _$insert(_el$54, () => t.id, _el$56);
404
- _$insert(_el$54, mdl, _el$56);
405
- _$insert(_el$54, lbl, _el$57);
406
- _$insert(_el$54, rev, _el$57);
407
- _$insert(_el$54, subStepStr, _el$57);
408
- _$insert(_el$54, displayEl, _el$57);
409
- _$insert(_el$54, () => t.title, null);
410
- _$effect((_$p) => _$setProp(_el$54, "style", st(lineKey), _$p));
411
- return _el$54;
379
+ var _el$48 = _$createElement("text");
380
+ _$insertNode(_el$48, _$createTextNode(` `));
381
+ return _el$48;
412
382
  })());
413
- const pv = t.model ? (t.model.split("/")[0] ?? "").split("-")[0] : "";
414
- const provCoach = pv ? s?.providers?.find((p) => p.id === pv || pv && p.id.startsWith(pv) || pv && pv.startsWith(p.id)) : s?.providers?.[0];
415
- const rawPct = provCoach?.fiveHour ?? s?.fiveHour ?? -1;
416
- const pct = rawPct < 0 ? 0 : rawPct;
417
- const pctLabel = rawPct < 0 ? "n/a" : `${rawPct}%`;
418
383
  nodes.push((() => {
419
- var _el$58 = _$createElement("box"), _el$59 = _$createElement("text"), _el$61 = _$createElement("text"), _el$62 = _$createElement("text"), _el$63 = _$createElement("text"), _el$64 = _$createTextNode(` `);
420
- _$insertNode(_el$58, _el$59);
421
- _$insertNode(_el$58, _el$61);
422
- _$insertNode(_el$58, _el$62);
423
- _$insertNode(_el$58, _el$63);
424
- _$setProp(_el$58, "flexDirection", "row");
425
- _$insertNode(_el$59, _$createTextNode(` 5h `));
426
- _$insert(_el$61, () => barFill(pct));
427
- _$insert(_el$62, () => barEmpty(pct));
428
- _$insertNode(_el$63, _el$64);
429
- _$insert(_el$63, pctLabel, null);
430
- _$effect((_p$) => {
431
- var _v$11 = st("text"), _v$12 = st("text");
432
- _v$11 !== _p$.e && (_p$.e = _$setProp(_el$61, "style", _v$11, _p$.e));
433
- _v$12 !== _p$.t && (_p$.t = _$setProp(_el$62, "style", _v$12, _p$.t));
434
- return _p$;
435
- }, {
436
- e: void 0,
437
- t: void 0
438
- });
439
- return _el$58;
384
+ var _el$50 = _$createElement("text"), _el$51 = _$createTextNode(`harness: `), _el$52 = _$createTextNode(` `), _el$53 = _$createTextNode(`/`);
385
+ _$insertNode(_el$50, _el$51);
386
+ _$insertNode(_el$50, _el$52);
387
+ _$insertNode(_el$50, _el$53);
388
+ _$insert(_el$50, () => h.name, _el$52);
389
+ _$insert(_el$50, () => h.current, _el$53);
390
+ _$insert(_el$50, () => h.total, null);
391
+ _$insert(_el$50, isStale ? " (stale)" : "", null);
392
+ _$effect((_$p) => _$setProp(_el$50, "style", st("textMuted"), _$p));
393
+ return _el$50;
440
394
  })());
395
+ for (const t of h.tasks) {
396
+ const TERMINAL = /* @__PURE__ */ new Set(["completed", "failed", "timed_out", "halted_quota"]);
397
+ const displayStatus = isStale && !TERMINAL.has(t.status) ? "stale" : t.status;
398
+ const sKey = statusKey[displayStatus] ?? "text";
399
+ const lbl = TLABEL[displayStatus] ?? displayStatus;
400
+ const rev = t.revisions > 0 && t.status === "revising" ? `(${t.revisions})` : "";
401
+ const mdl = t.model ? ` ${t.model.split("/").pop() ?? t.model}` : "";
402
+ const hasSub = !!t.subSessionId;
403
+ const subStepStr = hasSub && t.subStep !== void 0 && t.subStep > 0 ? ` step:${t.subStep}` : "";
404
+ const subEl = hasSub && t.subElapsed !== void 0 ? ` ${t.subElapsed}s` : "";
405
+ const subWarn = hasSub && (t.subElapsed ?? 0) > 300;
406
+ const elapsed = t.startedAt ? Math.max(0, Math.round((Date.now() - new Date(t.startedAt).getTime()) / 1e3)) : 0;
407
+ const taskEl = t.status === "completed" || t.status === "failed" ? "" : elapsed > 0 ? ` ${elapsed}s` : "";
408
+ const displayEl = hasSub ? subEl : taskEl;
409
+ const lineKey = subWarn ? "warning" : sKey;
410
+ nodes.push((() => {
411
+ var _el$54 = _$createElement("text"), _el$55 = _$createTextNode(` \u25CF `), _el$56 = _$createTextNode(` `), _el$57 = _$createTextNode(` `);
412
+ _$insertNode(_el$54, _el$55);
413
+ _$insertNode(_el$54, _el$56);
414
+ _$insertNode(_el$54, _el$57);
415
+ _$insert(_el$54, () => t.id, _el$56);
416
+ _$insert(_el$54, mdl, _el$56);
417
+ _$insert(_el$54, lbl, _el$57);
418
+ _$insert(_el$54, rev, _el$57);
419
+ _$insert(_el$54, subStepStr, _el$57);
420
+ _$insert(_el$54, displayEl, _el$57);
421
+ _$insert(_el$54, () => t.title, null);
422
+ _$effect((_$p) => _$setProp(_el$54, "style", st(lineKey), _$p));
423
+ return _el$54;
424
+ })());
425
+ const pv = t.model ? (t.model.split("/")[0] ?? "").split("-")[0] : "";
426
+ const provCoach = pv ? s?.providers?.find((p) => p.id === pv || pv && p.id.startsWith(pv) || pv && pv.startsWith(p.id)) : s?.providers?.[0];
427
+ const rawPct = provCoach?.fiveHour ?? s?.fiveHour ?? -1;
428
+ const pct = rawPct < 0 ? 0 : rawPct;
429
+ const pctLabel = rawPct < 0 ? "n/a" : `${rawPct}%`;
430
+ nodes.push((() => {
431
+ var _el$58 = _$createElement("box"), _el$59 = _$createElement("text"), _el$61 = _$createElement("text"), _el$62 = _$createElement("text"), _el$63 = _$createElement("text"), _el$64 = _$createTextNode(` `);
432
+ _$insertNode(_el$58, _el$59);
433
+ _$insertNode(_el$58, _el$61);
434
+ _$insertNode(_el$58, _el$62);
435
+ _$insertNode(_el$58, _el$63);
436
+ _$setProp(_el$58, "flexDirection", "row");
437
+ _$insertNode(_el$59, _$createTextNode(` 5h `));
438
+ _$insert(_el$61, () => barFill(pct));
439
+ _$insert(_el$62, () => barEmpty(pct));
440
+ _$insertNode(_el$63, _el$64);
441
+ _$insert(_el$63, pctLabel, null);
442
+ _$effect((_p$) => {
443
+ var _v$11 = st("text"), _v$12 = st("text");
444
+ _v$11 !== _p$.e && (_p$.e = _$setProp(_el$61, "style", _v$11, _p$.e));
445
+ _v$12 !== _p$.t && (_p$.t = _$setProp(_el$62, "style", _v$12, _p$.t));
446
+ return _p$;
447
+ }, {
448
+ e: void 0,
449
+ t: void 0
450
+ });
451
+ return _el$58;
452
+ })());
453
+ }
441
454
  }
442
455
  }
443
456
  return (() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-usage-coach",
3
- "version": "0.8.2",
3
+ "version": "0.8.3",
4
4
  "description": "opencode closed-loop usage coach — quota SENSE -> coaching DECIDE -> loop ACT + TUI integration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",