@songsid/agend 2.2.0-beta.7 → 2.2.0-beta.9

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 (87) hide show
  1. package/dist/agent-whats-new.js +9 -3
  2. package/dist/agent-whats-new.js.map +1 -1
  3. package/dist/backend/grok.d.ts +1 -0
  4. package/dist/backend/grok.js +5 -0
  5. package/dist/backend/grok.js.map +1 -1
  6. package/dist/backend/kiro.d.ts +24 -0
  7. package/dist/backend/kiro.js +51 -5
  8. package/dist/backend/kiro.js.map +1 -1
  9. package/dist/backend/muse.d.ts +17 -0
  10. package/dist/backend/muse.js +86 -16
  11. package/dist/backend/muse.js.map +1 -1
  12. package/dist/backend/types.d.ts +16 -1
  13. package/dist/backend/types.js.map +1 -1
  14. package/dist/channel/mcp-tools.js +1 -1
  15. package/dist/channel/mcp-tools.js.map +1 -1
  16. package/dist/config-validator.js +3 -0
  17. package/dist/config-validator.js.map +1 -1
  18. package/dist/daemon.d.ts +6 -1
  19. package/dist/daemon.js +12 -4
  20. package/dist/daemon.js.map +1 -1
  21. package/dist/fleet-manager.d.ts +13 -0
  22. package/dist/fleet-manager.js +52 -0
  23. package/dist/fleet-manager.js.map +1 -1
  24. package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +2 -0
  25. package/dist/general-knowledge/skills/worker-collaboration/SKILL.md +1 -1
  26. package/dist/instance-config-impact.js +1 -0
  27. package/dist/instance-config-impact.js.map +1 -1
  28. package/dist/instance-lifecycle.js +3 -1
  29. package/dist/instance-lifecycle.js.map +1 -1
  30. package/dist/kiro-log-gate.d.ts +42 -0
  31. package/dist/kiro-log-gate.js +39 -0
  32. package/dist/kiro-log-gate.js.map +1 -0
  33. package/dist/log-service.d.ts +99 -0
  34. package/dist/log-service.js +235 -0
  35. package/dist/log-service.js.map +1 -0
  36. package/dist/log-steps.d.ts +169 -0
  37. package/dist/log-steps.js +858 -0
  38. package/dist/log-steps.js.map +1 -0
  39. package/dist/public-web-gateway.js +1 -1
  40. package/dist/public-web-gateway.js.map +1 -1
  41. package/dist/public-web-link.js +15 -3
  42. package/dist/public-web-link.js.map +1 -1
  43. package/dist/settings-api.js +4 -0
  44. package/dist/settings-api.js.map +1 -1
  45. package/dist/settings-change.js +2 -0
  46. package/dist/settings-change.js.map +1 -1
  47. package/dist/settings-effect.js +2 -0
  48. package/dist/settings-effect.js.map +1 -1
  49. package/dist/tool-progress.js +3 -2
  50. package/dist/tool-progress.js.map +1 -1
  51. package/dist/transcript-jsonl.d.ts +80 -3
  52. package/dist/transcript-jsonl.js +147 -10
  53. package/dist/transcript-jsonl.js.map +1 -1
  54. package/dist/transcript-monitor.d.ts +11 -0
  55. package/dist/transcript-monitor.js +61 -13
  56. package/dist/transcript-monitor.js.map +1 -1
  57. package/dist/transcript-sources.d.ts +24 -0
  58. package/dist/transcript-sources.js +205 -55
  59. package/dist/transcript-sources.js.map +1 -1
  60. package/dist/types.d.ts +6 -0
  61. package/dist/ui/panel-log.js +428 -0
  62. package/dist/ui/panel-settings.js +6 -1
  63. package/dist/ui/settings-strings.js +2 -0
  64. package/dist/ui/shared/app-i18n.js +2 -2
  65. package/dist/ui/shared/app-route.js +6 -1
  66. package/dist/ui/shared/app-shell.js +3 -3
  67. package/dist/ui/shared/app-stream.js +2 -1
  68. package/dist/ui/shared/app.css +40 -5
  69. package/dist/ui/shared/app.js +5 -0
  70. package/dist/ui/shared/fonts/README.md +1 -1
  71. package/dist/ui/shared/instance-nav.js +9 -6
  72. package/dist/ui/shared/instance-switch.js +4 -4
  73. package/dist/ui/shared/tokens.css +1 -1
  74. package/dist/unrecognised-prompt.js +2 -2
  75. package/dist/unrecognised-prompt.js.map +1 -1
  76. package/dist/web-api.d.ts +3 -0
  77. package/dist/web-api.js +41 -0
  78. package/dist/web-api.js.map +1 -1
  79. package/dist/web-auth.js +2 -1
  80. package/dist/web-auth.js.map +1 -1
  81. package/dist/web-settings-patch.d.ts +3 -1
  82. package/dist/web-settings-patch.js +4 -1
  83. package/dist/web-settings-patch.js.map +1 -1
  84. package/dist/web-shell-routes.d.ts +4 -0
  85. package/dist/web-shell-routes.js +9 -0
  86. package/dist/web-shell-routes.js.map +1 -1
  87. package/package.json +1 -1
@@ -208,7 +208,7 @@ html:has(.shell), html:has(.shell) body { overflow: hidden; }
208
208
  :root { --text-scale: 1; }
209
209
  :root[data-text-size="s"] { --text-scale: 0.9; }
210
210
  :root[data-text-size="l"] { --text-scale: 1.15; }
211
- .thread, .p-details .panel-body, .p-fleet .panel-body {
211
+ .thread, .p-details .panel-body, .p-fleet .panel-body, .p-log .panel-body {
212
212
  --fs-xs: calc(12px * var(--text-scale)); --lh-xs: calc(16px * var(--text-scale));
213
213
  --fs-sm: calc(13px * var(--text-scale)); --lh-sm: calc(18px * var(--text-scale));
214
214
  --fs-md: calc(15px * var(--text-scale)); --lh-md: calc(24px * var(--text-scale));
@@ -217,10 +217,40 @@ html:has(.shell), html:has(.shell) body { overflow: hidden; }
217
217
  }
218
218
  /* #1523 N2: Details. */
219
219
  .p-details .d-tags { display: inline-flex; flex-wrap: wrap; gap: var(--s-1); }
220
+ /* #1218: an instance's Log — one column of steps, newest at the bottom; the filter bar above it. Classes only (#1300). */
221
+ .p-log .log-bar { display: flex; align-items: center; gap: var(--s-1); padding: var(--s-2) var(--s-4); border-bottom: 1px solid var(--border); flex: none; }
222
+ .p-log .log-bar .chip-btn.on { color: var(--text); background: var(--surface-2); font-weight: var(--fw-semibold); }
223
+ .p-log .log-live { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-xs); color: var(--text-3); }
224
+ .p-log .log-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--s-1); }
225
+ .p-log .log-item { padding: var(--s-2) var(--s-3); border-radius: var(--r-md); background: var(--surface); min-width: 0; overflow-wrap: anywhere; }
226
+ .p-log .log-item.turn-start { margin-top: var(--s-4); }
227
+ .p-log .log-item.k-user { background: var(--user-bubble); }
228
+ .p-log .log-item.k-turn_end, .p-log .log-item.k-state, .p-log .log-item.k-event { background: transparent; color: var(--text-3); padding-block: 2px; font-size: var(--fs-sm); }
229
+ .p-log .log-item.k-error, .p-log .log-item.s-failed { border-left: 3px solid var(--danger); }
230
+ .p-log .log-head { display: flex; align-items: baseline; gap: var(--s-2); min-width: 0; }
231
+ .p-log .log-icon { flex: none; }
232
+ .p-log .log-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
233
+ .p-log .log-cat { font-weight: var(--fw-semibold); }
234
+ .p-log .log-subject { font-size: var(--fs-sm); }
235
+ .p-log .log-time { flex: none; font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--text-3); white-space: nowrap; }
236
+ .p-log .log-status { flex: none; font-size: var(--fs-xs); color: var(--text-3); white-space: nowrap; }
237
+ .p-log .log-status.done { color: var(--ok); }
238
+ .p-log .log-status.failed { color: var(--danger); }
239
+ .p-log .log-status.interrupted { color: var(--warn, var(--text-3)); }
240
+ .p-log .log-status .spinner { display: inline-block; width: 8px; height: 8px; margin-right: 4px; border-radius: 50%; background: var(--accent); animation: pulse 1.2s ease-in-out infinite; }
241
+ .p-log .log-repeat { flex: none; font-size: var(--fs-xs); padding: 0 6px; border-radius: 8px; background: var(--surface-2); color: var(--text-2); }
242
+ .p-log .log-text { white-space: pre-wrap; margin-top: var(--s-1); font-size: var(--fs-sm); }
243
+ .p-log .log-text.mono { font-family: var(--font-mono); font-size: var(--fs-xs); }
244
+ .p-log .log-text.folded { max-height: 10.5em; overflow: hidden; mask-image: linear-gradient(to bottom, #000 70%, transparent); -webkit-mask-image: linear-gradient(to bottom, #000 70%, transparent); }
245
+ .p-log .link-btn { border: 0; background: none; padding: 2px 0; color: var(--accent); cursor: pointer; font-size: var(--fs-xs); }
246
+ .p-log .log-detail { margin-top: var(--s-1); display: flex; flex-direction: column; gap: var(--s-2); }
247
+ .p-log .log-sec-h { font-size: var(--fs-xs); color: var(--text-3); text-transform: uppercase; letter-spacing: 0.04em; }
248
+ .p-log .log-older, .p-log .log-start { text-align: center; margin: var(--s-2) 0; }
249
+ .p-log .log-off { padding: var(--s-6) var(--s-4); }
220
250
  .p-details .d-edit { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); flex-wrap: wrap; margin-top: var(--s-2); }
221
251
  @media (max-width: 899px) {
222
252
  .panel-head:has(.inst-switch) { flex-wrap: wrap; }
223
- .inst-switch.seg { order: 3; flex-basis: 100%; display: grid; grid-template-columns: repeat(3, 1fr); padding: 0 0 var(--s-1); }
253
+ .inst-switch.seg { order: 3; flex-basis: 100%; display: grid; grid-template-columns: repeat(4, 1fr); padding: 0 0 var(--s-1); }
224
254
  .inst-switch .seg-item { justify-content: center; border-radius: var(--r-sm); }
225
255
  }
226
256
  .panel-body { flex: 1; min-height: 0; overflow-y: auto; }
@@ -655,11 +685,16 @@ body.side-resizing, body.side-resizing * { cursor: col-resize !important; user-s
655
685
  .v-filter-clear { width: 28px; height: 28px; }
656
686
  .v-filter .note { padding: var(--s-1) var(--s-1) 0; font-variant-numeric: tabular-nums; }
657
687
  /* alpha.2 (N1): status and CLI chips under the filter box — each a group of checkboxes under its header (#1700). */
658
- .nav-facets { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--s-1) var(--s-2); padding: var(--s-2) var(--s-1) 0; }
659
- .nav-facet { font-size: var(--fs-xs); color: var(--text-2); }
688
+ /* #1776: the "N / M" count is on the headers' row, at its right end — not a row of its own. The headers (and an open
689
+ group's list, the reset) wrap in their own box beside it, so a filter's summary or a narrow sidebar moves a header
690
+ down, never the count; the count is as tall as a header, so the row does not grow. */
691
+ .nav-facets { display: flex; align-items: flex-start; gap: var(--s-2); padding: var(--s-2) var(--s-1) 0; }
692
+ .nav-facet-groups { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--s-1) var(--s-2); flex: 1 1 auto; min-width: 0; }
693
+ .nav-facets .nav-shown { flex: none; margin: 0 0 0 auto; padding: 2px 0; white-space: nowrap; }
694
+ .nav-facet { font-size: var(--fs-xs); color: var(--text-2); min-width: 0; max-width: 100%; }
660
695
  /* #1700: a facet group's header — the whole row toggles its list; folded with a filter set, a short summary. */
661
696
  .nav-facet-head { display: inline-flex; align-items: center; gap: var(--s-1); max-width: 100%; padding: 2px var(--s-2); border: 0; border-radius: var(--r-sm);
662
- background: transparent; color: inherit; font: inherit; cursor: pointer; text-align: left; }
697
+ background: transparent; color: inherit; font: inherit; cursor: pointer; text-align: left; white-space: nowrap; }
663
698
  .nav-facet-head:hover { background: var(--hover); }
664
699
  .nav-facet-head:focus-visible { outline: 2px solid var(--accent); }
665
700
  .nav-facet-head .caret { color: var(--text-3); flex: none; }
@@ -51,6 +51,8 @@ if (mode === "full") {
51
51
  stream.on("hydration", (hydration) => appStore.set({ hydration }));
52
52
  appStore.set({ retryHydration: () => stream.catchUp() });
53
53
  stream.on("needs", (d) => appStore.set({ needs: Array.isArray(d && d.items) ? d.items : [] }));
54
+ // #1218: a panel's way to hear one stream event (the Log's steps_tick), unsubscribed by its lease.
55
+ appStore.set({ streamOn: (name, fn) => stream.on(name, fn) });
54
56
  appStore.set({ connection: stream.connection() });
55
57
 
56
58
  // The chat's store must hear every message from the first frame, whatever panel is open: its module boots once,
@@ -67,6 +69,7 @@ if (mode === "full") {
67
69
  const loadSettings = retryable((a) => import(retryUrl("/ui/js/panel-settings.js", a)));
68
70
  const loadNeeds = retryable((a) => import(retryUrl("/ui/js/panel-needs.js", a)));
69
71
  const loadDetails = retryable((a) => import(retryUrl("/ui/js/panel-details.js", a)));
72
+ const loadLog = retryable((a) => import(retryUrl("/ui/js/panel-log.js", a)));
70
73
  // The stream opens once the chat listens, so the frames sent on connect (status, open prompts, ticks) reach it too.
71
74
  // If the chat cannot load (a session that just ended), the stream still opens for the sidebar.
72
75
  const chatBoot = loadChat();
@@ -80,6 +83,8 @@ if (mode === "full") {
80
83
  panels.set("needs", { load: () => loadNeeds().then((m) => m.NeedsPanel) });
81
84
  // #1523 N2: one instance's Details (/ui/fleet/agent/<name>).
82
85
  panels.set("details", { load: () => loadDetails().then((m) => m.DetailsPanel) });
86
+ // #1218: one instance's Log (/ui/log/<name>).
87
+ panels.set("log", { load: () => loadLog().then((m) => m.LogPanel) });
83
88
  // #1386 §6.3: desktop notifications for new "Needs you" items, in any panel, while this signed-in page is open.
84
89
  startNeedsNotifier({ open: (instance) => navigate(chatPath(instance)) });
85
90
  // #1665: this device's first upload of its own choices (once), then another device's changes at each status frame.
@@ -8,7 +8,7 @@
8
8
  - The optical-size axis is fixed at its text size (`opsz=14`).
9
9
  - The font is subset to Latin, with the same range as `unicode-range` in `tokens.css`.
10
10
  - It is saved as WOFF2. About 44 KB, against 352 KB for the full variable font.
11
- - Chinese and other scripts fall back to the system fonts named in `--font-ui` (PingFang TC → Noto Sans TC → Microsoft JhengHei → the system stack).
11
+ - Chinese and other scripts fall back to the system fonts named in `--font-ui` (PingFang TC → PingFang SC → Noto Sans TC → Noto Sans SC → Noto Sans CJK TC → Noto Sans CJK SC → Microsoft JhengHei → Microsoft YaHei → the system stack).
12
12
 
13
13
  Rebuilt with fontTools 4.59 (and `brotli` for WOFF2):
14
14
 
@@ -10,7 +10,7 @@
10
10
  import { html, useLayoutEffect, useRef, useState } from "./app-html.js";
11
11
  import { t } from "./app-i18n.js";
12
12
  import { appStore, createStore, useStore } from "./app-store.js";
13
- import { chatPath, detailsPath, viewPath } from "./app-route.js";
13
+ import { chatPath, detailsPath, logPath, viewPath } from "./app-route.js";
14
14
  import { Icon } from "./ui-icons.js";
15
15
  import { Skeleton } from "./ui-states.js";
16
16
  import { viewStore } from "./view-roster-store.js";
@@ -353,8 +353,9 @@ export function InstanceNav({ route, items, loaded = true, exec = {}, awaiting =
353
353
  // Where a row goes: the view the page is in (#1523 §3.1). View → View; Details, or a Fleet tab (Q4 = A), → Details;
354
354
  // everywhere else → Chat. The anonymous reader only ever has View.
355
355
  const rowPath = viewOnly || (route && route.panel === "view") ? viewPath
356
+ : route && route.panel === "log" ? logPath // #1218: Log → Log
356
357
  : route && (route.panel === "details" || route.panel === "fleet") ? detailsPath : chatPath;
357
- const active = route && (route.panel === "chat" || route.panel === "view" || route.panel === "details") ? route.instance : null;
358
+ const active = route && (route.panel === "chat" || route.panel === "view" || route.panel === "log" || route.panel === "details") ? route.instance : null;
358
359
  useLayoutEffect(() => { keepActiveInView(list.current); }, [active, items.length, loaded]);
359
360
  const own = (map, name) => Object.prototype.hasOwnProperty.call(map, name);
360
361
  const byName = new Map(items.map((it) => [nameOf(it), it]));
@@ -478,11 +479,13 @@ export function InstanceNav({ route, items, loaded = true, exec = {}, awaiting =
478
479
  onClick=${() => { setNavFilter({ q: "" }); filterRef.current && filterRef.current.focus(); }}><${Icon} name="close" size=${14} /></button>` : null}
479
480
  </label>
480
481
  <div class="nav-facets">
481
- ${viewOnly ? null : chips("status", STATUS_FACETS, tn("filterStatus"), statusText)}
482
- ${backends.length > 1 || f.cli.length ? chips("cli", backends, tn("filterCli"), backendLabel) : null}
483
- ${f.status.length || f.cli.length ? html`<button type="button" class="chip-btn nav-facet-reset" onClick=${() => setNavFilter({ status: [], cli: [] })}>${tn("filterFacetsReset")}</button>` : null}
482
+ <div class="nav-facet-groups">
483
+ ${viewOnly ? null : chips("status", STATUS_FACETS, tn("filterStatus"), statusText)}
484
+ ${backends.length > 1 || f.cli.length ? chips("cli", backends, tn("filterCli"), backendLabel) : null}
485
+ ${f.status.length || f.cli.length ? html`<button type="button" class="chip-btn nav-facet-reset" onClick=${() => setNavFilter({ status: [], cli: [] })}>${tn("filterFacetsReset")}</button>` : null}
486
+ </div>
487
+ <p class="note nav-shown" aria-live="polite">${shown.shown} / ${shown.total}${shown.active ? ` ${tn("filterShown")}` : ""}</p>
484
488
  </div>
485
- <p class="note" aria-live="polite">${shown.shown} / ${shown.total}${shown.active ? ` ${tn("filterShown")}` : ""}</p>
486
489
  </div>
487
490
  </div>`;
488
491
  }
@@ -1,16 +1,16 @@
1
1
  // #1523 N2 (§3.2): the instance view switch — Chat | View | Details of ONE instance. Each segment is a link to that
2
2
  // view's URL for the same instance, so switching keeps the instance (and the sidebar, which is never remounted).
3
- // Desktop: links in the header; a phone: the same three as top tabs under it (app.css). The anonymous View reader
3
+ // Desktop: links in the header; a phone: the same four as top tabs under it (app.css). The anonymous View reader
4
4
  // gets none (Chat and Details need a session): the caller does not render it there.
5
5
  import { html } from "./app-html.js";
6
6
  import { t } from "./app-i18n.js";
7
- import { chatPath, detailsPath, viewPath } from "./app-route.js";
7
+ import { chatPath, detailsPath, logPath, viewPath } from "./app-route.js";
8
8
 
9
- /** current: "chat" | "view" | "details". */
9
+ /** current: "chat" | "view" | "log" | "details". #1218: Log sits between View and Details. */
10
10
  export function InstanceSwitch({ name, current }) {
11
11
  const seg = (key, href, label) => html`<a key=${key} class=${`seg-item${current === key ? " active" : ""}`} href=${href}
12
12
  aria-current=${current === key ? "page" : undefined}>${label}</a>`;
13
13
  return html`<nav class="inst-switch seg" aria-label=${t("app.instanceViews", name)}>
14
- ${seg("chat", chatPath(name), t("app.chat"))}${seg("view", viewPath(name), t("app.view"))}${seg("details", detailsPath(name), t("app.details"))}
14
+ ${seg("chat", chatPath(name), t("app.chat"))}${seg("view", viewPath(name), t("app.view"))}${seg("log", logPath(name), t("app.log"))}${seg("details", detailsPath(name), t("app.details"))}
15
15
  </nav>`;
16
16
  }
@@ -22,7 +22,7 @@
22
22
 
23
23
  :root {
24
24
  /* ── Type ── */
25
- --font-ui: Inter, "PingFang TC", "Noto Sans TC", "Microsoft JhengHei", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
25
+ --font-ui: Inter, "PingFang TC", "PingFang SC", "Noto Sans TC", "Noto Sans SC", "Noto Sans CJK TC", "Noto Sans CJK SC", "Microsoft JhengHei", "Microsoft YaHei", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
26
26
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
27
27
  --fs-xs: 12px; --lh-xs: 16px;
28
28
  --fs-sm: 13px; --lh-sm: 18px;
@@ -13,8 +13,8 @@ const FOOTER_ROWS = 3;
13
13
  /** How far above the first option the question is looked for. */
14
14
  const QUESTION_ROWS = 8;
15
15
  export const QUESTION_MAX = 80;
16
- const CURSOR_OPTION = /^[ \t]*[❯›>][ \t]*(\d{1,2})[.)][ \t]+\S/;
17
- const OPTION = /^[ \t]*(?:[❯›>][ \t]*)?(\d{1,2})[.)][ \t]+\S/;
16
+ const CURSOR_OPTION = /^[ \t]*[❯›⟩>][ \t]*(\d{1,2})[.)][ \t]+\S/;
17
+ const OPTION = /^[ \t]*(?:[❯›⟩>][ \t]*)?(\d{1,2})[.)][ \t]+\S/;
18
18
  const YES_NO = /[[(][ \t]*[yY][ \t]*\/[ \t]*[nN][ \t]*[\])][ \t]*[:?]?[ \t]*$/;
19
19
  /** A rule or border row (box drawing, block elements, dashes): the top of a dialog. */
20
20
  const RULE = /^[ \t]*[─━═╌┄▔▁_\-=]{8,}[ \t]*$/;
@@ -1 +1 @@
1
- {"version":3,"file":"unrecognised-prompt.js","sourceRoot":"","sources":["../src/unrecognised-prompt.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"unrecognised-prompt.js","sourceRoot":"","sources":["../src/unrecognised-prompt.ts"],"names":[],"mappings":"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"}
package/dist/web-api.d.ts CHANGED
@@ -148,6 +148,8 @@ export interface WebApiContext {
148
148
  needsYouItems?(): unknown[];
149
149
  /** #1389: the org chart's structure (fleet.yaml's teams, General, descriptions, thread links); absent: an empty chart. */
150
150
  orgChart?(): unknown;
151
+ /** #1218: an instance's Log steps, read on demand (null: no such instance; `{ enabled: false }`: the Log is off). */
152
+ logSteps?(name: string, q: import("./log-service.js").LogQuery): Promise<unknown>;
151
153
  /** #1468: the prompt-cache expiry analysis for a window ("24h" | "7d" | "30d"); absent: not offered. */
152
154
  cacheReport?(window: string): Promise<unknown>;
153
155
  /** #1269: an instance's chat command from the web chat (web-commands.ts); absent: not offered. */
@@ -253,6 +255,7 @@ export interface AppShellContext {
253
255
  readonly fleetConfig?: {
254
256
  web?: {
255
257
  usage_panel?: boolean;
258
+ log_tab?: boolean;
256
259
  };
257
260
  } | null;
258
261
  /** #1665: the host's theme and language go into the page itself, so a device paints them before any script reads. */
package/dist/web-api.js CHANGED
@@ -347,6 +347,45 @@ export function handleWebRequest(req, res, url, ctx) {
347
347
  json(res, 200, { messages: ctx.webChatHistory?.list(instance, limit) ?? [], boot: ctx.webChatHistory?.boot ?? null, lastId: ctx.webChatHistory?.lastId ?? 0 });
348
348
  return true;
349
349
  }
350
+ // ── #1218: the Log tab ─────────────────────────────────
351
+ // An instance's steps, read on demand from its own transcript (log-service.ts). Read-only, and offered on the public
352
+ // link on purpose (the user's decision): the same masking applies to every viewer. Passive (web-auth.ts).
353
+ if (method === "GET" && path === "/ui/steps") {
354
+ const p = url.searchParams;
355
+ const instance = p.get("instance") ?? "";
356
+ const num = (k) => {
357
+ const v = p.get(k);
358
+ if (v === null)
359
+ return undefined;
360
+ const n = Number(v);
361
+ return /^\d{1,15}$/.test(v) && Number.isSafeInteger(n) ? n : null;
362
+ };
363
+ const after = num("after"), before = num("before"), ev = num("ev"), limit = num("limit");
364
+ const key = p.get("key");
365
+ if (!instance || instance.length > 128 || after === null || before === null || ev === null || limit === null
366
+ || (limit !== undefined && (limit < 1 || limit > 200)) || (key !== null && !/^\d{1,20}-\d{1,20}$/.test(key))) {
367
+ json(res, 400, { error: "instance (1-128 chars); after, before, ev: offsets; limit 1-200; key: <dev>-<ino>" });
368
+ return true;
369
+ }
370
+ if (!ctx.logSteps) {
371
+ json(res, 404, { error: "not available" });
372
+ return true;
373
+ }
374
+ ctx.logSteps(instance, {
375
+ ...(after !== undefined ? { after } : {}), ...(before !== undefined ? { before } : {}), ...(ev !== undefined ? { ev } : {}),
376
+ ...(limit !== undefined ? { limit } : {}), ...(key !== null ? { key } : {}),
377
+ skip: p.get("skip") === "1", watch: p.get("watch") === "1",
378
+ }).then(answer => {
379
+ if (answer === null)
380
+ json(res, 404, { error: `Instance not found: ${instance}` });
381
+ else
382
+ json(res, 200, answer);
383
+ }).catch(err => {
384
+ ctx.logger.error({ err: err.message, instance }, "Log steps read failed");
385
+ json(res, 500, { error: "could not read the steps" });
386
+ });
387
+ return true;
388
+ }
350
389
  // ── Send message ───────────────────────────────────────
351
390
  if (method === "POST" && path === "/ui/send") {
352
391
  handleSendMessage(req, res, ctx);
@@ -1612,6 +1651,8 @@ function shellBodyTag(req, ctx, mode) {
1612
1651
  + `${p?.detail ? ` data-preview-detail="${attr(p.detail)}"` : ""}`
1613
1652
  // #1523 N3: whether the fleet serves /api/ai-usage (web.usage_panel), for every page's ◔.
1614
1653
  + ` data-usage-panel="${ctx.fleetConfig?.web?.usage_panel === false ? "0" : "1"}"`
1654
+ // #1218: whether the Log tab is on (web.log_tab; off by default): the tab says so and offers to turn it on.
1655
+ + ` data-log-tab="${ctx.fleetConfig?.web?.log_tab === true ? "1" : "0"}"`
1615
1656
  // #1770: the fleet's zone (chat-logs' and fleet.log's), in which the chat reads its message times and days.
1616
1657
  + ` data-fleet-tz="${attr(resolveTz())}"`
1617
1658
  // #1589: the public link shows attachments as downloads only (no inline text or media): its scope is unchanged.